diff --git a/lib/wasm/src/code_translator.rs b/lib/wasm/src/code_translator.rs index 02cd7e1b10..681eb3b7d0 100644 --- a/lib/wasm/src/code_translator.rs +++ b/lib/wasm/src/code_translator.rs @@ -28,7 +28,7 @@ use cretonne::ir::condcodes::{IntCC, FloatCC}; use cton_frontend::{ILBuilder, FunctionBuilder}; use wasmparser::{Parser, ParserState, Operator, WasmDecoder, MemoryImmediate}; use translation_utils::{f32_translation, f64_translation, type_to_type, translate_type, Local}; -use translation_utils::{TableIndex, SignatureIndex, FunctionIndex}; +use translation_utils::{TableIndex, SignatureIndex, FunctionIndex, MemoryIndex}; use state::{TranslationState, ControlStackFrame}; use std::collections::HashMap; use runtime::{FuncEnvironment, GlobalValue, WasmRuntime}; @@ -458,12 +458,27 @@ fn translate_operator( * Memory management is handled by runtime. It is usually translated into calls to * special functions. ************************************************************************************/ - Operator::GrowMemory { reserved: _ } => { + Operator::GrowMemory { reserved } => { + // The WebAssembly MVP only supports one linear memory, but we expect the reserved + // argument to be a memory index. + let heap_index = reserved as MemoryIndex; + let heap = state.get_heap(builder.func, reserved, runtime); let val = state.pop1(); - state.push1(runtime.translate_grow_memory(builder, val)); + state.push1(runtime.translate_grow_memory( + builder.cursor(), + heap_index, + heap, + val, + )) } - Operator::CurrentMemory { reserved: _ } => { - state.push1(runtime.translate_current_memory(builder)); + Operator::CurrentMemory { reserved } => { + let heap_index = reserved as MemoryIndex; + let heap = state.get_heap(builder.func, reserved, runtime); + state.push1(runtime.translate_current_memory( + builder.cursor(), + heap_index, + heap, + )); } /******************************* Load instructions *********************************** * Wasm specifies an integer alignment flag but we drop it in Cretonne. diff --git a/lib/wasm/src/runtime/dummy.rs b/lib/wasm/src/runtime/dummy.rs index 178d39c5d1..703b5f164a 100644 --- a/lib/wasm/src/runtime/dummy.rs +++ b/lib/wasm/src/runtime/dummy.rs @@ -1,8 +1,7 @@ use runtime::{FuncEnvironment, GlobalValue, WasmRuntime}; -use translation_utils::{Local, Global, Memory, Table, GlobalIndex, TableIndex, SignatureIndex, +use translation_utils::{Global, Memory, Table, GlobalIndex, TableIndex, SignatureIndex, FunctionIndex, MemoryIndex}; -use cton_frontend::FunctionBuilder; -use cretonne::ir::{self, Value, InstBuilder}; +use cretonne::ir::{self, InstBuilder}; use cretonne::ir::types::*; use cretonne::cursor::FuncCursor; @@ -88,16 +87,28 @@ impl FuncEnvironment for DummyRuntime { ) -> ir::Inst { pos.ins().call_indirect(sig_ref, callee, call_args) } + + fn translate_grow_memory( + &mut self, + mut pos: FuncCursor, + _index: MemoryIndex, + _heap: ir::Heap, + _val: ir::Value, + ) -> ir::Value { + pos.ins().iconst(I32, -1) + } + + fn translate_current_memory( + &mut self, + mut pos: FuncCursor, + _index: MemoryIndex, + _heap: ir::Heap, + ) -> ir::Value { + pos.ins().iconst(I32, -1) + } } impl WasmRuntime for DummyRuntime { - fn translate_grow_memory(&mut self, builder: &mut FunctionBuilder, _: Value) -> Value { - builder.ins().iconst(I32, -1) - } - fn translate_current_memory(&mut self, builder: &mut FunctionBuilder) -> Value { - builder.ins().iconst(I32, -1) - } - fn declare_signature(&mut self, sig: &ir::Signature) { self.signatures.push(sig.clone()); } diff --git a/lib/wasm/src/runtime/spec.rs b/lib/wasm/src/runtime/spec.rs index 5750fe5520..35f8d9ea37 100644 --- a/lib/wasm/src/runtime/spec.rs +++ b/lib/wasm/src/runtime/spec.rs @@ -1,10 +1,9 @@ //! All the runtime support necessary for the wasm to cretonne translation is formalized by the //! trait `WasmRuntime`. -use cton_frontend::FunctionBuilder; -use cretonne::ir::{self, Value, InstBuilder}; +use cretonne::ir::{self, InstBuilder}; use cretonne::cursor::FuncCursor; -use translation_utils::{Local, SignatureIndex, FunctionIndex, TableIndex, GlobalIndex, - MemoryIndex, Global, Table, Memory}; +use translation_utils::{SignatureIndex, FunctionIndex, TableIndex, GlobalIndex, MemoryIndex, + Global, Table, Memory}; /// The value of a WebAssembly global variable. #[derive(Clone, Copy)] @@ -101,6 +100,35 @@ pub trait FuncEnvironment { ) -> ir::Inst { pos.ins().call(callee, call_args) } + + /// Translate a `grow_memory` WebAssembly instruction. + /// + /// The `index` provided identifies the linear memory to grow, and `heap` is the heap reference + /// returned by `make_heap` for the same index. + /// + /// The `val` value is the requested memory size in pages. + /// + /// Returns the old size (in pages) of the memory. + fn translate_grow_memory( + &mut self, + pos: FuncCursor, + index: MemoryIndex, + heap: ir::Heap, + val: ir::Value, + ) -> ir::Value; + + /// Translates a `current_memory` WebAssembly instruction. + /// + /// The `index` provided identifies the linear memory to query, and `heap` is the heap reference + /// returned by `make_heap` for the same index. + /// + /// Returns the size in pages of the memory. + fn translate_current_memory( + &mut self, + pos: FuncCursor, + index: MemoryIndex, + heap: ir::Heap, + ) -> ir::Value; } /// An object satisfyng the `WasmRuntime` trait can be passed as argument to the @@ -141,8 +169,4 @@ pub trait WasmRuntime: FuncEnvironment { fn begin_translation(&mut self); /// Call this function between each function body translation. fn next_function(&mut self); - /// Translates a `grow_memory` wasm instruction. Returns the old size (in pages) of the memory. - fn translate_grow_memory(&mut self, builder: &mut FunctionBuilder, val: Value) -> Value; - /// Translates a `current_memory` wasm instruction. Returns the size in pages of the memory. - fn translate_current_memory(&mut self, builder: &mut FunctionBuilder) -> Value; }