Browse Source

Allow ModuleTranslationState to be constructed with signatures.

This is needed to allow SpiderMonkey to provide function signature types
to the wasm translator when it uses Cranelift as a backend without
using the wasm translator to parse the entire module. There is perhaps a
better long-term design here where we allow an embedding that already
parses the Wasm module (such as SpiderMonkey) to provide information in
a more principled way, this suffices for now.

Patch is inspired by Ben's patch in
https://bugzilla.mozilla.org/show_bug.cgi?id=1641504, but does not
expose `wasmparser` types directly, instead using Cranelift types across
the API boundary.
pull/1834/head
Chris Fallin 4 years ago
parent
commit
59307625c8
  1. 38
      cranelift/wasm/src/state/module_state.rs

38
cranelift/wasm/src/state/module_state.rs

@ -1,6 +1,9 @@
use crate::environ::{WasmError, WasmResult};
use crate::translation_utils::SignatureIndex;
use cranelift_codegen::ir::{types, Type};
use cranelift_entity::PrimaryMap;
use std::boxed::Box;
use std::vec::Vec;
/// Map of signatures to a function's parameter and return types.
pub(crate) type WasmTypes =
@ -21,6 +24,21 @@ pub struct ModuleTranslationState {
pub(crate) wasm_types: WasmTypes,
}
fn cranelift_to_wasmparser_type(ty: Type) -> WasmResult<wasmparser::Type> {
Ok(match ty {
types::I32 => wasmparser::Type::I32,
types::I64 => wasmparser::Type::I64,
types::F32 => wasmparser::Type::F32,
types::F64 => wasmparser::Type::F64,
_ => {
return Err(WasmError::Unsupported(format!(
"Cannot convert Cranelift type to Wasm signature: {:?}",
ty
)));
}
})
}
impl ModuleTranslationState {
/// Creates a new empty ModuleTranslationState.
pub fn new() -> Self {
@ -28,4 +46,24 @@ impl ModuleTranslationState {
wasm_types: PrimaryMap::new(),
}
}
/// Create a new ModuleTranslationState with the given function signatures,
/// provided in terms of Cranelift types. The provided slice of signatures
/// is indexed by signature number, and contains pairs of (args, results)
/// slices.
pub fn from_func_sigs(sigs: &[(&[Type], &[Type])]) -> WasmResult<Self> {
let mut wasm_types = PrimaryMap::with_capacity(sigs.len());
for &(ref args, ref results) in sigs {
let args: Vec<wasmparser::Type> = args
.iter()
.map(|&ty| cranelift_to_wasmparser_type(ty))
.collect::<Result<_, _>>()?;
let results: Vec<wasmparser::Type> = results
.iter()
.map(|&ty| cranelift_to_wasmparser_type(ty))
.collect::<Result<_, _>>()?;
wasm_types.push((args.into_boxed_slice(), results.into_boxed_slice()));
}
Ok(Self { wasm_types })
}
}

Loading…
Cancel
Save