Imported Upstream version 1.46.0
[platform/upstream/nghttp2.git] / third-party / mruby / mrbgems / mruby-eval / src / eval.c
index fa687d6..eaf07ca 100644 (file)
@@ -9,214 +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);
-
-  for (i = 0; i < irep->ilen; ) {
-    insn = irep->iseq[i];
-    switch(insn){
-    case OP_EPUSH:
-      b = PEEK_S(irep->iseq+i+1);
-      patch_irep(mrb, irep->reps[b], bnest + 1, top);
-      break;
-
-    case OP_LAMBDA:
-    case OP_BLOCK:
-      a = PEEK_B(irep->iseq+i+1);
-      b = PEEK_B(irep->iseq+i+2);
-      patch_irep(mrb, irep->reps[b], bnest + 1, top);
-      break;
-
-    case OP_SEND:
-      b = PEEK_B(irep->iseq+i+2);
-      c = PEEK_B(irep->iseq+i+3);
-      if (c != 0) {
-        break;
-      }
-      else {
-        uint16_t arg = search_variable(mrb, irep->syms[b], bnest);
-        if (arg != 0) {
-          /* must replace */
-          irep->iseq[i] = OP_GETUPVAR;
-          irep->iseq[i+2] = arg >> 8;
-          irep->iseq[i+3] = arg & 0xff;
-        }
-      }
-      break;
-
-    case OP_MOVE:
-      a = PEEK_B(irep->iseq+i+1);
-      b = PEEK_B(irep->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 */
-          irep->iseq[i] = insn = OP_GETUPVAR;
-          irep->iseq[i+2] = arg >> 8;
-          irep->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 */
-          irep->iseq[i] = insn = OP_SETUPVAR;
-          irep->iseq[i+1] = (mrb_code)b;
-          irep->iseq[i+2] = arg >> 8;
-          irep->iseq[i+3] = arg & 0xff;
-        }
-      }
-      break;
-
-    case OP_GETUPVAR:
-      a = PEEK_B(irep->iseq+i+1);
-      b = PEEK_B(irep->iseq+i+2);
-      c = PEEK_B(irep->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 */
-            irep->iseq[i] = OP_GETUPVAR;
-            irep->iseq[i+2] = arg >> 8;
-            irep->iseq[i+3] = arg & 0xff;
-          }
-        }
-      }
-      break;
-
-    case OP_SETUPVAR:
-      a = PEEK_B(irep->iseq+i+1);
-      b = PEEK_B(irep->iseq+i+2);
-      c = PEEK_B(irep->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 */
-            irep->iseq[i] = OP_SETUPVAR;
-            irep->iseq[i+1] = a;
-            irep->iseq[i+2] = arg >> 8;
-            irep->iseq[i+3] = arg & 0xff;
-          }
-        }
-      }
-      break;
-
-    case OP_EXT1:
-      insn = PEEK_B(irep->iseq+i+1);
-      i += mrb_insn_size1[insn]+1;
-      continue;
-    case OP_EXT2:
-      insn = PEEK_B(irep->iseq+i+1);
-      i += mrb_insn_size2[insn]+1;
-      continue;
-    case OP_EXT3:
-      insn = PEEK_B(irep->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*
@@ -235,12 +27,13 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding,
   }
 
   cxt = mrbc_context_new(mrb);
-  cxt->lineno = (short)line;
+  cxt->lineno = (uint16_t)line;
 
   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);
 
@@ -254,15 +47,15 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding,
     mrb_value str;
 
     if (file) {
-      str = mrb_format(mrb, " file %S line %S: %S",
-                       mrb_str_new_cstr(mrb, file),
-                       mrb_fixnum_value(p->error_buffer[0].lineno),
-                       mrb_str_new_cstr(mrb, p->error_buffer[0].message));
+      str = mrb_format(mrb, "file %s line %d: %s",
+                       file,
+                       p->error_buffer[0].lineno,
+                       p->error_buffer[0].message);
     }
     else {
-      str = mrb_format(mrb, " line %S: %S",
-                       mrb_fixnum_value(p->error_buffer[0].lineno),
-                       mrb_str_new_cstr(mrb, p->error_buffer[0].message));
+      str = mrb_format(mrb, "line %d: %s",
+                       p->error_buffer[0].lineno,
+                       p->error_buffer[0].message);
     }
     mrb_parser_free(p);
     mrbc_context_free(mrb, cxt);
@@ -295,7 +88,7 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding,
       e->mid = ci->mid;
       e->stack = ci[1].stackent;
       e->cxt = mrb->c;
-      MRB_ENV_SET_STACK_LEN(e, ci->proc->body.irep->nlocals);
+      MRB_ENV_SET_LEN(e, ci->proc->body.irep->nlocals);
       bidx = ci->argc;
       if (ci->argc < 0) bidx = 2;
       else bidx += 1;
@@ -308,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);
@@ -387,7 +179,7 @@ void
 mrb_mruby_eval_gem_init(mrb_state* mrb)
 {
   mrb_define_module_function(mrb, mrb->kernel_module, "eval", f_eval, MRB_ARGS_ARG(1, 3));
-  mrb_define_method(mrb, mrb->kernel_module, "instance_eval", f_instance_eval, MRB_ARGS_ARG(1, 2));
+  mrb_define_method(mrb, mrb_class_get(mrb, "BasicObject"), "instance_eval", f_instance_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK());
 }
 
 void