Skip to content

Commit

Permalink
fix duplicated eval in op_asgn
Browse files Browse the repository at this point in the history
`a` in `a.m += c` or `a[b] += c` should be evaluated only once.
  • Loading branch information
matz committed Mar 30, 2016
1 parent 4979b52 commit d098d82
Showing 1 changed file with 47 additions and 2 deletions.
49 changes: 47 additions & 2 deletions mrbgems/mruby-compiler/core/codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -1716,7 +1716,7 @@ codegen(codegen_scope *s, node *tree, int val)
mrb_sym sym = sym(tree->cdr->car);
mrb_int len;
const char *name = mrb_sym2name_len(s->mrb, sym, &len);
int idx;
int idx, callargs = -1, vsp = -1;

if ((len == 2 && name[0] == '|' && name[1] == '|') &&
((intptr_t)tree->car->car == NODE_CONST ||
Expand All @@ -1737,6 +1737,34 @@ codegen(codegen_scope *s, node *tree, int val)
genop(s, MKOP_A(OP_LOADF, exc));
dispatch(s, noexc);
}
else if ((intptr_t)tree->car->car == NODE_CALL) {
node *n = tree->car->cdr;

if (val) {
vsp = cursp();
push();
}
codegen(s, n->car, VAL); /* receiver */
idx = new_msym(s, sym(n->cdr->car));
if (n->cdr->cdr->car) {
int i = gen_values(s, n->cdr->cdr->car->car, VAL);
if (i >= 0) {
pop_n(i);
genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), i));
}
genop(s, MKOP_AB(OP_MOVE, cursp()+1, cursp()-1));
genop(s, MKOP_AB(OP_MOVE, cursp()+2, cursp()));
push();
genop(s, MKOP_ABC(OP_SEND, cursp(), idx, CALL_MAXARGS));
callargs = CALL_MAXARGS;
}
else {
genop(s, MKOP_AB(OP_MOVE, cursp(), cursp()-1));
genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 0));
callargs = 1;
}
push();
}
else {
codegen(s, tree->car, VAL);
}
Expand Down Expand Up @@ -1785,8 +1813,25 @@ codegen(codegen_scope *s, node *tree, int val)
else {
genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 1));
}
if (callargs < 0) {
gen_assignment(s, tree->car, cursp(), val);
}
else {
if (callargs == CALL_MAXARGS) {
genop(s, MKOP_AB(OP_ARYPUSH, cursp()-1, cursp()));
if (val) {
genop(s, MKOP_AB(OP_MOVE, vsp, cursp()));
}
pop();
}
else if (val) {
genop(s, MKOP_AB(OP_MOVE, vsp, cursp()));
}
pop();
idx = new_msym(s, attrsym(s,sym(tree->car->cdr->cdr->car)));
genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs));
}
}
gen_assignment(s, tree->car, cursp(), val);
break;

case NODE_SUPER:
Expand Down

0 comments on commit d098d82

Please sign in to comment.