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:
@@ -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(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user