Merge pull request #3023 from alexcrichton/refactor-instance
Simplify the list of builtin intrinsics Wasmtime needs
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(
|
fn get_table_copy_func(
|
||||||
&mut self,
|
&mut self,
|
||||||
func: &mut Function,
|
func: &mut Function,
|
||||||
@@ -260,47 +214,6 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
|
|||||||
(sig, BuiltinFunctionIndex::elem_drop())
|
(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(
|
fn get_memory_atomic_wait(
|
||||||
&mut self,
|
&mut self,
|
||||||
func: &mut Function,
|
func: &mut Function,
|
||||||
@@ -308,38 +221,16 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
|
|||||||
ty: ir::Type,
|
ty: ir::Type,
|
||||||
) -> (ir::SigRef, usize, BuiltinFunctionIndex) {
|
) -> (ir::SigRef, usize, BuiltinFunctionIndex) {
|
||||||
match ty {
|
match ty {
|
||||||
I32 => {
|
I32 => (
|
||||||
if let Some(defined_memory_index) = self.module.defined_memory_index(memory_index) {
|
|
||||||
(
|
|
||||||
self.builtin_function_signatures.memory_atomic_wait32(func),
|
self.builtin_function_signatures.memory_atomic_wait32(func),
|
||||||
defined_memory_index.index(),
|
memory_index.index(),
|
||||||
BuiltinFunctionIndex::memory_atomic_wait32(),
|
BuiltinFunctionIndex::memory_atomic_wait32(),
|
||||||
)
|
),
|
||||||
} else {
|
I64 => (
|
||||||
(
|
|
||||||
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),
|
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(),
|
memory_index.index(),
|
||||||
BuiltinFunctionIndex::imported_memory_atomic_wait64(),
|
BuiltinFunctionIndex::memory_atomic_wait64(),
|
||||||
)
|
),
|
||||||
}
|
|
||||||
}
|
|
||||||
x => panic!("get_memory_atomic_wait unsupported type: {:?}", x),
|
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,
|
_heap: ir::Heap,
|
||||||
val: ir::Value,
|
val: ir::Value,
|
||||||
) -> WasmResult<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 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
|
let call_inst = pos
|
||||||
.ins()
|
.ins()
|
||||||
.call_indirect(func_sig, func_addr, &[vmctx, val, memory_index]);
|
.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,
|
index: MemoryIndex,
|
||||||
_heap: ir::Heap,
|
_heap: ir::Heap,
|
||||||
) -> WasmResult<ir::Value> {
|
) -> WasmResult<ir::Value> {
|
||||||
let (func_sig, index_arg, func_idx) = self.get_memory_size_func(&mut pos.func, index);
|
let pointer_type = self.pointer_type();
|
||||||
let memory_index = pos.ins().iconst(I32, index_arg as i64);
|
let vmctx = self.vmctx(&mut pos.func);
|
||||||
let (vmctx, func_addr) = self.translate_load_builtin_function_address(&mut pos, func_idx);
|
let base = pos.ins().global_value(pointer_type, vmctx);
|
||||||
let call_inst = pos
|
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()
|
.ins()
|
||||||
.call_indirect(func_sig, func_addr, &[vmctx, memory_index]);
|
.udiv_imm(current_length_in_bytes, i64::from(WASM_PAGE_SIZE));
|
||||||
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
|
Ok(current_length_in_pages)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn translate_memory_copy(
|
fn translate_memory_copy(
|
||||||
@@ -1554,12 +1474,13 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
|
|||||||
val: ir::Value,
|
val: ir::Value,
|
||||||
len: ir::Value,
|
len: ir::Value,
|
||||||
) -> WasmResult<()> {
|
) -> WasmResult<()> {
|
||||||
let (func_sig, memory_index, func_idx) =
|
let func_sig = self.builtin_function_signatures.memory_fill(&mut pos.func);
|
||||||
self.get_memory_fill_func(&mut pos.func, memory_index);
|
let memory_index = memory_index.index();
|
||||||
|
|
||||||
let memory_index_arg = pos.ins().iconst(I32, memory_index as i64);
|
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(
|
pos.ins().call_indirect(
|
||||||
func_sig,
|
func_sig,
|
||||||
@@ -1724,12 +1645,16 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
|
|||||||
addr: ir::Value,
|
addr: ir::Value,
|
||||||
count: ir::Value,
|
count: ir::Value,
|
||||||
) -> WasmResult<ir::Value> {
|
) -> WasmResult<ir::Value> {
|
||||||
let (func_sig, memory_index, func_idx) =
|
let func_sig = self
|
||||||
self.get_memory_atomic_notify(&mut pos.func, memory_index);
|
.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 =
|
let call_inst =
|
||||||
pos.ins()
|
pos.ins()
|
||||||
|
|||||||
@@ -5,12 +5,6 @@ macro_rules! foreach_builtin_function {
|
|||||||
$mac! {
|
$mac! {
|
||||||
/// Returns an index for wasm's `memory.grow` builtin function.
|
/// Returns an index for wasm's `memory.grow` builtin function.
|
||||||
memory32_grow(vmctx, i32, i32) -> (i32);
|
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
|
/// Returns an index for wasm's `table.copy` when both tables are locally
|
||||||
/// defined.
|
/// defined.
|
||||||
table_copy(vmctx, i32, i32, i32, i32, i32) -> ();
|
table_copy(vmctx, i32, i32, i32, i32, i32) -> ();
|
||||||
@@ -20,10 +14,8 @@ macro_rules! foreach_builtin_function {
|
|||||||
elem_drop(vmctx, i32) -> ();
|
elem_drop(vmctx, i32) -> ();
|
||||||
/// Returns an index for wasm's `memory.copy`
|
/// Returns an index for wasm's `memory.copy`
|
||||||
memory_copy(vmctx, i32, i32, i32, i32, i32) -> ();
|
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) -> ();
|
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.
|
/// Returns an index for wasm's `memory.init` instruction.
|
||||||
memory_init(vmctx, i32, i32, i32, i32, i32) -> ();
|
memory_init(vmctx, i32, i32, i32, i32, i32) -> ();
|
||||||
/// Returns an index for wasm's `data.drop` instruction.
|
/// Returns an index for wasm's `data.drop` instruction.
|
||||||
@@ -45,18 +37,12 @@ macro_rules! foreach_builtin_function {
|
|||||||
externref_global_get(vmctx, i32) -> (reference);
|
externref_global_get(vmctx, i32) -> (reference);
|
||||||
/// Returns an index for Wasm's `global.get` instruction for `externref`s.
|
/// Returns an index for Wasm's `global.get` instruction for `externref`s.
|
||||||
externref_global_set(vmctx, i32, reference) -> ();
|
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);
|
memory_atomic_notify(vmctx, i32, i32, i32) -> (i32);
|
||||||
/// Returns an index for wasm's `memory.atomic.notify` for imported memories.
|
/// Returns an index for wasm's `memory.atomic.wait32` instruction.
|
||||||
imported_memory_atomic_notify(vmctx, i32, i32, i32) -> (i32);
|
|
||||||
/// Returns an index for wasm's `memory.atomic.wait32` for locally defined memories.
|
|
||||||
memory_atomic_wait32(vmctx, i32, i32, i32, i64) -> (i32);
|
memory_atomic_wait32(vmctx, i32, i32, i32, i64) -> (i32);
|
||||||
/// Returns an index for wasm's `memory.atomic.wait32` for imported memories.
|
/// Returns an index for wasm's `memory.atomic.wait64` instruction.
|
||||||
imported_memory_atomic_wait32(vmctx, i32, i32, i32, i64) -> (i32);
|
|
||||||
/// Returns an index for wasm's `memory.atomic.wait64` for locally defined memories.
|
|
||||||
memory_atomic_wait64(vmctx, i32, i32, i64, i64) -> (i32);
|
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.
|
/// Invoked when fuel has run out while executing a function.
|
||||||
out_of_gas(vmctx) -> ();
|
out_of_gas(vmctx) -> ();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -386,68 +386,31 @@ impl Instance {
|
|||||||
///
|
///
|
||||||
/// Returns `None` if memory can't be grown by the specified amount
|
/// Returns `None` if memory can't be grown by the specified amount
|
||||||
/// of pages.
|
/// of pages.
|
||||||
pub(crate) fn memory_grow(
|
pub(crate) fn memory_grow(&mut self, index: MemoryIndex, delta: u32) -> Option<u32> {
|
||||||
&mut self,
|
let (idx, instance) = if let Some(idx) = self.module.defined_memory_index(index) {
|
||||||
memory_index: DefinedMemoryIndex,
|
(idx, self)
|
||||||
delta: u32,
|
} else {
|
||||||
) -> Option<u32> {
|
let import = self.imported_memory(index);
|
||||||
let limiter = unsafe { (*self.store()).limiter() };
|
unsafe {
|
||||||
let memory = self
|
let foreign_instance = (*import.vmctx).instance_mut();
|
||||||
.memories
|
let foreign_memory_def = &*import.from;
|
||||||
.get_mut(memory_index)
|
let foreign_memory_index = foreign_instance.memory_index(foreign_memory_def);
|
||||||
.unwrap_or_else(|| panic!("no memory for index {}", memory_index.index()));
|
(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 result = unsafe { memory.grow(delta, limiter) };
|
||||||
|
let vmmemory = memory.vmmemory();
|
||||||
|
|
||||||
// Keep current the VMContext pointers used by compiled wasm code.
|
// Update the state used by wasm code in case the base pointer and/or
|
||||||
self.set_memory(memory_index, self.memories[memory_index].vmmemory());
|
// the length changed.
|
||||||
|
instance.set_memory(idx, vmmemory);
|
||||||
|
|
||||||
result
|
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 {
|
pub(crate) fn table_element_type(&mut self, table_index: TableIndex) -> TableElementType {
|
||||||
unsafe { (*self.get_table(table_index)).element_type() }
|
unsafe { (*self.get_table(table_index)).element_type() }
|
||||||
}
|
}
|
||||||
@@ -671,14 +634,14 @@ impl Instance {
|
|||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// Returns a `Trap` error if the memory range is out of bounds.
|
/// Returns a `Trap` error if the memory range is out of bounds.
|
||||||
pub(crate) fn defined_memory_fill(
|
pub(crate) fn memory_fill(
|
||||||
&self,
|
&mut self,
|
||||||
memory_index: DefinedMemoryIndex,
|
memory_index: MemoryIndex,
|
||||||
dst: u32,
|
dst: u32,
|
||||||
val: u32,
|
val: u32,
|
||||||
len: u32,
|
len: u32,
|
||||||
) -> Result<(), Trap> {
|
) -> Result<(), Trap> {
|
||||||
let memory = self.memory(memory_index);
|
let memory = self.get_memory(memory_index);
|
||||||
|
|
||||||
if dst
|
if dst
|
||||||
.checked_add(len)
|
.checked_add(len)
|
||||||
@@ -700,27 +663,6 @@ impl Instance {
|
|||||||
Ok(())
|
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.
|
/// Performs the `memory.init` operation.
|
||||||
///
|
///
|
||||||
/// # Errors
|
/// # Errors
|
||||||
|
|||||||
@@ -63,8 +63,7 @@ use crate::vmcontext::{VMCallerCheckedAnyfunc, VMContext};
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr::{self, NonNull};
|
use std::ptr::{self, NonNull};
|
||||||
use wasmtime_environ::wasm::{
|
use wasmtime_environ::wasm::{
|
||||||
DataIndex, DefinedMemoryIndex, ElemIndex, GlobalIndex, MemoryIndex, TableElementType,
|
DataIndex, ElemIndex, GlobalIndex, MemoryIndex, TableElementType, TableIndex,
|
||||||
TableIndex,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const TOINT_32: f32 = 1.0 / f32::EPSILON;
|
const TOINT_32: f32 = 1.0 / f32::EPSILON;
|
||||||
@@ -192,46 +191,12 @@ pub unsafe extern "C" fn wasmtime_memory32_grow(
|
|||||||
memory_index: u32,
|
memory_index: u32,
|
||||||
) -> u32 {
|
) -> u32 {
|
||||||
let instance = (*vmctx).instance_mut();
|
let instance = (*vmctx).instance_mut();
|
||||||
let memory_index = DefinedMemoryIndex::from_u32(memory_index);
|
let memory_index = MemoryIndex::from_u32(memory_index);
|
||||||
|
|
||||||
instance
|
instance
|
||||||
.memory_grow(memory_index, delta)
|
.memory_grow(memory_index, delta)
|
||||||
.unwrap_or(u32::max_value())
|
.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`.
|
/// Implementation of `table.grow`.
|
||||||
pub unsafe extern "C" fn wasmtime_table_grow(
|
pub unsafe extern "C" fn wasmtime_table_grow(
|
||||||
vmctx: *mut VMContext,
|
vmctx: *mut VMContext,
|
||||||
@@ -243,13 +208,8 @@ pub unsafe extern "C" fn wasmtime_table_grow(
|
|||||||
) -> u32 {
|
) -> u32 {
|
||||||
let instance = (*vmctx).instance_mut();
|
let instance = (*vmctx).instance_mut();
|
||||||
let table_index = TableIndex::from_u32(table_index);
|
let table_index = TableIndex::from_u32(table_index);
|
||||||
match instance.table_element_type(table_index) {
|
let element = match instance.table_element_type(table_index) {
|
||||||
TableElementType::Func => {
|
TableElementType::Func => (init_value as *mut VMCallerCheckedAnyfunc).into(),
|
||||||
let func = init_value as *mut VMCallerCheckedAnyfunc;
|
|
||||||
instance
|
|
||||||
.table_grow(table_index, delta, func.into())
|
|
||||||
.unwrap_or(-1_i32 as u32)
|
|
||||||
}
|
|
||||||
TableElementType::Val(ty) => {
|
TableElementType::Val(ty) => {
|
||||||
debug_assert_eq!(ty, crate::ref_type());
|
debug_assert_eq!(ty, crate::ref_type());
|
||||||
|
|
||||||
@@ -258,12 +218,12 @@ pub unsafe extern "C" fn wasmtime_table_grow(
|
|||||||
} else {
|
} else {
|
||||||
Some(VMExternRef::clone_from_raw(init_value))
|
Some(VMExternRef::clone_from_raw(init_value))
|
||||||
};
|
};
|
||||||
|
init_value.into()
|
||||||
|
}
|
||||||
|
};
|
||||||
instance
|
instance
|
||||||
.table_grow(table_index, delta, init_value.into())
|
.table_grow(table_index, delta, element)
|
||||||
.unwrap_or(-1_i32 as u32)
|
.unwrap_or(-1_i32 as u32)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implementation of `table.fill`.
|
/// Implementation of `table.fill`.
|
||||||
@@ -377,29 +337,11 @@ pub unsafe extern "C" fn wasmtime_memory_fill(
|
|||||||
dst: u32,
|
dst: u32,
|
||||||
val: u32,
|
val: u32,
|
||||||
len: 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 result = {
|
||||||
let memory_index = MemoryIndex::from_u32(memory_index);
|
let memory_index = MemoryIndex::from_u32(memory_index);
|
||||||
let instance = (*vmctx).instance_mut();
|
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 {
|
if let Err(trap) = result {
|
||||||
raise_lib_trap(trap);
|
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.
|
/// Implementation of `memory.atomic.wait32` for locally defined memories.
|
||||||
pub unsafe extern "C" fn wasmtime_memory_atomic_wait32(
|
pub unsafe extern "C" fn wasmtime_memory_atomic_wait32(
|
||||||
_vmctx: *mut VMContext,
|
_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.
|
/// Implementation of `memory.atomic.wait64` for locally defined memories.
|
||||||
pub unsafe extern "C" fn wasmtime_memory_atomic_wait64(
|
pub unsafe extern "C" fn wasmtime_memory_atomic_wait64(
|
||||||
_vmctx: *mut VMContext,
|
_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.
|
/// Hook for when an instance runs out of fuel.
|
||||||
pub unsafe extern "C" fn wasmtime_out_of_gas(vmctx: *mut VMContext) {
|
pub unsafe extern "C" fn wasmtime_out_of_gas(vmctx: *mut VMContext) {
|
||||||
match (*(*vmctx).instance().store()).out_of_gas() {
|
match (*(*vmctx).instance().store()).out_of_gas() {
|
||||||
|
|||||||
@@ -597,12 +597,6 @@ impl VMBuiltinFunctionsArray {
|
|||||||
|
|
||||||
ptrs[BuiltinFunctionIndex::memory32_grow().index() as usize] =
|
ptrs[BuiltinFunctionIndex::memory32_grow().index() as usize] =
|
||||||
wasmtime_memory32_grow 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_copy().index() as usize] = wasmtime_table_copy as usize;
|
||||||
ptrs[BuiltinFunctionIndex::table_grow_funcref().index() as usize] =
|
ptrs[BuiltinFunctionIndex::table_grow_funcref().index() as usize] =
|
||||||
wasmtime_table_grow 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::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_copy().index() as usize] = wasmtime_memory_copy as usize;
|
||||||
ptrs[BuiltinFunctionIndex::memory_fill().index() as usize] = wasmtime_memory_fill 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::memory_init().index() as usize] = wasmtime_memory_init as usize;
|
||||||
ptrs[BuiltinFunctionIndex::data_drop().index() as usize] = wasmtime_data_drop as usize;
|
ptrs[BuiltinFunctionIndex::data_drop().index() as usize] = wasmtime_data_drop as usize;
|
||||||
ptrs[BuiltinFunctionIndex::drop_externref().index() as usize] =
|
ptrs[BuiltinFunctionIndex::drop_externref().index() as usize] =
|
||||||
@@ -630,16 +622,10 @@ impl VMBuiltinFunctionsArray {
|
|||||||
wasmtime_table_fill as usize;
|
wasmtime_table_fill as usize;
|
||||||
ptrs[BuiltinFunctionIndex::memory_atomic_notify().index() as usize] =
|
ptrs[BuiltinFunctionIndex::memory_atomic_notify().index() as usize] =
|
||||||
wasmtime_memory_atomic_notify 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] =
|
ptrs[BuiltinFunctionIndex::memory_atomic_wait32().index() as usize] =
|
||||||
wasmtime_memory_atomic_wait32 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] =
|
ptrs[BuiltinFunctionIndex::memory_atomic_wait64().index() as usize] =
|
||||||
wasmtime_memory_atomic_wait64 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;
|
ptrs[BuiltinFunctionIndex::out_of_gas().index() as usize] = wasmtime_out_of_gas as usize;
|
||||||
|
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
|
|||||||
Reference in New Issue
Block a user