Merge pull request #3023 from alexcrichton/refactor-instance

Simplify the list of builtin intrinsics Wasmtime needs
This commit is contained in:
Nick Fitzgerald
2021-06-23 11:21:09 -07:00
committed by GitHub
5 changed files with 95 additions and 352 deletions

View File

@@ -184,52 +184,6 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
})
}
/// Return the memory.grow function signature to call for the given index, along with the
/// translated index value to pass to it and its index in `VMBuiltinFunctionsArray`.
fn get_memory_grow_func(
&mut self,
func: &mut Function,
index: MemoryIndex,
) -> (ir::SigRef, usize, BuiltinFunctionIndex) {
if self.module.is_imported_memory(index) {
(
self.builtin_function_signatures
.imported_memory32_grow(func),
index.index(),
BuiltinFunctionIndex::imported_memory32_grow(),
)
} else {
(
self.builtin_function_signatures.memory32_grow(func),
self.module.defined_memory_index(index).unwrap().index(),
BuiltinFunctionIndex::memory32_grow(),
)
}
}
/// Return the memory.size function signature to call for the given index, along with the
/// translated index value to pass to it and its index in `VMBuiltinFunctionsArray`.
fn get_memory_size_func(
&mut self,
func: &mut Function,
index: MemoryIndex,
) -> (ir::SigRef, usize, BuiltinFunctionIndex) {
if self.module.is_imported_memory(index) {
(
self.builtin_function_signatures
.imported_memory32_size(func),
index.index(),
BuiltinFunctionIndex::imported_memory32_size(),
)
} else {
(
self.builtin_function_signatures.memory32_size(func),
self.module.defined_memory_index(index).unwrap().index(),
BuiltinFunctionIndex::memory32_size(),
)
}
}
fn get_table_copy_func(
&mut self,
func: &mut Function,
@@ -260,47 +214,6 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
(sig, BuiltinFunctionIndex::elem_drop())
}
fn get_memory_fill_func(
&mut self,
func: &mut Function,
memory_index: MemoryIndex,
) -> (ir::SigRef, usize, BuiltinFunctionIndex) {
if let Some(defined_memory_index) = self.module.defined_memory_index(memory_index) {
(
self.builtin_function_signatures.memory_fill(func),
defined_memory_index.index(),
BuiltinFunctionIndex::memory_fill(),
)
} else {
(
self.builtin_function_signatures.imported_memory_fill(func),
memory_index.index(),
BuiltinFunctionIndex::imported_memory_fill(),
)
}
}
fn get_memory_atomic_notify(
&mut self,
func: &mut Function,
memory_index: MemoryIndex,
) -> (ir::SigRef, usize, BuiltinFunctionIndex) {
if let Some(defined_memory_index) = self.module.defined_memory_index(memory_index) {
(
self.builtin_function_signatures.memory_atomic_notify(func),
defined_memory_index.index(),
BuiltinFunctionIndex::memory_atomic_notify(),
)
} else {
(
self.builtin_function_signatures
.imported_memory_atomic_notify(func),
memory_index.index(),
BuiltinFunctionIndex::imported_memory_atomic_notify(),
)
}
}
fn get_memory_atomic_wait(
&mut self,
func: &mut Function,
@@ -308,38 +221,16 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
ty: ir::Type,
) -> (ir::SigRef, usize, BuiltinFunctionIndex) {
match ty {
I32 => {
if let Some(defined_memory_index) = self.module.defined_memory_index(memory_index) {
(
I32 => (
self.builtin_function_signatures.memory_atomic_wait32(func),
defined_memory_index.index(),
memory_index.index(),
BuiltinFunctionIndex::memory_atomic_wait32(),
)
} else {
(
self.builtin_function_signatures
.imported_memory_atomic_wait32(func),
memory_index.index(),
BuiltinFunctionIndex::imported_memory_atomic_wait32(),
)
}
}
I64 => {
if let Some(defined_memory_index) = self.module.defined_memory_index(memory_index) {
(
),
I64 => (
self.builtin_function_signatures.memory_atomic_wait64(func),
defined_memory_index.index(),
BuiltinFunctionIndex::memory_atomic_wait64(),
)
} else {
(
self.builtin_function_signatures
.imported_memory_atomic_wait64(func),
memory_index.index(),
BuiltinFunctionIndex::imported_memory_atomic_wait64(),
)
}
}
BuiltinFunctionIndex::memory_atomic_wait64(),
),
x => panic!("get_memory_atomic_wait unsupported type: {:?}", x),
}
}
@@ -1494,9 +1385,16 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
_heap: ir::Heap,
val: ir::Value,
) -> WasmResult<ir::Value> {
let (func_sig, index_arg, func_idx) = self.get_memory_grow_func(&mut pos.func, index);
let func_sig = self
.builtin_function_signatures
.memory32_grow(&mut pos.func);
let index_arg = index.index();
let memory_index = pos.ins().iconst(I32, index_arg as i64);
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
let (vmctx, func_addr) = self.translate_load_builtin_function_address(
&mut pos,
BuiltinFunctionIndex::memory32_grow(),
);
let call_inst = pos
.ins()
.call_indirect(func_sig, func_addr, &[vmctx, val, memory_index]);
@@ -1509,13 +1407,35 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
index: MemoryIndex,
_heap: ir::Heap,
) -> WasmResult<ir::Value> {
let (func_sig, index_arg, func_idx) = self.get_memory_size_func(&mut pos.func, index);
let memory_index = pos.ins().iconst(I32, index_arg as i64);
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
let call_inst = pos
let pointer_type = self.pointer_type();
let vmctx = self.vmctx(&mut pos.func);
let base = pos.ins().global_value(pointer_type, vmctx);
let current_length_in_bytes = match self.module.defined_memory_index(index) {
Some(def_index) => {
let offset = i32::try_from(
self.offsets
.vmctx_vmmemory_definition_current_length(def_index),
)
.unwrap();
pos.ins().load(I32, ir::MemFlags::trusted(), base, offset)
}
None => {
let offset = i32::try_from(self.offsets.vmctx_vmmemory_import_from(index)).unwrap();
let vmmemory_ptr =
pos.ins()
.load(pointer_type, ir::MemFlags::trusted(), base, offset);
pos.ins().load(
I32,
ir::MemFlags::trusted(),
vmmemory_ptr,
i32::from(self.offsets.vmmemory_definition_current_length()),
)
}
};
let current_length_in_pages = pos
.ins()
.call_indirect(func_sig, func_addr, &[vmctx, memory_index]);
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
.udiv_imm(current_length_in_bytes, i64::from(WASM_PAGE_SIZE));
Ok(current_length_in_pages)
}
fn translate_memory_copy(
@@ -1554,12 +1474,13 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
val: ir::Value,
len: ir::Value,
) -> WasmResult<()> {
let (func_sig, memory_index, func_idx) =
self.get_memory_fill_func(&mut pos.func, memory_index);
let func_sig = self.builtin_function_signatures.memory_fill(&mut pos.func);
let memory_index = memory_index.index();
let memory_index_arg = pos.ins().iconst(I32, memory_index as i64);
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
let (vmctx, func_addr) = self
.translate_load_builtin_function_address(&mut pos, BuiltinFunctionIndex::memory_fill());
pos.ins().call_indirect(
func_sig,
@@ -1724,12 +1645,16 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
addr: ir::Value,
count: ir::Value,
) -> WasmResult<ir::Value> {
let (func_sig, memory_index, func_idx) =
self.get_memory_atomic_notify(&mut pos.func, memory_index);
let func_sig = self
.builtin_function_signatures
.memory_atomic_notify(&mut pos.func);
let memory_index_arg = pos.ins().iconst(I32, memory_index as i64);
let memory_index_arg = pos.ins().iconst(I32, memory_index.index() as i64);
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
let (vmctx, func_addr) = self.translate_load_builtin_function_address(
&mut pos,
BuiltinFunctionIndex::memory_atomic_notify(),
);
let call_inst =
pos.ins()

View File

@@ -5,12 +5,6 @@ macro_rules! foreach_builtin_function {
$mac! {
/// Returns an index for wasm's `memory.grow` builtin function.
memory32_grow(vmctx, i32, i32) -> (i32);
/// Returns an index for wasm's imported `memory.grow` builtin function.
imported_memory32_grow(vmctx, i32, i32) -> (i32);
/// Returns an index for wasm's `memory.size` builtin function.
memory32_size(vmctx, i32) -> (i32);
/// Returns an index for wasm's imported `memory.size` builtin function.
imported_memory32_size(vmctx, i32) -> (i32);
/// Returns an index for wasm's `table.copy` when both tables are locally
/// defined.
table_copy(vmctx, i32, i32, i32, i32, i32) -> ();
@@ -20,10 +14,8 @@ macro_rules! foreach_builtin_function {
elem_drop(vmctx, i32) -> ();
/// Returns an index for wasm's `memory.copy`
memory_copy(vmctx, i32, i32, i32, i32, i32) -> ();
/// Returns an index for wasm's `memory.fill` for locally defined memories.
/// Returns an index for wasm's `memory.fill` instruction.
memory_fill(vmctx, i32, i32, i32, i32) -> ();
/// Returns an index for wasm's `memory.fill` for imported memories.
imported_memory_fill(vmctx, i32, i32, i32, i32) -> ();
/// Returns an index for wasm's `memory.init` instruction.
memory_init(vmctx, i32, i32, i32, i32, i32) -> ();
/// Returns an index for wasm's `data.drop` instruction.
@@ -45,18 +37,12 @@ macro_rules! foreach_builtin_function {
externref_global_get(vmctx, i32) -> (reference);
/// Returns an index for Wasm's `global.get` instruction for `externref`s.
externref_global_set(vmctx, i32, reference) -> ();
/// Returns an index for wasm's `memory.atomic.notify` for locally defined memories.
/// Returns an index for wasm's `memory.atomic.notify` instruction.
memory_atomic_notify(vmctx, i32, i32, i32) -> (i32);
/// Returns an index for wasm's `memory.atomic.notify` for imported memories.
imported_memory_atomic_notify(vmctx, i32, i32, i32) -> (i32);
/// Returns an index for wasm's `memory.atomic.wait32` for locally defined memories.
/// Returns an index for wasm's `memory.atomic.wait32` instruction.
memory_atomic_wait32(vmctx, i32, i32, i32, i64) -> (i32);
/// Returns an index for wasm's `memory.atomic.wait32` for imported memories.
imported_memory_atomic_wait32(vmctx, i32, i32, i32, i64) -> (i32);
/// Returns an index for wasm's `memory.atomic.wait64` for locally defined memories.
/// Returns an index for wasm's `memory.atomic.wait64` instruction.
memory_atomic_wait64(vmctx, i32, i32, i64, i64) -> (i32);
/// Returns an index for wasm's `memory.atomic.wait64` for imported memories.
imported_memory_atomic_wait64(vmctx, i32, i32, i64, i64) -> (i32);
/// Invoked when fuel has run out while executing a function.
out_of_gas(vmctx) -> ();
}

View File

@@ -386,68 +386,31 @@ impl Instance {
///
/// Returns `None` if memory can't be grown by the specified amount
/// of pages.
pub(crate) fn memory_grow(
&mut self,
memory_index: DefinedMemoryIndex,
delta: u32,
) -> Option<u32> {
let limiter = unsafe { (*self.store()).limiter() };
let memory = self
.memories
.get_mut(memory_index)
.unwrap_or_else(|| panic!("no memory for index {}", memory_index.index()));
pub(crate) fn memory_grow(&mut self, index: MemoryIndex, delta: u32) -> Option<u32> {
let (idx, instance) = if let Some(idx) = self.module.defined_memory_index(index) {
(idx, self)
} else {
let import = self.imported_memory(index);
unsafe {
let foreign_instance = (*import.vmctx).instance_mut();
let foreign_memory_def = &*import.from;
let foreign_memory_index = foreign_instance.memory_index(foreign_memory_def);
(foreign_memory_index, foreign_instance)
}
};
let limiter = unsafe { (*instance.store()).limiter() };
let memory = &mut instance.memories[idx];
let result = unsafe { memory.grow(delta, limiter) };
let vmmemory = memory.vmmemory();
// Keep current the VMContext pointers used by compiled wasm code.
self.set_memory(memory_index, self.memories[memory_index].vmmemory());
// Update the state used by wasm code in case the base pointer and/or
// the length changed.
instance.set_memory(idx, vmmemory);
result
}
/// Grow imported memory by the specified amount of pages.
///
/// Returns `None` if memory can't be grown by the specified amount
/// of pages.
///
/// # Safety
/// This and `imported_memory_size` are currently unsafe because they
/// dereference the memory import's pointers.
pub(crate) unsafe fn imported_memory_grow(
&mut self,
memory_index: MemoryIndex,
delta: u32,
) -> Option<u32> {
let import = self.imported_memory(memory_index);
let foreign_instance = (*import.vmctx).instance_mut();
let foreign_memory = &*import.from;
let foreign_index = foreign_instance.memory_index(foreign_memory);
foreign_instance.memory_grow(foreign_index, delta)
}
/// Returns the number of allocated wasm pages.
pub(crate) fn memory_size(&self, memory_index: DefinedMemoryIndex) -> u32 {
self.memories
.get(memory_index)
.unwrap_or_else(|| panic!("no memory for index {}", memory_index.index()))
.size()
}
/// Returns the number of allocated wasm pages in an imported memory.
///
/// # Safety
/// This and `imported_memory_grow` are currently unsafe because they
/// dereference the memory import's pointers.
pub(crate) unsafe fn imported_memory_size(&self, memory_index: MemoryIndex) -> u32 {
let import = self.imported_memory(memory_index);
let foreign_instance = (&mut *import.vmctx).instance();
let foreign_memory = &mut *import.from;
let foreign_index = foreign_instance.memory_index(foreign_memory);
foreign_instance.memory_size(foreign_index)
}
pub(crate) fn table_element_type(&mut self, table_index: TableIndex) -> TableElementType {
unsafe { (*self.get_table(table_index)).element_type() }
}
@@ -671,14 +634,14 @@ impl Instance {
/// # Errors
///
/// Returns a `Trap` error if the memory range is out of bounds.
pub(crate) fn defined_memory_fill(
&self,
memory_index: DefinedMemoryIndex,
pub(crate) fn memory_fill(
&mut self,
memory_index: MemoryIndex,
dst: u32,
val: u32,
len: u32,
) -> Result<(), Trap> {
let memory = self.memory(memory_index);
let memory = self.get_memory(memory_index);
if dst
.checked_add(len)
@@ -700,27 +663,6 @@ impl Instance {
Ok(())
}
/// Perform the `memory.fill` operation on an imported memory.
///
/// # Errors
///
/// Returns a `Trap` error if the memory range is out of bounds.
pub(crate) fn imported_memory_fill(
&self,
memory_index: MemoryIndex,
dst: u32,
val: u32,
len: u32,
) -> Result<(), Trap> {
let import = self.imported_memory(memory_index);
unsafe {
let foreign_instance = (&*import.vmctx).instance();
let foreign_memory = &*import.from;
let foreign_index = foreign_instance.memory_index(foreign_memory);
foreign_instance.defined_memory_fill(foreign_index, dst, val, len)
}
}
/// Performs the `memory.init` operation.
///
/// # Errors

View File

@@ -63,8 +63,7 @@ use crate::vmcontext::{VMCallerCheckedAnyfunc, VMContext};
use std::mem;
use std::ptr::{self, NonNull};
use wasmtime_environ::wasm::{
DataIndex, DefinedMemoryIndex, ElemIndex, GlobalIndex, MemoryIndex, TableElementType,
TableIndex,
DataIndex, ElemIndex, GlobalIndex, MemoryIndex, TableElementType, TableIndex,
};
const TOINT_32: f32 = 1.0 / f32::EPSILON;
@@ -192,46 +191,12 @@ pub unsafe extern "C" fn wasmtime_memory32_grow(
memory_index: u32,
) -> u32 {
let instance = (*vmctx).instance_mut();
let memory_index = DefinedMemoryIndex::from_u32(memory_index);
let memory_index = MemoryIndex::from_u32(memory_index);
instance
.memory_grow(memory_index, delta)
.unwrap_or(u32::max_value())
}
/// Implementation of memory.grow for imported 32-bit memories.
pub unsafe extern "C" fn wasmtime_imported_memory32_grow(
vmctx: *mut VMContext,
delta: u32,
memory_index: u32,
) -> u32 {
let instance = (*vmctx).instance_mut();
let memory_index = MemoryIndex::from_u32(memory_index);
instance
.imported_memory_grow(memory_index, delta)
.unwrap_or(u32::max_value())
}
/// Implementation of memory.size for locally-defined 32-bit memories.
pub unsafe extern "C" fn wasmtime_memory32_size(vmctx: *mut VMContext, memory_index: u32) -> u32 {
let instance = (*vmctx).instance();
let memory_index = DefinedMemoryIndex::from_u32(memory_index);
instance.memory_size(memory_index)
}
/// Implementation of memory.size for imported 32-bit memories.
pub unsafe extern "C" fn wasmtime_imported_memory32_size(
vmctx: *mut VMContext,
memory_index: u32,
) -> u32 {
let instance = (*vmctx).instance();
let memory_index = MemoryIndex::from_u32(memory_index);
instance.imported_memory_size(memory_index)
}
/// Implementation of `table.grow`.
pub unsafe extern "C" fn wasmtime_table_grow(
vmctx: *mut VMContext,
@@ -243,13 +208,8 @@ pub unsafe extern "C" fn wasmtime_table_grow(
) -> u32 {
let instance = (*vmctx).instance_mut();
let table_index = TableIndex::from_u32(table_index);
match instance.table_element_type(table_index) {
TableElementType::Func => {
let func = init_value as *mut VMCallerCheckedAnyfunc;
instance
.table_grow(table_index, delta, func.into())
.unwrap_or(-1_i32 as u32)
}
let element = match instance.table_element_type(table_index) {
TableElementType::Func => (init_value as *mut VMCallerCheckedAnyfunc).into(),
TableElementType::Val(ty) => {
debug_assert_eq!(ty, crate::ref_type());
@@ -258,13 +218,13 @@ pub unsafe extern "C" fn wasmtime_table_grow(
} else {
Some(VMExternRef::clone_from_raw(init_value))
};
init_value.into()
}
};
instance
.table_grow(table_index, delta, init_value.into())
.table_grow(table_index, delta, element)
.unwrap_or(-1_i32 as u32)
}
}
}
/// Implementation of `table.fill`.
pub unsafe extern "C" fn wasmtime_table_fill(
@@ -377,29 +337,11 @@ pub unsafe extern "C" fn wasmtime_memory_fill(
dst: u32,
val: u32,
len: u32,
) {
let result = {
let memory_index = DefinedMemoryIndex::from_u32(memory_index);
let instance = (*vmctx).instance();
instance.defined_memory_fill(memory_index, dst, val, len)
};
if let Err(trap) = result {
raise_lib_trap(trap);
}
}
/// Implementation of `memory.fill` for imported memories.
pub unsafe extern "C" fn wasmtime_imported_memory_fill(
vmctx: *mut VMContext,
memory_index: u32,
dst: u32,
val: u32,
len: u32,
) {
let result = {
let memory_index = MemoryIndex::from_u32(memory_index);
let instance = (*vmctx).instance_mut();
instance.imported_memory_fill(memory_index, dst, val, len)
instance.memory_fill(memory_index, dst, val, len)
};
if let Err(trap) = result {
raise_lib_trap(trap);
@@ -517,18 +459,6 @@ pub unsafe extern "C" fn wasmtime_memory_atomic_notify(
))));
}
/// Implementation of `memory.atomic.notify` for imported memories.
pub unsafe extern "C" fn wasmtime_imported_memory_atomic_notify(
_vmctx: *mut VMContext,
_memory_index: u32,
_addr: u32,
_count: u32,
) -> u32 {
raise_lib_trap(Trap::User(Box::new(Unimplemented(
"wasm atomics (fn wasmtime_imported_memory_atomic_notify) unsupported",
))));
}
/// Implementation of `memory.atomic.wait32` for locally defined memories.
pub unsafe extern "C" fn wasmtime_memory_atomic_wait32(
_vmctx: *mut VMContext,
@@ -542,19 +472,6 @@ pub unsafe extern "C" fn wasmtime_memory_atomic_wait32(
))));
}
/// Implementation of `memory.atomic.wait32` for imported memories.
pub unsafe extern "C" fn wasmtime_imported_memory_atomic_wait32(
_vmctx: *mut VMContext,
_memory_index: u32,
_addr: u32,
_expected: u32,
_timeout: u64,
) -> u32 {
raise_lib_trap(Trap::User(Box::new(Unimplemented(
"wasm atomics (fn wasmtime_imported_memory_atomic_wait32) unsupported",
))));
}
/// Implementation of `memory.atomic.wait64` for locally defined memories.
pub unsafe extern "C" fn wasmtime_memory_atomic_wait64(
_vmctx: *mut VMContext,
@@ -568,19 +485,6 @@ pub unsafe extern "C" fn wasmtime_memory_atomic_wait64(
))));
}
/// Implementation of `memory.atomic.wait32` for imported memories.
pub unsafe extern "C" fn wasmtime_imported_memory_atomic_wait64(
_vmctx: *mut VMContext,
_memory_index: u32,
_addr: u32,
_expected: u64,
_timeout: u64,
) -> u32 {
raise_lib_trap(Trap::User(Box::new(Unimplemented(
"wasm atomics (fn wasmtime_imported_memory_atomic_wait64) unsupported",
))));
}
/// Hook for when an instance runs out of fuel.
pub unsafe extern "C" fn wasmtime_out_of_gas(vmctx: *mut VMContext) {
match (*(*vmctx).instance().store()).out_of_gas() {

View File

@@ -597,12 +597,6 @@ impl VMBuiltinFunctionsArray {
ptrs[BuiltinFunctionIndex::memory32_grow().index() as usize] =
wasmtime_memory32_grow as usize;
ptrs[BuiltinFunctionIndex::imported_memory32_grow().index() as usize] =
wasmtime_imported_memory32_grow as usize;
ptrs[BuiltinFunctionIndex::memory32_size().index() as usize] =
wasmtime_memory32_size as usize;
ptrs[BuiltinFunctionIndex::imported_memory32_size().index() as usize] =
wasmtime_imported_memory32_size as usize;
ptrs[BuiltinFunctionIndex::table_copy().index() as usize] = wasmtime_table_copy as usize;
ptrs[BuiltinFunctionIndex::table_grow_funcref().index() as usize] =
wasmtime_table_grow as usize;
@@ -612,8 +606,6 @@ impl VMBuiltinFunctionsArray {
ptrs[BuiltinFunctionIndex::elem_drop().index() as usize] = wasmtime_elem_drop as usize;
ptrs[BuiltinFunctionIndex::memory_copy().index() as usize] = wasmtime_memory_copy as usize;
ptrs[BuiltinFunctionIndex::memory_fill().index() as usize] = wasmtime_memory_fill as usize;
ptrs[BuiltinFunctionIndex::imported_memory_fill().index() as usize] =
wasmtime_imported_memory_fill as usize;
ptrs[BuiltinFunctionIndex::memory_init().index() as usize] = wasmtime_memory_init as usize;
ptrs[BuiltinFunctionIndex::data_drop().index() as usize] = wasmtime_data_drop as usize;
ptrs[BuiltinFunctionIndex::drop_externref().index() as usize] =
@@ -630,16 +622,10 @@ impl VMBuiltinFunctionsArray {
wasmtime_table_fill as usize;
ptrs[BuiltinFunctionIndex::memory_atomic_notify().index() as usize] =
wasmtime_memory_atomic_notify as usize;
ptrs[BuiltinFunctionIndex::imported_memory_atomic_notify().index() as usize] =
wasmtime_imported_memory_atomic_notify as usize;
ptrs[BuiltinFunctionIndex::memory_atomic_wait32().index() as usize] =
wasmtime_memory_atomic_wait32 as usize;
ptrs[BuiltinFunctionIndex::imported_memory_atomic_wait32().index() as usize] =
wasmtime_imported_memory_atomic_wait32 as usize;
ptrs[BuiltinFunctionIndex::memory_atomic_wait64().index() as usize] =
wasmtime_memory_atomic_wait64 as usize;
ptrs[BuiltinFunctionIndex::imported_memory_atomic_wait64().index() as usize] =
wasmtime_imported_memory_atomic_wait64 as usize;
ptrs[BuiltinFunctionIndex::out_of_gas().index() as usize] = wasmtime_out_of_gas as usize;
if cfg!(debug_assertions) {