Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
emscripten-core
GitHub Repository: emscripten-core/emscripten
Path: blob/main/test/embind/test_val_coro.cpp
4150 views
1
#include <emscripten.h>
2
#include <emscripten/bind.h>
3
#include <emscripten/val.h>
4
#include <assert.h>
5
#include <stdexcept>
6
7
using namespace emscripten;
8
9
EM_JS(EM_VAL, promise_sleep_impl, (int ms, int result), {
10
let promise = new Promise(resolve => setTimeout(resolve, ms, result));
11
let handle = Emval.toHandle(promise);
12
// FIXME. See https://github.com/emscripten-core/emscripten/issues/16975.
13
#if __wasm64__
14
handle = BigInt(handle);
15
#endif
16
return handle;
17
});
18
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
29
val promise_sleep(int ms, int result = 0) {
30
return val::take_ownership(promise_sleep_impl(ms, result));
31
}
32
33
val promise_fail() {
34
return val::take_ownership(promise_fail_impl());
35
}
36
37
// Test that we can subclass and make custom awaitable types.
38
template <typename T>
39
class typed_promise: public val {
40
public:
41
typed_promise(val&& promise): val(std::move(promise)) {}
42
43
auto operator co_await() const {
44
struct typed_awaiter: public val::awaiter {
45
T await_resume() {
46
return val::awaiter::await_resume().template as<T>();
47
}
48
};
49
50
return typed_awaiter(*this);
51
}
52
};
53
54
template <size_t N>
55
val asyncCoro() {
56
co_return co_await asyncCoro<N - 1>();
57
}
58
59
template <>
60
val asyncCoro<0>() {
61
// check that just sleeping works
62
co_await promise_sleep(1);
63
// check that sleeping and receiving value works
64
val v = co_await promise_sleep(1, 12);
65
assert(v.as<int>() == 12);
66
// check that awaiting a subclassed promise works and returns the correct type
67
int x = co_await typed_promise<int>(promise_sleep(1, 23));
68
assert(x == 23);
69
// check that returning value works (checked by JS in tests)
70
co_return 34;
71
}
72
73
template <size_t N>
74
val throwingCoro() {
75
co_await throwingCoro<N - 1>();
76
co_return 56;
77
}
78
79
template <>
80
val throwingCoro<0>() {
81
throw std::runtime_error("bang from throwingCoro!");
82
co_return 56;
83
}
84
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
EMSCRIPTEN_BINDINGS(test_val_coro) {
98
function("asyncCoro", asyncCoro<3>);
99
function("throwingCoro", throwingCoro<3>);
100
function("failingPromise", failingPromise<3>);
101
}
102
103