mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
vm: add OP_RETTRUE and OP_RETFALSE for returning boolean literals
Add single-byte opcodes for returning true/false directly, completing the set of literal return opcodes (RETSELF, RETNIL, RETTRUE, RETFALSE). Codegen applies peephole optimization to fuse LOADTRUE/LOADFALSE + RETURN. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -86,6 +86,7 @@ New super-instructions that fuse common opcode sequences to reduce bytecode size
|
||||
- `OP_MATCHERR`: Pattern matching error with conditional execution for `in` patterns ([944168a](https://github.com/mruby/mruby/commit/944168a), [e9a9ba4](https://github.com/mruby/mruby/commit/e9a9ba4))
|
||||
- `OP_BLKCALL`: Direct block call for `yield`, bypassing method dispatch (13-17% faster) ([3aa2872](https://github.com/mruby/mruby/commit/3aa2872))
|
||||
- `OP_RETNIL`: Single-byte instruction for `return nil` pattern ([64e30bf](https://github.com/mruby/mruby/commit/64e30bf))
|
||||
- `OP_RETTRUE`/`OP_RETFALSE`: Single-byte instructions for `return true`/`return false` patterns
|
||||
|
||||
# Fixed GitHub Issues
|
||||
|
||||
|
||||
@@ -75,6 +75,8 @@ OPCODE(RETURN, B) /* return R[a] (normal) */
|
||||
OPCODE(RETURN_BLK, B) /* return R[a] (in-block return) */
|
||||
OPCODE(RETSELF, Z) /* return self */
|
||||
OPCODE(RETNIL, Z) /* return nil */
|
||||
OPCODE(RETTRUE, Z) /* return true */
|
||||
OPCODE(RETFALSE, Z) /* return false */
|
||||
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] */
|
||||
|
||||
@@ -1156,7 +1156,18 @@ gen_return(codegen_scope *s, uint8_t op, uint16_t src)
|
||||
rewind_pc(s);
|
||||
genop_0(s, OP_RETNIL);
|
||||
}
|
||||
else if (data.insn != OP_RETURN && data.insn != OP_RETSELF && data.insn != OP_RETNIL) {
|
||||
else if (data.insn == OP_LOADTRUE && src == data.a && op == OP_RETURN) {
|
||||
/* LOADTRUE + RETURN -> RETTRUE */
|
||||
rewind_pc(s);
|
||||
genop_0(s, OP_RETTRUE);
|
||||
}
|
||||
else if (data.insn == OP_LOADFALSE && src == data.a && op == OP_RETURN) {
|
||||
/* LOADFALSE + RETURN -> RETFALSE */
|
||||
rewind_pc(s);
|
||||
genop_0(s, OP_RETFALSE);
|
||||
}
|
||||
else if (data.insn != OP_RETURN && data.insn != OP_RETSELF && data.insn != OP_RETNIL &&
|
||||
data.insn != OP_RETTRUE && data.insn != OP_RETFALSE) {
|
||||
genop_1(s, op, src);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -402,6 +402,12 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out)
|
||||
CASE(OP_RETNIL, Z):
|
||||
fprintf(out, "RETNIL\n");
|
||||
break;
|
||||
CASE(OP_RETTRUE, Z):
|
||||
fprintf(out, "RETTRUE\n");
|
||||
break;
|
||||
CASE(OP_RETFALSE, Z):
|
||||
fprintf(out, "RETFALSE\n");
|
||||
break;
|
||||
CASE(OP_BREAK, B):
|
||||
fprintf(out, "BREAK\t\tR%d\t", a);
|
||||
print_lv_a(mrb, irep, a, out);
|
||||
|
||||
@@ -2748,6 +2748,14 @@ RETRY_TRY_BLOCK:
|
||||
a = 0;
|
||||
goto L_RETURN_NIL;
|
||||
}
|
||||
CASE(OP_RETTRUE, Z) {
|
||||
a = 0;
|
||||
goto L_RETURN_TRUE;
|
||||
}
|
||||
CASE(OP_RETFALSE, Z) {
|
||||
a = 0;
|
||||
goto L_RETURN_FALSE;
|
||||
}
|
||||
CASE(OP_RETURN, B) {
|
||||
mrb_int acc;
|
||||
mrb_value v;
|
||||
@@ -2758,6 +2766,12 @@ RETRY_TRY_BLOCK:
|
||||
goto L_RETURN;
|
||||
L_RETURN_NIL:
|
||||
v = mrb_nil_value();
|
||||
goto L_RETURN;
|
||||
L_RETURN_TRUE:
|
||||
v = mrb_true_value();
|
||||
goto L_RETURN;
|
||||
L_RETURN_FALSE:
|
||||
v = mrb_false_value();
|
||||
L_RETURN:
|
||||
mrb_gc_protect(mrb, v);
|
||||
return_ci = ci;
|
||||
|
||||
Reference in New Issue
Block a user