mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
zsuper should respect block given; close #185
This commit is contained in:
+7
-2
@@ -1280,7 +1280,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
push();
|
||||
push(); /* room for receiver */
|
||||
if (tree) {
|
||||
node *args = tree->car;
|
||||
while (args) {
|
||||
@@ -1307,14 +1307,19 @@ codegen(codegen_scope *s, node *tree, int val)
|
||||
codegen_scope *s2 = s;
|
||||
int lv = 0, ainfo = 0;
|
||||
|
||||
push(); /* room for receiver */
|
||||
while (s2->ainfo < 0) {
|
||||
lv++;
|
||||
s2 = s2->prev;
|
||||
if (!s2) break;
|
||||
}
|
||||
if (s2) ainfo = s2->ainfo;
|
||||
push();
|
||||
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();
|
||||
genop(s, MKOP_ABC(OP_SUPER, cursp(), 0, CALL_MAXARGS));
|
||||
if (val) push();
|
||||
|
||||
+13
-3
@@ -754,11 +754,21 @@ args_with_block(parser_state *p, node *a, node *b)
|
||||
static void
|
||||
call_with_block(parser_state *p, node *a, node *b)
|
||||
{
|
||||
node *n = a->cdr->cdr->cdr;
|
||||
node *n;
|
||||
|
||||
if (!n->car) n->car = cons(0, b);
|
||||
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 {
|
||||
args_with_block(p, n->car, b);
|
||||
n = a->cdr->cdr->cdr;
|
||||
if (!n->car) n->car = cons(0, b);
|
||||
else {
|
||||
args_with_block(p, n->car, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -933,12 +933,13 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
int argc = mrb->ci->argc;
|
||||
mrb_value *argv = regs+1;
|
||||
int len = m1 + o + r + m2;
|
||||
mrb_value *blk = &argv[argc < 0 ? 1 : argc];
|
||||
|
||||
if (argc < 0) {
|
||||
struct RArray *ary = mrb_ary_ptr(regs[1]);
|
||||
argv = ary->ptr;
|
||||
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 (argc >= 0) {
|
||||
@@ -954,7 +955,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
|
||||
}
|
||||
mrb->ci->argc = len;
|
||||
if (argc < len) {
|
||||
regs[len+1] = argv[argc]; /* move block */
|
||||
regs[len+1] = *blk; /* move block */
|
||||
memmove(®s[1], argv, sizeof(mrb_value)*(argc-m2)); /* m1 + o */
|
||||
memmove(®s[len-m2+1], &argv[argc-m2], sizeof(mrb_value)*m2); /* m2 */
|
||||
if (r) { /* r */
|
||||
@@ -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);
|
||||
}
|
||||
memmove(®s[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;
|
||||
}
|
||||
JUMP;
|
||||
|
||||
Reference in New Issue
Block a user