Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions src/lib/libasync.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,10 +323,9 @@ addToLibrary({
// can just call the function with no args at all since the engine will produce zeros
// for all arguments. However, for i64 arguments we get `undefined cannot be converted to
// BigInt`.
return func(...Asyncify.restoreRewindArguments(original));
#else
return func();
func = func.bind(0, ...Asyncify.restoreRewindArguments(original));
#endif
return callUserCallback(func);
},

// This receives a function to call to start the async operation, and
Expand Down Expand Up @@ -480,9 +479,8 @@ addToLibrary({
#endif
},

emscripten_sleep__deps: ['$safeSetTimeout'],
emscripten_sleep__async: true,
emscripten_sleep: (ms) => Asyncify.handleSleep((wakeUp) => safeSetTimeout(wakeUp, ms)),
emscripten_sleep: (ms) => Asyncify.handleSleep((wakeUp) => setTimeout(wakeUp, ms)),

emscripten_wget_data__deps: ['$asyncLoad', 'malloc'],
emscripten_wget_data__async: 'auto',
Expand All @@ -501,15 +499,14 @@ addToLibrary({
}
},

emscripten_scan_registers__deps: ['$safeSetTimeout'],
emscripten_scan_registers__async: true,
emscripten_scan_registers: (func) => {
return Asyncify.handleSleep((wakeUp) => {
// We must first unwind, so things are spilled to the stack. Then while
// we are pausing we do the actual scan. After that we can resume. Note
// how using a timeout here avoids unbounded call stack growth, which
// could happen if we tried to scan the stack immediately after unwinding.
safeSetTimeout(() => {
setTimeout(() => {
var stackBegin = Asyncify.currData + {{{ C_STRUCTS.asyncify_data_s.__size__ }}};
var stackEnd = {{{ makeGetValue('Asyncify.currData', 0, '*') }}};
{{{ makeDynCall('vpp', 'func') }}}(stackBegin, stackEnd);
Expand Down
8 changes: 6 additions & 2 deletions src/lib/libcore.js
Original file line number Diff line number Diff line change
Expand Up @@ -1996,6 +1996,9 @@ addToLibrary({
err('Stack overflow detected. You can try increasing -sSTACK_SIZE (currently set to {{{ STACK_SIZE }}})');
}
}
#endif
#if RUNTIME_DEBUG
dbg("handleException: got unexpected exception, calling quit_")
#endif
quit_(1, e);
},
Expand Down Expand Up @@ -2066,10 +2069,11 @@ addToLibrary({
return;
}
try {
func();
maybeExit();
return func();
} catch (e) {
handleException(e);
} finally {
maybeExit();
}
},

Expand Down
8 changes: 4 additions & 4 deletions test/codesize/test_codesize_cxx_lto.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.out.js": 18993,
"a.out.js.gz": 7823,
"a.out.js": 19001,
"a.out.js.gz": 7824,
"a.out.nodebug.wasm": 106448,
"a.out.nodebug.wasm.gz": 42638,
"total": 125441,
"total_gz": 50461,
"total": 125449,
"total_gz": 50462,
"sent": [
"a (emscripten_resize_heap)",
"b (_setitimer_js)",
Expand Down
4 changes: 2 additions & 2 deletions test/codesize/test_codesize_hello_dylink_all.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"a.out.js": 244848,
"a.out.js": 244863,
"a.out.nodebug.wasm": 577879,
"total": 822727,
"total": 822742,
"sent": [
"IMG_Init",
"IMG_Load",
Expand Down
8 changes: 4 additions & 4 deletions test/codesize/test_codesize_minimal_pthreads.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.out.js": 7722,
"a.out.js.gz": 3812,
"a.out.js": 7737,
"a.out.js.gz": 3816,
"a.out.nodebug.wasm": 19604,
"a.out.nodebug.wasm.gz": 9079,
"total": 27326,
"total_gz": 12891,
"total": 27341,
"total_gz": 12895,
"sent": [
"a (memory)",
"b (emscripten_get_now)",
Expand Down
8 changes: 4 additions & 4 deletions test/codesize/test_codesize_minimal_pthreads_memgrowth.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.out.js": 8145,
"a.out.js.gz": 4011,
"a.out.js": 8160,
"a.out.js.gz": 4015,
"a.out.nodebug.wasm": 19605,
"a.out.nodebug.wasm.gz": 9080,
"total": 27750,
"total_gz": 13091,
"total": 27765,
"total_gz": 13095,
"sent": [
"a (memory)",
"b (emscripten_get_now)",
Expand Down
3 changes: 0 additions & 3 deletions test/embind_with_asyncify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,5 @@ int main() {
val async_text = response.call<val>("text");
std::string text = async_text.await().as<std::string>();
assert(text == "foo");
// This explicit exit() should not be necessary here.
// TODO(https://github.com/emscripten-core/emscripten/issues/26093)
exit(0);
return 0;
}
6 changes: 1 addition & 5 deletions test/test_async_exit_after_wakeup.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@ addToLibrary({
async_func__async: true,
async_func: (value) => {
return Asyncify.handleSleep((wakeUp) => {
// Currently with -sASYNCIFY the wakeUp call needs to be wrapped in
// callUserCallback, otherwise things like `exit()` won't work from
// the continuation.
// TODO(https://github.com/emscripten-core/emscripten/issues/26093)
setTimeout(() => callUserCallback(() => wakeUp(42)), 0);
setTimeout(() => wakeUp(42), 0);
});
},
});
2 changes: 1 addition & 1 deletion test/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -9587,7 +9587,7 @@ def test_embind_lib_with_asyncify(self, args):
'-sINCOMING_MODULE_JS_API=onRuntimeInitialized',
]
self.cflags += args
self.do_core_test('embind_lib_with_asyncify.cpp')
self.do_core_test('embind_lib_with_asyncify.cpp', assert_returncode=NON_ZERO)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this change?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason is that because the asyncify continuation are now run in callUserCallback the handleException: got unexpected exception, calling quit_` which sets the node exit code to non-zero.

This test explicit has delayed_throw in it which throws and exception in an asyncify continuation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But that delayed throw is handled early in the test,

    let delayedThrowResult = Module["delayed_throw"]();
    assert(delayedThrowResult instanceof Promise);
    let err = await delayedThrowResult.then(() => '', err => err.message);
    assert(err === 'my message', `"${err}" doesn't contain the expected error`);

The rest of the test runs after those lines, and it exits without error?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .then(() => '', err => err.message); part handles the error, but the exit code is remembered because handleExcetpion calls quit_ which under node sets the overall process exit code:

process.exitCode = status;

So its kind of like the node implementation is remember the exit code even though the exception was handled further up. I don't know if this is ideal, but I imagine changing it would be very hard at this point.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Yeah, probably not worth changing.

How about adding a comment in the python file, explaining why we expect the test to fail? Otherwise it is quite surprising I think.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed


@no_asan('asyncify stack operations confuse asan')
@with_asyncify_and_jspi
Expand Down
Loading