To follow up on what we discussed very briefly in the Jco meeting today towards P3, I reached out to @Joel Dice and he kindly answered:
Yeah, so there are really three export ABIs:
- Synchronous: cannot reenter until it returns
- Asynchronous, with a callback: cannot reenter until it "returns", but note that "returns" here doesn't mean it's done. It might be done or might just be unable to make more progress until one or more of its waitables have made progress, at which point the host will call its callback. The latter can happen multiple times, concurrently with other in-progress tasks. In this case, there's only ever one Wasm stack involved.
- Asynchronous, without a callback: can be reentered on a new stack concurrently (but not in parallel!). In this case there can be as many stacks as there are outstanding tasks.
Yeah, I expect Rust, C#, JS, and Python (i.e. the async/await languages) will use the second one, and e.g. Go and Java (the ones with stackful coroutines/fibers) will use the third one.
Hopefully I was able to repeat what you were intending correctly @Till Schneidereit but I noted that what you plan on using is approach (3)
@Yosh Wuyts @Tomasz Andrzejak @Calvin Prewitt
thank you for the follow-up!
I actually plan on using (2): asynchronous with callbacks. That's why this isn't reliant on JSPI support: there won't ever be multiple stacks involved. It's also a much better fit for JS semantics, because JS expects run-to-completion, not stack suspension
Ah right, Joel's note was right there -- I remembered the C API note and callbacks but noted the wrong one, thanks for the clarification.
To reiterate where we got to on the call, the JSPI/Asyncify stuff is only important for host primarily -- C API w/ async + callbacks for guests using StarlingMonkey
right, yeah. Or to put it another way: JSPI (or asyncify) is required to implement (3), and thus important for JCO to support all ABI variants, but it's not required to support specifically StarlingMonkey based components
JSPI (or Asyncify) on the JCO host might be also required to implement much of (1) Synchronous, to use the Web APIs that are async and we need the ability to block and suspend the Wasm execution.
Hi all. I chatted with @Till Schneidereit and @Luke Wagner about WASIp3 implementation logistics today and the TL;DR is that we do not need to support the async-without-callback ABI for 0.3.0.
We won't need it for StarlingMonkey-based guests according to Till, and TinyGo won't use it for the foreseeable future, so (as far as we know), there won't be any guest toolchains that use that ABI in the short-to-mid term, meaning there's no urgency to support it in 0.3.0. I've already implemented it in Wasmtime, so no point in backing that out, but I don't think we need it in Jco, and thus no need for JSPI or Asyncify AFAICT.
To be clear, we do want to support that ABI post-0.3.0, but it's no longer a blocker for 0.3.0.
Put another way: the Worker-thread-based hack we used to support wasi:io/poll
in Jco for WASIp2 should still be sufficient for 0.3.0. If folks are eager to remove that hack anyway, I won't try to talk them out of it, but I don't think that's needed for 0.3.0.
I don't think we need it in Jco, and thus no need for JSPI or Asyncify AFAICT.
I think this is still required for blocking APIs though? For example if a wasm module blocks on the result of a future that'll require JSPI to implement?
oh but I suppose that could use the same hack as before
For Jco, you could think of the JSPI / Asyncify implementation as an alternative to the hack using Workers and atomics.
Last updated: Jan 24 2025 at 00:11 UTC