Skip to content

Commit 8cd28a2

Browse files
authored
[JSPI] Do not automatically wrap async library functions. (#24550)
In a number of places library functions (e.g. `emscripten_async_wget_data`) use an `async` JS functions, but they do not actually want to use JSPI wrappers. Change it so functions must explicitly use `foo__async: true` to enable JSPI wrappers. Fixes #20289
1 parent e66cbd5 commit 8cd28a2

File tree

6 files changed

+55
-3
lines changed

6 files changed

+55
-3
lines changed

ChangeLog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ See docs/process.md for more on how version tagging works.
3434
for chrome, or
3535
emrun --browser=firefox --browser-args=-headless [..]
3636
for firefox. (#24537)
37+
- When JSPI is enabled `async` library functions are no longer automatically
38+
wrapped with `WebAssembly.Suspending` functions. To automatically wrap library
39+
functions for use with JSPI they must now explicitly set
40+
`myLibraryFunction__async: true`.
3741

3842
4.0.10 - 06/07/25
3943
-----------------

src/jsifier.mjs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -534,9 +534,7 @@ function(${args}) {
534534
if (ASYNCIFY) {
535535
const original = LibraryManager.library[symbol];
536536
if (typeof original == 'function') {
537-
isAsyncFunction =
538-
LibraryManager.library[symbol + '__async'] ||
539-
original.constructor.name == 'AsyncFunction';
537+
isAsyncFunction = LibraryManager.library[symbol + '__async'];
540538
}
541539
if (isAsyncFunction) {
542540
asyncFuncs.push(symbol);

src/lib/libasync.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,7 @@ addToLibrary({
559559
#endif
560560

561561
_load_secondary_module__sig: 'v',
562+
_load_secondary_module__async: true,
562563
_load_secondary_module: async function() {
563564
// Mark the module as loading for the wasm module (so it doesn't try to load it again).
564565
wasmExports['load_secondary_module_status'].value = 1;

src/lib/libpthread.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,6 +1026,9 @@ var LibraryPThread = {
10261026
'$runtimeKeepaliveCounter',
10271027
#endif
10281028
],
1029+
#if ASYNCIFY
1030+
$invokeEntryPoint__async: true,
1031+
#endif
10291032
$invokeEntryPoint: {{{ asyncIf(ASYNCIFY == 2) }}}(ptr, arg) => {
10301033
#if PTHREADS_DEBUG
10311034
dbg(`invokeEntryPoint: ${ptrToString(ptr)}`);

src/lib/libwasmfs_opfs.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ addToLibrary({
6969
},
7070

7171
_wasmfs_opfs_init_root_directory__deps: ['$wasmfsOPFSDirectoryHandles', '$wasmfsOPFSProxyFinish'],
72+
_wasmfs_opfs_init_root_directory__async: {{{ !PTHREADS }}},
7273
_wasmfs_opfs_init_root_directory: async function(ctx) {
7374
// allocated.length starts off as 1 since 0 is a reserved handle
7475
if (wasmfsOPFSDirectoryHandles.allocated.length == 1) {
@@ -88,6 +89,7 @@ addToLibrary({
8889
// corresponding to the error.
8990
$wasmfsOPFSGetOrCreateFile__deps: ['$wasmfsOPFSDirectoryHandles',
9091
'$wasmfsOPFSFileHandles'],
92+
$wasmfsOPFSGetOrCreateFile__async: {{{ !PTHREADS }}},
9193
$wasmfsOPFSGetOrCreateFile: async function(parent, name, create) {
9294
let parentHandle = wasmfsOPFSDirectoryHandles.get(parent);
9395
let fileHandle;
@@ -112,6 +114,7 @@ addToLibrary({
112114
// it if it doesn't exist and `create` or otherwise return a negative error
113115
// code corresponding to the error.
114116
$wasmfsOPFSGetOrCreateDir__deps: ['$wasmfsOPFSDirectoryHandles'],
117+
$wasmfsOPFSGetOrCreateDir__async: {{{ !PTHREADS }}},
115118
$wasmfsOPFSGetOrCreateDir: async function(parent, name, create) {
116119
let parentHandle = wasmfsOPFSDirectoryHandles.get(parent);
117120
let childHandle;
@@ -135,6 +138,7 @@ addToLibrary({
135138

136139
_wasmfs_opfs_get_child__deps: ['$wasmfsOPFSGetOrCreateFile',
137140
'$wasmfsOPFSGetOrCreateDir', '$wasmfsOPFSProxyFinish'],
141+
_wasmfs_opfs_get_child__async: {{{ !PTHREADS }}},
138142
_wasmfs_opfs_get_child:
139143
async function(ctx, parent, namePtr, childTypePtr, childIDPtr) {
140144
let name = UTF8ToString(namePtr);
@@ -155,6 +159,7 @@ addToLibrary({
155159
'$stackRestore',
156160
'_wasmfs_opfs_record_entry',
157161
],
162+
_wasmfs_opfs_get_entries__async: {{{ !PTHREADS }}},
158163
_wasmfs_opfs_get_entries: async function(ctx, dirID, entriesPtr, errPtr) {
159164
let dirHandle = wasmfsOPFSDirectoryHandles.get(dirID);
160165

@@ -179,6 +184,7 @@ addToLibrary({
179184
},
180185

181186
_wasmfs_opfs_insert_file__deps: ['$wasmfsOPFSGetOrCreateFile', '$wasmfsOPFSProxyFinish'],
187+
_wasmfs_opfs_insert_file__async: {{{ !PTHREADS }}},
182188
_wasmfs_opfs_insert_file: async function(ctx, parent, namePtr, childIDPtr) {
183189
let name = UTF8ToString(namePtr);
184190
let childID = await wasmfsOPFSGetOrCreateFile(parent, name, true);
@@ -187,6 +193,7 @@ addToLibrary({
187193
},
188194

189195
_wasmfs_opfs_insert_directory__deps: ['$wasmfsOPFSGetOrCreateDir', '$wasmfsOPFSProxyFinish'],
196+
_wasmfs_opfs_insert_directory__async: {{{ !PTHREADS }}},
190197
_wasmfs_opfs_insert_directory:
191198
async function(ctx, parent, namePtr, childIDPtr) {
192199
let name = UTF8ToString(namePtr);
@@ -198,6 +205,7 @@ addToLibrary({
198205
_wasmfs_opfs_move_file__deps: ['$wasmfsOPFSFileHandles',
199206
'$wasmfsOPFSDirectoryHandles',
200207
'$wasmfsOPFSProxyFinish'],
208+
_wasmfs_opfs_move_file__async: {{{ !PTHREADS }}},
201209
_wasmfs_opfs_move_file: async function(ctx, fileID, newParentID, namePtr, errPtr) {
202210
let name = UTF8ToString(namePtr);
203211
let fileHandle = wasmfsOPFSFileHandles.get(fileID);
@@ -212,6 +220,7 @@ addToLibrary({
212220
},
213221

214222
_wasmfs_opfs_remove_child__deps: ['$wasmfsOPFSDirectoryHandles', '$wasmfsOPFSProxyFinish'],
223+
_wasmfs_opfs_remove_child__async: {{{ !PTHREADS }}},
215224
_wasmfs_opfs_remove_child: async function(ctx, dirID, namePtr, errPtr) {
216225
let name = UTF8ToString(namePtr);
217226
let dirHandle = wasmfsOPFSDirectoryHandles.get(dirID);
@@ -240,6 +249,7 @@ addToLibrary({
240249
'$wasmfsOPFSCreateAsyncAccessHandle'
241250
#endif
242251
],
252+
_wasmfs_opfs_open_access__async: {{{ !PTHREADS }}},
243253
_wasmfs_opfs_open_access: async function(ctx, fileID, accessIDPtr) {
244254
let fileHandle = wasmfsOPFSFileHandles.get(fileID);
245255
let accessID;
@@ -279,6 +289,7 @@ addToLibrary({
279289

280290
_wasmfs_opfs_open_blob__deps: ['$wasmfsOPFSFileHandles',
281291
'$wasmfsOPFSBlobs', '$wasmfsOPFSProxyFinish'],
292+
_wasmfs_opfs_open_blob__async: {{{ !PTHREADS }}},
282293
_wasmfs_opfs_open_blob: async function(ctx, fileID, blobIDPtr) {
283294
let fileHandle = wasmfsOPFSFileHandles.get(fileID);
284295
let blobID;
@@ -300,6 +311,7 @@ addToLibrary({
300311
},
301312

302313
_wasmfs_opfs_close_access__deps: ['$wasmfsOPFSAccessHandles', '$wasmfsOPFSProxyFinish'],
314+
_wasmfs_opfs_close_access__async: {{{ !PTHREADS }}},
303315
_wasmfs_opfs_close_access: async function(ctx, accessID, errPtr) {
304316
let accessHandle = wasmfsOPFSAccessHandles.get(accessID);
305317
try {
@@ -319,6 +331,7 @@ addToLibrary({
319331

320332
_wasmfs_opfs_read_access__i53abi: true,
321333
_wasmfs_opfs_read_access__deps: ['$wasmfsOPFSAccessHandles'],
334+
_wasmfs_opfs_read_access__async: {{{ !PTHREADS }}},
322335
_wasmfs_opfs_read_access: {{{ asyncIf(!PTHREADS) }}}function(accessID, bufPtr, len, pos) {
323336
let accessHandle = wasmfsOPFSAccessHandles.get(accessID);
324337
let data = HEAPU8.subarray(bufPtr, bufPtr + len);
@@ -337,6 +350,7 @@ addToLibrary({
337350

338351
_wasmfs_opfs_read_blob__i53abi: true,
339352
_wasmfs_opfs_read_blob__deps: ['$wasmfsOPFSBlobs', '$wasmfsOPFSProxyFinish'],
353+
_wasmfs_opfs_read_blob__async: {{{ !PTHREADS }}},
340354
_wasmfs_opfs_read_blob: async function(ctx, blobID, bufPtr, len, pos, nreadPtr) {
341355
let blob = wasmfsOPFSBlobs.get(blobID);
342356
let slice = blob.slice(pos, pos + len);
@@ -367,6 +381,7 @@ addToLibrary({
367381

368382
_wasmfs_opfs_write_access__i53abi: true,
369383
_wasmfs_opfs_write_access__deps: ['$wasmfsOPFSAccessHandles'],
384+
_wasmfs_opfs_write_access__async: {{{ !PTHREADS }}},
370385
_wasmfs_opfs_write_access: {{{ asyncIf(!PTHREADS) }}}function(accessID, bufPtr, len, pos) {
371386
let accessHandle = wasmfsOPFSAccessHandles.get(accessID);
372387
let data = HEAPU8.subarray(bufPtr, bufPtr + len);
@@ -384,6 +399,7 @@ addToLibrary({
384399
},
385400

386401
_wasmfs_opfs_get_size_access__deps: ['$wasmfsOPFSAccessHandles', '$wasmfsOPFSProxyFinish'],
402+
_wasmfs_opfs_get_size_access__async: {{{ !PTHREADS }}},
387403
_wasmfs_opfs_get_size_access: async function(ctx, accessID, sizePtr) {
388404
let accessHandle = wasmfsOPFSAccessHandles.get(accessID);
389405
let size;
@@ -404,6 +420,7 @@ addToLibrary({
404420
},
405421

406422
_wasmfs_opfs_get_size_file__deps: ['$wasmfsOPFSFileHandles', '$wasmfsOPFSProxyFinish'],
423+
_wasmfs_opfs_get_size_file__async: {{{ !PTHREADS }}},
407424
_wasmfs_opfs_get_size_file: async function(ctx, fileID, sizePtr) {
408425
let fileHandle = wasmfsOPFSFileHandles.get(fileID);
409426
let size;
@@ -418,6 +435,7 @@ addToLibrary({
418435

419436
_wasmfs_opfs_set_size_access__i53abi: true,
420437
_wasmfs_opfs_set_size_access__deps: ['$wasmfsOPFSAccessHandles', '$wasmfsOPFSProxyFinish'],
438+
_wasmfs_opfs_set_size_access__async: {{{ !PTHREADS }}},
421439
_wasmfs_opfs_set_size_access: async function(ctx, accessID, size, errPtr) {
422440
let accessHandle = wasmfsOPFSAccessHandles.get(accessID);
423441
try {
@@ -431,6 +449,7 @@ addToLibrary({
431449

432450
_wasmfs_opfs_set_size_file__i53abi: true,
433451
_wasmfs_opfs_set_size_file__deps: ['$wasmfsOPFSFileHandles', '$wasmfsOPFSProxyFinish'],
452+
_wasmfs_opfs_set_size_file__async: {{{ !PTHREADS }}},
434453
_wasmfs_opfs_set_size_file: async function(ctx, fileID, size, errPtr) {
435454
let fileHandle = wasmfsOPFSFileHandles.get(fileID);
436455
try {
@@ -445,6 +464,7 @@ addToLibrary({
445464
},
446465

447466
_wasmfs_opfs_flush_access__deps: ['$wasmfsOPFSAccessHandles', '$wasmfsOPFSProxyFinish'],
467+
_wasmfs_opfs_flush_access__async: {{{ !PTHREADS }}},
448468
_wasmfs_opfs_flush_access: async function(ctx, accessID, errPtr) {
449469
let accessHandle = wasmfsOPFSAccessHandles.get(accessID);
450470
try {

test/test_other.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3484,6 +3484,32 @@ def test_jspi_add_function(self):
34843484
'-Wno-experimental']
34853485
self.do_runf('other/test_jspi_add_function.c', 'done')
34863486

3487+
@requires_jspi
3488+
def test_jspi_async_function(self):
3489+
# Make sure async library functions are not automatically JSPI'd.
3490+
create_file('lib.js', r'''
3491+
addToLibrary({
3492+
foo: async function(f) { await Promise.resolve(); },
3493+
});
3494+
''')
3495+
create_file('main.c', r'''
3496+
#include <emscripten.h>
3497+
extern void foo();
3498+
EMSCRIPTEN_KEEPALIVE void test() {
3499+
foo();
3500+
}
3501+
''')
3502+
create_file('post.js', r'''
3503+
Module.onRuntimeInitialized = () => {
3504+
_test()
3505+
console.log('done');
3506+
};
3507+
''')
3508+
self.do_runf('main.c', 'done', emcc_args=['-sJSPI',
3509+
'--js-library=lib.js',
3510+
'-Wno-experimental',
3511+
'--post-js=post.js'])
3512+
34873513
@requires_dev_dependency('typescript')
34883514
@parameterized({
34893515
'commonjs': [['-sMODULARIZE'], ['--module', 'commonjs', '--moduleResolution', 'node']],

0 commit comments

Comments
 (0)