diff --git a/crates/c-api/include/wasmtime.h b/crates/c-api/include/wasmtime.h index 972dfb2f8e..ee2c2fc002 100644 --- a/crates/c-api/include/wasmtime.h +++ b/crates/c-api/include/wasmtime.h @@ -299,6 +299,17 @@ WASM_API_EXTERN own wasmtime_error_t* wasmtime_wat2wasm( own wasm_byte_vec_t *ret ); +/** + * \brief Perform garbage collection within the given store. + * + * Garbage collects `externref`s that are used within this store. Any + * `externref`s that are discovered to be unreachable by other code or objects + * will have their finalizers run. + * + * The `store` argument must not be NULL. + */ +WASM_API_EXTERN void wasmtime_store_gc(wasm_store_t* store); + /** * \typedef wasmtime_linker_t * \brief Convenience alias for #wasmtime_linker_t diff --git a/crates/c-api/src/store.rs b/crates/c-api/src/store.rs index 625b3831ea..018f06729c 100644 --- a/crates/c-api/src/store.rs +++ b/crates/c-api/src/store.rs @@ -17,6 +17,11 @@ pub extern "C" fn wasm_store_new(engine: &wasm_engine_t) -> Box { }) } +#[no_mangle] +pub extern "C" fn wasmtime_store_gc(store: &wasm_store_t) { + store.store.gc(); +} + #[repr(C)] pub struct wasmtime_interrupt_handle_t { handle: InterruptHandle, diff --git a/examples/externref.c b/examples/externref.c index ded28bd072..4ec007ffa7 100644 --- a/examples/externref.c +++ b/examples/externref.c @@ -82,6 +82,9 @@ int main() { printf("Creating new `externref`...\n"); // Create a new `externref` value. + // + // Note that if you need clean up for after the externref is reclaimed, you + // can use `wasmtime_externref_new_with_finalizer`. wasm_val_t externref; wasmtime_externref_new("Hello, World!", &externref); assert(externref.kind == WASM_ANYREF); @@ -148,6 +151,11 @@ int main() { assert(results[0].kind == WASM_ANYREF); assert(wasm_ref_same(results[0].of.ref, externref.of.ref)); + // We can GC any now-unused references to our externref that the store is + // holding. + printf("GCing within the store...\n"); + wasmtime_store_gc(store); + // Clean up after ourselves at this point printf("All finished!\n"); ret = 0; diff --git a/examples/externref.rs b/examples/externref.rs index b301dba241..c42b543467 100644 --- a/examples/externref.rs +++ b/examples/externref.rs @@ -46,6 +46,9 @@ fn main() -> Result<()> { assert!(ret.is_some()); assert!(ret.unwrap().ptr_eq(&externref)); + println!("GCing within the store..."); + store.gc(); + println!("Done."); Ok(()) }