Skip to content

Commit

Permalink
Merge pull request bytecodealliance#3023 from alexcrichton/refactor-i…
Browse files Browse the repository at this point in the history
…nstance

Simplify the list of builtin intrinsics Wasmtime needs
  • Loading branch information
fitzgen authored Jun 23, 2021
2 parents 324d807 + a273add commit edfbd77
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 352 deletions.
193 changes: 59 additions & 134 deletions crates/cranelift/src/func_environ.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -260,86 +214,23 @@ 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,
memory_index: MemoryIndex,
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),
}
}
Expand Down Expand Up @@ -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]);
Expand All @@ -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(
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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()
Expand Down
22 changes: 4 additions & 18 deletions crates/environ/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) -> ();
Expand All @@ -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.
Expand All @@ -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) -> ();
}
Expand Down
Loading

0 comments on commit edfbd77

Please sign in to comment.