Dumped code from the wasm2cretonne repo.

Integrated wasm test suite translation as cretonne test

Fixes #146.
Fixes #143.
This commit is contained in:
Denis Merigoux
2017-08-10 16:05:04 -07:00
committed by Jakob Stoklund Olesen
parent e8276ed965
commit ee9989c4b9
20 changed files with 2804 additions and 5 deletions

View File

@@ -0,0 +1,93 @@
use runtime::WasmRuntime;
use translation_utils::{Local, Global, Memory, Table, GlobalIndex, TableIndex, FunctionIndex,
MemoryIndex};
use cton_frontend::FunctionBuilder;
use cretonne::ir::{Value, InstBuilder, SigRef};
use cretonne::ir::immediates::{Ieee32, Ieee64};
use cretonne::ir::types::*;
/// This runtime implementation is a "naïve" one, doing essentially nothing and emitting
/// placeholders when forced to. Don't try to execute code translated with this runtime, it is
/// essentially here for translation debug purposes.
pub struct DummyRuntime {
globals: Vec<Global>,
}
impl DummyRuntime {
/// Allocates the runtime data structures.
pub fn new() -> DummyRuntime {
DummyRuntime { globals: Vec::new() }
}
}
impl WasmRuntime for DummyRuntime {
fn translate_get_global(&self,
builder: &mut FunctionBuilder<Local>,
global_index: GlobalIndex)
-> Value {
let ref glob = self.globals.get(global_index as usize).unwrap();
match glob.ty {
I32 => builder.ins().iconst(glob.ty, -1),
I64 => builder.ins().iconst(glob.ty, -1),
F32 => builder.ins().f32const(Ieee32::with_bits(0xbf800000)), // -1.0
F64 => {
builder
.ins()
.f64const(Ieee64::with_bits(0xbff0000000000000))
} // -1.0
_ => panic!("should not happen"),
}
}
fn translate_set_global(&self, _: &mut FunctionBuilder<Local>, _: GlobalIndex, _: Value) {
// We do nothing
}
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 translate_call_indirect<'a>(&self,
builder: &'a mut FunctionBuilder<Local>,
sig_ref: SigRef,
index_val: Value,
call_args: &[Value])
-> &'a [Value] {
let call_inst = builder.ins().call_indirect(sig_ref, index_val, call_args);
builder.inst_results(call_inst)
}
fn translate_memory_base_address(&self,
builder: &mut FunctionBuilder<Local>,
_: MemoryIndex)
-> Value {
builder.ins().iconst(I64, 0)
}
fn declare_global(&mut self, global: Global) {
self.globals.push(global);
}
fn declare_table(&mut self, _: Table) {
//We do nothing
}
fn declare_table_elements(&mut self, _: TableIndex, _: usize, _: &[FunctionIndex]) {
//We do nothing
}
fn declare_memory(&mut self, _: Memory) {
//We do nothing
}
fn declare_data_initialization(&mut self,
_: MemoryIndex,
_: usize,
_: &[u8])
-> Result<(), String> {
// We do nothing
Ok(())
}
fn begin_translation(&mut self) {
// We do nothing
}
fn next_function(&mut self) {
// We do nothing
}
}

View File

@@ -0,0 +1,5 @@
mod spec;
mod dummy;
pub use runtime::spec::WasmRuntime;
pub use runtime::dummy::DummyRuntime;

View File

@@ -0,0 +1,61 @@
//! All the runtime support necessary for the wasm to cretonne translation is formalized by the
//! trait `WasmRuntime`.
use cton_frontend::FunctionBuilder;
use cretonne::ir::{Value, SigRef};
use translation_utils::{Local, FunctionIndex, TableIndex, GlobalIndex, MemoryIndex, Global, Table,
Memory};
/// An object satisfyng the `WasmRuntime` trait can be passed as argument to the
/// [`translate_module`](fn.translate_module.html) function. These methods should not be called
/// by the user, they are only for the `wasm2cretonne` internal use.
pub trait WasmRuntime {
/// Declares a global to the runtime.
fn declare_global(&mut self, global: Global);
/// Declares a table to the runtime.
fn declare_table(&mut self, table: Table);
/// Fills a declared table with references to functions in the module.
fn declare_table_elements(&mut self,
table_index: TableIndex,
offset: usize,
elements: &[FunctionIndex]);
/// Declares a memory to the runtime
fn declare_memory(&mut self, memory: Memory);
/// Fills a declared memory with bytes at module instantiation.
fn declare_data_initialization(&mut self,
memory_index: MemoryIndex,
offset: usize,
data: &[u8])
-> Result<(), String>;
/// Call this function after having declared all the runtime elements but prior to the
/// function body translation.
fn begin_translation(&mut self);
/// Call this function between each function body translation.
fn next_function(&mut self);
/// Translates a `get_global` wasm instruction.
fn translate_get_global(&self,
builder: &mut FunctionBuilder<Local>,
global_index: GlobalIndex)
-> Value;
/// Translates a `set_global` wasm instruction.
fn translate_set_global(&self,
builder: &mut FunctionBuilder<Local>,
global_index: GlobalIndex,
val: Value);
/// 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;
/// Returns the base address of a wasm memory as a Cretonne `Value`.
fn translate_memory_base_address(&self,
builder: &mut FunctionBuilder<Local>,
index: MemoryIndex)
-> Value;
/// Translates a `call_indirect` wasm instruction. It involves looking up the value contained
/// it the table at location `index_val` and calling the corresponding function.
fn translate_call_indirect<'a>(&self,
builder: &'a mut FunctionBuilder<Local>,
sig_ref: SigRef,
index_val: Value,
call_args: &[Value])
-> &'a [Value];
}