-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Support the WebAssembly javascript-promise integration proposal #3633
Comments
I don't think this needs an opt-in command-line flag with your proposal, because it's already explicitly opt-in by marking the function with PR's welcome! |
This part is a bit concerning to me - I've only skimmed the proposal, but I think making functions as At the very least, this means that a flag is definitely required. It'll also break certain uses of |
Thinking about this a bit more, adding a flag would be good to get a proper compile-time error if users don't support JSPI in their use-case but JSPI is used somewhere.
Why would we need to make every exported function |
We don't have to, but that's what @Aaron1011 is proposing. The alternative would be to also specify After thinking about this a bit more, it's harder to implement than I first thought, since there are allowed to be multiple Rust calls suspended at once. So, say that you call
Since the stack pointer's now pointing at |
Right. I would like to know exactly what Emscripten did here, because looking through it, it seems they have done something to allowing not every function to require
Indeed that is what Emscripten does: https://v8.dev/blog/jspi#limitations. |
Motivation
The javascript-promise integration proposal (see also https://v8.dev/blog/jspi) allows automatically suspending and resuming WebAssembly modules when they invoke a properly-annotated async Javascript function (which returns a
Promise
). From the perspective of WebAssembly, this behaves like a synchronous call. This proposal is currently in Phase 3 (Implementation): https://github.com/WebAssembly/proposals#phase-3---implementation-phase-cg--wgIn the case of Rust, this means the ability to invoke an async Javascript function without needing the Rust function to be
async
. If the call occurs deep within a Rust library, this would otherwise require making every single callerasync
(since blocking/looping on aFuture
is only possible on native application, not wasm).Proposed Solution
Importing
The
#[wasm_bindgen]
macro will support a newjspi
attribute (name bikesheddable) when used on JavaScript imports:This would bind to a JavaScript function:
When
wasm-bindgen
importsjs_async_function
, it will use thenew WebAssembly.Function
API described in the proposal to mark the function assuspending
. As a result, theExporting
When any functions are imported with the
jspi
attribute, wasm-bindgen will add an additionalsuspender
parameter to all exported functions. This is necessary to ensure that asuspender
object is always available whenever an importedjspi
function is invoked. Rust functions will be exported using thenew WebAssembly.Function
api described in the proposal to mark the function as 'promising'. Internally,wasm-bindgen
will need to store thesuspender
in a global variable, which will be read and used as an argument whenever an importedjspi
function is called.Because of the potential overhead from marking all exported functions as
promising
, this should require an explicit opt in from a--jspi
command-line flag.Alternatives
async
support can replace this feature in some places, it requires 'infecting' the entire call stack withasync
. This feature would allow calling async JavaScript functions from a synchronous context, without needing invasive changes to the entire program (or breaking changes for consumers, in the case of a library).Additional Context
The text was updated successfully, but these errors were encountered: