Move WasmRuntime::translate_call_indirect() into FuncEnvironment.
Add two new arguments: - table_index is the WebAssembly table referenced in the indirect call. - sig_index is the WebAssembly signature index. We still have the SigRef that was created by make_indirect_sig(), but the WebAssembly signature index may be needed for detecting type mismatches at runtime. Change the insertion location to a plain FuncCursor rather than a FunctionBuilder<Local>. The fact that cretonne-wasm uses FunctionBuilder should be an implementation detail, and the callbacks don't need to access WebAssembly locals, so they don't need the extended interface. Add a FunctionBuilder::cursor() method which creates a FuncCursor for inserting instructions in the current EBB. Also add a FuncEnvironment::translate_call() method which allows the environment to override direct calls the same way as indirect calls.
This commit is contained in:
@@ -2,8 +2,9 @@ use runtime::{FuncEnvironment, GlobalValue, WasmRuntime};
|
||||
use translation_utils::{Local, Global, Memory, Table, GlobalIndex, TableIndex, SignatureIndex,
|
||||
FunctionIndex, MemoryIndex};
|
||||
use cton_frontend::FunctionBuilder;
|
||||
use cretonne::ir::{self, Value, InstBuilder, SigRef};
|
||||
use cretonne::ir::{self, Value, InstBuilder};
|
||||
use cretonne::ir::types::*;
|
||||
use cretonne::cursor::FuncCursor;
|
||||
|
||||
/// 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
|
||||
@@ -75,6 +76,18 @@ impl FuncEnvironment for DummyRuntime {
|
||||
|
||||
func.dfg.ext_funcs.push(ir::ExtFuncData { name, signature })
|
||||
}
|
||||
|
||||
fn translate_call_indirect(
|
||||
&self,
|
||||
mut pos: FuncCursor,
|
||||
_table_index: TableIndex,
|
||||
_sig_index: SignatureIndex,
|
||||
sig_ref: ir::SigRef,
|
||||
callee: ir::Value,
|
||||
call_args: &[ir::Value],
|
||||
) -> ir::Inst {
|
||||
pos.ins().call_indirect(sig_ref, callee, call_args)
|
||||
}
|
||||
}
|
||||
|
||||
impl WasmRuntime for DummyRuntime {
|
||||
@@ -84,16 +97,6 @@ impl WasmRuntime for DummyRuntime {
|
||||
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 declare_signature(&mut self, sig: &ir::Signature) {
|
||||
self.signatures.push(sig.clone());
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
//! 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, SigRef};
|
||||
use cretonne::ir::{self, Value, InstBuilder};
|
||||
use cretonne::cursor::FuncCursor;
|
||||
use translation_utils::{Local, SignatureIndex, FunctionIndex, TableIndex, GlobalIndex,
|
||||
MemoryIndex, Global, Table, Memory};
|
||||
|
||||
@@ -64,6 +65,42 @@ pub trait FuncEnvironment {
|
||||
/// The function's signature will only be used for direct calls, even if the module has
|
||||
/// indirect calls with the same WebAssembly type.
|
||||
fn make_direct_func(&self, func: &mut ir::Function, index: FunctionIndex) -> ir::FuncRef;
|
||||
|
||||
/// Translate a `call_indirect` WebAssembly instruction at `pos`.
|
||||
///
|
||||
/// Insert instructions at `pos` for an indirect call to the function `callee` in the table
|
||||
/// `table_index` with WebAssembly signature `sig_index`. The `callee` value will have type
|
||||
/// `i32`.
|
||||
///
|
||||
/// The signature `sig_ref` was previously created by `make_indirect_sig()`.
|
||||
///
|
||||
/// Return the call instruction whose results are the WebAssembly return values.
|
||||
fn translate_call_indirect(
|
||||
&self,
|
||||
pos: FuncCursor,
|
||||
table_index: TableIndex,
|
||||
sig_index: SignatureIndex,
|
||||
sig_ref: ir::SigRef,
|
||||
callee: ir::Value,
|
||||
call_args: &[ir::Value],
|
||||
) -> ir::Inst;
|
||||
|
||||
/// Translate a `call` WebAssembly instruction at `pos`.
|
||||
///
|
||||
/// Insert instructions at `pos` for a direct call to the function `callee_index`.
|
||||
///
|
||||
/// The function reference `callee` was previously created by `make_direct_func()`.
|
||||
///
|
||||
/// Return the call instruction whose results are the WebAssembly return values.
|
||||
fn translate_call(
|
||||
&self,
|
||||
mut pos: FuncCursor,
|
||||
_callee_index: FunctionIndex,
|
||||
callee: ir::FuncRef,
|
||||
call_args: &[ir::Value],
|
||||
) -> ir::Inst {
|
||||
pos.ins().call(callee, call_args)
|
||||
}
|
||||
}
|
||||
|
||||
/// An object satisfyng the `WasmRuntime` trait can be passed as argument to the
|
||||
@@ -108,13 +145,4 @@ pub trait WasmRuntime: FuncEnvironment {
|
||||
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;
|
||||
/// 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];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user