-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Fix late-binding symbols with JSPI (implementation 2) #24161
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
base: main
Are you sure you want to change the base?
Conversation
Late-binding symbols get a JS stub import that resolves the symbol and then makes an onward call. This breaks JSPI. This is a second approach to solving the problem by using WebAssembly.promising and WebAssembly.Suspending with a JS trampoline. Unfortunately, as far as I can tell there is no way to make it work for both a promising entrypoint and a non-promising entrypoint. This is due to a change in the JSPI spec: early versions said that if a suspending import does not return a promise, the suspender was allowed to be null. However, the new version of JSPI eagerly traps if the suspender is null, even if the function does not return a promise.
} | ||
|
||
EM_JS(void, js_trampoline, (), { | ||
_not_promising(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, thanks... sounds like the JSPI spec changed and I haven't followed that closely.
@brendandahl is there some workaround for this issue?
If not, it sounds like this approach would need to add all late-binding symbols to JSPI_EXPORTS..?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think what would be needed would be to add all C functions that might call late-binding symbols to JSPI_EXPORTS
? In this case the problem is fixed by adding -sJSPI_EXPORTS=not_promising
.
If we wanted to go this way, we should probably make all exports JSPI_EXPORTS
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing we could do is make a selector function with body like:
try (result restype)
local.get 0
local.get 1
call suspendingTrampoline
catch $SuspendError
local.get 0
local.get 1
call nonsuspendingTrampoline
end
and then make both a suspending and nonsuspending version of the stub. But this still forces us to do most of the painful stuff in #23619 where we calculate the type and generate a dynamic wasm module.
Late-binding symbols get a JS stub import that resolves the symbol and then makes an onward call. This breaks JSPI.
This is a second approach to solving the problem by using WebAssembly.promising and WebAssembly.Suspending with a JS trampoline. Unfortunately, as far as I can tell there is no way to make it work for both a promising entrypoint and a non-promising entrypoint. This is due to a change in the JSPI spec: early versions said that if a suspending import does not return a promise, the suspender was allowed to be null. However, the new version of JSPI eagerly traps if the suspender is null, even if the function does not return a promise.