diff --git a/NEWS.md b/NEWS.md index 36385471f..1f1d1e418 100644 --- a/NEWS.md +++ b/NEWS.md @@ -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 diff --git a/include/mruby/ops.h b/include/mruby/ops.h index 187962c14..831403355 100644 --- a/include/mruby/ops.h +++ b/include/mruby/ops.h @@ -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] */ diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 65718c429..8d8078196 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -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); } } diff --git a/src/codedump.c b/src/codedump.c index 2444b6b43..6471e876d 100644 --- a/src/codedump.c +++ b/src/codedump.c @@ -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); diff --git a/src/vm.c b/src/vm.c index eac9d021d..f5e23be74 100644 --- a/src/vm.c +++ b/src/vm.c @@ -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;