-
Notifications
You must be signed in to change notification settings - Fork 3.4k
[jspi] Require async js functions when used with __async decorator. #25480
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?
[jspi] Require async js functions when used with __async decorator. #25480
Conversation
|
||
import assert from 'node:assert'; | ||
import * as fs from 'node:fs/promises'; | ||
import { isAsyncFunction } from 'node:util/types'; |
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.
Oh.. interesting. TIL about this.
emscripten_sleep__deps: ['$safeSetTimeout'], | ||
emscripten_sleep__async: true, | ||
emscripten_sleep: (ms) => Asyncify.handleSleep((wakeUp) => safeSetTimeout(wakeUp, ms)), | ||
emscripten_sleep: async (ms) => Asyncify.handleSleep((wakeUp) => safeSetTimeout(wakeUp, ms)), |
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.
What does flagging this async
gain here? (it costs code size)
I understand the rationale for async
is that one can await
for the return value, but for functions that return void, isn't the async
keyword dead code?
Though Asyncify and JSPI build modes itself do not need the functions to be flagged async do they? (in WebGPU JSPI support I went with this)
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.
It really doesn't add anything here, but consistency. We have a few spots where we auto modify the library js (e.g. memory 64). It's much easier in those wrapper functions to assume we're in a async
function and emit await
code (also the await
code is usually shorter).
f8b8c87
to
c8e1794
Compare
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.
lgtm % @juj's comment
Can this PR proceed? We'd be more than happy if this landed in the main branch. We're currently patching released Emscripten manually. |
The `_emval_await` library function is marked `_emval_await__async: true`, but the js function is not async. With memory64 enabled we auto convert to bigint and look for the async keyword (which is missing) to apply the await before creating the BigInt. With my changes __async will require an async js function, which signals the function is used with JSPI and the appropriate awaits are then inserted.
This is an automatic change generated by tools/maint/rebaseline_tests.py. The following (1) test expectation files were updated by running the tests with `--rebaseline`: ``` codesize/test_codesize_hello_dylink_all.json: 843553 => 843558 [+5 bytes / +0.00%] Average change: +0.00% (+0.00% - +0.00%) ```
233ee64
to
98c6feb
Compare
It's perfectly legitimate to return a promise instead, and sometimes that would result in cleaner code. This should be at most a warning, not a requirement. |
Right, but there is no harm in doing both, right? |
I guess.. though I think it would be slightly lower performance (probably not noticeable unless it's a really hot function.) Hmm. If you did require async functions to be AsyncFunctions, then could you do away with the __async decorator? |
According to AI there is not any extra overhead: Returning a promise from an async function in JavaScript does not create a second promise in the sense of a new, distinct promise object being generated on top of the one you explicitly return. Instead, the async function's inherent promise-returning nature integrates with the promise you return. Take that with as many grains of salt as you like .. |
The
_emval_await
library function is marked_emval_await__async: true
, but the js function is not async. With memory64 enabled we auto convert to bigint and look for the async keyword (which is missing) to apply the await before creating the BigInt. With my changes __async will require an async js function, which signals the function is used with JSPI and the appropriate awaits are then inserted.Fixes #25468