Skip to content

Async JS library funcs should not be marked for Asyncify transform #20289

Closed
@RReverser

Description

@RReverser

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:

  1. 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.
  2. 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.
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions