Shrinking the code in OP_BREAK and OP_RETURN_BLK

- Can refer directly to `proc->e.env` after `MRB_PROC_ENV_P()`.
  - Can omit `MRB_ENV_ONSTACK_P()` since `mrb->c` is never NULL and can be directly compared to `env->cxt`.
  - Can avoid `goto` by putting the code block that raises the `LocalJumpError` at the end.
This commit is contained in:
dearblue
2024-08-12 20:54:55 +09:00
parent 22eb7e87af
commit 682583a609
+18 -34
View File
@@ -2303,25 +2303,16 @@ RETRY_TRY_BLOCK:
CASE(OP_BREAK, B) {
if (MRB_PROC_STRICT_P(ci->proc)) goto NORMAL_RETURN;
if (MRB_PROC_ORPHAN_P(ci->proc) || !MRB_PROC_ENV_P(ci->proc) || !MRB_ENV_ONSTACK_P(MRB_PROC_ENV(ci->proc))) {
L_BREAK_ERROR:
RAISE_LIT(mrb, E_LOCALJUMP_ERROR, "break from proc-closure");
}
else {
struct REnv *e = MRB_PROC_ENV(ci->proc);
if (e->cxt != mrb->c) {
goto L_BREAK_ERROR;
if (!MRB_PROC_ORPHAN_P(ci->proc) && MRB_PROC_ENV_P(ci->proc) && ci->proc->e.env->cxt == mrb->c) {
const struct RProc *dst = ci->proc->upper;
for (ptrdiff_t i = ci - mrb->c->cibase; i > 0; i--, ci--) {
if (ci[-1].proc == dst) {
goto L_UNWINDING;
}
}
}
const struct RProc *dst = ci->proc->upper;
while (mrb->c->cibase < ci && ci[-1].proc != dst) {
ci--;
}
if (ci == mrb->c->cibase) {
goto L_BREAK_ERROR;
}
goto L_UNWINDING;
RAISE_LIT(mrb, E_LOCALJUMP_ERROR, "break from proc-closure");
/* not reached */
}
CASE(OP_RETURN_BLK, B) {
if (!MRB_PROC_ENV_P(ci->proc) || MRB_PROC_STRICT_P(ci->proc)) {
@@ -2329,25 +2320,18 @@ RETRY_TRY_BLOCK:
}
const struct RProc *dst = top_proc(mrb, ci->proc);
mrb_callinfo *cibase = mrb->c->cibase;
if (MRB_PROC_ENV_P(dst)) {
struct REnv *e = MRB_PROC_ENV(dst);
if (!MRB_ENV_ONSTACK_P(e) || e->cxt != mrb->c) {
localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
goto L_RAISE;
if (!MRB_PROC_ENV_P(dst) || dst->e.env->cxt == mrb->c) {
/* check jump destination */
for (ptrdiff_t i = ci - mrb->c->cibase; i >= 0; i--, ci--) {
if (ci->proc == dst) {
goto L_UNWINDING;
}
}
}
/* check jump destination */
while (cibase <= ci && ci->proc != dst) {
ci--;
}
if (ci <= cibase) { /* no jump destination */
localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
goto L_RAISE;
}
goto L_UNWINDING;
/* no jump destination */
localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
goto L_RAISE;
/* not reached */
}
CASE(OP_RETURN, B) {
mrb_int acc;