Move translate_grow_memory and translate_current_memory too.

This moves the last instruction-level callbacks into FuncEnvironment
such that the trait has all the information required to translate a
whole function.

Change the position argument to a FuncCursor. This eliminates all
exposure of FunctionBuilder<Local>, so its use properly becomes an
implementation detail.
This commit is contained in:
Jakob Stoklund Olesen
2017-09-06 15:44:23 -07:00
parent 26048c2ecc
commit b10faca534
3 changed files with 73 additions and 23 deletions

View File

@@ -28,7 +28,7 @@ use cretonne::ir::condcodes::{IntCC, FloatCC};
use cton_frontend::{ILBuilder, FunctionBuilder}; use cton_frontend::{ILBuilder, FunctionBuilder};
use wasmparser::{Parser, ParserState, Operator, WasmDecoder, MemoryImmediate}; use wasmparser::{Parser, ParserState, Operator, WasmDecoder, MemoryImmediate};
use translation_utils::{f32_translation, f64_translation, type_to_type, translate_type, Local}; 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 state::{TranslationState, ControlStackFrame};
use std::collections::HashMap; use std::collections::HashMap;
use runtime::{FuncEnvironment, GlobalValue, WasmRuntime}; 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 * Memory management is handled by runtime. It is usually translated into calls to
* special functions. * 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(); 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: _ } => { Operator::CurrentMemory { reserved } => {
state.push1(runtime.translate_current_memory(builder)); 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 *********************************** /******************************* Load instructions ***********************************
* Wasm specifies an integer alignment flag but we drop it in Cretonne. * Wasm specifies an integer alignment flag but we drop it in Cretonne.

View File

@@ -1,8 +1,7 @@
use runtime::{FuncEnvironment, GlobalValue, WasmRuntime}; 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}; FunctionIndex, MemoryIndex};
use cton_frontend::FunctionBuilder; use cretonne::ir::{self, InstBuilder};
use cretonne::ir::{self, Value, InstBuilder};
use cretonne::ir::types::*; use cretonne::ir::types::*;
use cretonne::cursor::FuncCursor; use cretonne::cursor::FuncCursor;
@@ -88,16 +87,28 @@ impl FuncEnvironment for DummyRuntime {
) -> ir::Inst { ) -> ir::Inst {
pos.ins().call_indirect(sig_ref, callee, call_args) 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 { impl WasmRuntime for DummyRuntime {
fn translate_grow_memory(&mut self, builder: &mut FunctionBuilder<Local>, _: Value) -> Value {
builder.ins().iconst(I32, -1)
}
fn translate_current_memory(&mut self, builder: &mut FunctionBuilder<Local>) -> Value {
builder.ins().iconst(I32, -1)
}
fn declare_signature(&mut self, sig: &ir::Signature) { fn declare_signature(&mut self, sig: &ir::Signature) {
self.signatures.push(sig.clone()); self.signatures.push(sig.clone());
} }

View File

@@ -1,10 +1,9 @@
//! All the runtime support necessary for the wasm to cretonne translation is formalized by the //! All the runtime support necessary for the wasm to cretonne translation is formalized by the
//! trait `WasmRuntime`. //! trait `WasmRuntime`.
use cton_frontend::FunctionBuilder; use cretonne::ir::{self, InstBuilder};
use cretonne::ir::{self, Value, InstBuilder};
use cretonne::cursor::FuncCursor; use cretonne::cursor::FuncCursor;
use translation_utils::{Local, SignatureIndex, FunctionIndex, TableIndex, GlobalIndex, use translation_utils::{SignatureIndex, FunctionIndex, TableIndex, GlobalIndex, MemoryIndex,
MemoryIndex, Global, Table, Memory}; Global, Table, Memory};
/// The value of a WebAssembly global variable. /// The value of a WebAssembly global variable.
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
@@ -101,6 +100,35 @@ pub trait FuncEnvironment {
) -> ir::Inst { ) -> ir::Inst {
pos.ins().call(callee, call_args) 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 /// 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); fn begin_translation(&mut self);
/// Call this function between each function body translation. /// Call this function between each function body translation.
fn next_function(&mut self); 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<Local>, 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<Local>) -> Value;
} }