From e9904ddb2a2fbc73166f7ccd9f5c05c0d7252680 Mon Sep 17 00:00:00 2001 From: dearblue Date: Fri, 15 Dec 2023 21:46:00 +0900 Subject: [PATCH] Move `L_RAISE` and `L_BREAK` blocks to `OP_RAISEIF` `OP_RAISEIF` should be easier to relate than `OP_RETURN`. --- src/vm.c | 124 +++++++++++++++++++++++++++---------------------------- 1 file changed, 60 insertions(+), 64 deletions(-) diff --git a/src/vm.c b/src/vm.c index 35e1650f9..21a2c1a30 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1747,14 +1747,66 @@ RETRY_TRY_BLOCK: } CASE(OP_RAISEIF, B) { - mrb_value exc = regs[a]; - if (mrb_break_p(exc)) { - mrb->exc = mrb_obj_ptr(exc); - goto L_BREAK; + mrb_value exc; + exc = regs[a]; + if (mrb_nil_p(exc)) { + mrb->exc = NULL; } - mrb_exc_set(mrb, exc); - if (mrb->exc) { - goto L_RAISE; + else if (mrb_break_p(exc)) { + struct RBreak *brk; + mrb->exc = mrb_obj_ptr(exc); + L_BREAK: + brk = (struct RBreak*)mrb->exc; + switch (mrb_break_tag_get(brk)) { +#define DISPATCH_CHECKPOINTS(n, i) case n: goto CHECKPOINT_LABEL_MAKE(n); + RBREAK_TAG_FOREACH(DISPATCH_CHECKPOINTS) +#undef DISPATCH_CHECKPOINTS + default: + mrb_assert(!"wrong break tag"); + } + } + else { + mrb_callinfo *ci; + mrb_exc_set(mrb, exc); + L_RAISE: + ci = mrb->c->ci; + while ((ch = catch_handler_find(mrb, ci, ci->pc, MRB_CATCH_FILTER_ALL)) == NULL) { + if (ci != mrb->c->cibase) { + ci = cipop(mrb); + if (ci[1].cci == CINFO_SKIP) { + mrb_assert(prev_jmp != NULL); + mrb->jmp = prev_jmp; + MRB_THROW(prev_jmp); + } + } + else if (mrb->c == mrb->root_c) { + mrb->c->ci->stack = mrb->c->stbase; + goto L_STOP; + } + else { + struct mrb_context *c = mrb->c; + + c->status = MRB_FIBER_TERMINATED; + mrb->c = c->prev; + if (!mrb->c) mrb->c = mrb->root_c; + else c->prev = NULL; + if (!c->vmexec) goto L_RAISE; + mrb->jmp = prev_jmp; + if (!prev_jmp) return mrb_obj_value(mrb->exc); + MRB_THROW(prev_jmp); + } + } + + if (FALSE) { + L_CATCH_TAGGED_BREAK: /* from THROW_TAGGED_BREAK() or UNWIND_ENSURE() */ + ci = mrb->c->ci; + } + proc = ci->proc; + irep = proc->body.irep; + pool = irep->pool; + syms = irep->syms; + stack_extend(mrb, irep->nregs); + pc = irep->iseq + mrb_irep_catch_handler_unpack(ch->target); } NEXT; } @@ -2224,45 +2276,7 @@ RETRY_TRY_BLOCK: ci = mrb->c->ci; if (mrb->exc) { - L_RAISE: - ci = mrb->c->ci; - while ((ch = catch_handler_find(mrb, ci, ci->pc, MRB_CATCH_FILTER_ALL)) == NULL) { - if (ci != mrb->c->cibase) { - ci = cipop(mrb); - if (ci[1].cci == CINFO_SKIP) { - mrb_assert(prev_jmp != NULL); - mrb->jmp = prev_jmp; - MRB_THROW(prev_jmp); - } - } - else if (mrb->c == mrb->root_c) { - mrb->c->ci->stack = mrb->c->stbase; - goto L_STOP; - } - else { - struct mrb_context *c = mrb->c; - - c->status = MRB_FIBER_TERMINATED; - mrb->c = c->prev; - if (!mrb->c) mrb->c = mrb->root_c; - else c->prev = NULL; - if (!c->vmexec) goto L_RAISE; - mrb->jmp = prev_jmp; - if (!prev_jmp) return mrb_obj_value(mrb->exc); - MRB_THROW(prev_jmp); - } - } - - if (FALSE) { - L_CATCH_TAGGED_BREAK: /* from THROW_TAGGED_BREAK() or UNWIND_ENSURE() */ - ci = mrb->c->ci; - } - proc = ci->proc; - irep = proc->body.irep; - pool = irep->pool; - syms = irep->syms; - stack_extend(mrb, irep->nregs); - pc = irep->iseq + mrb_irep_catch_handler_unpack(ch->target); + goto L_RAISE; } else { mrb_int acc; @@ -2344,24 +2358,6 @@ RETRY_TRY_BLOCK: if (ci == mrb->c->cibase) { goto L_BREAK_ERROR; } - if (FALSE) { - struct RBreak *brk; - - L_BREAK: - brk = (struct RBreak*)mrb->exc; - ci = &mrb->c->cibase[brk->ci_break_index]; - proc = ci->proc; - v = mrb_break_value_get(brk); - pc = ci->pc; - - switch (mrb_break_tag_get(brk)) { -#define DISPATCH_CHECKPOINTS(n, i) case n: goto CHECKPOINT_LABEL_MAKE(n); - RBREAK_TAG_FOREACH(DISPATCH_CHECKPOINTS) -#undef DISPATCH_CHECKPOINTS - default: - mrb_assert(!"wrong break tag"); - } - } break; default: /* cannot happen */