Add support for emitting code with a single return at the end. (#153)
This also enables testing of the wasmtests tests. This also updates for wabt updating to the official "wat" filename extension, as opposed to "wast".
This commit is contained in:
@@ -329,8 +329,20 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
|
||||
}
|
||||
}
|
||||
Operator::Return => {
|
||||
let return_count = state.control_stack[0].return_values().len();
|
||||
builder.ins().return_(state.peekn(return_count));
|
||||
let (return_count, br_destination) = {
|
||||
let frame = &mut state.control_stack[0];
|
||||
frame.set_reachable();
|
||||
let return_count = frame.return_values().len();
|
||||
(return_count, frame.br_destination())
|
||||
};
|
||||
{
|
||||
let args = state.peekn(return_count);
|
||||
if environ.flags().return_at_end() {
|
||||
builder.ins().jump(br_destination, args);
|
||||
} else {
|
||||
builder.ins().return_(args);
|
||||
}
|
||||
}
|
||||
state.popn(return_count);
|
||||
state.real_unreachable_stack_depth = 1;
|
||||
}
|
||||
|
||||
@@ -237,7 +237,7 @@ mod tests {
|
||||
];
|
||||
|
||||
let mut trans = FuncTranslator::new();
|
||||
let mut runtime = DummyRuntime::new();
|
||||
let mut runtime = DummyRuntime::default();
|
||||
let mut ctx = Context::new();
|
||||
|
||||
ctx.func.name = ir::FunctionName::new("small1");
|
||||
@@ -271,7 +271,7 @@ mod tests {
|
||||
];
|
||||
|
||||
let mut trans = FuncTranslator::new();
|
||||
let mut runtime = DummyRuntime::new();
|
||||
let mut runtime = DummyRuntime::default();
|
||||
let mut ctx = Context::new();
|
||||
|
||||
ctx.func.name = ir::FunctionName::new("small2");
|
||||
@@ -314,7 +314,7 @@ mod tests {
|
||||
];
|
||||
|
||||
let mut trans = FuncTranslator::new();
|
||||
let mut runtime = DummyRuntime::new();
|
||||
let mut runtime = DummyRuntime::default();
|
||||
let mut ctx = Context::new();
|
||||
|
||||
ctx.func.name = ir::FunctionName::new("infloop");
|
||||
|
||||
@@ -4,6 +4,7 @@ use translation_utils::{Global, Memory, Table, GlobalIndex, TableIndex, Signatur
|
||||
use cretonne::ir::{self, InstBuilder};
|
||||
use cretonne::ir::types::*;
|
||||
use cretonne::cursor::FuncCursor;
|
||||
use cretonne::settings;
|
||||
|
||||
/// 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
|
||||
@@ -18,23 +19,32 @@ pub struct DummyRuntime {
|
||||
|
||||
// Names of imported functions.
|
||||
imported_funcs: Vec<ir::FunctionName>,
|
||||
|
||||
// Compilation setting flags.
|
||||
flags: settings::Flags,
|
||||
}
|
||||
|
||||
impl DummyRuntime {
|
||||
/// Allocates the runtime data structures.
|
||||
pub fn new() -> Self {
|
||||
/// Allocates the runtime data structures with default flags.
|
||||
pub fn default() -> Self {
|
||||
Self::with_flags(settings::Flags::new(&settings::builder()))
|
||||
}
|
||||
|
||||
/// Allocates the runtime data structures with the given flags.
|
||||
pub fn with_flags(flags: settings::Flags) -> Self {
|
||||
Self {
|
||||
signatures: Vec::new(),
|
||||
globals: Vec::new(),
|
||||
func_types: Vec::new(),
|
||||
imported_funcs: Vec::new(),
|
||||
flags,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FuncEnvironment for DummyRuntime {
|
||||
fn native_pointer(&self) -> ir::Type {
|
||||
ir::types::I64
|
||||
fn flags(&self) -> &settings::Flags {
|
||||
&self.flags
|
||||
}
|
||||
|
||||
fn make_global(&self, func: &mut ir::Function, index: GlobalIndex) -> GlobalValue {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
//! trait `WasmRuntime`.
|
||||
use cretonne::ir::{self, InstBuilder};
|
||||
use cretonne::cursor::FuncCursor;
|
||||
use cretonne::settings::Flags;
|
||||
use translation_utils::{SignatureIndex, FunctionIndex, TableIndex, GlobalIndex, MemoryIndex,
|
||||
Global, Table, Memory};
|
||||
|
||||
@@ -26,10 +27,19 @@ pub enum GlobalValue {
|
||||
/// IL. The function environment provides information about the WebAssembly module as well as the
|
||||
/// runtime environment.
|
||||
pub trait FuncEnvironment {
|
||||
/// Get the flags for the current compilation.
|
||||
fn flags(&self) -> &Flags;
|
||||
|
||||
/// Get the Cretonne integer type to use for native pointers.
|
||||
///
|
||||
/// This should be `I64` for 64-bit architectures and `I32` for 32-bit architectures.
|
||||
fn native_pointer(&self) -> ir::Type;
|
||||
/// This returns `I64` for 64-bit architectures and `I32` for 32-bit architectures.
|
||||
fn native_pointer(&self) -> ir::Type {
|
||||
if self.flags().is_64bit() {
|
||||
ir::types::I64
|
||||
} else {
|
||||
ir::types::I32
|
||||
}
|
||||
}
|
||||
|
||||
/// Set up the necessary preamble definitions in `func` to access the global variable
|
||||
/// identified by `index`.
|
||||
@@ -138,7 +148,7 @@ pub trait FuncEnvironment {
|
||||
|
||||
/// 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.
|
||||
/// by the user, they are only for `cretonne-wasm` internal use.
|
||||
pub trait WasmRuntime: FuncEnvironment {
|
||||
/// Declares a function signature to the runtime.
|
||||
fn declare_signature(&mut self, sig: &ir::Signature);
|
||||
|
||||
Reference in New Issue
Block a user