1*a631d20aSPaul Osborne use cranelift_codegen::ir;
2*a631d20aSPaul Osborne use cranelift_codegen::ir::InstBuilder;
3*a631d20aSPaul Osborne 
4*a631d20aSPaul Osborne /// Returns the Cranelift type used to represent all of the following:
5*a631d20aSPaul Osborne /// - wasm values of type `(ref null $ct)` and `(ref $ct)`
6*a631d20aSPaul Osborne /// - equivalently: runtime values of type `Option<VMContObj>` and `VMContObj`
7*a631d20aSPaul Osborne /// Note that a `VMContObj` is a fat pointer consisting of a pointer to
8*a631d20aSPaul Osborne /// `VMContRef` and a pointer-sized revision counter. We represent this as 2 words
9*a631d20aSPaul Osborne /// (pointer and usize).
fatpointer_type(env: &crate::func_environ::FuncEnvironment) -> ir::Type10*a631d20aSPaul Osborne pub fn fatpointer_type(env: &crate::func_environ::FuncEnvironment) -> ir::Type {
11*a631d20aSPaul Osborne     let ptr_bits = env.pointer_type().bits();
12*a631d20aSPaul Osborne     ir::Type::int((2 * ptr_bits).try_into().unwrap()).unwrap()
13*a631d20aSPaul Osborne }
14*a631d20aSPaul Osborne 
15*a631d20aSPaul Osborne /// Turns a (possibly null) reference to a continuation object into a tuple
16*a631d20aSPaul Osborne /// (revision, contref_ptr). If `contobj` denotes a wasm null reference, the
17*a631d20aSPaul Osborne /// contref_ptr part will be a null pointer.
deconstruct<'a>( env: &mut crate::func_environ::FuncEnvironment<'a>, pos: &mut cranelift_codegen::cursor::FuncCursor, contobj: ir::Value, ) -> (ir::Value, ir::Value)18*a631d20aSPaul Osborne pub(crate) fn deconstruct<'a>(
19*a631d20aSPaul Osborne     env: &mut crate::func_environ::FuncEnvironment<'a>,
20*a631d20aSPaul Osborne     pos: &mut cranelift_codegen::cursor::FuncCursor,
21*a631d20aSPaul Osborne     contobj: ir::Value,
22*a631d20aSPaul Osborne ) -> (ir::Value, ir::Value) {
23*a631d20aSPaul Osborne     debug_assert_eq!(pos.func.dfg.value_type(contobj), fatpointer_type(env));
24*a631d20aSPaul Osborne     let ptr_ty = env.pointer_type();
25*a631d20aSPaul Osborne     let ptr_bits = ptr_ty.bits();
26*a631d20aSPaul Osborne 
27*a631d20aSPaul Osborne     let contref = pos.ins().ireduce(ptr_ty, contobj);
28*a631d20aSPaul Osborne     let shifted = pos.ins().ushr_imm(contobj, i64::from(ptr_bits));
29*a631d20aSPaul Osborne     let revision_counter = pos.ins().ireduce(ptr_ty, shifted);
30*a631d20aSPaul Osborne 
31*a631d20aSPaul Osborne     (revision_counter, contref)
32*a631d20aSPaul Osborne }
33*a631d20aSPaul Osborne 
34*a631d20aSPaul Osborne /// Constructs a continuation object from a given contref and revision pointer.
35*a631d20aSPaul Osborne /// The contref_addr may be 0, to indicate that we want to build a wasm null reference.
construct<'a>( env: &mut crate::func_environ::FuncEnvironment<'a>, pos: &mut cranelift_codegen::cursor::FuncCursor, revision_counter: ir::Value, contref_addr: ir::Value, ) -> ir::Value36*a631d20aSPaul Osborne pub(crate) fn construct<'a>(
37*a631d20aSPaul Osborne     env: &mut crate::func_environ::FuncEnvironment<'a>,
38*a631d20aSPaul Osborne     pos: &mut cranelift_codegen::cursor::FuncCursor,
39*a631d20aSPaul Osborne     revision_counter: ir::Value,
40*a631d20aSPaul Osborne     contref_addr: ir::Value,
41*a631d20aSPaul Osborne ) -> ir::Value {
42*a631d20aSPaul Osborne     let ptr_ty = env.pointer_type();
43*a631d20aSPaul Osborne     let ptr_bits = ptr_ty.bits();
44*a631d20aSPaul Osborne     let fat_ptr_ty = fatpointer_type(env);
45*a631d20aSPaul Osborne 
46*a631d20aSPaul Osborne     debug_assert_eq!(pos.func.dfg.value_type(contref_addr), ptr_ty);
47*a631d20aSPaul Osborne     debug_assert_eq!(pos.func.dfg.value_type(revision_counter), ptr_ty);
48*a631d20aSPaul Osborne 
49*a631d20aSPaul Osborne     let contref_addr = pos.ins().uextend(fat_ptr_ty, contref_addr);
50*a631d20aSPaul Osborne     let revision_counter = pos.ins().uextend(fat_ptr_ty, revision_counter);
51*a631d20aSPaul Osborne     let shifted_counter = pos.ins().ishl_imm(revision_counter, i64::from(ptr_bits));
52*a631d20aSPaul Osborne     let contobj = pos.ins().bor(shifted_counter, contref_addr);
53*a631d20aSPaul Osborne 
54*a631d20aSPaul Osborne     contobj
55*a631d20aSPaul Osborne }
56