vm: add OP_RETSELF instruction for returning self

Fuse LOADSELF + RETURN sequence into single RETSELF instruction.
Saves 2 bytes per occurrence (3 bytes -> 1 byte).

Found 25 occurrences in mrblib, saving 50 bytes total.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2026-01-19 14:15:28 +09:00
parent dece8cb343
commit 724a2e2638
4 changed files with 14 additions and 1 deletions
+1
View File
@@ -71,6 +71,7 @@ OPCODE(KEYEND, Z) /* raise unless kdict.empty? */
OPCODE(KARG, BB) /* R[a] = kdict[Syms[b]]; kdict.delete(Syms[b]) */
OPCODE(RETURN, B) /* return R[a] (normal) */
OPCODE(RETURN_BLK, B) /* return R[a] (in-block return) */
OPCODE(RETSELF, Z) /* return self */
OPCODE(BREAK, B) /* break R[a] */
OPCODE(BLKPUSH, BS) /* R[a] = block (16=m5:r1:m5:d1:lv4) */
OPCODE(ADD, B) /* R[a] = R[a]+R[a+1] */
+6 -1
View File
@@ -1141,7 +1141,12 @@ gen_return(codegen_scope *s, uint8_t op, uint16_t src)
rewind_pc(s);
genop_1(s, op, data.b);
}
else if (data.insn != OP_RETURN) {
else if (data.insn == OP_LOADSELF && src == data.a && op == OP_RETURN) {
/* LOADSELF + RETURN -> RETSELF */
rewind_pc(s);
genop_0(s, OP_RETSELF);
}
else if (data.insn != OP_RETURN && data.insn != OP_RETSELF) {
genop_1(s, op, src);
}
}
+3
View File
@@ -390,6 +390,9 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out)
fprintf(out, "RETURN_BLK\tR%d\t", a);
print_lv_a(mrb, irep, a, out);
break;
CASE(OP_RETSELF, Z):
fprintf(out, "RETSELF\n");
break;
CASE(OP_BREAK, B):
fprintf(out, "BREAK\t\tR%d\t", a);
print_lv_a(mrb, irep, a, out);
+4
View File
@@ -2661,6 +2661,10 @@ RETRY_TRY_BLOCK:
RAISE_LIT(mrb, E_LOCALJUMP_ERROR, "unexpected return");
/* not reached */
}
CASE(OP_RETSELF, Z) {
a = 0;
goto NORMAL_RETURN;
}
CASE(OP_RETURN, B) {
mrb_int acc;
mrb_value v;