From 5d5e4f521464d134250501774f49f61f11dc3997 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 19 Oct 2021 12:03:12 +0900 Subject: ops.h: add new instructions `OP_SSEND` and `OP_SSENDB`. These instructions call methods of the receiver. --- include/mruby/ops.h | 2 ++ src/codedump.c | 8 ++++++++ src/vm.c | 18 +++++++++++++++--- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/include/mruby/ops.h b/include/mruby/ops.h index 90e1c39de..f62d8cdfa 100644 --- a/include/mruby/ops.h +++ b/include/mruby/ops.h @@ -57,6 +57,8 @@ OPCODE(JMPUW, S) /* unwind_and_jump_to(a) */ OPCODE(EXCEPT, B) /* R[a] = exc */ OPCODE(RESCUE, BB) /* R[b] = R[a].isa?(R[b]) */ OPCODE(RAISEIF, B) /* raise(R[a]) if 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(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(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) /* R[0] = self.call(frame.argc, frame.argv) */ diff --git a/src/codedump.c b/src/codedump.c index 6a9fcfb6a..28c8040c4 100644 --- a/src/codedump.c +++ b/src/codedump.c @@ -318,6 +318,14 @@ codedump(mrb_state *mrb, const mrb_irep *irep) printf("OP_JMPNIL\tR%d\t%03d\t", a, (int)i+(int16_t)b); print_lv_a(mrb, irep, a); break; + CASE(OP_SSEND, BBB): + printf("OP_SSEND\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + print_args(c); + break; + CASE(OP_SSENDB, BBB): + printf("OP_SSENDB\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); + print_args(c); + break; CASE(OP_SEND, BBB): printf("OP_SEND\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); print_args(c); diff --git a/src/vm.c b/src/vm.c index ba60429ab..3457ce33c 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1539,6 +1539,17 @@ RETRY_TRY_BLOCK: NEXT; } + CASE(OP_SSEND, BBB) { + regs[a] = regs[0]; + insn = OP_SEND; + } + goto L_SENDB; + + CASE(OP_SSENDB, BBB) { + regs[a] = regs[0]; + } + goto L_SENDB; + CASE(OP_SEND, BBB) goto L_SENDB; @@ -1556,7 +1567,7 @@ RETRY_TRY_BLOCK: int n = c&0xf; int nk = (c>>4)&0xf; mrb_callinfo *ci = mrb->c->ci; - mrb_int bidx = a + ((n == 15) ? 1 : n) + ((nk == 15) ? 1 : 2*nk) + 1; + mrb_int bidx = a + mrb_bidx(c); mrb_method_t m; struct RClass *cls; mrb_value recv; @@ -1570,11 +1581,12 @@ RETRY_TRY_BLOCK: } mrb_assert(bidx < irep->nregs+a); - mrb_value blk = mrb_nil_value(); - mrb_int new_bidx = a+((n==15)?1:n)+1+(nk==15); + mrb_value blk; + mrb_int new_bidx = a+mrb_bidx(c); if (insn == OP_SEND) { /* clear block argument */ SET_NIL_VALUE(regs[new_bidx]); + SET_NIL_VALUE(blk); } else { blk = regs[bidx]; -- cgit v1.2.3