From 8a62bf25c8e5a5524469f22e9a6f7dccb96dc103 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 30 Oct 2022 23:05:29 +0900 Subject: [PATCH] Simplify the `L_RAISE` block The current flow of the `L_RAISE` block is as follows: ```mermaid flowchart LR raise((raise)) raise --> citop{"top of call info?"} citop -- YES --> chftop{"no catch handler?"} citop -- NO --> chf{"no catch handler?"} chftop -- YES --> fiber{"root of fiber?"} chftop -- NO --> vmexec((vmexec)) fiber -- YES --> vmstop((vmstop)) fiber -- NO --> fswitch["switch fiber"] fswitch --> citop chf -- YES --> cipop["cipop"] chf -- NO --> vmexec((vmexec)) cipop --> citop ``` This patch makes the catch handler search first: ```mermaid flowchart LR raise((raise)) raise --> chf{"no catch handler?"} chf -- NO --> vmexec((vmexec)) chf -- YES --> citop{"top of call info?"} citop -- YES --> fiber{"root of fiber?"} citop -- NO --> cipop["cipop"] cipop --> chf fiber -- YES --> vmstop((vmstop)) fiber -- NO --> fswitch["switch fiber"] fswitch --> chf ``` --- src/vm.c | 50 +++++++++++++++++++++----------------------------- 1 file changed, 21 insertions(+), 29 deletions(-) diff --git a/src/vm.c b/src/vm.c index e90fd816d..4acb1a9b4 100644 --- a/src/vm.c +++ b/src/vm.c @@ -2189,39 +2189,31 @@ RETRY_TRY_BLOCK: if (mrb->exc) { L_RAISE: ci = mrb->c->ci; - if (ci == mrb->c->cibase) { - ch = catch_handler_find(mrb, ci, pc, MRB_CATCH_FILTER_ALL); - if (ch == NULL) goto L_FTOP; - goto L_CATCH; - } while ((ch = catch_handler_find(mrb, ci, pc, MRB_CATCH_FILTER_ALL)) == NULL) { - ci = cipop(mrb); - if (ci[1].cci == CINFO_SKIP && prev_jmp) { - mrb->jmp = prev_jmp; - MRB_THROW(prev_jmp); - } - pc = ci[0].pc; - if (ci == mrb->c->cibase) { - ch = catch_handler_find(mrb, ci, pc, MRB_CATCH_FILTER_ALL); - if (ch == NULL) { - L_FTOP: /* fiber top */ - 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; - c->prev = NULL; - goto L_RAISE; - } + if (ci != mrb->c->cibase) { + ci = cipop(mrb); + if (ci[1].cci == CINFO_SKIP && prev_jmp) { + mrb->jmp = prev_jmp; + MRB_THROW(prev_jmp); + } + pc = ci[0].pc; + } + 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; + c->prev = NULL; + goto L_RAISE; } - break; } } - L_CATCH: + if (ch == NULL) goto L_STOP; if (FALSE) { L_CATCH_TAGGED_BREAK: /* from THROW_TAGGED_BREAK() or UNWIND_ENSURE() */