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:
Nick Fitzgerald
2019-10-02 12:40:35 -07:00
committed by GitHub
parent f9d802fb1d
commit 10be3e4ba8
30 changed files with 610 additions and 138 deletions

View File

@@ -7,7 +7,7 @@
//! The special case of the initialize expressions for table elements offsets or global variables
//! is handled, according to the semantics of WebAssembly, to only specific expressions that are
//! interpreted on the fly.
use crate::environ::{ModuleEnvironment, WasmResult};
use crate::environ::{ModuleEnvironment, WasmResult, WasmTypesMap};
use crate::translation_utils::{
tabletype_to_type, type_to_type, FuncIndex, Global, GlobalIndex, GlobalInit, Memory,
MemoryIndex, SignatureIndex, Table, TableElementType, TableIndex,
@@ -29,16 +29,19 @@ use wasmparser::{
/// Parses the Type section of the wasm module.
pub fn parse_type_section(
types: TypeSectionReader,
wasm_types: &mut WasmTypesMap,
environ: &mut dyn ModuleEnvironment,
) -> WasmResult<()> {
environ.reserve_signatures(types.get_count())?;
let count = types.get_count();
wasm_types.inner.reserve(count as usize);
environ.reserve_signatures(count)?;
for entry in types {
match entry? {
FuncType {
form: wasmparser::Type::Func,
ref params,
ref returns,
params,
returns,
} => {
let mut sig = Signature::new(environ.target_config().default_call_conv);
sig.params.extend(params.iter().map(|ty| {
@@ -52,6 +55,7 @@ pub fn parse_type_section(
AbiParam::new(cret_arg)
}));
environ.declare_signature(sig)?;
wasm_types.inner.push((params, returns));
}
ty => {
return Err(wasm_unsupported!(
@@ -323,13 +327,14 @@ pub fn parse_element_section<'data>(
/// Parses the Code section of the wasm module.
pub fn parse_code_section<'data>(
code: CodeSectionReader<'data>,
wasm_types: &WasmTypesMap,
environ: &mut dyn ModuleEnvironment<'data>,
) -> WasmResult<()> {
for body in code {
let mut reader = body?.get_binary_reader();
let size = reader.bytes_remaining();
let offset = reader.original_position();
environ.define_function_body(reader.read_bytes(size)?, offset)?;
environ.define_function_body(wasm_types, reader.read_bytes(size)?, offset)?;
}
Ok(())
}