cranelift-wasm: support multi-value Wasm (#1049)
This commit introduces initial support for multi-value Wasm. Wasm blocks and calls can now take and return an arbitrary number of values. The encoding for multi-value blocks means that we need to keep the contents of the "Types" section around when translating function bodies. To do this, we introduce a `WasmTypesMap` type that maps the type indices to their parameters and returns, construct it when parsing the "Types" section, and shepherd it through a bunch of functions and methods when translating function bodies.
This commit is contained in:
@@ -5,7 +5,9 @@
|
||||
//! [wasmtime-environ]: https://crates.io/crates/wasmtime-environ
|
||||
//! [Wasmtime]: https://github.com/CraneStation/wasmtime
|
||||
|
||||
use crate::environ::{FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode, WasmResult};
|
||||
use crate::environ::{
|
||||
FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode, WasmResult, WasmTypesMap,
|
||||
};
|
||||
use crate::func_translator::FuncTranslator;
|
||||
use crate::translation_utils::{
|
||||
DefinedFuncIndex, FuncIndex, Global, GlobalIndex, Memory, MemoryIndex, SignatureIndex, Table,
|
||||
@@ -529,6 +531,7 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment {
|
||||
|
||||
fn define_function_body(
|
||||
&mut self,
|
||||
wasm_types: &WasmTypesMap,
|
||||
body_bytes: &'data [u8],
|
||||
body_offset: usize,
|
||||
) -> WasmResult<()> {
|
||||
@@ -542,8 +545,13 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment {
|
||||
if self.debug_info {
|
||||
func.collect_debug_info();
|
||||
}
|
||||
self.trans
|
||||
.translate(body_bytes, body_offset, &mut func, &mut func_environ)?;
|
||||
self.trans.translate(
|
||||
wasm_types,
|
||||
body_bytes,
|
||||
body_offset,
|
||||
&mut func,
|
||||
&mut func_environ,
|
||||
)?;
|
||||
func
|
||||
};
|
||||
self.func_bytecode_sizes.push(body_bytes.len());
|
||||
|
||||
@@ -7,4 +7,5 @@ mod spec;
|
||||
pub use crate::environ::dummy::DummyEnvironment;
|
||||
pub use crate::environ::spec::{
|
||||
FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode, WasmError, WasmResult,
|
||||
WasmTypesMap,
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@ use cranelift_codegen::cursor::FuncCursor;
|
||||
use cranelift_codegen::ir::immediates::Offset32;
|
||||
use cranelift_codegen::ir::{self, InstBuilder};
|
||||
use cranelift_codegen::isa::TargetFrontendConfig;
|
||||
use cranelift_entity::PrimaryMap;
|
||||
use cranelift_frontend::FunctionBuilder;
|
||||
use failure_derive::Fail;
|
||||
use std::boxed::Box;
|
||||
@@ -103,6 +104,24 @@ pub enum ReturnMode {
|
||||
FallthroughReturn,
|
||||
}
|
||||
|
||||
/// A map containing a Wasm module's original, raw signatures.
|
||||
///
|
||||
/// This is used for translating multi-value Wasm blocks inside functions, which
|
||||
/// are encoded to refer to their type signature via index.
|
||||
#[derive(Debug)]
|
||||
pub struct WasmTypesMap {
|
||||
pub(crate) inner:
|
||||
PrimaryMap<SignatureIndex, (Box<[wasmparser::Type]>, Box<[wasmparser::Type]>)>,
|
||||
}
|
||||
|
||||
impl WasmTypesMap {
|
||||
pub(crate) fn new() -> Self {
|
||||
WasmTypesMap {
|
||||
inner: PrimaryMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Environment affecting the translation of a single WebAssembly function.
|
||||
///
|
||||
/// A `FuncEnvironment` trait object is required to translate a WebAssembly function to Cranelift
|
||||
@@ -449,6 +468,7 @@ pub trait ModuleEnvironment<'data> {
|
||||
/// functions is already provided by `reserve_func_types`.
|
||||
fn define_function_body(
|
||||
&mut self,
|
||||
wasm_types: &WasmTypesMap,
|
||||
body_bytes: &'data [u8],
|
||||
body_offset: usize,
|
||||
) -> WasmResult<()>;
|
||||
|
||||
Reference in New Issue
Block a user