cranelift_wasm/
translation_utils.rs1use crate::environ::TargetEnvironment;
3use crate::WasmResult;
4use core::convert::TryInto;
5use core::u32;
6use cranelift_codegen::ir;
7use cranelift_frontend::FunctionBuilder;
8#[cfg(feature = "enable-serde")]
9use serde::{Deserialize, Serialize};
10use wasmparser::{FuncValidator, WasmFuncType, WasmModuleResources};
11
12pub fn blocktype_params_results<'a, T>(
14 validator: &'a FuncValidator<T>,
15 ty: wasmparser::BlockType,
16) -> WasmResult<(
17 impl ExactSizeIterator<Item = wasmparser::ValType> + Clone + 'a,
18 impl ExactSizeIterator<Item = wasmparser::ValType> + Clone + 'a,
19)>
20where
21 T: WasmModuleResources,
22{
23 return Ok(match ty {
24 wasmparser::BlockType::Empty => {
25 let params: &'static [wasmparser::ValType] = &[];
26 let results: &'static [wasmparser::ValType] = &[];
27 (
28 itertools::Either::Left(params.iter().copied()),
29 itertools::Either::Left(results.iter().copied()),
30 )
31 }
32 wasmparser::BlockType::Type(ty) => {
33 let params: &'static [wasmparser::ValType] = &[];
34 let results: &'static [wasmparser::ValType] = match ty {
35 wasmparser::ValType::I32 => &[wasmparser::ValType::I32],
36 wasmparser::ValType::I64 => &[wasmparser::ValType::I64],
37 wasmparser::ValType::F32 => &[wasmparser::ValType::F32],
38 wasmparser::ValType::F64 => &[wasmparser::ValType::F64],
39 wasmparser::ValType::V128 => &[wasmparser::ValType::V128],
40 wasmparser::ValType::EXTERNREF => &[wasmparser::ValType::EXTERNREF],
41 wasmparser::ValType::FUNCREF => &[wasmparser::ValType::FUNCREF],
42 wasmparser::ValType::Ref(_) => unimplemented!("function references proposal"),
43 };
44 (
45 itertools::Either::Left(params.iter().copied()),
46 itertools::Either::Left(results.iter().copied()),
47 )
48 }
49 wasmparser::BlockType::FuncType(ty_index) => {
50 let ty = validator
51 .resources()
52 .func_type_at(ty_index)
53 .expect("should be valid");
54 (
55 itertools::Either::Right(ty.inputs()),
56 itertools::Either::Right(ty.outputs()),
57 )
58 }
59 });
60}
61
62pub fn block_with_params<PE: TargetEnvironment + ?Sized>(
64 builder: &mut FunctionBuilder,
65 params: impl IntoIterator<Item = wasmparser::ValType>,
66 environ: &PE,
67) -> WasmResult<ir::Block> {
68 let block = builder.create_block();
69 for ty in params {
70 match ty {
71 wasmparser::ValType::I32 => {
72 builder.append_block_param(block, ir::types::I32);
73 }
74 wasmparser::ValType::I64 => {
75 builder.append_block_param(block, ir::types::I64);
76 }
77 wasmparser::ValType::F32 => {
78 builder.append_block_param(block, ir::types::F32);
79 }
80 wasmparser::ValType::F64 => {
81 builder.append_block_param(block, ir::types::F64);
82 }
83 wasmparser::ValType::Ref(ty) => {
84 builder.append_block_param(block, environ.reference_type(ty.try_into()?));
85 }
86 wasmparser::ValType::V128 => {
87 builder.append_block_param(block, ir::types::I8X16);
88 }
89 }
90 }
91 Ok(block)
92}
93
94pub fn f32_translation(x: wasmparser::Ieee32) -> ir::immediates::Ieee32 {
96 ir::immediates::Ieee32::with_bits(x.bits())
97}
98
99pub fn f64_translation(x: wasmparser::Ieee64) -> ir::immediates::Ieee64 {
101 ir::immediates::Ieee64::with_bits(x.bits())
102}
103
104pub fn get_vmctx_value_label() -> ir::ValueLabel {
106 const VMCTX_LABEL: u32 = 0xffff_fffe;
107 ir::ValueLabel::from_u32(VMCTX_LABEL)
108}