wasmer_compiler_cranelift/translator/
translation_utils.rs1use crate::func_environ::FuncEnvironment;
4use crate::translator::EXN_REF_TYPE;
5use cranelift_codegen::{
6 binemit::Reloc,
7 ir::{self, AbiParam},
8 isa::TargetFrontendConfig,
9};
10use cranelift_frontend::FunctionBuilder;
11use wasmer_compiler::{
12 types::relocation::RelocationKind,
13 wasmparser::{self, RefType},
14};
15use wasmer_types::{FunctionType, LibCall, Type, WasmError, WasmResult};
16
17pub fn signature_to_cranelift_ir(
19 signature: &FunctionType,
20 target_config: TargetFrontendConfig,
21) -> ir::Signature {
22 let mut sig = ir::Signature::new(target_config.default_call_conv);
23 sig.params.extend(signature.params().iter().map(|&ty| {
24 let cret_arg: ir::Type = type_to_irtype(ty, target_config)
25 .expect("only numeric types are supported in function signatures");
26 AbiParam::new(cret_arg)
27 }));
28 sig.returns.extend(signature.results().iter().map(|&ty| {
29 let cret_arg: ir::Type = type_to_irtype(ty, target_config)
30 .expect("only numeric types are supported in function signatures");
31 AbiParam::new(cret_arg)
32 }));
33 sig.params.insert(
35 0,
36 AbiParam::special(target_config.pointer_type(), ir::ArgumentPurpose::VMContext),
37 );
38 sig
39}
40
41pub fn reference_type(target_config: TargetFrontendConfig) -> WasmResult<ir::Type> {
43 Ok(target_config.pointer_type())
44}
45
46pub fn type_to_irtype(ty: Type, target_config: TargetFrontendConfig) -> WasmResult<ir::Type> {
48 match ty {
49 Type::I32 => Ok(ir::types::I32),
50 Type::I64 => Ok(ir::types::I64),
51 Type::F32 => Ok(ir::types::F32),
52 Type::F64 => Ok(ir::types::F64),
53 Type::V128 => Ok(ir::types::I8X16),
54 Type::ExternRef | Type::FuncRef => reference_type(target_config),
55 Type::ExceptionRef => Ok(EXN_REF_TYPE),
56 }
58}
59
60pub fn irlibcall_to_libcall(libcall: ir::LibCall) -> LibCall {
62 match libcall {
63 ir::LibCall::Probestack => LibCall::Probestack,
64 ir::LibCall::CeilF32 => LibCall::CeilF32,
65 ir::LibCall::CeilF64 => LibCall::CeilF64,
66 ir::LibCall::FloorF32 => LibCall::FloorF32,
67 ir::LibCall::FloorF64 => LibCall::FloorF64,
68 ir::LibCall::TruncF32 => LibCall::TruncF32,
69 ir::LibCall::TruncF64 => LibCall::TruncF64,
70 ir::LibCall::NearestF32 => LibCall::NearestF32,
71 ir::LibCall::NearestF64 => LibCall::NearestF64,
72 _ => panic!("Unsupported libcall"),
73 }
74}
75
76pub fn irreloc_to_relocationkind(reloc: Reloc) -> RelocationKind {
78 match reloc {
79 Reloc::Abs4 => RelocationKind::Abs4,
80 Reloc::Abs8 => RelocationKind::Abs8,
81 Reloc::X86PCRel4 => RelocationKind::PCRel4,
82 Reloc::X86CallPCRel4 => RelocationKind::X86CallPCRel4,
83 Reloc::X86CallPLTRel4 => RelocationKind::X86CallPLTRel4,
84 Reloc::X86GOTPCRel4 => RelocationKind::X86GOTPCRel4,
85 Reloc::Arm64Call => RelocationKind::Arm64Call,
86 Reloc::RiscvCallPlt => RelocationKind::RiscvCall,
87 _ => panic!("The relocation {reloc} is not yet supported."),
88 }
89}
90
91pub fn block_with_params<'a>(
93 builder: &mut FunctionBuilder,
94 params: impl Iterator<Item = &'a wasmparser::ValType>,
95 environ: &FuncEnvironment<'_>,
96) -> WasmResult<ir::Block> {
97 let block = builder.create_block();
98 for ty in params.into_iter() {
99 match ty {
100 wasmparser::ValType::I32 => {
101 builder.append_block_param(block, ir::types::I32);
102 }
103 wasmparser::ValType::I64 => {
104 builder.append_block_param(block, ir::types::I64);
105 }
106 wasmparser::ValType::F32 => {
107 builder.append_block_param(block, ir::types::F32);
108 }
109 wasmparser::ValType::F64 => {
110 builder.append_block_param(block, ir::types::F64);
111 }
112 wasmparser::ValType::Ref(ty) => {
113 if ty.is_extern_ref() || ty.is_func_ref() {
114 builder.append_block_param(block, environ.reference_type());
115 } else if ty == &RefType::EXNREF || ty == &RefType::EXN {
116 builder.append_block_param(block, EXN_REF_TYPE);
118 } else {
119 return Err(WasmError::Unsupported(format!(
120 "unsupported reference type: {ty:?}"
121 )));
122 }
123 }
124 wasmparser::ValType::V128 => {
125 builder.append_block_param(block, ir::types::I8X16);
126 }
127 }
128 }
129 Ok(block)
130}
131
132pub fn f32_translation(x: wasmparser::Ieee32) -> ir::immediates::Ieee32 {
134 ir::immediates::Ieee32::with_bits(x.bits())
135}
136
137pub fn f64_translation(x: wasmparser::Ieee64) -> ir::immediates::Ieee64 {
139 ir::immediates::Ieee64::with_bits(x.bits())
140}
141
142pub fn get_vmctx_value_label() -> ir::ValueLabel {
144 const VMCTX_LABEL: u32 = 0xffff_fffe;
145 ir::ValueLabel::from_u32(VMCTX_LABEL)
146}