[embind] Allow awaiting Promises in non-Promise coroutines & catching Promise C++ exceptions#26195
[embind] Allow awaiting Promises in non-Promise coroutines & catching Promise C++ exceptions#26195stevenwdv wants to merge 26 commits into
Conversation
…ipten-core#26064), allow catching Promise C++ exceptions (closes emscripten-core#25396) Still crashes on `test_embind_val_coro_catch_cpp_exception`, not sure why. TODO: What to do on rejection in the !__cpp_exceptions case in a non-Promise coroutine?
|
Btw, if anyone knows why the rethrow of the |
|
The cause of the crash seems to be #26213 |
I'll not terminate here so non-C++ exceptions still propagate to `await_resume`
Add -fno-exceptions test
Add separate test_embind_val_coro_propagate_js_error_disabled_catch test
|
Currently |
Actually, the error message for But I don't see where I'm referencing Besides that |
Sorry for the delay. I submitted #26519 that should fix #26290. About
And the below is its suggested fix. I'm not familiar with embind so I'm not sure how much this makes sense though. But it seems to fix the error. diff --git a/system/include/emscripten/val.h b/system/include/emscripten/val.h
index bfe6c47bf..ecb7d017c 100644
--- a/system/include/emscripten/val.h
+++ b/system/include/emscripten/val.h
@@ -690,7 +690,9 @@ class val::awaiter {
> state;
void awaitSuspendImpl(state_coro coro) {
- internal::_emval_coro_suspend(std::get<state_promise>(state).promise.as_handle(), this);
+ auto* promise_ptr = std::get_if<state_promise>(&state);
+ assert(promise_ptr);
+ internal::_emval_coro_suspend(promise_ptr->promise.as_handle(), this);
state.emplace<state_coro>(coro);
}
@@ -720,7 +722,9 @@ public:
// When JS invokes `resume_with` with some value, store that value and resume
// the coroutine.
void resume_with(val&& result) {
- auto coro = std::get<state_coro>(state);
+ auto* coro_ptr = std::get_if<state_coro>(&state);
+ assert(coro_ptr);
+ auto coro = *coro_ptr;
state.emplace<state_result>(std::move(result));
coro.handle.resume();
}
@@ -737,7 +741,10 @@ public:
return std::move(result->result);
}
// If a JS exception ended up here, it will be uncaught as C++ code cannot catch it
- std::get<state_error>(state).error.throw_();
+ auto* error_ptr = std::get_if<state_error>(&state);
+ assert(error_ptr);
+ error_ptr->error.throw_();
+ __builtin_unreachable();
}
};
@@ -799,7 +806,9 @@ public:
};
inline void val::awaiter::reject_with(val&& error) {
- auto coro = std::get<state_coro>(state);
+ auto* coro_ptr = std::get_if<state_coro>(&state);
+ assert(coro_ptr);
+ auto coro = *coro_ptr;
if (coro.isValPromise) { |
TODO: fix _emval_is_cpp_exception
|
@aheejin Thanks! Your suggestions seem to fix the problems I was having! I'm surprised Gemini was actually able to find this. Let's see if the CI builds fine now. |
It's fine like it was
|
Almost. Still some failures:
|
Running |
This is an automatic change generated by tools/maint/rebaseline_tests.py. The following (1) test expectation files were updated by running the tests with `--rebaseline`: ``` codesize/test_codesize_cxx_lto.json: 120519 => 120725 [+206 bytes / +0.17%] Average change: +0.17% (+0.17% - +0.17%) ```
This is an automatic change generated by tools/maint/rebaseline_tests.py. The following (3) test expectation files were updated by running the tests with `--rebaseline`: ``` codesize/test_codesize_cxx_lto.json: 120725 => 120519 [-206 bytes / -0.17%] codesize/test_codesize_minimal_pthreads.json: 26409 => 26409 [+0 bytes / +0.00%] codesize/test_codesize_minimal_pthreads_memgrowth.json: 26812 => 26812 [+0 bytes / +0.00%] Average change: -0.06% (-0.17% - +0.00%) ```
|
@aheejin Ah, thanks, missed that. It's still not working though, but it literally says:
This seems a little odd... |
brendandahl
left a comment
There was a problem hiding this comment.
Minor nit on a comment, but looks good overall.
# Conflicts: # test/codesize/test_codesize_minimal_pthreads.json # test/codesize/test_codesize_minimal_pthreads_memgrowth.json
This is an automatic change generated by tools/maint/rebaseline_tests.py. The following (1) test expectation files were updated by running the tests with `--rebaseline`: ``` codesize/test_codesize_cxx_lto.json: 120519 => 120725 [+206 bytes / +0.17%] Average change: +0.17% (+0.17% - +0.17%) ```
|
Huh, again I did the code size rebaseline after installing the latest |
|
I just landed #26651 .. if you rebase on top of that the codesize tests should match again. |
|
@brendandahl we can land this without the rebase if you are good with it? |
|
Actually we probably should rebase because this change can effect codesize I think |
This is an automatic change generated by tools/maint/rebaseline_tests.py. The following (4) test expectation files were updated by running the tests with `--rebaseline`: ``` codesize/test_minimal_runtime_code_size_hello_webgl2_wasm.json: 13200 => 13200 [+0 bytes / +0.00%] codesize/test_minimal_runtime_code_size_hello_webgl2_wasm2js.json: 18537 => 18534 [-3 bytes / -0.02%] codesize/test_minimal_runtime_code_size_hello_webgl_wasm.json: 12738 => 12738 [+0 bytes / +0.00%] codesize/test_minimal_runtime_code_size_hello_webgl_wasm2js.json: 18063 => 18060 [-3 bytes / -0.02%] Average change: -0.01% (-0.02% - +0.00%) ```
- Remove unnecessary options, clarify necessary ones - Parameterize tests
This is an automatic change generated by tools/maint/rebaseline_tests.py. The following (4) test expectation files were updated by running the tests with `--rebaseline`: ``` codesize/test_minimal_runtime_code_size_hello_webgl2_wasm.json: 13200 => 13200 [+0 bytes / +0.00%] codesize/test_minimal_runtime_code_size_hello_webgl2_wasm2js.json: 18534 => 18537 [+3 bytes / +0.02%] codesize/test_minimal_runtime_code_size_hello_webgl_wasm.json: 12738 => 12738 [+0 bytes / +0.00%] codesize/test_minimal_runtime_code_size_hello_webgl_wasm2js.json: 18060 => 18063 [+3 bytes / +0.02%] Average change: +0.01% (+0.00% - +0.02%) ```
sbc100
left a comment
There was a problem hiding this comment.
lgtm, but I really don't understand the C++ coro stuff, so I'll leave it to @RReverser or @brendandahl to give final approval.
Still crashes on
test_embind_val_coro_catch_cpp_exception,not sure whydue to #26213. EDIT: resolved.TODO:
What to do on rejection in the!__cpp_exceptionscase in a non-Promise coroutine?await_resumeanyway.Seems hard to distinguish since there's 3 possible exception types depending on the compiler settings, once of which is just a number.test_embind_val_coro_propagate_js_errorfailsFixes: #26064
Fixes: #25396