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
```
This commit is contained in:
dearblue
2022-10-30 23:05:29 +09:00
parent 4371b736b7
commit 8a62bf25c8
+21 -29
View File
@@ -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() */