1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
use crate::{SignatureIndex, WasmError, WasmResult};
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::ValType]>, Box<[wasmparser::ValType]>)>;
/// 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::ValType> {
Ok(match ty {
types::I32 => wasmparser::ValType::I32,
types::I64 => wasmparser::ValType::I64,
types::F32 => wasmparser::ValType::F32,
types::F64 => wasmparser::ValType::F64,
types::R32 | types::R64 => wasmparser::ValType::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::ValType> = args
.iter()
.map(|&ty| cranelift_to_wasmparser_type(ty))
.collect::<Result<_, _>>()?;
let results: Vec<wasmparser::ValType> = 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 })
}
}