11use cranelift_codegen:: ir;
22use cranelift_codegen:: ir:: InstBuilder ;
33
4- /// The Cranelift type used to represent all of the following:
4+ /// Returns the Cranelift type used to represent all of the following:
55/// - wasm values of type `(ref null $ct)` and `(ref $ct)`
66/// - equivalently: runtime values of type `Option<VMContObj>` and `VMContObj`
7- /// Note that a `VMContObj` is a fat pointer
8- /// consisting of a pointer to `VMContRef` and a 64 bit sequence
9- /// counter.
10- /// We represent this here as a 128bit value, with the same representation as
11- /// `core::mem::transmute::<i128, VMContObj>`.
12- pub const POINTER_TYPE : ir:: Type = ir:: types:: I128 ;
7+ /// Note that a `VMContObj` is a fat pointer consisting of a pointer to
8+ /// `VMContRef` and a pointer-sized revision counter. We represent this as 2 words
9+ /// (pointer and usize).
10+ pub 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+ }
1314
1415/// Turns a (possibly null) reference to a continuation object into a tuple
1516/// (revision, contref_ptr). If `contobj` denotes a wasm null reference, the
@@ -19,13 +20,13 @@ pub(crate) fn deconstruct<'a>(
1920 pos : & mut cranelift_codegen:: cursor:: FuncCursor ,
2021 contobj : ir:: Value ,
2122) -> ( ir:: Value , ir:: Value ) {
22- debug_assert_eq ! ( pos. func. dfg. value_type( contobj) , POINTER_TYPE ) ;
23+ debug_assert_eq ! ( pos. func. dfg. value_type( contobj) , fatpointer_type ( env ) ) ;
2324 let ptr_ty = env. pointer_type ( ) ;
24- assert ! ( ptr_ty. bits( ) <= 64 ) ;
25+ let ptr_bits = ptr_ty. bits ( ) ;
2526
2627 let contref = pos. ins ( ) . ireduce ( ptr_ty, contobj) ;
27- let shifted = pos. ins ( ) . ushr_imm ( contobj, 64 ) ;
28- let revision_counter = pos. ins ( ) . ireduce ( ir :: types :: I64 , shifted) ;
28+ let shifted = pos. ins ( ) . ushr_imm ( contobj, i64 :: from ( ptr_bits ) ) ;
29+ let revision_counter = pos. ins ( ) . ireduce ( ptr_ty , shifted) ;
2930
3031 ( revision_counter, contref)
3132}
@@ -38,13 +39,16 @@ pub(crate) fn construct<'a>(
3839 revision_counter : ir:: Value ,
3940 contref_addr : ir:: Value ,
4041) -> ir:: Value {
41- debug_assert_eq ! ( pos. func. dfg. value_type( contref_addr) , env. pointer_type( ) ) ;
42- debug_assert_eq ! ( pos. func. dfg. value_type( revision_counter) , ir:: types:: I64 ) ;
43- assert ! ( env. pointer_type( ) . bits( ) <= 64 ) ;
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) ;
4448
45- let contref_addr = pos. ins ( ) . uextend ( ir :: types :: I128 , contref_addr) ;
46- let revision_counter = pos. ins ( ) . uextend ( ir :: types :: I128 , revision_counter) ;
47- let shifted_counter = pos. ins ( ) . ishl_imm ( revision_counter, 64 ) ;
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 ) ) ;
4852 let contobj = pos. ins ( ) . bor ( shifted_counter, contref_addr) ;
4953
5054 contobj
0 commit comments