Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

c-api: Create RootScope where necessary #8374

Merged
merged 2 commits into from Apr 15, 2024

Conversation

alexcrichton
Copy link
Member

This commit changes the wasmtime_val_t::{from_val, to_val} methods to take a RootScope instead of any AsContextMut. This then required a number of refactorings in callers to ensure that a RootScope was created for any function that needed one. This is required to ensure that GC references in the C API aren't forced to live for the entire lifetime of the store.

This additionally added *_unrooted variants which do the same thing but don't require RootScope. This was needed for when the C API calls out to the embedder through a function call because a new RootScope wouldn't work for return values (they're bound to a scope within the closure when we want them to outlive the closure). In these situations though we know a RootScope is already present at the entrypoint.

Closes #8367

This commit changes the `wasmtime_val_t::{from_val, to_val}` methods to
take a `RootScope` instead of any `AsContextMut`. This then required a
number of refactorings in callers to ensure that a `RootScope` was
created for any function that needed one. This is required to ensure
that GC references in the C API aren't forced to live for the entire
lifetime of the store.

This additionally added `*_unrooted` variants which do the same thing
but don't require `RootScope`. This was needed for when the C API calls
out to the embedder through a function call because a new `RootScope`
wouldn't work for return values (they're bound to a scope within the
closure when we want them to outlive the closure). In these situations
though we know a `RootScope` is already present at the entrypoint.

Closes bytecodealliance#8367
@alexcrichton alexcrichton requested a review from a team as a code owner April 15, 2024 21:26
@alexcrichton alexcrichton requested review from fitzgen and removed request for a team April 15, 2024 21:26
/// elsewhere on the stack. For example this is used when we call back out
/// to the embedder. In such a situation we know we previously entered with
/// some other call so the root scope is on the stack there.
pub fn from_val_unrooted(cx: impl AsContextMut, val: Val) -> wasmtime_val_t {
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we can rename this from_val_unscoped or something? "unrooted" had me convinced that this was passing around ExternRef::to_raw results and stuff like that potentially across GCs which is not what's going on.

Copy link
Member

Choose a reason for hiding this comment

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

Also, the wasmtime_val_t::from_val[_unrooted] constructors never create Rooteds so I don't think we actually need two variants of these ones? Its just creating a Val (which contains a Rooted and means we might be creating a Rooted ourselves) that needs the scoping.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point about the naming, I'll switch to your suggestion.

I thought the same for from_val but I ended up realizing that APIs like wasmtime_global_get also will want a RootScope on them. That's only calling from_val but if we forgot a RootScope there the any value coming out of a global would forever-after be attached to the store (since the Rooted coming out has no other scope). That convinced me to leave the from_val{,_unscoped} distinction to continue to encourage the use of RootScope anywhere in the C API that might use it.

@github-actions github-actions bot added the wasmtime:c-api Issues pertaining to the C API. label Apr 15, 2024
Copy link

Subscribe to Label Action

cc @peterhuene

This issue or pull request has been labeled: "wasmtime:c-api"

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

  • peterhuene: wasmtime:c-api

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

Learn more.

@alexcrichton alexcrichton added this pull request to the merge queue Apr 15, 2024
alexcrichton added a commit to alexcrichton/wasmtime that referenced this pull request Apr 15, 2024
* c-api: Create `RootScope` where necessary

This commit changes the `wasmtime_val_t::{from_val, to_val}` methods to
take a `RootScope` instead of any `AsContextMut`. This then required a
number of refactorings in callers to ensure that a `RootScope` was
created for any function that needed one. This is required to ensure
that GC references in the C API aren't forced to live for the entire
lifetime of the store.

This additionally added `*_unrooted` variants which do the same thing
but don't require `RootScope`. This was needed for when the C API calls
out to the embedder through a function call because a new `RootScope`
wouldn't work for return values (they're bound to a scope within the
closure when we want them to outlive the closure). In these situations
though we know a `RootScope` is already present at the entrypoint.

Closes bytecodealliance#8367

* Review comments
Merged via the queue into bytecodealliance:main with commit 9187f2d Apr 15, 2024
24 checks passed
@alexcrichton alexcrichton deleted the fix-c-api-and-gc branch April 15, 2024 22:43
fitzgen pushed a commit that referenced this pull request Apr 15, 2024
* c-api: Create `RootScope` where necessary

This commit changes the `wasmtime_val_t::{from_val, to_val}` methods to
take a `RootScope` instead of any `AsContextMut`. This then required a
number of refactorings in callers to ensure that a `RootScope` was
created for any function that needed one. This is required to ensure
that GC references in the C API aren't forced to live for the entire
lifetime of the store.

This additionally added `*_unrooted` variants which do the same thing
but don't require `RootScope`. This was needed for when the C API calls
out to the embedder through a function call because a new `RootScope`
wouldn't work for return values (they're bound to a scope within the
closure when we want them to outlive the closure). In these situations
though we know a `RootScope` is already present at the entrypoint.

Closes #8367

* Review comments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wasmtime:c-api Issues pertaining to the C API.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

C API prevents GC'ing externref values
2 participants