Skip to content

Commit 8db0828

Browse files
committed
Expose GC refs to Wasm in gc_alloc_raw libcall
As we are returning a GC reference to Wasm, we need to mark that GC reference as exposed to Wasm. Fixes bytecodealliance#9669
1 parent 6336065 commit 8db0828

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

crates/wasmtime/src/runtime/vm/libcalls.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,14 @@ unsafe fn gc_alloc_raw(
529529
}
530530
};
531531

532-
Ok(gc_ref.as_raw_u32())
532+
let raw = gc_ref.as_raw_u32();
533+
534+
store
535+
.store_opaque_mut()
536+
.unwrap_gc_store_mut()
537+
.expose_gc_ref_to_wasm(gc_ref);
538+
539+
Ok(raw)
533540
}
534541

535542
// Intern a `funcref` into the GC heap, returning its `FuncRefTableId`.

tests/all/gc.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,3 +1003,52 @@ fn ref_matches() -> Result<()> {
10031003

10041004
Ok(())
10051005
}
1006+
1007+
#[test]
1008+
fn issue_9669() -> Result<()> {
1009+
let _ = env_logger::try_init();
1010+
1011+
let mut config = Config::new();
1012+
config.wasm_function_references(true);
1013+
config.wasm_gc(true);
1014+
config.collector(Collector::DeferredReferenceCounting);
1015+
1016+
let engine = Engine::new(&config)?;
1017+
1018+
let module = Module::new(
1019+
&engine,
1020+
r#"
1021+
(module
1022+
(type $empty (struct))
1023+
(type $thing (struct
1024+
(field $field1 (ref $empty))
1025+
(field $field2 (ref $empty))
1026+
))
1027+
1028+
(func (export "run")
1029+
(local $object (ref $thing))
1030+
1031+
struct.new $empty
1032+
struct.new $empty
1033+
struct.new $thing
1034+
1035+
local.tee $object
1036+
struct.get $thing $field1
1037+
drop
1038+
1039+
local.get $object
1040+
struct.get $thing $field2
1041+
drop
1042+
)
1043+
)
1044+
"#,
1045+
)?;
1046+
1047+
let mut store = Store::new(&engine, ());
1048+
let instance = Instance::new(&mut store, &module, &[])?;
1049+
1050+
let func = instance.get_typed_func::<(), ()>(&mut store, "run")?;
1051+
func.call(&mut store, ())?;
1052+
1053+
Ok(())
1054+
}

0 commit comments

Comments
 (0)