From a3861dcb538d9df78c44af9a55a74a3546f5d67e Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 2 Mar 2026 12:04:48 +0900 Subject: [PATCH] vm.c: scope down `tc` variable from function to block scope Inline L_DEF_METHOD body into OP_TDEF and OP_SDEF, making `tc` (target class) a block-local variable in each case. This eliminates the cross-case goto and frees one register at function scope. `ch` (catch handler) cannot be scoped down because UNWIND_ENSURE sets it before goto L_CATCH_TAGGED_BREAK where ch->target is consumed (cross-goto flow requires function-scope visibility). Co-authored-by: Claude --- src/vm.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/vm.c b/src/vm.c index b0b0b5b12..0ff62efe1 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1681,7 +1681,6 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *begin_proc, const mrb_code *iseq uint16_t b; uint16_t c; mrb_sym mid; - struct RClass *tc; /* target class for OP_TDEF/OP_SDEF */ const struct mrb_irep_catch_handler *ch; #ifndef MRB_USE_VM_SWITCH_DISPATCH @@ -3517,16 +3516,26 @@ RETRY_TRY_BLOCK: } CASE(OP_TDEF, BBB) { - tc = check_target_class(mrb); + struct RClass *tc = check_target_class(mrb); + struct RProc *p; + mrb_method_t m; + if (mrb_unlikely(!tc)) goto L_RAISE; + p = mrb_proc_new(mrb, irep->reps[c]); + mid = irep->syms[b]; + p->flags |= MRB_PROC_SCOPE | MRB_PROC_STRICT; + MRB_METHOD_FROM_PROC(m, p); + MRB_METHOD_SET_VISIBILITY(m, MRB_METHOD_VDEFAULT_FL); + mrb_define_method_raw(mrb, tc, mid, m); + mrb_method_added(mrb, tc, mid); + ci = mrb->c->ci; + mrb_gc_arena_restore(mrb, ai); + regs[a] = mrb_symbol_value(mid); + NEXT; } - goto L_DEF_METHOD; CASE(OP_SDEF, BBB) { - tc = mrb_class_ptr(mrb_singleton_class(mrb, regs[a])); - } - L_DEF_METHOD: - { + struct RClass *tc = mrb_class_ptr(mrb_singleton_class(mrb, regs[a])); struct RProc *p = mrb_proc_new(mrb, irep->reps[c]); mrb_method_t m;