Path: blob/main/crates/cranelift/src/func_environ/stack_switching/fatpointer.rs
1693 views
use cranelift_codegen::ir;1use cranelift_codegen::ir::InstBuilder;23/// Returns the Cranelift type used to represent all of the following:4/// - wasm values of type `(ref null $ct)` and `(ref $ct)`5/// - equivalently: runtime values of type `Option<VMContObj>` and `VMContObj`6/// Note that a `VMContObj` is a fat pointer consisting of a pointer to7/// `VMContRef` and a pointer-sized revision counter. We represent this as 2 words8/// (pointer and usize).9pub fn fatpointer_type(env: &crate::func_environ::FuncEnvironment) -> ir::Type {10let ptr_bits = env.pointer_type().bits();11ir::Type::int((2 * ptr_bits).try_into().unwrap()).unwrap()12}1314/// Turns a (possibly null) reference to a continuation object into a tuple15/// (revision, contref_ptr). If `contobj` denotes a wasm null reference, the16/// contref_ptr part will be a null pointer.17pub(crate) fn deconstruct<'a>(18env: &mut crate::func_environ::FuncEnvironment<'a>,19pos: &mut cranelift_codegen::cursor::FuncCursor,20contobj: ir::Value,21) -> (ir::Value, ir::Value) {22debug_assert_eq!(pos.func.dfg.value_type(contobj), fatpointer_type(env));23let ptr_ty = env.pointer_type();24let ptr_bits = ptr_ty.bits();2526let contref = pos.ins().ireduce(ptr_ty, contobj);27let shifted = pos.ins().ushr_imm(contobj, i64::from(ptr_bits));28let revision_counter = pos.ins().ireduce(ptr_ty, shifted);2930(revision_counter, contref)31}3233/// Constructs a continuation object from a given contref and revision pointer.34/// The contref_addr may be 0, to indicate that we want to build a wasm null reference.35pub(crate) fn construct<'a>(36env: &mut crate::func_environ::FuncEnvironment<'a>,37pos: &mut cranelift_codegen::cursor::FuncCursor,38revision_counter: ir::Value,39contref_addr: ir::Value,40) -> ir::Value {41let ptr_ty = env.pointer_type();42let ptr_bits = ptr_ty.bits();43let fat_ptr_ty = fatpointer_type(env);4445debug_assert_eq!(pos.func.dfg.value_type(contref_addr), ptr_ty);46debug_assert_eq!(pos.func.dfg.value_type(revision_counter), ptr_ty);4748let contref_addr = pos.ins().uextend(fat_ptr_ty, contref_addr);49let revision_counter = pos.ins().uextend(fat_ptr_ty, revision_counter);50let shifted_counter = pos.ins().ishl_imm(revision_counter, i64::from(ptr_bits));51let contobj = pos.ins().bor(shifted_counter, contref_addr);5253contobj54}555657