[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 17 commits intoemscripten-core:mainfrom
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... |
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