From 29d3a40418dd41dfb0e10f92d08ce313bb439eca Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 16 May 2016 01:46:37 +0900 Subject: stack adjustment after NODE_OP_ASGN with NODE_CALL was wrong; fix #3159 --- mrbgems/mruby-compiler/core/codegen.c | 55 ++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 11 deletions(-) diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 4b45beab8..37a7cbd0d 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -1747,21 +1747,32 @@ codegen(codegen_scope *s, node *tree, int val) 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)); + int base = cursp()-1; + int nargs = gen_values(s, n->cdr->cdr->car->car, VAL); + + /* copy receiver and arguments */ + if (nargs >= 0) { + int i; + + genop(s, MKOP_AB(OP_MOVE, cursp(), base)); + for (i=0; icdr->cdr->car, VAL); pop(); - gen_assignment(s, tree->car, cursp(), val); + if (val) { + genop(s, MKOP_AB(OP_MOVE, vsp, cursp())); + } + if ((intptr_t)tree->car->car == NODE_CALL) { + mrb_sym m = sym(tree->car->cdr->cdr->car); + mrb_sym m2 = attrsym(s, m); + + idx = new_msym(s, m2); + pop(); + if (callargs == CALL_MAXARGS) { + genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1)); + pop(); + genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs)); + } + else { + pop_n(callargs); + genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs+1)); + } + } + else { + gen_assignment(s, tree->car, cursp(), val); + } dispatch(s, pos); return; } -- cgit v1.2.3