diff --git a/lib/exec.c b/lib/exec.c index 3c194573..916c8c71 100644 --- a/lib/exec.c +++ b/lib/exec.c @@ -540,15 +540,15 @@ do_host_call(struct exec_context *ctx, const struct funcinst *finst) ret = finst->u.host.func(ctx, finst->u.host.instance, ft, &VEC_NEXTELEM(ctx->stack), &VEC_NEXTELEM(ctx->stack)); - assert(ret == ETOYWASMRESTART || ctx->restart_type == RESTART_NONE); + assert(IS_RESTARTABLE(ret) || ctx->restart_type == RESTART_NONE); if (ret != 0) { - if (ret == ETOYWASMRESTART) { + if (IS_RESTARTABLE(ret)) { /* * Restore the stack pointer for restarting. * * Note: it's a responsibility of host functions * to keep function arguments on the stack intact - * when returning ETOYWASMRESTART. + * when returning a restartable error. */ ctx->stack.lsize += nparams; STAT_INC(ctx->stats.call_restart); @@ -984,7 +984,7 @@ exec_expr_continue(struct exec_context *ctx) assert(ctx->frames.lsize > 0); ret = do_return_call(ctx, ctx->event_u.call.func); if (ret != 0) { - if (ret == ETOYWASMRESTART) { + if (IS_RESTARTABLE(ret)) { ctx->event = EXEC_EVENT_CALL; /* * Note: because we have changed @@ -1028,7 +1028,7 @@ exec_expr_continue(struct exec_context *ctx) * * Instead, this implementation relies on the * opcode functions set up an explicit execution - * event when returning ETOYWASMRESTART. + * event when returning a restartable error. */ ret = restart_insn(ctx); goto after_insn; @@ -1044,7 +1044,7 @@ exec_expr_continue(struct exec_context *ctx) n = 0; ret = check_interrupt(ctx); if (ret != 0) { - if (ret == ETOYWASMRESTART) { + if (IS_RESTARTABLE(ret)) { STAT_INC(ctx->stats.exec_loop_restart); } return ret; @@ -1053,7 +1053,7 @@ exec_expr_continue(struct exec_context *ctx) struct cell *stack = &VEC_NEXTELEM(ctx->stack); ret = fetch_exec_next_insn(ctx->p, stack, ctx); after_insn: - assert((ret == ETOYWASMRESTART) == + assert(IS_RESTARTABLE(ret) == (ctx->event == EXEC_EVENT_RESTART_INSN)); if (ret != 0) { if (ctx->trapped) { @@ -1149,7 +1149,7 @@ exec_const_expr(const struct expr *expr, enum valtype type, struct val *result, * it's very unlikely for a const expr to use a restart. * but just in case. */ - while (ret == ETOYWASMRESTART) { + while (IS_RESTARTABLE(ret)) { xlog_trace("%s: restarting execution of a const expr\n", __func__); ret = exec_expr_continue(ctx); @@ -1605,7 +1605,7 @@ retry:; } ret = 0; fail: - if (ret == ETOYWASMRESTART) { + if (IS_RESTARTABLE(ret)) { if (abstimeout != NULL) { assert(abstimeout == &ctx->restart_u.timer.abstimeout); ctx->restart_type = RESTART_TIMER; diff --git a/lib/exec_context.h b/lib/exec_context.h index c5df9a5b..a7df6274 100644 --- a/lib/exec_context.h +++ b/lib/exec_context.h @@ -38,6 +38,8 @@ struct funcframe { #define ETOYWASMTRAP -1 #define ETOYWASMRESTART -2 +#define IS_RESTARTABLE(error) ((error) == ETOYWASMRESTART) + enum trapid { TRAP_MISC, TRAP_DIV_BY_ZERO, diff --git a/lib/insn.c b/lib/insn.c index fcef9798..9926bcb9 100644 --- a/lib/insn.c +++ b/lib/insn.c @@ -490,7 +490,7 @@ read_memarg_nocheck(const uint8_t **pp, struct memarg *arg) #define INSN_FAIL_RESTARTABLE(NAME) \ assert(ret != 0); \ if (EXECUTING) { \ - if (ret == ETOYWASMRESTART) { \ + if (IS_RESTARTABLE(ret)) { \ struct exec_context *ectx = ECTX; \ ectx->stack.lsize = saved_stack_ptr; \ ectx->event = EXEC_EVENT_RESTART_INSN; \ @@ -501,7 +501,7 @@ read_memarg_nocheck(const uint8_t **pp, struct memarg *arg) #endif #define INSN_FAIL \ assert(ret != 0); \ - assert(ret != ETOYWASMRESTART); \ + assert(!IS_RESTARTABLE(ret)); \ return ret #define STACK &VEC_NEXTELEM(ECTX->stack) #define STACK_ADJ(n) ECTX->stack.lsize += (n) @@ -553,7 +553,7 @@ read_memarg_nocheck(const uint8_t **pp, struct memarg *arg) #define PREPARE_FOR_POSSIBLE_RESTART struct cell *saved_stack_ptr = stack #define INSN_FAIL_RESTARTABLE(NAME) \ assert(ret != 0); \ - if (ret == ETOYWASMRESTART) { \ + if (IS_RESTARTABLE(ret)) { \ ctx->p = ORIG_PC; \ stack = saved_stack_ptr; \ SAVE_STACK_PTR; \ @@ -563,7 +563,7 @@ read_memarg_nocheck(const uint8_t **pp, struct memarg *arg) return ret #define INSN_FAIL \ assert(ret != 0); \ - assert(ret != ETOYWASMRESTART); \ + assert(!IS_RESTARTABLE(ret)); \ return ret #define ep NULL #define STACK stack diff --git a/lib/instance.c b/lib/instance.c index a270075f..b9aef62f 100644 --- a/lib/instance.c +++ b/lib/instance.c @@ -487,7 +487,7 @@ instance_create_execute_init(struct instance *inst, struct exec_context *ctx) assert(m->start < m->nimportedfuncs + m->nfuncs); struct funcinst *finst = VEC_ELEM(inst->funcs, m->start); ret = invoke(finst, NULL, NULL, NULL, NULL, ctx); - while (ret == ETOYWASMRESTART) { + while (IS_RESTARTABLE(ret)) { xlog_trace("%s: restarting execution of the start " "function\n", __func__); @@ -581,7 +581,7 @@ instance_execute_func(struct exec_context *ctx, uint32_t funcidx, ctx); if (ret == 0) { vals_from_cells(results, result_cells, resulttype); - } else if (ret == ETOYWASMRESTART) { + } else if (IS_RESTARTABLE(ret)) { /* * ctx->nresults is set by invoke(). * while it's redundant, it can be used by @@ -640,7 +640,7 @@ int instance_execute_handle_restart(struct exec_context *ctx, int exec_ret) { int ret = exec_ret; - while (ret == ETOYWASMRESTART) { + while (IS_RESTARTABLE(ret)) { #if defined(TOYWASM_ENABLE_WASM_THREADS) suspend_parked(ctx->cluster); #endif diff --git a/lib/instance.h b/lib/instance.h index 3d141da5..c598d1a2 100644 --- a/lib/instance.h +++ b/lib/instance.h @@ -48,9 +48,12 @@ void instance_destroy(struct instance *inst); * execute the function. * * in addition to usual error numbers, this function can - * return following toywasm-specific errors: + * return following toywasm-specific errors. + * Some of them are restartable, which can be checked using + * the IS_RESTARTABLE macro. * - * ETOYWASMRESTART: the execution has been suspended for some reasons. + * ETOYWASMRESTART (or other restartable error): + * the execution has been suspended for some reasons. * possible reasons include: * * - suspend_threads mechanism, which is used for @@ -83,7 +86,7 @@ int instance_execute_func_nocheck(struct exec_context *ctx, uint32_t funcidx, * instance_execute_continue: * * when one of instance_execute_xxx functions including the following ones - * returned ETOYWASMRESTART, the app can resume the execution by calling + * returned a restartable error, the app can resume the execution by calling * this function. * * - instance_execute_func @@ -97,9 +100,9 @@ int instance_execute_continue(struct exec_context *ctx); /* * instance_execute_handle_restart: * - * perform the default ETOYWASMRESTART handling. - * this function never returns ETOYWASMRESTART. - * if the given exec_ret is not ETOYWASMRESTART, this function just + * perform the default handling of a restartable error. + * this function never returns a restartable error. + * if the given exec_ret is not a restartable error, this function just * returns it as it is. */ int instance_execute_handle_restart(struct exec_context *ctx, int exec_ret); diff --git a/lib/usched.c b/lib/usched.c index 9d410f98..530a18aa 100644 --- a/lib/usched.c +++ b/lib/usched.c @@ -68,7 +68,7 @@ sched_run(struct sched *sched, struct exec_context *caller) * calling sched_enqueue. */ ret = instance_execute_continue(ctx); - if (ret == ETOYWASMRESTART) { + if (IS_RESTARTABLE(ret)) { xlog_trace("%s: re-enqueueing ctx %p", __func__, (void *)ctx); LIST_INSERT_TAIL(q, ctx, rq); diff --git a/libwasi/wasi.c b/libwasi/wasi.c index 1e9e41e8..27a99334 100644 --- a/libwasi/wasi.c +++ b/libwasi/wasi.c @@ -607,7 +607,7 @@ wasi_poll(struct exec_context *ctx, struct pollfd *fds, nfds_t nfds, host_ret = check_interrupt(ctx); if (host_ret != 0) { - if (host_ret == ETOYWASMRESTART) { + if (IS_RESTARTABLE(host_ret)) { if (abstimeout != NULL) { assert(abstimeout == &ctx->restart_u.timer @@ -656,8 +656,7 @@ wasi_poll(struct exec_context *ctx, struct pollfd *fds, nfds_t nfds, fail: assert(host_ret != 0 || ret >= 0); assert(host_ret != 0 || ret != 0 || *neventsp > 0); - assert(host_ret == ETOYWASMRESTART || - ctx->restart_type == RESTART_NONE); + assert(IS_RESTARTABLE(host_ret) || ctx->restart_type == RESTART_NONE); if (host_ret == 0) { *retp = ret; } @@ -672,7 +671,7 @@ wait_fd_ready(struct exec_context *ctx, int hostfd, short event, int *retp) pfd.events = event; int nev; int ret = wasi_poll(ctx, &pfd, 1, -1, retp, &nev); - if (ret == ETOYWASMRESTART) { + if (IS_RESTARTABLE(ret)) { xlog_trace("%s: restarting", __func__); } return ret; @@ -2026,12 +2025,12 @@ wasi_poll_oneoff(struct exec_context *ctx, struct host_instance *hi, wasi_convert_errno(ret)); } free(pollfds); - if (host_ret != ETOYWASMRESTART) { + if (!IS_RESTARTABLE(host_ret)) { /* * avoid leaving a stale restart state. * * consider: - * 1. poll_oneoff returns ETOYWASMRESTART with + * 1. poll_oneoff returns a restartable error with * restart_abstimeout saved. * 2. exec_expr_continue restarts the poll_oneoff. * 3. however, for some reasons, poll_oneoff doesn't diff --git a/libwasi/wasi_threads.c b/libwasi/wasi_threads.c index c56f615e..979f5b22 100644 --- a/libwasi/wasi_threads.c +++ b/libwasi/wasi_threads.c @@ -359,7 +359,7 @@ user_runner_exec_start(struct thread_arg *arg) ctx->exec_done = user_runner_exec_done; ctx->exec_done_arg = arg; ret = exec_thread_start_func(ctx, arg); - if (ret == ETOYWASMRESTART) { + if (IS_RESTARTABLE(ret)) { struct sched *sched = wasi_threads_sched(arg->wasi); sched_enqueue(sched, ctx); } else { @@ -381,7 +381,7 @@ runner(void *vp) exec_context_init(ctx, arg->inst); ret = exec_thread_start_func(ctx, arg); - while (ret == ETOYWASMRESTART) { + while (IS_RESTARTABLE(ret)) { suspend_parked(ctx->cluster); xlog_trace("%s: restarting execution\n", __func__); ret = instance_execute_continue(ctx);