Skip to content

GC: replace ManuallyRooted with OwnedRooted.#11514

Merged
cfallin merged 10 commits intobytecodealliance:mainfrom
cfallin:owned-rooted-gc
Aug 26, 2025
Merged

GC: replace ManuallyRooted with OwnedRooted.#11514
cfallin merged 10 commits intobytecodealliance:mainfrom
cfallin:owned-rooted-gc

Conversation

@cfallin
Copy link
Member

@cfallin cfallin commented Aug 22, 2025

This implements the ideas from #11445: it replaces ManuallyRooted, which requires an explicit unroot action with a mut borrow of the store (making it impossible to implement in a standard Drop impl), with OwnedRooted, which holds an Arc only to a small auxiliary memory allocation (an Arc<()>) and uses this externalized "liveness flag" to allow for a Store-less drop. These liveness flags are scanned during a "trim" pass, which happens both when new owned roots are created, and just before a GC.

This should greatly increase safety for host-side users of GC: it provides a way to have a handle whose ownership works like any other Rust value, alive until dropped. It is still not quite as efficient as LIFO-scoped handles (by analogy, for the same reason that individually-freed RAII types are not as efficient as arena allocation), so those remain for efficiency-minded users that have a clear picture of reference lifetimes.

At some later time we may wish to use OwnedRooted exclusively in our public APIs rather than Rooted, and we may wish to rename Rooted to ScopedRooted, but I haven't done either of those things yet.

I opted to replace ManuallyRooted rather than add a third kind of root, after discussion with fitzgen. One implication of this is that the C API's anyref and externref types are now 24 or 20 bytes rather than 16 (because of the Arc pointer), and correspondingly the Val union grew to that size. I believe this is an acceptable tradeoff, but I'm happy to put ManuallyRooted back if not.

Fixes #11445.

@cfallin cfallin requested a review from fitzgen August 22, 2025 22:24
@cfallin cfallin requested a review from a team as a code owner August 22, 2025 22:24
@cfallin cfallin force-pushed the owned-rooted-gc branch 6 times, most recently from d1af10a to cd66959 Compare August 23, 2025 00:10
This implements the ideas from bytecodealliance#11445: it replaces `ManuallyRooted`,
which requires an explicit unroot action with a mut borrow of the store
(making it impossible to implement in a standard `Drop` impl), with
`OwnedRooted`, which holds an `Arc` only to a small auxiliary memory
allocation (an `Arc<()>`) and uses this externalized "liveness flag" to
allow for a `Store`-less drop. These liveness flags are scanned during a
"trim" pass, which happens both when new owned roots are created, and
just before a GC.

This should greatly increase safety for host-side users of GC: it
provides a way to have a handle whose ownership works like any other
Rust value, alive until dropped. It is still not quite as efficient as
LIFO-scoped handles (by analogy, for the same reason that
individually-freed RAII types are not as efficient as arena allocation),
so those remain for efficiency-minded users that have a clear picture of
reference lifetimes.

At some later time we may wish to use `OwnedRooted` exclusively in our
public APIs rather than `Rooted`, and we may wish to rename `Rooted` to
`ScopedRooted`, but I haven't done either of those things yet.

I opted to *replace* `ManuallyRooted` rather than add a third kind of
root, after discussion with fitzgen. One implication of this is that the
C API's `anyref` and `externref` types are now 24 or 20 bytes rather
than 16 (because of the `Arc` pointer), and correspondingly the Val
union grew to that size. I *believe* this is an acceptable tradeoff, but
I'm happy to put `ManuallyRooted` back if not.

Fixes bytecodealliance#11445.
@github-actions github-actions bot added wasmtime:api Related to the API of the `wasmtime` crate itself wasmtime:c-api Issues pertaining to the C API. wasmtime:ref-types Issues related to reference types and GC in Wasmtime labels Aug 23, 2025
@github-actions
Copy link

Subscribe to Label Action

cc @fitzgen

Details This issue or pull request has been labeled: "wasmtime:api", "wasmtime:c-api", "wasmtime:ref-types"

Thus the following users have been cc'd because of the following labels:

  • fitzgen: wasmtime:ref-types

To subscribe or unsubscribe from this label, edit the .github/subscribe-to-label.json configuration file.

Learn more.

@cfallin
Copy link
Member Author

cfallin commented Aug 23, 2025

I've come up with a way to avoid the size growth on the C-API ValUnion, I think -- will update on Monday. (actually perhaps not: the idea was to put the Weak directly in the slab of owned GC ref roots, but then the trim pass requires iteration over the whole index space rather than only live roots. The original C API struct tweak is probably better than pessimizing the otherwise fairly good asymptotic behavior here for the common case)

@alexcrichton
Copy link
Member

alexcrichton commented Aug 25, 2025

Updating C API bits I think is fine, but naively I'm surprised that this is still using a generational index. I thought that was only necessary due to the manual nature of ManuallyRooted and for something with a dtor like this we wouldn't need generational indices? I haven't fully thought this through but that feels redundant now.

Considering the C API some more too, this'll want to go over documentation with a fine-tooth comb as well because we've probably documented "you should call unroot, but nothing bad happens if you don't so long as you free the store". Now that needs to be changed to "you must call unroot or host memory will leak". That's a pretty big departure in behavior from before, which while not bad we need to be sure is clearly communicated.

Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fantastic! Thanks for whipping this up!

@cfallin
Copy link
Member Author

cfallin commented Aug 25, 2025

Updating C API bits I think is fine, but naively I'm surprised that this is still using a generational index. I thought that was only necessary due to the manual nature of ManuallyRooted and for something with a dtor like this we wouldn't need generational indices? I haven't fully thought this through but that feels redundant now.

This is a plumbing issue, mostly, I think -- the GcRootIndex carries the generation (this is true because of the LIFO case still, at least, and the type is shared between LIFO and owned), and we need to reconstruct the GcRootIndex when the raw bits from C are passed back in. We could in theory read them out from the slab, but we would need access to the store to do that (ah, a familiar theme in my recent work!), so it seemed simpler not to touch the way it works other than to add the liveness flag. Happy to hear other thoughts if you or Nick have any (or see this refactored further on followup).

Considering the C API some more too, this'll want to go over documentation with a fine-tooth comb as well because we've probably documented "you should call unroot, but nothing bad happens if you don't so long as you free the store". Now that needs to be changed to "you must call unroot or host memory will leak". That's a pretty big departure in behavior from before, which while not bad we need to be sure is clearly communicated.

At least in wasmtime/val.h, we do have

  * Anyref values are required to be explicitly unrooted via
  * #wasmtime_anyref_unroot to enable them to be garbage-collected.

I suppose that we don't warn more explicitly than that, but it seems reasonably documented that the usual "free what you allocate" C API rules apply? Happy to iterate here as well in followup!

@cfallin cfallin enabled auto-merge August 25, 2025 20:52
@cfallin cfallin added this pull request to the merge queue Aug 25, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Aug 25, 2025
@alexcrichton
Copy link
Member

As a minor request, could this use void* instead of usize (in C and Rust) to carry the "this is a pointer" bit along?

it seems reasonably documented that the usual "free what you allocate" C API rules apply?

My main worry about this is that it's the only allocated "value" in the C API (as a discriminant of wasmtime_valunion_t). All other values are scalars and were previously scalars too. I'm not sure how many users this would affect though in that I'm not sure anyone's using GC right now.

I know I've had historical issues binding owned values to other languages like Python and Go in the past, but I don't recall the specifics.

@cfallin
Copy link
Member Author

cfallin commented Aug 25, 2025

@alexcrichton sure thing!

  • See 20a929b for the pointer-rather-than-usize change; needs unsafe impls of Send/Sync on the wrapper struct in the C layer but this should be straightforwardly OK because it's an Arc (I think).
  • See 8b3bf8f for some additional warnings in the header docs about the need to unroot explicitly.
  • See the other commit loosening the size assert slightly because riscv32imac gotta be different wrt padding (sad).

Let me know what you think...

@alexcrichton alexcrichton added this pull request to the merge queue Aug 26, 2025
@alexcrichton
Copy link
Member

Oh, sorry, I'm just bemoaning the state of managed values. I don't really want to get this working with the C API in other languages but I'm not sure anyone else wants to either. I don't have a great alternative, however, so all I can point out is that it's objectively more dangerous to switch to a "real pointer" from an index because mistakes are segfaults rather than panics. That doesn't mean we shouldn't do this, so that's sort of me just bemoaning that there's not really any motivation to fully flesh this out on the C side right now

@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Aug 26, 2025
@cfallin
Copy link
Member Author

cfallin commented Aug 26, 2025

@fitzgen a review of one more bit if you don't mind -- I just pushed a07c3b0 that switches to a different amortized algorithm for root trimming.

It doesn't grow the high-water mark exponentially; instead it sets it adaptively based on the last post-trim live-root set size. I realized that the former will still result in unbounded liveness-flag-array growth between GCs if one creates and drops many GC roots without mutating the GC graph itself. The new algorithm is "self-equilibriating" -- it provides a strong guarantee that the size is at most double the max true live-set size, and still has amortized constant-time root creation. I wrote a proof in the doc-comment to convince myself :-)

Let me know what you think!

Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes of course. This is actually what I was assuming we were going to do in the original issue discussion and then it fled my mind when I actually reviewed the code. Looks great! And with a proof as well!

@cfallin cfallin enabled auto-merge August 26, 2025 17:36
@cfallin cfallin added this pull request to the merge queue Aug 26, 2025
@cfallin cfallin removed this pull request from the merge queue due to a manual request Aug 26, 2025
@cfallin
Copy link
Member Author

cfallin commented Aug 26, 2025

(Added one more detail after staring at this again: should not have gated the high-water mark update on eager (GC) vs root-creation mode; only the early-out is gated on that.)

@cfallin cfallin enabled auto-merge August 26, 2025 17:57
@cfallin cfallin added this pull request to the merge queue Aug 26, 2025
@cfallin cfallin removed this pull request from the merge queue due to a manual request Aug 26, 2025
@cfallin cfallin enabled auto-merge August 26, 2025 18:35
@cfallin cfallin added this pull request to the merge queue Aug 26, 2025
Merged via the queue into bytecodealliance:main with commit 9826719 Aug 26, 2025
46 checks passed
@cfallin cfallin deleted the owned-rooted-gc branch August 26, 2025 19:34
alexcrichton added a commit to alexcrichton/wasmtime that referenced this pull request Oct 7, 2025
This commit is a follow-up to bytecodealliance#11514 which was discovered through
failing tests in the wasmtime-py repository when updating to Wasmtime
37.0.0. Effectively a combination of bugs in the Rust API meant that it
wasn't possible to use `externref` or `anyref` bindings correctly. The
Rust changes in this commit are:

* `wasmtime_val_unroot` correctly drops the value now as opposed to
  effectively being a noop from before (typo of using `as_externref` vs
  `from_externref`).
* `wasmtime_{anyref,externref,val}_t` now have a `Drop` implementation
  in Rust to correctly drop them if a value in Rust is dropped. This is
  required to correctly manage memory in the `wasmtime_func_{call,new}`
  implementations, for example.
* `wasmtime_{anyref,externref,val}_clone` no longer have an unnecessary
  context parameter.
* `wasmtime_{anyref,externref,val}_unroot` no longer have an unnecessary
  context parameter.

Changes in the C/C++ APIs are:

* `Result::{ok,err}_ref` APIs were added in addition to the preexisting
  rvalue accessors.
* Loading/storing typed arguments now has an overload for `const T&` and
  `T&&` which behaves differently. Notably transferring ownership for
  `T&&` and not for `const T&`. This means that passing parameters when
  calling a wasm function uses `const T&`, but passing results from a
  host import uses `T&&`.
* `TypedFunc::call` now uses `const Params&` instead of `Params` to
  explicitly specify it doesn't modify the parameters and forces using
  the `const T&` store method.
* `Store::gc` is now a convenience method for `store.context().gc()`
* `ExternRef`, `AnyRef`, and `Val` now have ownership semantics and
  destructors. This matches the spirit of bytecodealliance#11514 for Rust but models it
  in C++ as well. This required filling out move/copy
  constructors/assignments.
* The explicit `ExternRef` now takes `std::any` instead of `T`.
* Minor issues related to ownership are fixed in `Val` bindings.

Valgrind was used to ensure that there were no leaks for the test suite
which additionally resulted in a number of `*_delete` calls being added
to tests using the C API (accidental omissions).

The original goal of this change was to be a patch release for 37.0.1 to
enable updating wasmtime-py to the 37.0.x releases of Wasmtime. In the
end though the changes here were broad enough that I no longer feel that
this is a good idea, so wasmtime-py will be skipping the 37 version of
Wasmtime.
alexcrichton added a commit to alexcrichton/wasmtime that referenced this pull request Oct 7, 2025
This commit is a follow-up to bytecodealliance#11514 which was discovered through
failing tests in the wasmtime-py repository when updating to Wasmtime
37.0.0. This is a backport to the 37.0.x release branch which contains
the minimal infrastructure necessary to get to parity with `main` in
terms of avoiding leaks. Care is taken to avoid changing any public APIs
here which means that some previously-provided parameters are no longer
used, for example.
alexcrichton added a commit that referenced this pull request Oct 7, 2025
* Fix externref/anyref ownership in C/C++ API

This commit is a follow-up to #11514 which was discovered through
failing tests in the wasmtime-py repository when updating to Wasmtime
37.0.0. This is a backport to the 37.0.x release branch which contains
the minimal infrastructure necessary to get to parity with `main` in
terms of avoiding leaks. Care is taken to avoid changing any public APIs
here which means that some previously-provided parameters are no longer
used, for example.

* Run `clang-format`
github-merge-queue bot pushed a commit that referenced this pull request Oct 7, 2025
* Fix externref/anyref ownership in C/C++ API

This commit is a follow-up to #11514 which was discovered through
failing tests in the wasmtime-py repository when updating to Wasmtime
37.0.0. Effectively a combination of bugs in the Rust API meant that it
wasn't possible to use `externref` or `anyref` bindings correctly. The
Rust changes in this commit are:

* `wasmtime_val_unroot` correctly drops the value now as opposed to
  effectively being a noop from before (typo of using `as_externref` vs
  `from_externref`).
* `wasmtime_{anyref,externref,val}_t` now have a `Drop` implementation
  in Rust to correctly drop them if a value in Rust is dropped. This is
  required to correctly manage memory in the `wasmtime_func_{call,new}`
  implementations, for example.
* `wasmtime_{anyref,externref,val}_clone` no longer have an unnecessary
  context parameter.
* `wasmtime_{anyref,externref,val}_unroot` no longer have an unnecessary
  context parameter.

Changes in the C/C++ APIs are:

* `Result::{ok,err}_ref` APIs were added in addition to the preexisting
  rvalue accessors.
* Loading/storing typed arguments now has an overload for `const T&` and
  `T&&` which behaves differently. Notably transferring ownership for
  `T&&` and not for `const T&`. This means that passing parameters when
  calling a wasm function uses `const T&`, but passing results from a
  host import uses `T&&`.
* `TypedFunc::call` now uses `const Params&` instead of `Params` to
  explicitly specify it doesn't modify the parameters and forces using
  the `const T&` store method.
* `Store::gc` is now a convenience method for `store.context().gc()`
* `ExternRef`, `AnyRef`, and `Val` now have ownership semantics and
  destructors. This matches the spirit of #11514 for Rust but models it
  in C++ as well. This required filling out move/copy
  constructors/assignments.
* The explicit `ExternRef` now takes `std::any` instead of `T`.
* Minor issues related to ownership are fixed in `Val` bindings.

Valgrind was used to ensure that there were no leaks for the test suite
which additionally resulted in a number of `*_delete` calls being added
to tests using the C API (accidental omissions).

The original goal of this change was to be a patch release for 37.0.1 to
enable updating wasmtime-py to the 37.0.x releases of Wasmtime. In the
end though the changes here were broad enough that I no longer feel that
this is a good idea, so wasmtime-py will be skipping the 37 version of
Wasmtime.

* Run `clang-format`

prtest:full
alexcrichton added a commit to alexcrichton/wasmtime that referenced this pull request Oct 7, 2025
* Fix externref/anyref ownership in C/C++ API

This commit is a follow-up to bytecodealliance#11514 which was discovered through
failing tests in the wasmtime-py repository when updating to Wasmtime
37.0.0. Effectively a combination of bugs in the Rust API meant that it
wasn't possible to use `externref` or `anyref` bindings correctly. The
Rust changes in this commit are:

* `wasmtime_val_unroot` correctly drops the value now as opposed to
  effectively being a noop from before (typo of using `as_externref` vs
  `from_externref`).
* `wasmtime_{anyref,externref,val}_t` now have a `Drop` implementation
  in Rust to correctly drop them if a value in Rust is dropped. This is
  required to correctly manage memory in the `wasmtime_func_{call,new}`
  implementations, for example.
* `wasmtime_{anyref,externref,val}_clone` no longer have an unnecessary
  context parameter.
* `wasmtime_{anyref,externref,val}_unroot` no longer have an unnecessary
  context parameter.

Changes in the C/C++ APIs are:

* `Result::{ok,err}_ref` APIs were added in addition to the preexisting
  rvalue accessors.
* Loading/storing typed arguments now has an overload for `const T&` and
  `T&&` which behaves differently. Notably transferring ownership for
  `T&&` and not for `const T&`. This means that passing parameters when
  calling a wasm function uses `const T&`, but passing results from a
  host import uses `T&&`.
* `TypedFunc::call` now uses `const Params&` instead of `Params` to
  explicitly specify it doesn't modify the parameters and forces using
  the `const T&` store method.
* `Store::gc` is now a convenience method for `store.context().gc()`
* `ExternRef`, `AnyRef`, and `Val` now have ownership semantics and
  destructors. This matches the spirit of bytecodealliance#11514 for Rust but models it
  in C++ as well. This required filling out move/copy
  constructors/assignments.
* The explicit `ExternRef` now takes `std::any` instead of `T`.
* Minor issues related to ownership are fixed in `Val` bindings.

Valgrind was used to ensure that there were no leaks for the test suite
which additionally resulted in a number of `*_delete` calls being added
to tests using the C API (accidental omissions).

The original goal of this change was to be a patch release for 37.0.1 to
enable updating wasmtime-py to the 37.0.x releases of Wasmtime. In the
end though the changes here were broad enough that I no longer feel that
this is a good idea, so wasmtime-py will be skipping the 37 version of
Wasmtime.

* Run `clang-format`

prtest:full
alexcrichton added a commit that referenced this pull request Oct 7, 2025
* Fix externref/anyref ownership in C/C++ API

This commit is a follow-up to #11514 which was discovered through
failing tests in the wasmtime-py repository when updating to Wasmtime
37.0.0. Effectively a combination of bugs in the Rust API meant that it
wasn't possible to use `externref` or `anyref` bindings correctly. The
Rust changes in this commit are:

* `wasmtime_val_unroot` correctly drops the value now as opposed to
  effectively being a noop from before (typo of using `as_externref` vs
  `from_externref`).
* `wasmtime_{anyref,externref,val}_t` now have a `Drop` implementation
  in Rust to correctly drop them if a value in Rust is dropped. This is
  required to correctly manage memory in the `wasmtime_func_{call,new}`
  implementations, for example.
* `wasmtime_{anyref,externref,val}_clone` no longer have an unnecessary
  context parameter.
* `wasmtime_{anyref,externref,val}_unroot` no longer have an unnecessary
  context parameter.

Changes in the C/C++ APIs are:

* `Result::{ok,err}_ref` APIs were added in addition to the preexisting
  rvalue accessors.
* Loading/storing typed arguments now has an overload for `const T&` and
  `T&&` which behaves differently. Notably transferring ownership for
  `T&&` and not for `const T&`. This means that passing parameters when
  calling a wasm function uses `const T&`, but passing results from a
  host import uses `T&&`.
* `TypedFunc::call` now uses `const Params&` instead of `Params` to
  explicitly specify it doesn't modify the parameters and forces using
  the `const T&` store method.
* `Store::gc` is now a convenience method for `store.context().gc()`
* `ExternRef`, `AnyRef`, and `Val` now have ownership semantics and
  destructors. This matches the spirit of #11514 for Rust but models it
  in C++ as well. This required filling out move/copy
  constructors/assignments.
* The explicit `ExternRef` now takes `std::any` instead of `T`.
* Minor issues related to ownership are fixed in `Val` bindings.

Valgrind was used to ensure that there were no leaks for the test suite
which additionally resulted in a number of `*_delete` calls being added
to tests using the C API (accidental omissions).

The original goal of this change was to be a patch release for 37.0.1 to
enable updating wasmtime-py to the 37.0.x releases of Wasmtime. In the
end though the changes here were broad enough that I no longer feel that
this is a good idea, so wasmtime-py will be skipping the 37 version of
Wasmtime.

* Run `clang-format`

prtest:full
bongjunj pushed a commit to prosyslab/wasmtime that referenced this pull request Oct 20, 2025
* GC: replace ManuallyRooted with OwnedRooted.

This implements the ideas from bytecodealliance#11445: it replaces `ManuallyRooted`,
which requires an explicit unroot action with a mut borrow of the store
(making it impossible to implement in a standard `Drop` impl), with
`OwnedRooted`, which holds an `Arc` only to a small auxiliary memory
allocation (an `Arc<()>`) and uses this externalized "liveness flag" to
allow for a `Store`-less drop. These liveness flags are scanned during a
"trim" pass, which happens both when new owned roots are created, and
just before a GC.

This should greatly increase safety for host-side users of GC: it
provides a way to have a handle whose ownership works like any other
Rust value, alive until dropped. It is still not quite as efficient as
LIFO-scoped handles (by analogy, for the same reason that
individually-freed RAII types are not as efficient as arena allocation),
so those remain for efficiency-minded users that have a clear picture of
reference lifetimes.

At some later time we may wish to use `OwnedRooted` exclusively in our
public APIs rather than `Rooted`, and we may wish to rename `Rooted` to
`ScopedRooted`, but I haven't done either of those things yet.

I opted to *replace* `ManuallyRooted` rather than add a third kind of
root, after discussion with fitzgen. One implication of this is that the
C API's `anyref` and `externref` types are now 24 or 20 bytes rather
than 16 (because of the `Arc` pointer), and correspondingly the Val
union grew to that size. I *believe* this is an acceptable tradeoff, but
I'm happy to put `ManuallyRooted` back if not.

Fixes bytecodealliance#11445.

* Review feedback.

* Fix for riscv32imac: loosen asserts on struct size slightly to allow for different padding.

* C API: use a `*const ()` to pass the liveness-flag Arc through C.

* Add some additional documentation warning about unrooting in the C API.

* Fix size-of test on 32-bit platforms.

* New amortized algorithm for root trimming.

* core::cmp, not std::cmp

* Always set high-water mark, even if eager.

* Make val size-assert tolerant of padding bytes in crates/c-api/src/val.rs too.
bongjunj pushed a commit to prosyslab/wasmtime that referenced this pull request Oct 20, 2025
* Fix externref/anyref ownership in C/C++ API

This commit is a follow-up to bytecodealliance#11514 which was discovered through
failing tests in the wasmtime-py repository when updating to Wasmtime
37.0.0. Effectively a combination of bugs in the Rust API meant that it
wasn't possible to use `externref` or `anyref` bindings correctly. The
Rust changes in this commit are:

* `wasmtime_val_unroot` correctly drops the value now as opposed to
  effectively being a noop from before (typo of using `as_externref` vs
  `from_externref`).
* `wasmtime_{anyref,externref,val}_t` now have a `Drop` implementation
  in Rust to correctly drop them if a value in Rust is dropped. This is
  required to correctly manage memory in the `wasmtime_func_{call,new}`
  implementations, for example.
* `wasmtime_{anyref,externref,val}_clone` no longer have an unnecessary
  context parameter.
* `wasmtime_{anyref,externref,val}_unroot` no longer have an unnecessary
  context parameter.

Changes in the C/C++ APIs are:

* `Result::{ok,err}_ref` APIs were added in addition to the preexisting
  rvalue accessors.
* Loading/storing typed arguments now has an overload for `const T&` and
  `T&&` which behaves differently. Notably transferring ownership for
  `T&&` and not for `const T&`. This means that passing parameters when
  calling a wasm function uses `const T&`, but passing results from a
  host import uses `T&&`.
* `TypedFunc::call` now uses `const Params&` instead of `Params` to
  explicitly specify it doesn't modify the parameters and forces using
  the `const T&` store method.
* `Store::gc` is now a convenience method for `store.context().gc()`
* `ExternRef`, `AnyRef`, and `Val` now have ownership semantics and
  destructors. This matches the spirit of bytecodealliance#11514 for Rust but models it
  in C++ as well. This required filling out move/copy
  constructors/assignments.
* The explicit `ExternRef` now takes `std::any` instead of `T`.
* Minor issues related to ownership are fixed in `Val` bindings.

Valgrind was used to ensure that there were no leaks for the test suite
which additionally resulted in a number of `*_delete` calls being added
to tests using the C API (accidental omissions).

The original goal of this change was to be a patch release for 37.0.1 to
enable updating wasmtime-py to the 37.0.x releases of Wasmtime. In the
end though the changes here were broad enough that I no longer feel that
this is a good idea, so wasmtime-py will be skipping the 37 version of
Wasmtime.

* Run `clang-format`

prtest:full
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

wasmtime:api Related to the API of the `wasmtime` crate itself wasmtime:c-api Issues pertaining to the C API. wasmtime:ref-types Issues related to reference types and GC in Wasmtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Wasm GC host API: a slightly less manual owned Rooted type?

3 participants