Skip to content

Commit 4383248

Browse files
authored
Fix OwnedRooted<T>::wasm_ty_store missing i31ref check (#12451)
1 parent 49ca138 commit 4383248

2 files changed

Lines changed: 47 additions & 1 deletion

File tree

crates/wasmtime/src/runtime/gc/enabled/rooting.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1827,7 +1827,15 @@ where
18271827
val_raw: impl Fn(u32) -> ValRaw,
18281828
) -> Result<()> {
18291829
let gc_ref = self.try_clone_gc_ref(store)?;
1830-
let raw = store.require_gc_store_mut()?.expose_gc_ref_to_wasm(gc_ref);
1830+
1831+
let raw = match store.optional_gc_store_mut() {
1832+
Some(s) => s.expose_gc_ref_to_wasm(gc_ref),
1833+
None => {
1834+
debug_assert!(gc_ref.is_i31());
1835+
gc_ref.as_raw_non_zero_u32()
1836+
}
1837+
};
1838+
18311839
ptr.write(val_raw(raw.get()));
18321840
Ok(())
18331841
}

tests/all/i31ref.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,41 @@ fn i31ref_to_raw_round_trip() -> Result<()> {
4040

4141
Ok(())
4242
}
43+
44+
#[test]
45+
#[cfg_attr(miri, ignore)]
46+
fn owned_rooted_i31ref_through_typed_wasm_func() -> Result<()> {
47+
// OwnedRooted<AnyRef>::wasm_ty_store should handle i31ref values without
48+
// requiring a GC heap to be allocated.
49+
50+
let mut config = Config::new();
51+
config.wasm_function_references(true);
52+
config.wasm_gc(true);
53+
54+
let engine = Engine::new(&config)?;
55+
let mut store = Store::new(&engine, ());
56+
57+
let module = Module::new(
58+
&engine,
59+
r#"(module (func (export "f") (param (ref null any)) (result (ref null any)) local.get 0))"#,
60+
)?;
61+
let instance = Instance::new(&mut store, &module, &[])?;
62+
let f = instance.get_typed_func::<Option<OwnedRooted<AnyRef>>, Option<OwnedRooted<AnyRef>>>(
63+
&mut store, "f",
64+
)?;
65+
66+
// No GC heap objects created; the store has no GcStore allocated yet.
67+
let anyref = AnyRef::from_i31(&mut store, I31::wrapping_u32(42));
68+
let owned = anyref.to_owned_rooted(&mut store)?;
69+
let result = f.call(&mut store, Some(owned))?.unwrap();
70+
assert_eq!(
71+
result
72+
.to_rooted(&mut store)
73+
.as_i31(&store)?
74+
.unwrap()
75+
.get_u32(),
76+
42
77+
);
78+
79+
Ok(())
80+
}

0 commit comments

Comments
 (0)