Simplify the list of builtin intrinsics Wasmtime needs
This commit slims down the list of builtin intrinsics. It removes the duplicated intrinsics for imported and locally defined items, instead always using one intrinsic for both. This was previously inconsistently applied where some intrinsics got two copies (one for imported one for local) and other intrinsics got only one copy. This does add an extra branch in intrinsics since they need to determine whether something is local or not, but that's generally much lower cost than the intrinsics themselves. This also removes the `memory32_size` intrinsic, instead inlining the codegen directly into the clif IR. This matches what the `table.size` instruction does and removes the need for a few functions on a `wasmtime_runtime::Instance`.
This commit is contained in:
@@ -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) {
|
||||
(
|
||||
self.builtin_function_signatures.memory_atomic_wait32(func),
|
||||
defined_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) {
|
||||
(
|
||||
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(),
|
||||
)
|
||||
}
|
||||
}
|
||||
I32 => (
|
||||
self.builtin_function_signatures.memory_atomic_wait32(func),
|
||||
memory_index.index(),
|
||||
BuiltinFunctionIndex::memory_atomic_wait32(),
|
||||
),
|
||||
I64 => (
|
||||
self.builtin_function_signatures.memory_atomic_wait64(func),
|
||||
memory_index.index(),
|
||||
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()
|
||||
|
||||
@@ -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) -> ();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,12 +218,12 @@ pub unsafe extern "C" fn wasmtime_table_grow(
|
||||
} else {
|
||||
Some(VMExternRef::clone_from_raw(init_value))
|
||||
};
|
||||
|
||||
instance
|
||||
.table_grow(table_index, delta, init_value.into())
|
||||
.unwrap_or(-1_i32 as u32)
|
||||
init_value.into()
|
||||
}
|
||||
}
|
||||
};
|
||||
instance
|
||||
.table_grow(table_index, delta, element)
|
||||
.unwrap_or(-1_i32 as u32)
|
||||
}
|
||||
|
||||
/// Implementation of `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() {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user