diff options
Diffstat (limited to 'mrbgems/mruby-compiler/core/codegen.c')
| -rw-r--r-- | mrbgems/mruby-compiler/core/codegen.c | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index ba8ed2c71..fce5ac490 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -278,6 +278,19 @@ genop_peep(codegen_scope *s, mrb_code i, int val) } } break; + case OP_GETUPVAR: + if (c0 == OP_SETUPVAR) { + if (GETARG_B(i) == GETARG_B(i0) && GETARG_C(i) == GETARG_C(i0)) { + if (GETARG_A(i) == GETARG_A(i0)) { + /* just skip OP_SETUPVAR */ + return 0; + } + else { + return genop(s, MKOP_AB(OP_MOVE, GETARG_A(i), GETARG_A(i0))); + } + } + } + break; case OP_EPOP: if (c0 == OP_EPOP) { s->iseq[s->pc-1] = MKOP_A(OP_EPOP, GETARG_A(i0)+GETARG_A(i)); @@ -335,6 +348,14 @@ genop_peep(codegen_scope *s, mrb_code i, int val) s->iseq[s->pc-1] = MKOP_ABC(OP_SUBI, GETARG_A(i), GETARG_B(i), -c); return 0; } + break; + case OP_ARYCAT: + case OP_ARYPUSH: + if (c0 == OP_MOVE && GETARG_A(i0) >= s->nlocals) { + s->iseq[s->pc-1] = MKOP_AB(c1, GETARG_A(i), GETARG_B(i0)); + return 0; + } + break; case OP_STRCAT: if (c0 == OP_STRING) { mrb_value v = s->irep->pool[GETARG_Bx(i0)]; @@ -826,10 +847,10 @@ gen_values(codegen_scope *s, node *t, int val, int extra) codegen(s, t->car, VAL); pop(); pop(); if (is_splat) { - genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1)); + genop_peep(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1), NOVAL); } else { - genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1)); + genop_peep(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1), NOVAL); } } t = t->cdr; @@ -838,10 +859,10 @@ gen_values(codegen_scope *s, node *t, int val, int extra) codegen(s, t->car, VAL); pop(); pop(); if (nint(t->car->car) == NODE_SPLAT) { - genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1)); + genop_peep(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1), NOVAL); } else { - genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1)); + genop_peep(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1), NOVAL); } t = t->cdr; } @@ -2146,7 +2167,7 @@ codegen(codegen_scope *s, node *tree, int val) while (up) { idx = lv_idx(up, nsym(tree)); if (idx > 0) { - genop(s, MKOP_ABC(OP_GETUPVAR, cursp(), idx, lv)); + genop_peep(s, MKOP_ABC(OP_GETUPVAR, cursp(), idx, lv), VAL); break; } lv++; @@ -3031,6 +3052,9 @@ mrb_generate_code(mrb_state *mrb, parser_state *p) mrb_irep_decref(mrb, scope->irep); mrb_pool_close(scope->mpool); proc->c = NULL; + if (mrb->c->cibase && mrb->c->cibase->proc == proc->upper) { + proc->upper = NULL; + } mrb->jmp = prev_jmp; return proc; } |
