@@ -16,10 +16,24 @@ EM_JS(EM_VAL, promise_sleep_impl, (int ms, int result), {
1616 return handle;
1717});
1818
19+ EM_JS (EM_VAL, promise_fail_impl, (), {
20+ let promise = new Promise ((_, reject) => setTimeout (reject, 1 , new Error (" bang from JS promise!" )));
21+ let handle = Emval.toHandle (promise);
22+ // FIXME. See https://github.com/emscripten-core/emscripten/issues/16975.
23+ #if __wasm64__
24+ handle = BigInt (handle);
25+ #endif
26+ return handle;
27+ });
28+
1929val promise_sleep (int ms, int result = 0 ) {
2030 return val::take_ownership (promise_sleep_impl (ms, result));
2131}
2232
33+ val promise_fail () {
34+ return val::take_ownership (promise_fail_impl ());
35+ }
36+
2337// Test that we can subclass and make custom awaitable types.
2438template <typename T>
2539class typed_promise : public val {
@@ -37,7 +51,13 @@ class typed_promise: public val {
3751 }
3852};
3953
54+ template <size_t N>
4055val asyncCoro () {
56+ co_return co_await asyncCoro<N - 1 >();
57+ }
58+
59+ template <>
60+ val asyncCoro<0 >() {
4161 // check that just sleeping works
4262 co_await promise_sleep (1 );
4363 // check that sleeping and receiving value works
@@ -50,12 +70,48 @@ val asyncCoro() {
5070 co_return 34 ;
5171}
5272
73+ template <size_t N>
5374val throwingCoro () {
75+ co_await throwingCoro<N - 1 >();
76+ co_return 56 ;
77+ }
78+
79+ template <>
80+ val throwingCoro<0 >() {
5481 throw std::runtime_error (" bang from throwingCoro!" );
5582 co_return 56 ;
5683}
5784
85+ template <size_t N>
86+ val failingPromise () {
87+ co_await failingPromise<N - 1 >();
88+ co_return 65 ;
89+ }
90+
91+ template <>
92+ val failingPromise<0 >() {
93+ co_await promise_fail ();
94+ co_return 65 ;
95+ }
96+
97+ val caughtException () {
98+ int result = 0 ;
99+ try {
100+ co_return co_await throwingCoro<2 >();
101+ } catch (const val&) { // runtime_error turns into emscripten::val
102+ result += 21 ;
103+ }
104+ try {
105+ co_return co_await failingPromise<2 >();
106+ } catch (const val&) {
107+ result += 21 ;
108+ }
109+ co_return result;
110+ }
111+
58112EMSCRIPTEN_BINDINGS (test_val_coro) {
59- function (" asyncCoro" , asyncCoro);
60- function (" throwingCoro" , throwingCoro);
113+ function (" asyncCoro" , asyncCoro<3 >);
114+ function (" throwingCoro" , throwingCoro<3 >);
115+ function (" failingPromise" , failingPromise<3 >);
116+ function (" caughtException" , caughtException);
61117}
0 commit comments