Index: EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-eval/src/eval.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-eval/src/eval.c	(revision 331)
+++ EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-eval/src/eval.c	(revision 439)
@@ -13,27 +13,12 @@
 get_closure_irep(mrb_state *mrb, int level)
 {
-  struct mrb_context *c = mrb->c;
-  struct REnv *e = c->ci[-1].proc->env;
-  struct RProc *proc;
-
-  if (level == 0) {
-    proc = c->ci[-1].proc;
-    if (MRB_PROC_CFUNC_P(proc)) {
-      return NULL;
-    }
-    return proc->body.irep;
-  }
-
-  while (--level) {
-    e = (struct REnv*)e->c;
-    if (!e) return NULL;
-  }
-
-  if (!e) return NULL;
-  if (!MRB_ENV_STACK_SHARED_P(e)) return NULL;
-  c = e->cxt.c;
-  proc = c->cibase[e->cioff].proc;
-
-  if (!proc || MRB_PROC_CFUNC_P(proc)) {
+  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;
   }
@@ -41,5 +26,24 @@
 }
 
-static inline mrb_code
+/* 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)
 {
@@ -49,14 +53,28 @@
 
   for (level = 0; (virep = get_closure_irep(mrb, level)); level++) {
-    if (!virep || virep->lv == NULL) {
+    if (virep->lv == NULL) {
       continue;
     }
     for (pos = 0; pos < virep->nlocals - 1; pos++) {
       if (vsym == virep->lv[pos].name) {
-        return (MKARG_B(pos + 1) | MKARG_C(level + bnest));
-      }
-    }
-  }
-
+        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;
 }
@@ -71,44 +89,50 @@
 }
 
+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)
-{
-  size_t i;
-  mrb_code c;
-  int argc = 0;
-
-  for (i = 0; i < irep->ilen; i++) {
-    c = irep->iseq[i];
-    switch(GET_OPCODE(c)){
-    case OP_ENTER:
-      {
-        mrb_aspec ax = GETARG_Ax(c);
-        /* extra 1 means a slot for block */
-        argc = MRB_ASPEC_REQ(ax)+MRB_ASPEC_OPT(ax)+MRB_ASPEC_REST(ax)+MRB_ASPEC_POST(ax)+1;
-      }
-      break;
-
+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:
-      patch_irep(mrb, irep->reps[GETARG_Bx(c)], bnest + 1);
+      a = PEEK_B(iseq+i+1);
+      patch_irep(mrb, irep->reps[a], bnest + 1, top);
       break;
 
     case OP_LAMBDA:
-      {
-        int arg_c = GETARG_c(c);
-        if (arg_c & OP_L_CAPTURE) {
-          patch_irep(mrb, irep->reps[GETARG_b(c)], bnest + 1);
-        }
-      }
+    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:
-      if (GETARG_C(c) != 0) {
+      b = PEEK_B(iseq+i+2);
+      c = PEEK_B(iseq+i+3);
+      if (c != 0) {
         break;
       }
-      {
-        mrb_code arg = search_variable(mrb, irep->syms[GETARG_B(c)], bnest);
+      else {
+        uint16_t arg = search_variable(mrb, irep->syms[b], bnest);
         if (arg != 0) {
           /* must replace */
-          irep->iseq[i] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg;
+          iseq[i] = OP_GETUPVAR;
+          iseq[i+2] = arg >> 8;
+          iseq[i+3] = arg & 0xff;
         }
       }
@@ -116,28 +140,82 @@
 
     case OP_MOVE:
+      a = PEEK_B(iseq+i+1);
+      b = PEEK_B(iseq+i+2);
       /* src part */
-      if (potential_upvar_p(irep->lv, GETARG_B(c), argc, irep->nlocals)) {
-        mrb_code arg = search_variable(mrb, irep->lv[GETARG_B(c) - 1].name, bnest);
+      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] = MKOPCODE(OP_GETUPVAR) | MKARG_A(GETARG_A(c)) | arg;
+          iseq[i] = insn = OP_GETUPVAR;
+          iseq[i+2] = arg >> 8;
+          iseq[i+3] = arg & 0xff;
         }
       }
       /* dst part */
-      if (potential_upvar_p(irep->lv, GETARG_A(c), argc, irep->nlocals)) {
-        mrb_code arg = search_variable(mrb, irep->lv[GETARG_A(c) - 1].name, bnest);
+      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] = MKOPCODE(OP_SETUPVAR) | MKARG_A(GETARG_B(c)) | arg;
-        }
-      }
-      break;
-
-    case OP_STOP:
-      if (mrb->c->ci->acc >= 0) {
-        irep->iseq[i] = MKOP_AB(OP_RETURN, irep->nlocals, OP_R_NORMAL);
-      }
-      break;
-    }
+          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];
   }
 }
@@ -146,5 +224,5 @@
 
 static struct RProc*
-create_proc_from_string(mrb_state *mrb, char *s, int len, mrb_value binding, const char *file, mrb_int line)
+create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding, const char *file, mrb_int line)
 {
   mrbc_context *cxt;
@@ -152,5 +230,7 @@
   struct RProc *proc;
   struct REnv *e;
-  struct mrb_context *c = mrb->c;
+  mrb_callinfo *ci; /* callinfo of eval caller */
+  struct RClass *target_class = NULL;
+  int bidx;
 
   if (!mrb_nil_p(binding)) {
@@ -159,9 +239,10 @@
 
   cxt = mrbc_context_new(mrb);
-  cxt->lineno = 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;
 
   p = mrb_parse_nstring(mrb, s, len, cxt);
@@ -177,13 +258,13 @@
 
     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);
@@ -199,18 +280,38 @@
     mrb_raise(mrb, E_SCRIPT_ERROR, "codegen error");
   }
-  if (c->ci[-1].proc->target_class) {
-    proc->target_class = c->ci[-1].proc->target_class;
-  }
-  e = c->ci[-1].proc->env;
-  if (!e) e = c->ci[-1].env;
-  e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)e);
-  e->cxt.c = c;
-  e->cioff = c->ci - c->cibase;
-  e->stack = c->ci->stackent;
-  MRB_SET_ENV_STACK_LEN(e, c->ci->proc->body.irep->nlocals);
-  c->ci->target_class = proc->target_class;
-  c->ci->env = 0;
-  proc->env = e;
-  patch_irep(mrb, proc->body.irep, 0);
+  if (mrb->c->ci > mrb->c->cibase) {
+    ci = &mrb->c->ci[-1];
+  }
+  else {
+    ci = mrb->c->cibase;
+  }
+  if (ci->proc) {
+    target_class = MRB_PROC_TARGET_CLASS(ci->proc);
+  }
+  if (ci->proc && !MRB_PROC_CFUNC_P(ci->proc)) {
+    if (ci->env) {
+      e = ci->env;
+    }
+    else {
+      e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV,
+                                      (struct RClass*)target_class);
+      e->mid = ci->mid;
+      e->stack = ci[1].stackent;
+      e->cxt = mrb->c;
+      MRB_ENV_SET_STACK_LEN(e, ci->proc->body.irep->nlocals);
+      bidx = ci->argc;
+      if (ci->argc < 0) bidx = 2;
+      else bidx += 1;
+      MRB_ENV_SET_BIDX(e, bidx);
+      ci->env = e;
+    }
+    proc->e.env = e;
+    proc->flags |= MRB_PROC_ENVSET;
+    mrb_field_write_barrier(mrb, (struct RBasic*)proc, (struct RBasic*)e);
+  }
+  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);
@@ -223,11 +324,17 @@
 exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc)
 {
+  /* no argument passed from eval() */
+  mrb->c->ci->argc = 0;
   if (mrb->c->ci->acc < 0) {
-    mrb_value ret = mrb_top_run(mrb, proc, mrb->c->stack[0], 0);
+    ptrdiff_t cioff = mrb->c->ci - mrb->c->cibase;
+    mrb_value ret = mrb_top_run(mrb, proc, self, 0);
     if (mrb->exc) {
       mrb_exc_raise(mrb, mrb_obj_value(mrb->exc));
     }
+    mrb->c->ci = mrb->c->cibase + cioff;
     return ret;
   }
+  /* clear block */
+  mrb->c->stack[1] = mrb_nil_value();
   return mrb_exec_irep(mrb, self, proc);
 }
@@ -256,5 +363,5 @@
   mrb_int argc; mrb_value *argv;
 
-  mrb_get_args(mrb, "*&", &argv, &argc, &b);
+  mrb_get_args(mrb, "*!&", &argv, &argc, &b);
 
   if (mrb_nil_p(b)) {
@@ -269,7 +376,7 @@
     cv = mrb_singleton_class(mrb, self);
     proc = create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line);
-    proc->target_class = mrb_class_ptr(cv);
-    mrb->c->ci->env = NULL;
+    MRB_PROC_SET_TARGET_CLASS(proc, mrb_class_ptr(cv));
     mrb_assert(!MRB_PROC_CFUNC_P(proc));
+    mrb->c->ci->target_class = mrb_class_ptr(cv);
     return exec_irep(mrb, self, proc);
   }
@@ -284,5 +391,5 @@
 {
   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());
 }
 
