Fix references passed to async functions #3188
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #3167
#3167 was happening because references to
JsValue
s work by pushing the JS value onto the JS stack, and then popping it off again when the function returns. This breaks for async functions, because theJsValue
needs to remain valid for the lifetime of the future, not just the initial synchronous call.To fix this, I introduced a new descriptor,
LONGREF
, which is used instead ofREF
in async functions and marks that the reference can't be invalidated after the function returns. I then made aLONGREF
to aJsValue
behave the same as an ownedJsValue
, while working like a regularREF
for everything else.I also had to add a new version of
RefFromWasmAbi
,LongRefFromWasmAbi
, to accomodate forLONGREF
s toJsValue
s requiring that theJsValue
is destroyed from the Rust side.While working on that, I also noticed that mutable references to slices were broken in async functions. They work by copying the data from JS to Rust, and then copying it back after the function returns to apply the changes. For async functions, that means that it's copied back before the future is actually finished, and so the changes won't be applied properly. To fix that, I changed it so that the data is copied back from the Rust side when the anchor is dropped, which happens when the future resolves for async functions.
I also bumped the schema version, since this is a breaking change in the interface between the macro and the CLI, even though the schema itself is unchanged.