This commit adds the inital support to allow reftypes to flow through the program when targetting aarch64. It also adds a fix to the `ModuleTranslationState` needed to send R32/R64 types over from the SpiderMonkey embedding. This commit does not include any support for safepoints in aarch64 or the `MachInst` infrastructure; that is in the next commit. This commit also makes a drive-by improvement to `Bint`, avoiding an unneeded zero-extension op when the extended value comes directly from a conditional-set (which produces a full-width 0 or 1).
71 lines
2.6 KiB
Rust
71 lines
2.6 KiB
Rust
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 })
|
|
}
|
|
}
|