Commit 13a542d4 authored by Yukihiro Matsumoto's avatar Yukihiro Matsumoto

zsuper should respect block given; close #185

parent 8f020f28
...@@ -1280,7 +1280,7 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -1280,7 +1280,7 @@ codegen(codegen_scope *s, node *tree, int val)
{ {
int n = 0; int n = 0;
push(); push(); /* room for receiver */
if (tree) { if (tree) {
node *args = tree->car; node *args = tree->car;
while (args) { while (args) {
...@@ -1307,14 +1307,19 @@ codegen(codegen_scope *s, node *tree, int val) ...@@ -1307,14 +1307,19 @@ codegen(codegen_scope *s, node *tree, int val)
codegen_scope *s2 = s; codegen_scope *s2 = s;
int lv = 0, ainfo = 0; int lv = 0, ainfo = 0;
push(); /* room for receiver */
while (s2->ainfo < 0) { while (s2->ainfo < 0) {
lv++; lv++;
s2 = s2->prev; s2 = s2->prev;
if (!s2) break; if (!s2) break;
} }
if (s2) ainfo = s2->ainfo; if (s2) ainfo = s2->ainfo;
push();
genop(s, MKOP_ABx(OP_ARGARY, cursp(), (ainfo<<4)|(lv & 0xf))); genop(s, MKOP_ABx(OP_ARGARY, cursp(), (ainfo<<4)|(lv & 0xf)));
if (tree && tree->cdr) {
push();
codegen(s, tree->cdr, VAL);
pop_n(2);
}
pop(); pop();
genop(s, MKOP_ABC(OP_SUPER, cursp(), 0, CALL_MAXARGS)); genop(s, MKOP_ABC(OP_SUPER, cursp(), 0, CALL_MAXARGS));
if (val) push(); if (val) push();
......
...@@ -754,12 +754,22 @@ args_with_block(parser_state *p, node *a, node *b) ...@@ -754,12 +754,22 @@ args_with_block(parser_state *p, node *a, node *b)
static void static void
call_with_block(parser_state *p, node *a, node *b) call_with_block(parser_state *p, node *a, node *b)
{ {
node *n = a->cdr->cdr->cdr; node *n;
if (a->car == (node*)NODE_SUPER ||
a->car == (node*)NODE_ZSUPER) {
if (!a->cdr) a->cdr = cons(0, b);
else {
args_with_block(p, a->cdr, b);
}
}
else {
n = a->cdr->cdr->cdr;
if (!n->car) n->car = cons(0, b); if (!n->car) n->car = cons(0, b);
else { else {
args_with_block(p, n->car, b); args_with_block(p, n->car, b);
} }
}
} }
static node* static node*
......
...@@ -933,12 +933,13 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ...@@ -933,12 +933,13 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
int argc = mrb->ci->argc; int argc = mrb->ci->argc;
mrb_value *argv = regs+1; mrb_value *argv = regs+1;
int len = m1 + o + r + m2; int len = m1 + o + r + m2;
mrb_value *blk = &argv[argc < 0 ? 1 : argc];
if (argc < 0) { if (argc < 0) {
struct RArray *ary = mrb_ary_ptr(regs[1]); struct RArray *ary = mrb_ary_ptr(regs[1]);
argv = ary->ptr; argv = ary->ptr;
argc = ary->len; argc = ary->len;
regs[len+2] = regs[1]; /* save argary in register */ mrb_gc_protect(mrb, regs[1]);
} }
if (mrb->ci->proc && MRB_PROC_STRICT_P(mrb->ci->proc)) { if (mrb->ci->proc && MRB_PROC_STRICT_P(mrb->ci->proc)) {
if (argc >= 0) { if (argc >= 0) {
...@@ -954,7 +955,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ...@@ -954,7 +955,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
} }
mrb->ci->argc = len; mrb->ci->argc = len;
if (argc < len) { if (argc < len) {
regs[len+1] = argv[argc]; /* move block */ regs[len+1] = *blk; /* move block */
memmove(&regs[1], argv, sizeof(mrb_value)*(argc-m2)); /* m1 + o */ memmove(&regs[1], argv, sizeof(mrb_value)*(argc-m2)); /* m1 + o */
memmove(&regs[len-m2+1], &argv[argc-m2], sizeof(mrb_value)*m2); /* m2 */ memmove(&regs[len-m2+1], &argv[argc-m2], sizeof(mrb_value)*m2); /* m2 */
if (r) { /* r */ if (r) { /* r */
...@@ -968,7 +969,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ...@@ -968,7 +969,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
regs[m1+o+1] = mrb_ary_new_elts(mrb, argc-m1-o-m2, argv+m1+o); regs[m1+o+1] = mrb_ary_new_elts(mrb, argc-m1-o-m2, argv+m1+o);
} }
memmove(&regs[m1+o+r+1], &argv[argc-m2], sizeof(mrb_value)*m2); memmove(&regs[m1+o+r+1], &argv[argc-m2], sizeof(mrb_value)*m2);
regs[len+1] = argv[argc]; /* move block */ regs[len+1] = *blk; /* move block */
pc += o + 1; pc += o + 1;
} }
JUMP; JUMP;
......
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