Path: blob/main/test/embind/test_val_coro.cpp
4150 views
#include <emscripten.h>1#include <emscripten/bind.h>2#include <emscripten/val.h>3#include <assert.h>4#include <stdexcept>56using namespace emscripten;78EM_JS(EM_VAL, promise_sleep_impl, (int ms, int result), {9let promise = new Promise(resolve => setTimeout(resolve, ms, result));10let handle = Emval.toHandle(promise);11// FIXME. See https://github.com/emscripten-core/emscripten/issues/16975.12#if __wasm64__13handle = BigInt(handle);14#endif15return handle;16});1718EM_JS(EM_VAL, promise_fail_impl, (), {19let promise = new Promise((_, reject) => setTimeout(reject, 1, new Error("bang from JS promise!")));20let handle = Emval.toHandle(promise);21// FIXME. See https://github.com/emscripten-core/emscripten/issues/16975.22#if __wasm64__23handle = BigInt(handle);24#endif25return handle;26});2728val promise_sleep(int ms, int result = 0) {29return val::take_ownership(promise_sleep_impl(ms, result));30}3132val promise_fail() {33return val::take_ownership(promise_fail_impl());34}3536// Test that we can subclass and make custom awaitable types.37template <typename T>38class typed_promise: public val {39public:40typed_promise(val&& promise): val(std::move(promise)) {}4142auto operator co_await() const {43struct typed_awaiter: public val::awaiter {44T await_resume() {45return val::awaiter::await_resume().template as<T>();46}47};4849return typed_awaiter(*this);50}51};5253template <size_t N>54val asyncCoro() {55co_return co_await asyncCoro<N - 1>();56}5758template <>59val asyncCoro<0>() {60// check that just sleeping works61co_await promise_sleep(1);62// check that sleeping and receiving value works63val v = co_await promise_sleep(1, 12);64assert(v.as<int>() == 12);65// check that awaiting a subclassed promise works and returns the correct type66int x = co_await typed_promise<int>(promise_sleep(1, 23));67assert(x == 23);68// check that returning value works (checked by JS in tests)69co_return 34;70}7172template <size_t N>73val throwingCoro() {74co_await throwingCoro<N - 1>();75co_return 56;76}7778template <>79val throwingCoro<0>() {80throw std::runtime_error("bang from throwingCoro!");81co_return 56;82}8384template <size_t N>85val failingPromise() {86co_await failingPromise<N - 1>();87co_return 65;88}8990template <>91val failingPromise<0>() {92co_await promise_fail();93co_return 65;94}9596EMSCRIPTEN_BINDINGS(test_val_coro) {97function("asyncCoro", asyncCoro<3>);98function("throwingCoro", throwingCoro<3>);99function("failingPromise", failingPromise<3>);100}101102103