After #19093 any async function () { } in JS libraries is marked for Asyncify transform. It's a bit hard to describe why, but I don't think this is correct:
- For Asyncify (
-s ASYNCIFY), functions must be wrapped into Asyncify.handleAsync to work correctly, which would make them not recognised by this check. And, vice versa, if an unwrapped async function () {} is recognised by this check, as it is now, it will be passed to Binaryen and transformed - which expands the file size - for no reason, since it's going to be called only directly and not inside Asyncify.handleAsync/Asyncify.handleSleep.
- For JSPI, we can sort of get away with it since it's much less reliant on wrapping, so it at least seems to work, but since such functions are still not wrapped into
handleAsync, they don't get the runtime keepalive counter increased/decreased upon entering/exit correspondingly.
- For
PROXY_TO_PTHREAD mode, such functions need to be treated as void as async wakeup is happening manually via proxying.h functions. Which means that again, they shouldn't be marked as Asyncify functions.
For example, looking at current usages in
|
_wasmfs_jsimpl_async_read: async function(ctx, backend, file, buffer, length, offset, result_p) { |
|
#if ASSERTIONS |
|
assert(wasmFS$backends[backend]); |
|
#endif |
|
var result = await wasmFS$backends[backend].read(file, buffer, length, offset); |
|
{{{ makeSetValue('result_p', 0, 'result', SIZE_TYPE) }}}; |
|
_emscripten_proxy_finish(ctx); |
|
}, |
, if someone compiles this with
-s ASYNCIFY -s PROXY_TO_PTHREAD (because their project depends on both of those features), right now this function will be passed to and transformed by Binaryen as Asyncify function, increasing the Wasm size, but then never used as Asyncify function because it's not wrapped into
Asyncify.handleAsync.
This seems like a footgun.
I'd suggest that we should either 1) require users to explicitly mark functions as __async: true, which is easy to put into #ifdef so that it only activates when the function is really meant to be used with Asyncify or 2) provide some more magic & automatic wrapping for all async functions that would perform proxying.h-based wakeup in PROXY_TO_PTHREAD mode and Asyncify-based wakeup otherwise.
cc @brendandahl
After #19093 any
async function () { }in JS libraries is marked for Asyncify transform. It's a bit hard to describe why, but I don't think this is correct:-s ASYNCIFY), functions must be wrapped intoAsyncify.handleAsyncto work correctly, which would make them not recognised by this check. And, vice versa, if an unwrappedasync function () {}is recognised by this check, as it is now, it will be passed to Binaryen and transformed - which expands the file size - for no reason, since it's going to be called only directly and not insideAsyncify.handleAsync/Asyncify.handleSleep.handleAsync, they don't get the runtime keepalive counter increased/decreased upon entering/exit correspondingly.PROXY_TO_PTHREADmode, such functions need to be treated asvoidas async wakeup is happening manually viaproxying.hfunctions. Which means that again, they shouldn't be marked as Asyncify functions.For example, looking at current usages in
emscripten/src/library_wasmfs_jsimpl.js
Lines 92 to 99 in 992d1e9
-s ASYNCIFY -s PROXY_TO_PTHREAD(because their project depends on both of those features), right now this function will be passed to and transformed by Binaryen as Asyncify function, increasing the Wasm size, but then never used as Asyncify function because it's not wrapped intoAsyncify.handleAsync.This seems like a footgun.
I'd suggest that we should either 1) require users to explicitly mark functions as
__async: true, which is easy to put into#ifdefso that it only activates when the function is really meant to be used with Asyncify or 2) provide some more magic & automatic wrapping for all async functions that would performproxying.h-based wakeup inPROXY_TO_PTHREADmode and Asyncify-based wakeup otherwise.cc @brendandahl