diff options
Diffstat (limited to 'third_party/rust/cranelift-wasm/src/state/module_state.rs')
-rw-r--r-- | third_party/rust/cranelift-wasm/src/state/module_state.rs | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/third_party/rust/cranelift-wasm/src/state/module_state.rs b/third_party/rust/cranelift-wasm/src/state/module_state.rs new file mode 100644 index 0000000000..e1b96b8c82 --- /dev/null +++ b/third_party/rust/cranelift-wasm/src/state/module_state.rs @@ -0,0 +1,70 @@ +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 = + PrimaryMap<SignatureIndex, (Box<[wasmparser::Type]>, Box<[wasmparser::Type]>)>; + +/// Contains information decoded from the Wasm module that must be referenced +/// during each Wasm function's translation. +/// +/// This is only for data that is maintained by `cranelift-wasm` itself, as +/// opposed to being maintained by the embedder. Data that is maintained by the +/// embedder is represented with `ModuleEnvironment`. +#[derive(Debug)] +pub struct ModuleTranslationState { + /// 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. + 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, + types::R32 | types::R64 => wasmparser::Type::ExternRef, + _ => { + return Err(WasmError::Unsupported(format!( + "Cannot convert Cranelift type to Wasm signature: {:?}", + ty + ))); + } + }) +} + +impl ModuleTranslationState { + /// Creates a new empty ModuleTranslationState. + pub fn new() -> Self { + Self { + 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 }) + } +} |