Skip to content

Asyncify: spill reference-typed locals to tables - #9159

Open
NellowTCS wants to merge 1 commit into
WebAssembly:mainfrom
NellowTCS:asyncify-reference-types
Open

NellowTCS wants to merge 1 commit into
WebAssembly:mainfrom
NellowTCS:asyncify-reference-types

Conversation

@NellowTCS

@NellowTCS NellowTCS commented Sep 26, 2026 •

Copy link
Copy Markdown

Fixes #3739.

Right now wasm-opt --asyncify aborts if a reference-typed value is live across an unwind. Asyncify spills locals into a linear-memory stack, and references can't be stored there, so it gives up.
This was annoying for my IPC/RPC runtime, Saikuro, so I decided to go fix Asyncify.

As discussed by @kripken, @martianboy, and @surma in #3739, the fix is to spill references into tables instead of linear memory.

The Asyncify ABI/API remains unchanged, so this shouldn't impact users beyond fixing reference-type support, I believe.
Asyncify still only supports one active pause at a time, though. As a result, asyncify_start_unwind now traps if it sees a nonzero cursor.

However, multi-pause support would need per-pause regions in the tables. As pointed out, that's a separate problem and a much bigger change, so I left it out of this PR.

Note: This is essentially a cleaned-up and "productionized" version of the proof-of-concept @alexdoesh posted in #3739.

@NellowTCS
NellowTCS requested a review from a team as a code owner September 26, 2026 05:28
@NellowTCS
NellowTCS requested review from kripken and removed request for a team September 26, 2026 05:28
@NellowTCS NellowTCS changed the title spill reference locals to growable tables Asyncify: spill reference-typed locals to tables Sep 26, 2026
@kripken

kripken commented Sep 28, 2026

Copy link
Copy Markdown
Member

Back in the day we did think this would make sense eventually, but meanwhile JSPI provides what Asyncify does but in the VM itself, which is a lot more efficient. That support of course includes reference-typed locals.

It sounds like you might be using Asyncify in some other way? Can you explain the motivation and how important this is for you?

@NellowTCS

Copy link
Copy Markdown
Author

Hi!!!
I definitely agree that JSPI does this (and does it much better), but the problem with it is adoption. Currently, it's a new Baseline feature, so a lot of devices/people don't have support for it yet.

I was planning to use this for Saikuro's executor abstraction (saikuro-exec) on its WASM path. I had implemented a block_on that prefers JSPI when available, but will eventually (using the changes in this PR) also fall back to Asyncify in environments where JSPI is unavailable.

The main issue I ran into is that reference-typed values can remain live across suspension points (which is often the case in Saikuro). In those cases Asyncify currently aborts, which makes it impossible to transform otherwise-valid modules.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reference types crash wasm-opt‘s asyncify pass

2 participants