Path: blob/main/crates/cranelift/src/translate/translation_utils.rs
1692 views
//! Helper functions and structures for the translation.1use crate::translate::environ::TargetEnvironment;2use core::u32;3use cranelift_codegen::ir;4use cranelift_frontend::FunctionBuilder;5use wasmparser::{FuncValidator, WasmModuleResources};6use wasmtime_environ::WasmResult;78/// Get the parameter and result types for the given Wasm blocktype.9pub fn blocktype_params_results<'a, T>(10validator: &'a FuncValidator<T>,11ty: wasmparser::BlockType,12) -> WasmResult<(13impl ExactSizeIterator<Item = wasmparser::ValType> + Clone + 'a,14impl ExactSizeIterator<Item = wasmparser::ValType> + Clone + 'a,15)>16where17T: WasmModuleResources,18{19return Ok(match ty {20wasmparser::BlockType::Empty => (21itertools::Either::Left(std::iter::empty()),22itertools::Either::Left(None.into_iter()),23),24wasmparser::BlockType::Type(ty) => (25itertools::Either::Left(std::iter::empty()),26itertools::Either::Left(Some(ty).into_iter()),27),28wasmparser::BlockType::FuncType(ty_index) => {29let ty = validator30.resources()31.sub_type_at(ty_index)32.expect("should be valid")33.unwrap_func();3435(36itertools::Either::Right(ty.params().iter().copied()),37itertools::Either::Right(ty.results().iter().copied()),38)39}40});41}4243/// Create a `Block` with the given Wasm parameters.44pub fn block_with_params<PE: TargetEnvironment + ?Sized>(45builder: &mut FunctionBuilder,46params: impl IntoIterator<Item = wasmparser::ValType>,47environ: &PE,48) -> WasmResult<ir::Block> {49let block = builder.create_block();50for ty in params {51match ty {52wasmparser::ValType::I32 => {53builder.append_block_param(block, ir::types::I32);54}55wasmparser::ValType::I64 => {56builder.append_block_param(block, ir::types::I64);57}58wasmparser::ValType::F32 => {59builder.append_block_param(block, ir::types::F32);60}61wasmparser::ValType::F64 => {62builder.append_block_param(block, ir::types::F64);63}64wasmparser::ValType::Ref(rt) => {65let hty = environ.convert_heap_type(rt.heap_type())?;66let (ty, needs_stack_map) = environ.reference_type(hty);67let val = builder.append_block_param(block, ty);68if needs_stack_map {69builder.declare_value_needs_stack_map(val);70}71}72wasmparser::ValType::V128 => {73builder.append_block_param(block, ir::types::I8X16);74}75}76}77Ok(block)78}7980/// Turns a `wasmparser` `f32` into a `Cranelift` one.81pub fn f32_translation(x: wasmparser::Ieee32) -> ir::immediates::Ieee32 {82ir::immediates::Ieee32::with_bits(x.bits())83}8485/// Turns a `wasmparser` `f64` into a `Cranelift` one.86pub fn f64_translation(x: wasmparser::Ieee64) -> ir::immediates::Ieee64 {87ir::immediates::Ieee64::with_bits(x.bits())88}8990/// Special VMContext value label. It is tracked as 0xffff_fffe label.91pub fn get_vmctx_value_label() -> ir::ValueLabel {92const VMCTX_LABEL: u32 = 0xffff_fffe;93ir::ValueLabel::from_u32(VMCTX_LABEL)94}959697