Skip to content

Commit ad57240

Browse files
committed
Add __async: auto decorator
This decorator automatically generates the Asyncify.handleAsync wrapper code. Hopefully we can transition all out `__async` functions soon and just make this the default.
1 parent a6bc307 commit ad57240

File tree

5 files changed

+41
-23
lines changed

5 files changed

+41
-23
lines changed

src/jsifier.mjs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,19 @@ ${body};
350350
});
351351
}
352352

353+
function handleAsyncFunction(snippet) {
354+
return modifyJSFunction(snippet, (args, body, async_, oneliner) => {
355+
if (!oneliner) {
356+
body = `{\n${body}\n}`;
357+
}
358+
return `\
359+
${async_}function(${args}) {
360+
let innerFunc = ${async_} () => ${body};
361+
return Asyncify.handleAsync(innerFunc);
362+
}\n`;
363+
});
364+
}
365+
353366
export async function runJSify(outputFile, symbolsOnly) {
354367
const libraryItems = [];
355368
const symbolDeps = {};
@@ -440,6 +453,11 @@ function(${args}) {
440453
compileTimeContext.i53ConversionDeps.forEach((d) => deps.push(d));
441454
}
442455

456+
const isAsyncFunction = LibraryManager.library[symbol + '__async'];
457+
if (ASYNCIFY && isAsyncFunction == 'auto') {
458+
snippet = handleAsyncFunction(snippet);
459+
}
460+
443461
const proxyingMode = LibraryManager.library[symbol + '__proxy'];
444462
if (proxyingMode) {
445463
if (!['sync', 'async', 'none'].includes(proxyingMode)) {

src/lib/libasync.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -485,8 +485,8 @@ addToLibrary({
485485
emscripten_sleep: (ms) => Asyncify.handleSleep((wakeUp) => safeSetTimeout(wakeUp, ms)),
486486

487487
emscripten_wget_data__deps: ['$asyncLoad', 'malloc'],
488-
emscripten_wget_data__async: true,
489-
emscripten_wget_data: (url, pbuffer, pnum, perror) => Asyncify.handleAsync(async () => {
488+
emscripten_wget_data__async: 'auto',
489+
emscripten_wget_data: async (url, pbuffer, pnum, perror) => {
490490
/* no need for run dependency, this is async but will not do any prepare etc. step */
491491
try {
492492
const byteArray = await asyncLoad(UTF8ToString(url));
@@ -499,7 +499,7 @@ addToLibrary({
499499
} catch (err) {
500500
{{{ makeSetValue('perror', 0, '1', 'i32') }}};
501501
}
502-
}),
502+
},
503503

504504
emscripten_scan_registers__deps: ['$safeSetTimeout'],
505505
emscripten_scan_registers__async: true,

src/lib/libidbstore.js

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -92,56 +92,56 @@ var LibraryIDBStore = {
9292
},
9393

9494
#if ASYNCIFY
95-
emscripten_idb_load__async: true,
95+
emscripten_idb_load__async: 'auto',
9696
emscripten_idb_load__deps: ['malloc'],
97-
emscripten_idb_load: (db, id, pbuffer, pnum, perror) => Asyncify.handleSleep((wakeUp) => {
97+
emscripten_idb_load: (db, id, pbuffer, pnum, perror) => new Promise((resolve) => {
9898
IDBStore.getFile(UTF8ToString(db), UTF8ToString(id), (error, byteArray) => {
9999
if (error) {
100100
{{{ makeSetValue('perror', 0, '1', 'i32') }}};
101-
wakeUp();
101+
resolve();
102102
return;
103103
}
104104
var buffer = _malloc(byteArray.length); // must be freed by the caller!
105105
HEAPU8.set(byteArray, buffer);
106106
{{{ makeSetValue('pbuffer', 0, 'buffer', '*') }}};
107107
{{{ makeSetValue('pnum', 0, 'byteArray.length', 'i32') }}};
108108
{{{ makeSetValue('perror', 0, '0', 'i32') }}};
109-
wakeUp();
109+
resolve();
110110
});
111111
}),
112-
emscripten_idb_store__async: true,
113-
emscripten_idb_store: (db, id, ptr, num, perror) => Asyncify.handleSleep((wakeUp) => {
112+
emscripten_idb_store__async: 'auto',
113+
emscripten_idb_store: (db, id, ptr, num, perror) => new Promise((resolve) => {
114114
IDBStore.setFile(UTF8ToString(db), UTF8ToString(id), new Uint8Array(HEAPU8.subarray(ptr, ptr+num)), (error) => {
115115
// Closure warns about storing booleans in TypedArrays.
116116
/** @suppress{checkTypes} */
117117
{{{ makeSetValue('perror', 0, '!!error', 'i32') }}};
118-
wakeUp();
118+
resolve();
119119
});
120120
}),
121-
emscripten_idb_delete__async: true,
122-
emscripten_idb_delete: (db, id, perror) => Asyncify.handleSleep((wakeUp) => {
121+
emscripten_idb_delete__async: 'auto',
122+
emscripten_idb_delete: (db, id, perror) => new Promise((resolve) => {
123123
IDBStore.deleteFile(UTF8ToString(db), UTF8ToString(id), (error) => {
124124
/** @suppress{checkTypes} */
125125
{{{ makeSetValue('perror', 0, '!!error', 'i32') }}};
126-
wakeUp();
126+
resolve();
127127
});
128128
}),
129-
emscripten_idb_exists__async: true,
130-
emscripten_idb_exists: (db, id, pexists, perror) => Asyncify.handleSleep((wakeUp) => {
129+
emscripten_idb_exists__async: 'auto',
130+
emscripten_idb_exists: (db, id, pexists, perror) => new Promise((resolve) => {
131131
IDBStore.existsFile(UTF8ToString(db), UTF8ToString(id), (error, exists) => {
132132
/** @suppress{checkTypes} */
133133
{{{ makeSetValue('pexists', 0, '!!exists', 'i32') }}};
134134
/** @suppress{checkTypes} */
135135
{{{ makeSetValue('perror', 0, '!!error', 'i32') }}};
136-
wakeUp();
136+
resolve();
137137
});
138138
}),
139-
emscripten_idb_clear__async: true,
140-
emscripten_idb_clear: (db, perror) => Asyncify.handleSleep((wakeUp) => {
139+
emscripten_idb_clear__async: 'auto',
140+
emscripten_idb_clear: (db, perror) => new Promise((resolve) => {
141141
IDBStore.clearStore(UTF8ToString(db), (error) => {
142142
/** @suppress{checkTypes} */
143143
{{{ makeSetValue('perror', 0, '!!error', 'i32') }}};
144-
wakeUp();
144+
resolve();
145145
});
146146
}),
147147
#else

src/lib/libpromise.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ addToLibrary({
257257
return id;
258258
},
259259
260-
emscripten_promise_await__async: true,
260+
emscripten_promise_await__async: 'auto',
261261
#if ASYNCIFY
262262
emscripten_promise_await__deps: ['$getPromise', '$setPromiseResult'],
263263
#endif
@@ -266,10 +266,10 @@ addToLibrary({
266266
#if RUNTIME_DEBUG
267267
dbg(`emscripten_promise_await: ${id}`);
268268
#endif
269-
return Asyncify.handleAsync(() => getPromise(id).then(
269+
return getPromise(id).then(
270270
value => setPromiseResult(returnValuePtr, true, value),
271271
error => setPromiseResult(returnValuePtr, false, error)
272-
));
272+
);
273273
#else
274274
abort('emscripten_promise_await is only available with ASYNCIFY');
275275
#endif

src/utility.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ export function mergeInto(obj, other, options = null) {
186186
__noleakcheck: 'boolean',
187187
__internal: 'boolean',
188188
__user: 'boolean',
189-
__async: 'boolean',
189+
__async: ['string', 'boolean'],
190190
__i53abi: 'boolean',
191191
};
192192
const expected = decoratorTypes[decoratorName];

0 commit comments

Comments
 (0)