diff --git a/include/mruby/ops.h b/include/mruby/ops.h index 831403355..90efdc595 100644 --- a/include/mruby/ops.h +++ b/include/mruby/ops.h @@ -60,8 +60,10 @@ OPCODE(RESCUE, BB) /* R[b] = R[a].isa?(R[b]) */ OPCODE(RAISEIF, B) /* raise(R[a]) if R[a] */ OPCODE(MATCHERR, B) /* raise NoMatchingPatternError unless R[a] */ OPCODE(SSEND, BBB) /* R[a] = self.send(Syms[b],R[a+1]..,R[a+n+1]:R[a+n+2]..) (c=n|k<<4) */ +OPCODE(SSEND0, BB) /* R[a] = self.send(Syms[b]) (no args) */ OPCODE(SSENDB, BBB) /* R[a] = self.send(Syms[b],R[a+1]..,R[a+n+1]:R[a+n+2]..,&R[a+n+2k+1]) */ OPCODE(SEND, BBB) /* R[a] = R[a].send(Syms[b],R[a+1]..,R[a+n+1]:R[a+n+2]..) (c=n|k<<4) */ +OPCODE(SEND0, BB) /* R[a] = R[a].send(Syms[b]) (no args) */ OPCODE(SENDB, BBB) /* R[a] = R[a].send(Syms[b],R[a+1]..,R[a+n+1]:R[a+n+2]..,&R[a+n+2k+1]) */ OPCODE(CALL, Z) /* self.call(*, **, &) (But overlay the current call frame; tailcall) */ OPCODE(BLKCALL, BB) /* R[a] = R[a].call(R[a+1],... ,R[a+b]); direct block call */ diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 8d8078196..2aa9832ac 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -3643,7 +3643,15 @@ codegen_call(codegen_scope *s, node *varnode, int val) /* constant folding succeeded */ } else if (noself) { - genop_3(s, blk ? OP_SSENDB : OP_SSEND, cursp(), sym_idx(s, sym), n|(nk<<4)); + if (!blk && n == 0 && nk == 0) { + genop_2(s, OP_SSEND0, cursp(), sym_idx(s, sym)); + } + else { + genop_3(s, blk ? OP_SSENDB : OP_SSEND, cursp(), sym_idx(s, sym), n|(nk<<4)); + } + } + else if (!blk && n == 0 && nk == 0) { + genop_2(s, OP_SEND0, cursp(), sym_idx(s, sym)); } else { genop_3(s, blk ? OP_SENDB : OP_SEND, cursp(), sym_idx(s, sym), n|(nk<<4)); diff --git a/src/codedump.c b/src/codedump.c index 6471e876d..c1ef09231 100644 --- a/src/codedump.c +++ b/src/codedump.c @@ -336,6 +336,9 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out) fprintf(out, "SSEND\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); print_args(c, out); break; + CASE(OP_SSEND0, BB): + fprintf(out, "SSEND0\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b])); + break; CASE(OP_SSENDB, BBB): fprintf(out, "SSENDB\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); print_args(c, out); @@ -344,6 +347,9 @@ codedump(mrb_state *mrb, const mrb_irep *irep, FILE *out) fprintf(out, "SEND\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); print_args(c, out); break; + CASE(OP_SEND0, BB): + fprintf(out, "SEND0\t\tR%d\t:%s\n", a, mrb_sym_dump(mrb, irep->syms[b])); + break; CASE(OP_SENDB, BBB): fprintf(out, "SENDB\t\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); print_args(c, out); diff --git a/src/vm.c b/src/vm.c index 713160d48..a2f5b1f3d 100644 --- a/src/vm.c +++ b/src/vm.c @@ -2211,6 +2211,12 @@ RETRY_TRY_BLOCK: } goto L_SENDB; + CASE(OP_SSEND0, BB) { + regs[a] = regs[0]; + c = 0; + } + goto L_SENDB; + CASE(OP_SSENDB, BBB) { regs[a] = regs[0]; } @@ -2219,6 +2225,11 @@ RETRY_TRY_BLOCK: CASE(OP_SEND, BBB) goto L_SENDB; + CASE(OP_SEND0, BB) { + c = 0; + } + goto L_SENDB; + L_SEND_SYM: c = 1; /* push nil after arguments */ @@ -2259,7 +2270,7 @@ RETRY_TRY_BLOCK: } mrb_assert(bidx < irep->nregs); - if (insn == OP_SEND || insn == OP_SSEND) { + if (insn == OP_SEND || insn == OP_SEND0 || insn == OP_SSEND || insn == OP_SSEND0) { /* clear block argument */ SET_NIL_VALUE(regs[new_bidx]); SET_NIL_VALUE(blk); @@ -2280,7 +2291,7 @@ RETRY_TRY_BLOCK: else { ci->mid = mid; } - if (insn == OP_SEND || insn == OP_SENDB) { + if (insn == OP_SEND || insn == OP_SEND0 || insn == OP_SENDB) { mrb_bool priv = TRUE; if (m.flags & MRB_METHOD_PRIVATE_FL) { vis_err:;