codegen.c: fixed a bug regarding attribute assignment with kargs.

parent be189ae9
...@@ -1642,7 +1642,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) ...@@ -1642,7 +1642,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe)
{ {
mrb_sym sym = name ? name : nsym(tree->cdr->car); mrb_sym sym = name ? name : nsym(tree->cdr->car);
int skip = 0; int skip = 0;
int n = 0, nk = 0, st = 0, noop = 0, blk = 0; int n = 0, nk = 0, noop = 0, blk = 0, sp_save = cursp();
codegen(s, tree->car, VAL); /* receiver */ codegen(s, tree->car, VAL); /* receiver */
if (safe) { if (safe) {
...@@ -1653,9 +1653,8 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) ...@@ -1653,9 +1653,8 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe)
tree = tree->cdr->cdr->car; tree = tree->cdr->cdr->car;
if (tree) { if (tree) {
if (tree->car) { /* positional arguments */ if (tree->car) { /* positional arguments */
st = n = gen_values(s, tree->car, VAL, sp?1:0, 14); n = gen_values(s, tree->car, VAL, sp?1:0, 14);
if (n < 0) { /* variable length */ if (n < 0) { /* variable length */
st = 1; /* one stack element */
noop = 1; /* not operator */ noop = 1; /* not operator */
n = 15; n = 15;
push(); push();
...@@ -1664,12 +1663,22 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) ...@@ -1664,12 +1663,22 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe)
if (tree->cdr->car) { /* keyword arguments */ if (tree->cdr->car) { /* keyword arguments */
noop = 1; noop = 1;
nk = gen_hash(s, tree->cdr->car->cdr, VAL, 14); nk = gen_hash(s, tree->cdr->car->cdr, VAL, 14);
if (nk < 0) {st++; nk = 15;} if (nk < 0) nk = 15;
else st += 2*nk;
} }
} }
if (sp) { /* last argument pushed (attr=, []=) */ if (sp) { /* last argument pushed (attr=, []=) */
/* pack keyword arguments */
if (nk > 0 && nk < 15) {
pop_n(nk*2);
genop_2(s, OP_HASH, cursp(), nk);
push();
}
if (n == CALL_MAXARGS) { if (n == CALL_MAXARGS) {
if (nk > 0) {
pop(); pop();
genop_2(s, OP_ARYPUSH, cursp(), 1);
push();
}
gen_move(s, cursp(), sp, 0); gen_move(s, cursp(), sp, 0);
pop(); pop();
genop_2(s, OP_ARYPUSH, cursp(), 1); genop_2(s, OP_ARYPUSH, cursp(), 1);
...@@ -1678,8 +1687,10 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) ...@@ -1678,8 +1687,10 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe)
else { else {
gen_move(s, cursp(), sp, 0); gen_move(s, cursp(), sp, 0);
push(); push();
n++; st++; if (nk > 0) n++;
n++;
} }
nk = 0;
} }
if (tree && tree->cdr && tree->cdr->cdr) { if (tree && tree->cdr && tree->cdr->cdr) {
codegen(s, tree->cdr->cdr, VAL); codegen(s, tree->cdr->cdr, VAL);
...@@ -1688,7 +1699,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) ...@@ -1688,7 +1699,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe)
blk = 1; blk = 1;
} }
push();pop(); push();pop();
pop_n(st+1); s->sp = sp_save;
if (!noop && sym == MRB_OPSYM_2(s->mrb, add) && n == 1) { if (!noop && sym == MRB_OPSYM_2(s->mrb, add) && n == 1) {
gen_addsub(s, OP_ADD, cursp()); gen_addsub(s, OP_ADD, cursp());
} }
......
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