diff options
Diffstat (limited to 'mrbgems/mruby-eval/src/eval.c')
| -rw-r--r-- | mrbgems/mruby-eval/src/eval.c | 215 |
1 files changed, 2 insertions, 213 deletions
diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index ca046d88e..73e23392b 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -9,217 +9,6 @@ mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p); mrb_value mrb_obj_instance_eval(mrb_state *mrb, mrb_value self); -static struct mrb_irep * -get_closure_irep(mrb_state *mrb, int level) -{ - struct RProc *proc = mrb->c->ci[-1].proc; - - while (level--) { - if (!proc) return NULL; - proc = proc->upper; - } - if (!proc) return NULL; - if (MRB_PROC_CFUNC_P(proc)) { - return NULL; - } - return proc->body.irep; -} - -/* search for irep lev above the bottom */ -static mrb_irep* -search_irep(mrb_irep *top, int bnest, int lev, mrb_irep *bottom) -{ - int i; - - for (i=0; i<top->rlen; i++) { - mrb_irep* tmp = top->reps[i]; - - if (tmp == bottom) return top; - tmp = search_irep(tmp, bnest-1, lev, bottom); - if (tmp) { - if (bnest == lev) return top; - return tmp; - } - } - return NULL; -} - -static uint16_t -search_variable(mrb_state *mrb, mrb_sym vsym, int bnest) -{ - mrb_irep *virep; - int level; - int pos; - - for (level = 0; (virep = get_closure_irep(mrb, level)); level++) { - if (virep->lv == NULL) { - continue; - } - for (pos = 0; pos < virep->nlocals - 1; pos++) { - if (vsym == virep->lv[pos].name) { - return (pos+1)<<8 | (level+bnest); - } - } - } - - return 0; -} - -static int -irep_argc(mrb_irep *irep) -{ - mrb_code c; - - c = irep->iseq[0]; - if (c == OP_ENTER) { - mrb_aspec ax = PEEK_W(irep->iseq+1); - /* extra 1 means a slot for block */ - return MRB_ASPEC_REQ(ax)+MRB_ASPEC_OPT(ax)+MRB_ASPEC_REST(ax)+MRB_ASPEC_POST(ax)+1; - } - return 0; -} - -static mrb_bool -potential_upvar_p(struct mrb_locals *lv, uint16_t v, int argc, uint16_t nlocals) -{ - if (v >= nlocals) return FALSE; - /* skip arguments */ - if (v < argc+1) return FALSE; - return TRUE; -} - -extern uint8_t mrb_insn_size[]; -extern uint8_t mrb_insn_size1[]; -extern uint8_t mrb_insn_size2[]; -extern uint8_t mrb_insn_size3[]; - -static void -patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest, mrb_irep *top) -{ - int i; - uint32_t a; - uint16_t b; - uint8_t c; - mrb_code insn; - int argc = irep_argc(irep); - mrb_code *iseq = (mrb_code *)irep->iseq; - - mrb_assert((irep->flags & MRB_ISEQ_NO_FREE) == 0); - - for (i = 0; i < irep->ilen; ) { - insn = iseq[i]; - switch(insn){ - case OP_EPUSH: - a = PEEK_B(iseq+i+1); - patch_irep(mrb, irep->reps[a], bnest + 1, top); - break; - - case OP_LAMBDA: - case OP_BLOCK: - a = PEEK_B(iseq+i+1); - b = PEEK_B(iseq+i+2); - patch_irep(mrb, irep->reps[b], bnest + 1, top); - break; - - case OP_SEND: - b = PEEK_B(iseq+i+2); - c = PEEK_B(iseq+i+3); - if (c != 0) { - break; - } - else { - uint16_t arg = search_variable(mrb, irep->syms[b], bnest); - if (arg != 0) { - /* must replace */ - iseq[i] = OP_GETUPVAR; - iseq[i+2] = arg >> 8; - iseq[i+3] = arg & 0xff; - } - } - break; - - case OP_MOVE: - a = PEEK_B(iseq+i+1); - b = PEEK_B(iseq+i+2); - /* src part */ - if (potential_upvar_p(irep->lv, b, argc, irep->nlocals)) { - uint16_t arg = search_variable(mrb, irep->lv[b - 1].name, bnest); - if (arg != 0) { - /* must replace */ - iseq[i] = insn = OP_GETUPVAR; - iseq[i+2] = arg >> 8; - iseq[i+3] = arg & 0xff; - } - } - /* dst part */ - if (potential_upvar_p(irep->lv, a, argc, irep->nlocals)) { - uint16_t arg = search_variable(mrb, irep->lv[a - 1].name, bnest); - if (arg != 0) { - /* must replace */ - iseq[i] = insn = OP_SETUPVAR; - iseq[i+1] = (mrb_code)b; - iseq[i+2] = arg >> 8; - iseq[i+3] = arg & 0xff; - } - } - break; - - case OP_GETUPVAR: - a = PEEK_B(iseq+i+1); - b = PEEK_B(iseq+i+2); - c = PEEK_B(iseq+i+3); - { - int lev = c+1; - mrb_irep *tmp = search_irep(top, bnest, lev, irep); - if (potential_upvar_p(tmp->lv, b, irep_argc(tmp), tmp->nlocals)) { - uint16_t arg = search_variable(mrb, tmp->lv[b-1].name, bnest); - if (arg != 0) { - /* must replace */ - iseq[i] = OP_GETUPVAR; - iseq[i+2] = arg >> 8; - iseq[i+3] = arg & 0xff; - } - } - } - break; - - case OP_SETUPVAR: - a = PEEK_B(iseq+i+1); - b = PEEK_B(iseq+i+2); - c = PEEK_B(iseq+i+3); - { - int lev = c+1; - mrb_irep *tmp = search_irep(top, bnest, lev, irep); - if (potential_upvar_p(tmp->lv, b, irep_argc(tmp), tmp->nlocals)) { - uint16_t arg = search_variable(mrb, tmp->lv[b-1].name, bnest); - if (arg != 0) { - /* must replace */ - iseq[i] = OP_SETUPVAR; - iseq[i+1] = a; - iseq[i+2] = arg >> 8; - iseq[i+3] = arg & 0xff; - } - } - } - break; - - case OP_EXT1: - insn = PEEK_B(iseq+i+1); - i += mrb_insn_size1[insn]+1; - continue; - case OP_EXT2: - insn = PEEK_B(iseq+i+1); - i += mrb_insn_size2[insn]+1; - continue; - case OP_EXT3: - insn = PEEK_B(iseq+i+1); - i += mrb_insn_size3[insn]+1; - continue; - } - i+=mrb_insn_size[insn]; - } -} - void mrb_codedump_all(mrb_state*, struct RProc*); static struct RProc* @@ -243,7 +32,8 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding, mrbc_filename(mrb, cxt, file ? file : "(eval)"); cxt->capture_errors = TRUE; cxt->no_optimize = TRUE; - cxt->on_eval = TRUE; + ci = (mrb->c->ci > mrb->c->cibase) ? mrb->c->ci - 1 : mrb->c->cibase; + cxt->upper = ci->proc && MRB_PROC_CFUNC_P(ci->proc) ? NULL : ci->proc; p = mrb_parse_nstring(mrb, s, len, cxt); @@ -311,7 +101,6 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding, } proc->upper = ci->proc; mrb->c->ci->target_class = target_class; - patch_irep(mrb, proc->body.irep, 0, proc->body.irep); /* mrb_codedump_all(mrb, proc); */ mrb_parser_free(p); |
