vm: add OP_TDEF/OP_SDEF for fused method definition

TDEF fuses TCLASS+METHOD+DEF for normal method definitions.
SDEF fuses SCLASS+METHOD+DEF for singleton method definitions.
Saves 4 bytes per method definition (8 bytes -> 4 bytes).
Falls back to unfused instructions if irep index exceeds 255.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2026-01-20 13:02:06 +09:00
parent 51e8da6614
commit 48a88ed79b
4 changed files with 68 additions and 12 deletions
+6
View File
@@ -427,6 +427,12 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out)
CASE(OP_DEF, BB):
fprintf(out, "DEF\t\tR%d\t:%s\t(R%d)\n", a, mrb_sym_dump(mrb, irep->syms[b]),a+1);
break;
CASE(OP_TDEF, BBB):
fprintf(out, "TDEF\t\tR%d\t:%s\tI[%d]\n", a, mrb_sym_dump(mrb, irep->syms[b]), c);
break;
CASE(OP_SDEF, BBB):
fprintf(out, "SDEF\t\tR%d\t:%s\tI[%d]\n", a, mrb_sym_dump(mrb, irep->syms[b]), c);
break;
CASE(OP_UNDEF, B):
fprintf(out, "UNDEF\t\t:%s\n", mrb_sym_dump(mrb, irep->syms[a]));
break;
+36
View File
@@ -3396,6 +3396,42 @@ RETRY_TRY_BLOCK:
NEXT;
}
CASE(OP_TDEF, BBB) {
struct RClass *target = check_target_class(mrb);
if (!target) goto L_RAISE;
struct RProc *p = mrb_proc_new(mrb, irep->reps[c]);
mrb_method_t m;
mrb_sym 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, target, mid, m);
mrb_method_added(mrb, target, mid);
ci = mrb->c->ci;
mrb_gc_arena_restore(mrb, ai);
regs[a] = mrb_symbol_value(mid);
NEXT;
}
CASE(OP_SDEF, BBB) {
mrb_value recv = regs[a];
struct RClass *target = mrb_class_ptr(mrb_singleton_class(mrb, recv));
struct RProc *p = mrb_proc_new(mrb, irep->reps[c]);
mrb_method_t m;
mrb_sym 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, target, mid, m);
mrb_method_added(mrb, target, mid);
ci = mrb->c->ci;
mrb_gc_arena_restore(mrb, ai);
regs[a] = mrb_symbol_value(mid);
NEXT;
}
CASE(OP_SCLASS, B) {
regs[a] = mrb_singleton_class(mrb, regs[a]);
mrb_gc_arena_restore(mrb, ai);