diff --git a/cranelift/wasm/src/state/module_state.rs b/cranelift/wasm/src/state/module_state.rs index e997305858..4f6ce35394 100644 --- a/cranelift/wasm/src/state/module_state.rs +++ b/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 { + 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 { + let mut wasm_types = PrimaryMap::with_capacity(sigs.len()); + for &(ref args, ref results) in sigs { + let args: Vec = args + .iter() + .map(|&ty| cranelift_to_wasmparser_type(ty)) + .collect::>()?; + let results: Vec = results + .iter() + .map(|&ty| cranelift_to_wasmparser_type(ty)) + .collect::>()?; + wasm_types.push((args.into_boxed_slice(), results.into_boxed_slice())); + } + Ok(Self { wasm_types }) + } }