27#include "wasm/asyncify.h"
28#include "wasm/machine.h"
29#include "wasm/setjmp.h"
31#ifdef RB_WASM_ENABLE_DEBUG_LOG
33# define RB_WASM_DEBUG_LOG(...) fprintf(stderr, __VA_ARGS__)
35# define RB_WASM_DEBUG_LOG(...)
38enum rb_wasm_jmp_buf_state {
40 JMP_BUF_STATE_INITIALIZED = 0,
43 JMP_BUF_STATE_CAPTURING = 1,
45 JMP_BUF_STATE_CAPTURED = 2,
48 JMP_BUF_STATE_RETURNING = 3,
54 buf->top = &buf->buffer[0];
55 buf->end = &buf->buffer[WASM_SETJMP_STACK_BUFFER_SIZE];
60void *rb_asyncify_unwind_buf;
66 RB_WASM_DEBUG_LOG(
"[%s] env = %p, env->state = %d, _rb_wasm_active_jmpbuf = %p\n", __func__, env, env->state, _rb_wasm_active_jmpbuf);
68 case JMP_BUF_STATE_INITIALIZED: {
69 RB_WASM_DEBUG_LOG(
"[%s] JMP_BUF_STATE_INITIALIZED\n", __func__);
70 env->state = JMP_BUF_STATE_CAPTURING;
72 _rb_wasm_active_jmpbuf = env;
73 async_buf_init(&env->setjmp_buf);
74 asyncify_start_unwind(&env->setjmp_buf);
77 case JMP_BUF_STATE_CAPTURING: {
78 asyncify_stop_rewind();
79 RB_WASM_DEBUG_LOG(
"[%s] JMP_BUF_STATE_CAPTURING\n", __func__);
80 env->state = JMP_BUF_STATE_CAPTURED;
81 _rb_wasm_active_jmpbuf = NULL;
84 case JMP_BUF_STATE_RETURNING: {
85 asyncify_stop_rewind();
86 RB_WASM_DEBUG_LOG(
"[%s] JMP_BUF_STATE_RETURNING\n", __func__);
87 env->state = JMP_BUF_STATE_CAPTURED;
88 _rb_wasm_active_jmpbuf = NULL;
92 assert(0 &&
"unexpected state");
100 RB_WASM_DEBUG_LOG(
"[%s] env = %p, env->state = %d, value = %d\n", __func__, env, env->state, value);
101 assert(env->state == JMP_BUF_STATE_CAPTURED);
103 env->state = JMP_BUF_STATE_RETURNING;
104 env->payload = value;
105 _rb_wasm_active_jmpbuf = env;
106 async_buf_init(&env->longjmp_buf);
107 asyncify_start_unwind(&env->longjmp_buf);
111enum try_catch_phase {
112 TRY_CATCH_PHASE_MAIN = 0,
113 TRY_CATCH_PHASE_RESCUE = 1,
118 rb_wasm_try_catch_func_t try_f,
119 rb_wasm_try_catch_func_t catch_f,
122 try_catch->state = TRY_CATCH_PHASE_MAIN;
123 try_catch->try_f = try_f;
124 try_catch->catch_f = catch_f;
125 try_catch->context = context;
132 extern void *rb_asyncify_unwind_buf;
135 target->state = JMP_BUF_STATE_CAPTURED;
137 switch ((
enum try_catch_phase)try_catch->state) {
138 case TRY_CATCH_PHASE_MAIN: {
140 try_catch->try_f(try_catch->context);
143 case TRY_CATCH_PHASE_RESCUE: {
144 if (try_catch->catch_f) {
146 try_catch->catch_f(try_catch->context);
154 if (rb_asyncify_unwind_buf && _rb_wasm_active_jmpbuf == target) {
159 asyncify_stop_rewind();
161 _rb_wasm_active_jmpbuf = NULL;
163 target->state = JMP_BUF_STATE_CAPTURED;
165 try_catch->state = TRY_CATCH_PHASE_RESCUE;
166 if (try_catch->catch_f) {
167 try_catch->catch_f(try_catch->context);
170 }
else if (rb_asyncify_unwind_buf ) {
180rb_wasm_handle_jmp_unwind(
void)
182 RB_WASM_DEBUG_LOG(
"[%s] _rb_wasm_active_jmpbuf = %p\n", __func__, _rb_wasm_active_jmpbuf);
183 if (!_rb_wasm_active_jmpbuf) {
187 switch (_rb_wasm_active_jmpbuf->state) {
188 case JMP_BUF_STATE_CAPTURING: {
189 RB_WASM_DEBUG_LOG(
"[%s] JMP_BUF_STATE_CAPTURING\n", __func__);
191 _rb_wasm_active_jmpbuf->dst_buf_top = _rb_wasm_active_jmpbuf->setjmp_buf.top;
194 case JMP_BUF_STATE_RETURNING: {
195 RB_WASM_DEBUG_LOG(
"[%s] JMP_BUF_STATE_RETURNING\n", __func__);
197 _rb_wasm_active_jmpbuf->setjmp_buf.top = _rb_wasm_active_jmpbuf->dst_buf_top;
201 assert(0 &&
"unexpected state");
203 return &_rb_wasm_active_jmpbuf->setjmp_buf;