summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-eval/src/eval.c
diff options
context:
space:
mode:
authordearblue <[email protected]>2020-05-21 21:27:51 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2020-06-02 14:49:27 +0900
commitf85906b67920c0e69599c6e59d843274aef152be (patch)
tree1f6852e91266cd14899974d725dffbeedfb9cd37 /mrbgems/mruby-eval/src/eval.c
parent1fc9345b4567bf65ed27d1ed7a84002b898f08d2 (diff)
downloadmruby-f85906b67920c0e69599c6e59d843274aef152be.tar.gz
mruby-f85906b67920c0e69599c6e59d843274aef152be.zip
Remove `patch_irep()` in `mruby-eval`
- It can now deal with operands in the range of `OP_EXT*`. - It can now call the same method as the variable name without arguments. ```ruby def a "Safe!" end a = "Auto!" eval "a()" # call method `a` ```
Diffstat (limited to 'mrbgems/mruby-eval/src/eval.c')
-rw-r--r--mrbgems/mruby-eval/src/eval.c215
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);