wasmtime_internal_cranelift/func_environ/stack_switching/
fatpointer.rs1use cranelift_codegen::ir;
2use cranelift_codegen::ir::InstBuilder;
3
4pub fn fatpointer_type(env: &crate::func_environ::FuncEnvironment) -> ir::Type {
11 let ptr_bits = env.pointer_type().bits();
12 ir::Type::int((2 * ptr_bits).try_into().unwrap()).unwrap()
13}
14
15pub(crate) fn deconstruct<'a>(
19 env: &mut crate::func_environ::FuncEnvironment<'a>,
20 pos: &mut cranelift_codegen::cursor::FuncCursor,
21 contobj: ir::Value,
22) -> (ir::Value, ir::Value) {
23 debug_assert_eq!(pos.func.dfg.value_type(contobj), fatpointer_type(env));
24 let ptr_ty = env.pointer_type();
25 let ptr_bits = ptr_ty.bits();
26
27 let contref = pos.ins().ireduce(ptr_ty, contobj);
28 let shifted = pos.ins().ushr_imm(contobj, i64::from(ptr_bits));
29 let revision_counter = pos.ins().ireduce(ptr_ty, shifted);
30
31 (revision_counter, contref)
32}
33
34pub(crate) fn construct<'a>(
37 env: &mut crate::func_environ::FuncEnvironment<'a>,
38 pos: &mut cranelift_codegen::cursor::FuncCursor,
39 revision_counter: ir::Value,
40 contref_addr: ir::Value,
41) -> ir::Value {
42 let ptr_ty = env.pointer_type();
43 let ptr_bits = ptr_ty.bits();
44 let fat_ptr_ty = fatpointer_type(env);
45
46 debug_assert_eq!(pos.func.dfg.value_type(contref_addr), ptr_ty);
47 debug_assert_eq!(pos.func.dfg.value_type(revision_counter), ptr_ty);
48
49 let contref_addr = pos.ins().uextend(fat_ptr_ty, contref_addr);
50 let revision_counter = pos.ins().uextend(fat_ptr_ty, revision_counter);
51 let shifted_counter = pos.ins().ishl_imm(revision_counter, i64::from(ptr_bits));
52 let contobj = pos.ins().bor(shifted_counter, contref_addr);
53
54 contobj
55}