ops.h: add new instructions `OP_SSEND` and `OP_SSENDB`.

These instructions call methods of the receiver.
parent 45491cdd
...@@ -57,6 +57,8 @@ OPCODE(JMPUW, S) /* unwind_and_jump_to(a) */ ...@@ -57,6 +57,8 @@ OPCODE(JMPUW, S) /* unwind_and_jump_to(a) */
OPCODE(EXCEPT, B) /* R[a] = exc */ OPCODE(EXCEPT, B) /* R[a] = exc */
OPCODE(RESCUE, BB) /* R[b] = R[a].isa?(R[b]) */ OPCODE(RESCUE, BB) /* R[b] = R[a].isa?(R[b]) */
OPCODE(RAISEIF, B) /* raise(R[a]) if R[a] */ 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(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(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) */ OPCODE(CALL, Z) /* R[0] = self.call(frame.argc, frame.argv) */
......
...@@ -318,6 +318,14 @@ codedump(mrb_state *mrb, const mrb_irep *irep) ...@@ -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); printf("OP_JMPNIL\tR%d\t%03d\t", a, (int)i+(int16_t)b);
print_lv_a(mrb, irep, a); print_lv_a(mrb, irep, a);
break; 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): CASE(OP_SEND, BBB):
printf("OP_SEND\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b])); printf("OP_SEND\tR%d\t:%s\t", a, mrb_sym_dump(mrb, irep->syms[b]));
print_args(c); print_args(c);
......
...@@ -1539,6 +1539,17 @@ RETRY_TRY_BLOCK: ...@@ -1539,6 +1539,17 @@ RETRY_TRY_BLOCK:
NEXT; 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) CASE(OP_SEND, BBB)
goto L_SENDB; goto L_SENDB;
...@@ -1556,7 +1567,7 @@ RETRY_TRY_BLOCK: ...@@ -1556,7 +1567,7 @@ RETRY_TRY_BLOCK:
int n = c&0xf; int n = c&0xf;
int nk = (c>>4)&0xf; int nk = (c>>4)&0xf;
mrb_callinfo *ci = mrb->c->ci; 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; mrb_method_t m;
struct RClass *cls; struct RClass *cls;
mrb_value recv; mrb_value recv;
...@@ -1570,11 +1581,12 @@ RETRY_TRY_BLOCK: ...@@ -1570,11 +1581,12 @@ RETRY_TRY_BLOCK:
} }
mrb_assert(bidx < irep->nregs+a); mrb_assert(bidx < irep->nregs+a);
mrb_value blk = mrb_nil_value(); mrb_value blk;
mrb_int new_bidx = a+((n==15)?1:n)+1+(nk==15); mrb_int new_bidx = a+mrb_bidx(c);
if (insn == OP_SEND) { if (insn == OP_SEND) {
/* clear block argument */ /* clear block argument */
SET_NIL_VALUE(regs[new_bidx]); SET_NIL_VALUE(regs[new_bidx]);
SET_NIL_VALUE(blk);
} }
else { else {
blk = regs[bidx]; blk = regs[bidx];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment