File tree Expand file tree Collapse file tree 2 files changed +31
-2
lines changed
crates/wasmtime/src/runtime/gc/enabled Expand file tree Collapse file tree 2 files changed +31
-2
lines changed Original file line number Diff line number Diff line change @@ -278,7 +278,11 @@ impl AnyRef {
278278 // (Not actually memory unsafe since we have indexed GC heaps.)
279279 pub ( crate ) fn _from_raw ( store : & mut AutoAssertNoGc , raw : u32 ) -> Option < Rooted < Self > > {
280280 let gc_ref = VMGcRef :: from_raw_u32 ( raw) ?;
281- let gc_ref = store. unwrap_gc_store_mut ( ) . clone_gc_ref ( & gc_ref) ;
281+ let gc_ref = if gc_ref. is_i31 ( ) {
282+ gc_ref. copy_i31 ( )
283+ } else {
284+ store. unwrap_gc_store_mut ( ) . clone_gc_ref ( & gc_ref)
285+ } ;
282286 Some ( Self :: from_cloned_gc_ref ( store, gc_ref) )
283287 }
284288
@@ -331,7 +335,11 @@ impl AnyRef {
331335
332336 pub ( crate ) unsafe fn _to_raw ( & self , store : & mut AutoAssertNoGc < ' _ > ) -> Result < u32 > {
333337 let gc_ref = self . inner . try_clone_gc_ref ( store) ?;
334- let raw = store. gc_store_mut ( ) ?. expose_gc_ref_to_wasm ( gc_ref) ;
338+ let raw = if gc_ref. is_i31 ( ) {
339+ gc_ref. as_raw_non_zero_u32 ( )
340+ } else {
341+ store. gc_store_mut ( ) ?. expose_gc_ref_to_wasm ( gc_ref)
342+ } ;
335343 Ok ( raw. get ( ) )
336344 }
337345
Original file line number Diff line number Diff line change @@ -19,3 +19,24 @@ fn always_pop_i31ref_lifo_roots() -> Result<()> {
1919
2020 Ok ( ( ) )
2121}
22+
23+ #[ test]
24+ fn i31ref_to_raw_round_trip ( ) -> Result < ( ) > {
25+ let mut config = Config :: new ( ) ;
26+ config. wasm_function_references ( true ) ;
27+ config. wasm_gc ( true ) ;
28+
29+ let engine = Engine :: new ( & config) ?;
30+ let mut store = Store :: new ( & engine, ( ) ) ;
31+
32+ // Should be able to round trip an `i31ref` to its raw representation and
33+ // back again even though we have not forced the allocation of the `GcStore`
34+ // yet.
35+ let anyref = AnyRef :: from_i31 ( & mut store, I31 :: wrapping_u32 ( 42 ) ) ;
36+ let raw = unsafe { anyref. to_raw ( & mut store) ? } ;
37+ let anyref = unsafe { AnyRef :: from_raw ( & mut store, raw) . expect ( "should be non-null" ) } ;
38+ assert ! ( anyref. is_i31( & store) ?) ;
39+ assert_eq ! ( anyref. as_i31( & store) ?. unwrap( ) . get_u32( ) , 42 ) ;
40+
41+ Ok ( ( ) )
42+ }
You can’t perform that action at this time.
0 commit comments