remove OP_LOADNIL before OP_SEND by introducing OP_SENDB (send with block)

This commit is contained in:
Yukihiro Matsumoto
2012-09-03 08:32:57 +09:00
parent 8fb23fe67d
commit 5340126443
3 changed files with 26 additions and 32 deletions
+16 -18
View File
@@ -517,7 +517,7 @@ for_body(codegen_scope *s, node *tree)
genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx - base, OP_L_BLOCK));
pop();
idx = new_msym(s, mrb_intern(s->mrb, "each"));
genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 0));
genop(s, MKOP_ABC(OP_SENDB, cursp(), idx, 0));
}
static int
@@ -766,11 +766,13 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val)
genop(s, MKOP_ABC(OP_EQ, cursp(), idx, n));
}
else {
if (blk > 0) { /* no block */
genop(s, MKOP_A(OP_LOADNIL, blk));
}
if (sendv) n = CALL_MAXARGS;
genop(s, MKOP_ABC(OP_SEND, cursp(), idx, n));
if (blk > 0) { /* no block */
genop(s, MKOP_ABC(OP_SEND, cursp(), idx, n));
}
else {
genop(s, MKOP_ABC(OP_SENDB, cursp(), idx, n));
}
}
}
if (val) {
@@ -987,9 +989,7 @@ codegen(codegen_scope *s, node *tree, int val)
push();
}
genop(s, MKOP_AB(OP_MOVE, cursp(), exc));
push();
genop(s, MKOP_A(OP_LOADNIL, cursp()));
pop(); pop();
pop();
genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern(s->mrb, "===")), 1));
tmp = new_label(s);
genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
@@ -1179,9 +1179,7 @@ codegen(codegen_scope *s, node *tree, int val)
codegen(s, n->car, VAL);
if (head) {
genop(s, MKOP_AB(OP_MOVE, cursp(), head));
push();
genop(s, MKOP_A(OP_LOADNIL, cursp()));
pop(); pop();
pop();
genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern(s->mrb, "===")), 1));
}
tmp = new_label(s);
@@ -1376,7 +1374,7 @@ codegen(codegen_scope *s, node *tree, int val)
mrb_sym sym = (mrb_sym)tree->cdr->car;
int len;
const char *name = mrb_sym2name_len(s->mrb, sym, &len);
int idx, blk = 0;
int idx;
codegen(s, tree->car, VAL);
if (len == 2 &&
@@ -1394,7 +1392,6 @@ codegen(codegen_scope *s, node *tree, int val)
break;
}
codegen(s, tree->cdr->cdr->car, VAL);
blk = cursp();
pop(); pop();
idx = new_msym(s, sym);
@@ -1417,10 +1414,7 @@ codegen(codegen_scope *s, node *tree, int val)
genop(s, MKOP_ABC(OP_GE, cursp(), idx, 1));
}
else {
if (blk > 0) {
genop(s, MKOP_A(OP_LOADNIL, blk));
}
genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 1));
genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 1));
}
}
gen_assignment(s, tree->car, cursp(), val);
@@ -1511,7 +1505,6 @@ codegen(codegen_scope *s, node *tree, int val)
push();
}
}
genop(s, MKOP_A(OP_LOADNIL, cursp()));
pop_n(n+1);
if (sendv) n = CALL_MAXARGS;
genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern(s->mrb, "call")), n));
@@ -2279,6 +2272,11 @@ codedump(mrb_state *mrb, int n)
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
GETARG_C(c));
break;
case OP_SENDB:
printf("OP_SENDB\tR%d\t:%s\t%d\n", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
GETARG_C(c));
break;
case OP_TAILCALL:
printf("OP_TAILCALL\tR%d\t:%s\t%d\n", GETARG_A(c),
mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
+1 -1
View File
@@ -83,8 +83,8 @@ OP_EPUSH,/* Bx ensure_push(SEQ[Bx]) */
OP_EPOP,/* A A.times{ensure_pop().call} */
OP_SEND,/* A B C R(A) := call(R(A),mSym(B),R(A+1),...,R(A+C)) */
OP_SENDB,/* A B C R(A) := call(R(A),mSym(B),R(A+1),...,R(A+C),&R(A+C+1))*/
OP_FSEND,/* A B C R(A) := fcall(R(A),mSym(B),R(A+1),...,R(A+C-1)) */
OP_VSEND,/* A B R(A) := vcall(R(A),mSym(B)) */
OP_CALL,/* A B C R(A) := self.call(R(A),.., R(A+C)) */
OP_SUPER,/* A B C R(A) := super(R(A+1),... ,R(A+C-1)) */
OP_ARGARY,/* A Bx R(A) := argument array (16=6:1:5:4) */
+9 -13
View File
@@ -459,7 +459,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
&&L_OP_GETUPVAR, &&L_OP_SETUPVAR,
&&L_OP_JMP, &&L_OP_JMPIF, &&L_OP_JMPNOT,
&&L_OP_ONERR, &&L_OP_RESCUE, &&L_OP_POPERR, &&L_OP_RAISE, &&L_OP_EPUSH, &&L_OP_EPOP,
&&L_OP_SEND, &&L_OP_FSEND, &&L_OP_VSEND,
&&L_OP_SEND, &&L_OP_SEND, &&L_OP_FSEND,
&&L_OP_CALL, &&L_OP_SUPER, &&L_OP_ARGARY, &&L_OP_ENTER,
&&L_OP_KARG, &&L_OP_KDICT, &&L_OP_RETURN, &&L_OP_TAILCALL, &&L_OP_BLKPUSH,
&&L_OP_ADD, &&L_OP_ADDI, &&L_OP_SUB, &&L_OP_SUBI, &&L_OP_MUL, &&L_OP_DIV,
@@ -739,6 +739,14 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
mrb_sym mid = syms[GETARG_B(i)];
recv = regs[a];
if (GET_OPCODE(i) != OP_SENDB) {
if (n == CALL_MAXARGS) {
SET_NIL_VALUE(regs[a+2]);
}
else {
SET_NIL_VALUE(regs[a+n+1]);
}
}
c = mrb_class(mrb, recv);
m = mrb_method_search_vm(mrb, &c, mid);
if (!m) {
@@ -810,11 +818,6 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
NEXT;
}
CASE(OP_VSEND) {
/* A B R(A) := vcall(R(A),Sym(B)) */
NEXT;
}
CASE(OP_CALL) {
/* A R(A) := self.call(frame.argc, frame.argv) */
mrb_callinfo *ci;
@@ -1297,7 +1300,6 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]);
break;
default:
SET_NIL_VALUE(regs[a+2]);
i = MKOP_ABC(OP_SEND, a, GETARG_B(i), GETARG_C(i));
goto L_SEND;
}
@@ -1339,7 +1341,6 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
OP_MATH_BODY(-,attr_f,attr_f);
break;
default:
SET_NIL_VALUE(regs[a+2]);
i = MKOP_ABC(OP_SEND, a, GETARG_B(i), GETARG_C(i));
goto L_SEND;
}
@@ -1381,7 +1382,6 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
OP_MATH_BODY(*,attr_f,attr_f);
break;
default:
SET_NIL_VALUE(regs[a+2]);
i = MKOP_ABC(OP_SEND, a, GETARG_B(i), GETARG_C(i));
goto L_SEND;
}
@@ -1415,7 +1415,6 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
OP_MATH_BODY(/,attr_f,attr_f);
break;
default:
SET_NIL_VALUE(regs[a+2]);
i = MKOP_ABC(OP_SEND, a, GETARG_B(i), GETARG_C(i));
goto L_SEND;
}
@@ -1435,7 +1434,6 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
regs[a].attr_f += GETARG_C(i);
break;
default:
SET_NIL_VALUE(regs[a+2]);
SET_INT_VALUE(regs[a+1], GETARG_C(i));
i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1);
goto L_SEND;
@@ -1456,7 +1454,6 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
regs[a].attr_f -= GETARG_C(i);
break;
default:
SET_NIL_VALUE(regs[a+2]);
SET_INT_VALUE(regs[a+1], GETARG_C(i));
i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1);
goto L_SEND;
@@ -1490,7 +1487,6 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
OP_CMP_BODY(op,attr_f,attr_f);\
break;\
default:\
SET_NIL_VALUE(regs[a+2]);\
i = MKOP_ABC(OP_SEND, a, GETARG_B(i), GETARG_C(i));\
goto L_SEND;\
}\