Skip to content

Commit 66c66e5

Browse files
committed
Add a new way to mark async imports in library files.
Allow library functions to be asyncify'd with either an `async` function or adding `$name_async`.
1 parent b116323 commit 66c66e5

File tree

5 files changed

+19
-2
lines changed

5 files changed

+19
-2
lines changed

emcc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
}
102102

103103
DEFAULT_ASYNCIFY_IMPORTS = [
104-
'emscripten_sleep', 'emscripten_wget', 'emscripten_wget_data', 'emscripten_idb_load',
104+
'emscripten_wget', 'emscripten_wget_data', 'emscripten_idb_load',
105105
'emscripten_idb_store', 'emscripten_idb_delete', 'emscripten_idb_exists',
106106
'emscripten_idb_load_blob', 'emscripten_idb_store_blob', 'SDL_Delay',
107107
'emscripten_scan_registers', 'emscripten_lazy_load_code',

emscripten.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,9 @@ def emscript(in_wasm, out_wasm, outfile_js, memfile):
393393

394394
report_missing_symbols(forwarded_json['librarySymbols'])
395395

396+
if settings.ASYNCIFY:
397+
settings.ASYNCIFY_IMPORTS += ['env.' + x for x in forwarded_json['asyncFuncs']]
398+
396399
if not outfile_js:
397400
logger.debug('emscript: skipping remaining js glue generation')
398401
return

src/jsifier.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ function isDefined(symName) {
6969
function runJSify() {
7070
const libraryItems = [];
7171
const symbolDeps = {};
72+
const asyncFuncs = [];
7273
let postSets = [];
7374

7475
LibraryManager.load();
@@ -335,6 +336,7 @@ function ${name}(${args}) {
335336
}
336337
});
337338
let isFunction = false;
339+
let isAsyncFunction = false;
338340

339341
if (typeof snippet == 'string') {
340342
if (snippet[0] != '=') {
@@ -352,6 +354,7 @@ function ${name}(${args}) {
352354
addImplicitDeps(snippet, deps);
353355
} else if (typeof snippet == 'function') {
354356
isFunction = true;
357+
isAsyncFunction = snippet.constructor.name == 'AsyncFunction';
355358
snippet = processLibraryFunction(snippet, symbol, mangled, deps);
356359
addImplicitDeps(snippet, deps);
357360
}
@@ -410,6 +413,10 @@ function ${name}(${args}) {
410413
contentText = `var ${mangled} = ${snippet};`;
411414
}
412415
const sig = LibraryManager.library[symbol + '__sig'];
416+
isAsyncFunction = LibraryManager.library[symbol + '__async'] ?? isAsyncFunction;
417+
if (isAsyncFunction) {
418+
asyncFuncs.push(symbol);
419+
}
413420
// asm module exports are done in emscripten.py, after the asm module is ready. Here
414421
// we also export library methods as necessary.
415422
if ((EXPORT_ALL || EXPORTED_FUNCTIONS.has(mangled)) && !isStub) {
@@ -423,6 +430,9 @@ function ${name}(${args}) {
423430
if (sig && (RELOCATABLE || ASYNCIFY == 2)) {
424431
contentText += `\n${mangled}.sig = '${sig}';`;
425432
}
433+
if (isAsyncFunction) {
434+
contentText += `\n${mangled}.isAsync = true;`;
435+
}
426436
if (isStub) {
427437
contentText += `\n${mangled}.stub = true;`;
428438
if (ASYNCIFY) {
@@ -529,6 +539,7 @@ function ${name}(${args}) {
529539
print('//FORWARDED_DATA:' + JSON.stringify({
530540
librarySymbols: librarySymbols,
531541
warnings: warnings,
542+
asyncFuncs,
532543
ATINITS: ATINITS.join('\n'),
533544
ATMAINS: ATMAINS.join('\n'),
534545
ATEXITS: ATEXITS.join('\n'),

src/library_async.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ mergeInto(LibraryManager.library, {
4040
var original = imports[x];
4141
var sig = original.sig;
4242
if (typeof original == 'function') {
43-
var isAsyncifyImport = ASYNCIFY_IMPORTS.indexOf(x) >= 0 ||
43+
var isAsyncifyImport = original.isAsync ||
44+
ASYNCIFY_IMPORTS.indexOf(x) >= 0 ||
4445
x.startsWith('__asyncjs__');
4546
#if ASYNCIFY == 2
4647
// Wrap async imports with a suspending WebAssembly function.
@@ -452,6 +453,7 @@ mergeInto(LibraryManager.library, {
452453

453454
emscripten_sleep__sig: 'vi',
454455
emscripten_sleep__deps: ['$safeSetTimeout'],
456+
emscripten_sleep__async: true,
455457
emscripten_sleep: function(ms) {
456458
// emscripten_sleep() does not return a value, but we still need a |return|
457459
// here for stack switching support (ASYNCIFY=2). In that mode this function

src/utility.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ function isJsLibraryConfigIdentifier(ident) {
168168
'__noleakcheck',
169169
'__internal',
170170
'__user',
171+
'__async',
171172
];
172173
return suffixes.some((suffix) => ident.endsWith(suffix));
173174
}

0 commit comments

Comments
 (0)