Index: EcnlProtoTool/trunk/mruby-1.3.0/src/array.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/array.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/array.c	(revision 331)
@@ -5,9 +5,9 @@
 */
 
-#include "mruby.h"
-#include "mruby/array.h"
-#include "mruby/class.h"
-#include "mruby/string.h"
-#include "mruby/range.h"
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/class.h>
+#include <mruby/string.h>
+#include <mruby/range.h>
 #include "value_array.h"
 
@@ -17,18 +17,9 @@
 #define ARY_MAX_SIZE ((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? (mrb_int)ARY_C_MAX_SIZE : MRB_INT_MAX-1)
 
-static inline mrb_value
-ary_elt(mrb_value ary, mrb_int offset)
-{
-  if (offset < 0 || RARRAY_LEN(ary) <= offset) {
-    return mrb_nil_value();
-  }
-  return RARRAY_PTR(ary)[offset];
-}
-
 static struct RArray*
 ary_new_capa(mrb_state *mrb, mrb_int capa)
 {
   struct RArray *a;
-  mrb_int blen;
+  size_t blen;
 
   if (capa > ARY_MAX_SIZE) {
@@ -36,7 +27,4 @@
   }
   blen = capa * sizeof(mrb_value);
-  if (blen < capa) {
-    mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
-  }
 
   a = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class);
@@ -121,4 +109,8 @@
 ary_modify(mrb_state *mrb, struct RArray *a)
 {
+  if (MRB_FROZEN_P(a)) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen array");
+  }
+
   if (ARY_SHARED_P(a)) {
     mrb_shared_array *shared = a->aux.shared;
@@ -179,4 +171,5 @@
 
   if (len > ARY_MAX_SIZE) {
+  size_error:
     mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
   }
@@ -186,8 +179,14 @@
   }
   while (capa < len) {
-    capa *= 2;
-  }
-
-  if (capa > ARY_MAX_SIZE) capa = ARY_MAX_SIZE; /* len <= capa <= ARY_MAX_SIZE */
+    if (capa <= ARY_MAX_SIZE / 2) {
+      capa *= 2;
+    }
+    else {
+      capa = len;
+    }
+  }
+  if (capa < len || capa > ARY_MAX_SIZE) {
+    goto size_error;
+  }
 
   if (capa > a->aux.capa) {
@@ -244,22 +243,34 @@
 
 static mrb_value
-mrb_ary_s_create(mrb_state *mrb, mrb_value self)
-{
+mrb_ary_s_create(mrb_state *mrb, mrb_value klass)
+{
+  mrb_value ary;
   mrb_value *vals;
   mrb_int len;
+  struct RArray *a;
 
   mrb_get_args(mrb, "*", &vals, &len);
-
-  return mrb_ary_new_from_values(mrb, len, vals);
+  ary = mrb_ary_new_from_values(mrb, len, vals);
+  a = mrb_ary_ptr(ary);
+  a->c = mrb_class_ptr(klass);
+
+  return ary;
 }
 
 static void
-ary_concat(mrb_state *mrb, struct RArray *a, mrb_value *ptr, mrb_int blen)
-{
-  mrb_int len = a->len + blen;
+ary_concat(mrb_state *mrb, struct RArray *a, struct RArray *a2)
+{
+  mrb_int len;
+
+  if (a2->len > ARY_MAX_SIZE - a->len) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
+  }
+  len = a->len + a2->len;
 
   ary_modify(mrb, a);
-  if (a->aux.capa < len) ary_expand_capa(mrb, a, len);
-  array_copy(a->ptr+a->len, ptr, blen);
+  if (a->aux.capa < len) {
+    ary_expand_capa(mrb, a, len);
+  }
+  array_copy(a->ptr+a->len, a2->ptr, a2->len);
   mrb_write_barrier(mrb, (struct RBasic*)a);
   a->len = len;
@@ -271,5 +282,5 @@
   struct RArray *a2 = mrb_ary_ptr(other);
 
-  ary_concat(mrb, mrb_ary_ptr(self), a2->ptr, a2->len);
+  ary_concat(mrb, mrb_ary_ptr(self), a2);
 }
 
@@ -277,9 +288,8 @@
 mrb_ary_concat_m(mrb_state *mrb, mrb_value self)
 {
-  mrb_value *ptr;
-  mrb_int blen;
-
-  mrb_get_args(mrb, "a", &ptr, &blen);
-  ary_concat(mrb, mrb_ary_ptr(self), ptr, blen);
+  mrb_value ary;
+
+  mrb_get_args(mrb, "A", &ary);
+  mrb_ary_concat(mrb, self, ary);
   return self;
 }
@@ -319,7 +329,10 @@
 mrb_ary_replace(mrb_state *mrb, mrb_value self, mrb_value other)
 {
+  struct RArray *a1 = mrb_ary_ptr(self);
   struct RArray *a2 = mrb_ary_ptr(other);
 
-  ary_replace(mrb, mrb_ary_ptr(self), a2->ptr, a2->len);
+  if (a1 != a2) {
+    ary_replace(mrb, a1, a2->ptr, a2->len);
+  }
 }
 
@@ -433,4 +446,5 @@
   struct RArray *a = mrb_ary_ptr(ary);
 
+  ary_modify(mrb, a);
   if (a->len == 0) return mrb_nil_value();
   return a->ptr[--a->len];
@@ -445,4 +459,5 @@
   mrb_value val;
 
+  ary_modify(mrb, a);
   if (a->len == 0) return mrb_nil_value();
   if (ARY_SHARED_P(a)) {
@@ -507,4 +522,7 @@
 
   mrb_get_args(mrb, "*", &vals, &len);
+  if (len > ARY_MAX_SIZE - a->len) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big");
+  }
   if (ARY_SHARED_P(a)
       && a->aux.shared->refcnt == 1 /* shared only referenced from this array */
@@ -564,11 +582,20 @@
 }
 
+static struct RArray*
+ary_dup(mrb_state *mrb, struct RArray *a)
+{
+  struct RArray *d = ary_new_capa(mrb, a->len);
+
+  ary_replace(mrb, d, a->ptr, a->len);
+  return d;
+}
+
 MRB_API mrb_value
 mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_value rpl)
 {
   struct RArray *a = mrb_ary_ptr(ary);
-  mrb_int tail, size;
   const mrb_value *argv;
-  mrb_int i, argc;
+  mrb_int argc;
+  mrb_int tail;
 
   ary_modify(mrb, a);
@@ -584,8 +611,8 @@
     }
   }
-  if (a->len < len || a->len < head + len) {
+  tail = head + len;
+  if (a->len < len || a->len < tail) {
     len = a->len - head;
   }
-  tail = head + len;
 
   /* size check */
@@ -593,4 +620,13 @@
     argc = RARRAY_LEN(rpl);
     argv = RARRAY_PTR(rpl);
+    if (argv == a->ptr) {
+      struct RArray *r;
+
+      if (argc > 32767) {
+        mrb_raise(mrb, E_ARGUMENT_ERROR, "too big recursive splice");
+      }
+      r = ary_dup(mrb, a);
+      argv = r->ptr;
+    }
   }
   else {
@@ -598,24 +634,39 @@
     argv = &rpl;
   }
-  size = head + argc;
-
-  if (tail < a->len) size += a->len - tail;
-  if (size > a->aux.capa)
-    ary_expand_capa(mrb, a, size);
-
-  if (head > a->len) {
+  if (head >= a->len) {
+    if (head > ARY_MAX_SIZE - argc) {
+      mrb_raisef(mrb, E_INDEX_ERROR, "index %S too big", mrb_fixnum_value(head));
+    }
+    len = head + argc;
+    if (len > a->aux.capa) {
+      ary_expand_capa(mrb, a, head + argc);
+    }
     ary_fill_with_nil(a->ptr + a->len, head - a->len);
-  }
-  else if (head < a->len) {
-    value_move(a->ptr + head + argc, a->ptr + tail, a->len - tail);
-  }
-
-  for (i = 0; i < argc; i++) {
-    *(a->ptr + head + i) = *(argv + i);
-    mrb_field_write_barrier_value(mrb, (struct RBasic*)a, argv[i]);
-  }
-
-  a->len = size;
-
+    if (argc > 0) {
+      array_copy(a->ptr + head, argv, argc);
+    }
+    a->len = len;
+  }
+  else {
+    mrb_int alen;
+
+    if (a->len - len > ARY_MAX_SIZE - argc) {
+      mrb_raisef(mrb, E_INDEX_ERROR, "index %S too big", mrb_fixnum_value(a->len + argc - len));
+    }
+    alen = a->len + argc - len;
+    if (alen > a->aux.capa) {
+      ary_expand_capa(mrb, a, alen);
+    }
+
+    if (len != argc) {
+      tail = head + len;
+      value_move(a->ptr + head + argc, a->ptr + tail, a->len - tail);
+      a->len = alen;
+    }
+    if (argc > 0) {
+      value_move(a->ptr + head, argv, argc);
+    }
+  }
+  mrb_write_barrier(mrb, (struct RBasic*)a);
   return ary;
 }
@@ -703,5 +754,5 @@
       /* a[n..m] */
     case MRB_TT_RANGE:
-      if (mrb_range_beg_len(mrb, index, &i, &len, a->len)) {
+      if (mrb_range_beg_len(mrb, index, &i, &len, a->len, TRUE) == 1) {
         return ary_subseq(mrb, a, i, len);
       }
@@ -767,18 +818,16 @@
   mrb_int i, len;
 
+  mrb_ary_modify(mrb, mrb_ary_ptr(self));
   if (mrb_get_args(mrb, "oo|o", &v1, &v2, &v3) == 2) {
-    switch (mrb_type(v1)) {
     /* a[n..m] = v */
-    case MRB_TT_RANGE:
-      if (mrb_range_beg_len(mrb, v1, &i, &len, RARRAY_LEN(self))) {
-        mrb_ary_splice(mrb, self, i, len, v2);
-      }
+    switch (mrb_range_beg_len(mrb, v1, &i, &len, RARRAY_LEN(self), FALSE)) {
+    case 0:                   /* not range */
+      mrb_ary_set(mrb, self, aget_index(mrb, v1), v2);
       break;
-    /* a[n] = v */
-    case MRB_TT_FIXNUM:
-      mrb_ary_set(mrb, self, mrb_fixnum(v1), v2);
+    case 1:                   /* range */
+      mrb_ary_splice(mrb, self, i, len, v2);
       break;
-    default:
-      mrb_ary_set(mrb, self, aget_index(mrb, v1), v2);
+    case 2:                   /* out of range */
+      mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", v1);
       break;
     }
@@ -878,5 +927,5 @@
 {
   mrb_value obj;
-  mrb_int i;
+  mrb_int i, len;
 
   mrb_get_args(mrb, "o", &obj);
@@ -885,4 +934,7 @@
       return mrb_fixnum_value(i);
     }
+    if (i > (len = RARRAY_LEN(self))) {
+      i = len;
+    }
   }
   return mrb_nil_value();
@@ -892,12 +944,30 @@
 mrb_ary_splat(mrb_state *mrb, mrb_value v)
 {
+  mrb_value a, recv_class;
+
   if (mrb_array_p(v)) {
     return v;
   }
-  if (mrb_respond_to(mrb, v, mrb_intern_lit(mrb, "to_a"))) {
-    return mrb_funcall(mrb, v, "to_a", 0);
+
+  if (!mrb_respond_to(mrb, v, mrb_intern_lit(mrb, "to_a"))) {
+    return mrb_ary_new_from_values(mrb, 1, &v);
+  }
+
+  a = mrb_funcall(mrb, v, "to_a", 0);
+  if (mrb_array_p(a)) {
+    return a;
+  }
+  else if (mrb_nil_p(a)) {
+    return mrb_ary_new_from_values(mrb, 1, &v);
   }
   else {
-    return mrb_ary_new_from_values(mrb, 1, &v);
+    recv_class = mrb_obj_value(mrb_obj_class(mrb, v));
+    mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %S to Array (%S#to_a gives %S)",
+      recv_class,
+      recv_class,
+      mrb_obj_value(mrb_obj_class(mrb, a))
+    );
+    /* not reached */
+    return mrb_undef_value();
   }
 }
@@ -916,4 +986,5 @@
   struct RArray *a = mrb_ary_ptr(self);
 
+  ary_modify(mrb, a);
   if (ARY_SHARED_P(a)) {
     mrb_ary_decref(mrb, a->aux.shared);
@@ -988,13 +1059,15 @@
 
     default:
-      tmp = mrb_check_string_type(mrb, val);
-      if (!mrb_nil_p(tmp)) {
-        val = tmp;
-        goto str_join;
-      }
-      tmp = mrb_check_convert_type(mrb, val, MRB_TT_ARRAY, "Array", "to_ary");
-      if (!mrb_nil_p(tmp)) {
-        val = tmp;
-        goto ary_join;
+      if (!mrb_immediate_p(val)) {
+        tmp = mrb_check_string_type(mrb, val);
+        if (!mrb_nil_p(tmp)) {
+          val = tmp;
+          goto str_join;
+        }
+        tmp = mrb_check_convert_type(mrb, val, MRB_TT_ARRAY, "Array", "to_ary");
+        if (!mrb_nil_p(tmp)) {
+          val = tmp;
+          goto ary_join;
+        }
       }
       val = mrb_obj_as_string(mrb, val);
@@ -1011,5 +1084,7 @@
 mrb_ary_join(mrb_state *mrb, mrb_value ary, mrb_value sep)
 {
-  sep = mrb_obj_as_string(mrb, sep);
+  if (!mrb_nil_p(sep)) {
+    sep = mrb_obj_as_string(mrb, sep);
+  }
   return join_ary(mrb, ary, sep, mrb_ary_new(mrb));
 }
@@ -1091,4 +1166,5 @@
   mrb_define_method(mrb, a, "pop",             mrb_ary_pop,          MRB_ARGS_NONE()); /* 15.2.12.5.21 */
   mrb_define_method(mrb, a, "push",            mrb_ary_push_m,       MRB_ARGS_ANY());  /* 15.2.12.5.22 */
+  mrb_define_method(mrb, a, "append",          mrb_ary_push_m,       MRB_ARGS_ANY());
   mrb_define_method(mrb, a, "replace",         mrb_ary_replace_m,    MRB_ARGS_REQ(1)); /* 15.2.12.5.23 */
   mrb_define_method(mrb, a, "reverse",         mrb_ary_reverse,      MRB_ARGS_NONE()); /* 15.2.12.5.24 */
@@ -1099,4 +1175,5 @@
   mrb_define_method(mrb, a, "slice",           mrb_ary_aget,         MRB_ARGS_ANY());  /* 15.2.12.5.29 */
   mrb_define_method(mrb, a, "unshift",         mrb_ary_unshift_m,    MRB_ARGS_ANY());  /* 15.2.12.5.30 */
+  mrb_define_method(mrb, a, "prepend",         mrb_ary_unshift_m,    MRB_ARGS_ANY());
 
   mrb_define_method(mrb, a, "__ary_eq",        mrb_ary_eq,           MRB_ARGS_REQ(1));
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/backtrace.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/backtrace.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/backtrace.c	(revision 331)
@@ -5,97 +5,34 @@
 */
 
-#include "mruby.h"
-#include "mruby/variable.h"
-#include "mruby/proc.h"
-#include "mruby/array.h"
-#include "mruby/string.h"
-#include "mruby/class.h"
-#include "mruby/debug.h"
-#include "mruby/error.h"
-#include "mruby/numeric.h"
+#include <mruby.h>
+#include <mruby/variable.h>
+#include <mruby/proc.h>
+#include <mruby/array.h>
+#include <mruby/string.h>
+#include <mruby/class.h>
+#include <mruby/debug.h>
+#include <mruby/error.h>
+#include <mruby/numeric.h>
+#include <mruby/data.h>
 
 struct backtrace_location {
-  int i;
   int lineno;
   const char *filename;
-  const char *method;
-  const char *sep;
-  const char *class_name;
+  mrb_sym method_id;
 };
 
-typedef void (*output_stream_func)(mrb_state*, struct backtrace_location*, void*);
-
-#ifndef MRB_DISABLE_STDIO
-
-struct print_backtrace_args {
-  FILE *stream;
-  int tracehead;
-};
-
-static void
-print_backtrace_i(mrb_state *mrb, struct backtrace_location *loc, void *data)
-{
-  struct print_backtrace_args *args;
-
-  args = (struct print_backtrace_args*)data;
-
-  if (args->tracehead) {
-    fprintf(args->stream, "trace:\n");
-    args->tracehead = FALSE;
-  }
-
-  fprintf(args->stream, "\t[%d] %s:%d", loc->i, loc->filename, loc->lineno);
-
-  if (loc->method) {
-    if (loc->class_name) {
-      fprintf(args->stream, ":in %s%s%s", loc->class_name, loc->sep, loc->method);
-    }
-    else {
-      fprintf(args->stream, ":in %s", loc->method);
-    }
-  }
-
-  fprintf(args->stream, "\n");
-}
-
-#endif
-
-static void
-get_backtrace_i(mrb_state *mrb, struct backtrace_location *loc, void *data)
-{
-  mrb_value ary, str;
-  int ai;
-
-  ai = mrb_gc_arena_save(mrb);
-  ary = mrb_obj_value((struct RArray*)data);
-
-  str = mrb_str_new_cstr(mrb, loc->filename);
-  mrb_str_cat_lit(mrb, str, ":");
-  mrb_str_concat(mrb, str, mrb_fixnum_to_str(mrb, mrb_fixnum_value(loc->lineno), 10));
-
-  if (loc->method) {
-    mrb_str_cat_lit(mrb, str, ":in ");
-
-    if (loc->class_name) {
-      mrb_str_cat_cstr(mrb, str, loc->class_name);
-      mrb_str_cat_cstr(mrb, str, loc->sep);
-    }
-
-    mrb_str_cat_cstr(mrb, str, loc->method);
-  }
-
-  mrb_ary_push(mrb, ary, str);
-  mrb_gc_arena_restore(mrb, ai);
-}
-
-static void
-output_backtrace(mrb_state *mrb, mrb_int ciidx, mrb_code *pc0, output_stream_func func, void *data)
-{
-  int i;
+typedef void (*each_backtrace_func)(mrb_state*, int i, struct backtrace_location*, void*);
+
+static const mrb_data_type bt_type = { "Backtrace", mrb_free };
+
+static void
+each_backtrace(mrb_state *mrb, mrb_int ciidx, mrb_code *pc0, each_backtrace_func func, void *data)
+{
+  int i, j;
 
   if (ciidx >= mrb->c->ciend - mrb->c->cibase)
     ciidx = 10; /* ciidx is broken... */
 
-  for (i = ciidx; i >= 0; i--) {
+  for (i=ciidx, j=0; i >= 0; i--,j++) {
     struct backtrace_location loc;
     mrb_callinfo *ci;
@@ -109,4 +46,5 @@
 
     irep = ci->proc->body.irep;
+    if (!irep) continue;
 
     if (mrb->c->cibase[i].err) {
@@ -124,62 +62,87 @@
     if (loc.lineno == -1) continue;
 
-    if (ci->target_class == ci->proc->target_class) {
-      loc.sep = ".";
-    }
-    else {
-      loc.sep = "#";
-    }
-
     if (!loc.filename) {
       loc.filename = "(unknown)";
     }
 
-    loc.method = mrb_sym2name(mrb, ci->mid);
-    loc.class_name = mrb_class_name(mrb, ci->proc->target_class);
-    loc.i = i;
-    func(mrb, &loc, data);
-  }
-}
-
-static void
-exc_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func func, void *stream)
-{
-  mrb_value lastpc;
-  mrb_code *code;
-
-  lastpc = mrb_obj_iv_get(mrb, exc, mrb_intern_lit(mrb, "lastpc"));
-  if (mrb_nil_p(lastpc)) {
-    code = NULL;
-  } else {
-    code = (mrb_code*)mrb_cptr(lastpc);
-  }
-
-  output_backtrace(mrb, mrb_fixnum(mrb_obj_iv_get(mrb, exc, mrb_intern_lit(mrb, "ciidx"))),
-                   code, func, stream);
-}
-
-/* mrb_print_backtrace/mrb_get_backtrace:
-
-   function to retrieve backtrace information from the exception.
-   note that if you call method after the exception, call stack will be
-   overwritten.  So invoke these functions just after detecting exceptions.
+    loc.method_id = ci->mid;
+    func(mrb, j, &loc, data);
+  }
+}
+
+#ifndef MRB_DISABLE_STDIO
+
+static void
+print_backtrace(mrb_state *mrb, mrb_value backtrace)
+{
+  int i, n;
+  FILE *stream = stderr;
+
+  if (!mrb_array_p(backtrace)) return;
+  fprintf(stream, "trace:\n");
+
+  n = RARRAY_LEN(backtrace);
+  for (i=0; n--; i++) {
+    mrb_value entry = RARRAY_PTR(backtrace)[n];
+
+    if (mrb_string_p(entry)) {
+      fprintf(stream, "\t[%d] %.*s\n", i, (int)RSTRING_LEN(entry), RSTRING_PTR(entry));
+    }
+  }
+}
+
+static void
+print_packed_backtrace(mrb_state *mrb, mrb_value packed)
+{
+  FILE *stream = stderr;
+  struct backtrace_location *bt;
+  int n, i;
+
+  bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, packed, &bt_type);
+  if (bt == NULL) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "broken backtrace");
+  }
+  n = (mrb_int)RDATA(packed)->flags;
+
+  fprintf(stream, "trace:\n");
+  for (i = 0; n--; i++) {
+    int ai = mrb_gc_arena_save(mrb);
+    struct backtrace_location *entry = &bt[n];
+    if (entry->filename == NULL) continue;
+    fprintf(stream, "\t[%d] %s:%d", (int)i, entry->filename, entry->lineno);
+    if (entry->method_id != 0) {
+      const char *method_name;
+
+      method_name = mrb_sym2name(mrb, entry->method_id);
+      fprintf(stream, ":in %s", method_name);
+      mrb_gc_arena_restore(mrb, ai);
+    }
+    fprintf(stream, "\n");
+  }
+}
+
+/* mrb_print_backtrace
+
+   function to retrieve backtrace information from the last exception.
 */
-
-#ifndef MRB_DISABLE_STDIO
 
 MRB_API void
 mrb_print_backtrace(mrb_state *mrb)
 {
-  struct print_backtrace_args args;
-
-  if (!mrb->exc || mrb_obj_is_kind_of(mrb, mrb_obj_value(mrb->exc), E_SYSSTACK_ERROR)) {
+  mrb_value backtrace;
+
+  if (!mrb->exc) {
     return;
   }
 
-  args.stream = stderr;
-  args.tracehead = TRUE;
-  exc_output_backtrace(mrb, mrb->exc, print_backtrace_i, (void*)&args);
-}
-
+  backtrace = mrb_obj_iv_get(mrb, mrb->exc, mrb_intern_lit(mrb, "backtrace"));
+  if (mrb_nil_p(backtrace)) return;
+  if (mrb_array_p(backtrace)) {
+    print_backtrace(mrb, backtrace);
+  }
+  else {
+    print_packed_backtrace(mrb, backtrace);
+  }
+}
 #else
 
@@ -191,13 +154,90 @@
 #endif
 
+static void
+pack_backtrace_i(mrb_state *mrb,
+                 int i,
+                 struct backtrace_location *loc,
+                 void *data)
+{
+  struct backtrace_location *entry = (struct backtrace_location*)data;
+
+  entry[i] = *loc;
+}
+
+static mrb_value
+packed_backtrace(mrb_state *mrb)
+{
+  struct RData *backtrace;
+  ptrdiff_t ciidx = mrb->c->ci - mrb->c->cibase;
+  mrb_int len = (ciidx+1)*sizeof(struct backtrace_location);
+  void *ptr;
+
+  ptr = mrb_malloc(mrb, len);
+  memset(ptr, 0, len);
+  backtrace = mrb_data_object_alloc(mrb, NULL, ptr, &bt_type);
+  backtrace->flags = (unsigned int)ciidx+1;
+  each_backtrace(mrb, ciidx, mrb->c->ci->pc, pack_backtrace_i, ptr);
+  return mrb_obj_value(backtrace);
+}
+
+void
+mrb_keep_backtrace(mrb_state *mrb, mrb_value exc)
+{
+  mrb_value backtrace;
+  int ai = mrb_gc_arena_save(mrb);
+
+  backtrace = packed_backtrace(mrb);
+  mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "backtrace"), backtrace);
+  mrb_gc_arena_restore(mrb, ai);
+}
+
+mrb_value
+mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace)
+{
+  struct backtrace_location *bt;
+  mrb_int n, i;
+
+  if (mrb_nil_p(backtrace)) return mrb_ary_new_capa(mrb, 0);
+  if (mrb_array_p(backtrace)) return backtrace;
+  bt = (struct backtrace_location*)mrb_data_check_get_ptr(mrb, backtrace, &bt_type);
+  if (bt == NULL) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "broken backtrace");
+  }
+  n = (mrb_int)RDATA(backtrace)->flags;
+  backtrace = mrb_ary_new_capa(mrb, n);
+  for (i = 0; i < n; i++) {
+    int ai = mrb_gc_arena_save(mrb);
+    struct backtrace_location *entry = &bt[i];
+    mrb_value btline;
+
+    if (entry->filename == NULL) continue;
+    btline = mrb_format(mrb, "%S:%S",
+                              mrb_str_new_cstr(mrb, entry->filename),
+                              mrb_fixnum_value(entry->lineno));
+    if (entry->method_id != 0) {
+      mrb_str_cat_lit(mrb, btline, ":in ");
+      mrb_str_cat_cstr(mrb, btline, mrb_sym2name(mrb, entry->method_id));
+    }
+    mrb_ary_push(mrb, backtrace, btline);
+    mrb_gc_arena_restore(mrb, ai);
+  }
+
+  return backtrace;
+}
+
 MRB_API mrb_value
-mrb_exc_backtrace(mrb_state *mrb, mrb_value self)
-{
-  mrb_value ary;
-
-  ary = mrb_ary_new(mrb);
-  exc_output_backtrace(mrb, mrb_obj_ptr(self), get_backtrace_i, (void*)mrb_ary_ptr(ary));
-
-  return ary;
+mrb_exc_backtrace(mrb_state *mrb, mrb_value exc)
+{
+  mrb_sym attr_name;
+  mrb_value backtrace;
+
+  attr_name = mrb_intern_lit(mrb, "backtrace");
+  backtrace = mrb_iv_get(mrb, exc, attr_name);
+  if (mrb_nil_p(backtrace) || mrb_array_p(backtrace)) {
+    return backtrace;
+  }
+  backtrace = mrb_unpack_backtrace(mrb, backtrace);
+  mrb_iv_set(mrb, exc, attr_name, backtrace);
+  return backtrace;
 }
 
@@ -205,13 +245,4 @@
 mrb_get_backtrace(mrb_state *mrb)
 {
-  mrb_value ary;
-  mrb_callinfo *ci = mrb->c->ci;
-  mrb_code *pc = ci->pc;
-  mrb_int ciidx = (mrb_int)(ci - mrb->c->cibase - 1);
-
-  if (ciidx < 0) ciidx = 0;
-  ary = mrb_ary_new(mrb);
-  output_backtrace(mrb, ciidx, pc, get_backtrace_i, (void*)mrb_ary_ptr(ary));
-
-  return ary;
-}
+  return mrb_unpack_backtrace(mrb, packed_backtrace(mrb));
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/class.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/class.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/class.c	(revision 331)
@@ -6,13 +6,14 @@
 
 #include <stdarg.h>
-#include "mruby.h"
-#include "mruby/array.h"
-#include "mruby/class.h"
-#include "mruby/numeric.h"
-#include "mruby/proc.h"
-#include "mruby/string.h"
-#include "mruby/variable.h"
-#include "mruby/error.h"
-#include "mruby/data.h"
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/class.h>
+#include <mruby/numeric.h>
+#include <mruby/proc.h>
+#include <mruby/string.h>
+#include <mruby/variable.h>
+#include <mruby/error.h>
+#include <mruby/data.h>
+#include <mruby/istruct.h>
 
 KHASH_DEFINE(mt, mrb_sym, struct RProc*, TRUE, kh_int_hash_func, kh_int_hash_equal)
@@ -97,4 +98,5 @@
   else {
     sc->super = o->c;
+    prepare_singleton_class(mrb, (struct RBasic*)sc);
   }
   o->c = sc;
@@ -122,16 +124,6 @@
 }
 
-MRB_API struct RClass*
-mrb_class_outer_module(mrb_state *mrb, struct RClass *c)
-{
-  mrb_value outer;
-
-  outer = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"));
-  if (mrb_nil_p(outer)) return NULL;
-  return mrb_class_ptr(outer);
-}
-
-static void
-check_if_class_or_module(mrb_state *mrb, mrb_value obj)
+static mrb_bool
+class_ptr_p(mrb_value obj)
 {
   switch (mrb_type(obj)) {
@@ -139,6 +131,35 @@
   case MRB_TT_SCLASS:
   case MRB_TT_MODULE:
-    return;
+    return TRUE;
   default:
+    return FALSE;
+  }
+}
+
+MRB_API struct RClass*
+mrb_class_outer_module(mrb_state *mrb, struct RClass *c)
+{
+  mrb_value outer;
+  struct RClass *cls;
+
+  outer = mrb_obj_iv_get(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"));
+  if (mrb_nil_p(outer)) return NULL;
+  cls = mrb_class_ptr(outer);
+  if (cls->tt == MRB_TT_SCLASS)
+  {
+    mrb_value klass;
+    klass = mrb_obj_iv_get(mrb, (struct RObject *)cls,
+                           mrb_intern_lit(mrb, "__attached__"));
+    if (class_ptr_p(klass)) {
+      cls = mrb_class_ptr(klass);
+    }
+  }
+  return cls;
+}
+
+static void
+check_if_class_or_module(mrb_state *mrb, mrb_value obj)
+{
+  if (!class_ptr_p(obj)) {
     mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class/module", mrb_inspect(mrb, obj));
   }
@@ -175,4 +196,12 @@
 {
   check_if_class_or_module(mrb, outer);
+  if (mrb_const_defined_at(mrb, outer, id)) {
+    mrb_value old = mrb_const_get(mrb, outer, id);
+
+    if (mrb_type(old) != MRB_TT_MODULE) {
+      mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a module", mrb_inspect(mrb, old));
+    }
+    return mrb_class_ptr(old);
+  }
   return define_module(mrb, id, mrb_class_ptr(outer));
 }
@@ -232,10 +261,20 @@
 }
 
+static mrb_value mrb_bob_init(mrb_state *mrb, mrb_value cv);
+
 static void
 mrb_class_inherited(mrb_state *mrb, struct RClass *super, struct RClass *klass)
 {
+  mrb_value s;
+  mrb_sym mid;
+
   if (!super)
     super = mrb->object_class;
-  mrb_funcall(mrb, mrb_obj_value(super), "inherited", 1, mrb_obj_value(klass));
+  s = mrb_obj_value(super);
+  mid = mrb_intern_lit(mrb, "inherited");
+  if (!mrb_func_basic_p(mrb, s, mid, mrb_bob_init)) {
+    mrb_value c = mrb_obj_value(klass);
+    mrb_funcall_argv(mrb, mrb_obj_value(super), mid, 1, &c);
+  }
 }
 
@@ -248,5 +287,6 @@
   if (!mrb_nil_p(super)) {
     if (mrb_type(super) != MRB_TT_CLASS) {
-      mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%S given)", super);
+      mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%S given)",
+                 mrb_inspect(mrb, super));
     }
     s = mrb_class_ptr(super);
@@ -256,4 +296,19 @@
   }
   check_if_class_or_module(mrb, outer);
+  if (mrb_const_defined_at(mrb, outer, id)) {
+    mrb_value old = mrb_const_get(mrb, outer, id);
+
+    if (mrb_type(old) != MRB_TT_CLASS) {
+      mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class", mrb_inspect(mrb, old));
+    }
+    c = mrb_class_ptr(old);
+    if (s) {
+      /* check super class */
+      if (mrb_class_real(c->super) != s) {
+        mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for class %S", old);
+      }
+    }
+    return c;
+  }
   c = define_class(mrb, id, s, mrb_class_ptr(outer));
   mrb_class_inherited(mrb, mrb_class_real(c->super), c);
@@ -272,4 +327,14 @@
 }
 
+MRB_API mrb_bool
+mrb_class_defined_under(mrb_state *mrb, struct RClass *outer, const char *name)
+{
+  mrb_value sym = mrb_check_intern_cstr(mrb, name);
+  if (mrb_nil_p(sym)) {
+    return FALSE;
+  }
+  return mrb_const_defined_at(mrb, mrb_obj_value(outer), mrb_symbol(sym));
+}
+
 MRB_API struct RClass *
 mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name)
@@ -282,4 +347,24 @@
 {
   return mrb_class_get_under(mrb, mrb->object_class, name);
+}
+
+MRB_API struct RClass *
+mrb_exc_get(mrb_state *mrb, const char *name)
+{
+  struct RClass *exc, *e;
+  mrb_value c = mrb_const_get(mrb, mrb_obj_value(mrb->object_class),
+                              mrb_intern_cstr(mrb, name));
+
+  if (mrb_type(c) != MRB_TT_CLASS) {
+    mrb_raise(mrb, mrb->eException_class, "exception corrupted");
+  }
+  exc = e = mrb_class_ptr(c);
+
+  while (e) {
+    if (e == mrb->eException_class)
+      return exc;
+    e = e->super;
+  }
+  return mrb->eException_class;
 }
 
@@ -337,8 +422,15 @@
   h = c->mt;
 
+  if (MRB_FROZEN_P(c)) {
+    if (c->tt == MRB_TT_MODULE)
+      mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen module");
+    else
+      mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen class");
+  }
   if (!h) h = c->mt = kh_init(mt, mrb);
   k = kh_put(mt, mrb, h, mid);
   kh_value(h, k) = p;
   if (p) {
+    p->c = NULL;
     mrb_field_write_barrier(mrb, (struct RBasic *)c, (struct RBasic *)p);
   }
@@ -430,4 +522,6 @@
     mrb_value obj = mrb_funcall(mrb, ss, "inspect", 0);
     mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", obj);
+    /* not reached */
+    return 0;
   }
 }
@@ -457,4 +551,5 @@
     n:      Symbol         [mrb_sym]
     d:      Data           [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified
+    I:      Inline struct  [void*]
     &:      Block          [mrb_value]
     *:      rest argument  [mrb_value*,mrb_int]   Receive the rest of the arguments as an array.
@@ -467,7 +562,8 @@
   char c;
   int i = 0;
-  mrb_value *sp = mrb->c->stack + 1;
   va_list ap;
   int argc = mrb->c->ci->argc;
+  int arg_i = 0;
+  mrb_bool array_argv;
   mrb_bool opt = FALSE;
   mrb_bool given = TRUE;
@@ -478,6 +574,13 @@
 
     argc = a->len;
-    sp = a->ptr;
-  }
+    array_argv = TRUE;
+  }
+  else {
+    array_argv = FALSE;
+  }
+
+#define ARGV \
+  (array_argv ? mrb_ary_ptr(mrb->c->stack[1])->ptr : (mrb->c->stack + 1))
+
   while ((c = *format++)) {
     switch (c) {
@@ -503,5 +606,5 @@
         p = va_arg(ap, mrb_value*);
         if (i < argc) {
-          *p = *sp++;
+          *p = ARGV[arg_i++];
           i++;
         }
@@ -516,13 +619,7 @@
           mrb_value ss;
 
-          ss = *sp++;
-          switch (mrb_type(ss)) {
-          case MRB_TT_CLASS:
-          case MRB_TT_MODULE:
-          case MRB_TT_SCLASS:
-            break;
-          default:
+          ss = ARGV[arg_i++];
+          if (!class_ptr_p(ss)) {
             mrb_raisef(mrb, E_TYPE_ERROR, "%S is not class/module", ss);
-            break;
           }
           *p = ss;
@@ -538,6 +635,6 @@
         if (*format == '!') {
           format++;
-          if (i < argc && mrb_nil_p(*sp)) {
-            *p = *sp++;
+          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
+            *p = ARGV[arg_i++];
             i++;
             break;
@@ -545,5 +642,5 @@
         }
         if (i < argc) {
-          *p = to_str(mrb, *sp++);
+          *p = to_str(mrb, ARGV[arg_i++]);
           i++;
         }
@@ -557,6 +654,6 @@
         if (*format == '!') {
           format++;
-          if (i < argc && mrb_nil_p(*sp)) {
-            *p = *sp++;
+          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
+            *p = ARGV[arg_i++];
             i++;
             break;
@@ -564,5 +661,5 @@
         }
         if (i < argc) {
-          *p = to_ary(mrb, *sp++);
+          *p = to_ary(mrb, ARGV[arg_i++]);
           i++;
         }
@@ -576,6 +673,6 @@
         if (*format == '!') {
           format++;
-          if (i < argc && mrb_nil_p(*sp)) {
-            *p = *sp++;
+          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
+            *p = ARGV[arg_i++];
             i++;
             break;
@@ -583,5 +680,5 @@
         }
         if (i < argc) {
-          *p = to_hash(mrb, *sp++);
+          *p = to_hash(mrb, ARGV[arg_i++]);
           i++;
         }
@@ -598,13 +695,13 @@
         if (*format == '!') {
           format++;
-          if (i < argc && mrb_nil_p(*sp)) {
+          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
             *ps = NULL;
             *pl = 0;
-            i++;
+            i++; arg_i++;
             break;
           }
         }
         if (i < argc) {
-          ss = to_str(mrb, *sp++);
+          ss = to_str(mrb, ARGV[arg_i++]);
           *ps = RSTRING_PTR(ss);
           *pl = RSTRING_LEN(ss);
@@ -621,12 +718,12 @@
         if (*format == '!') {
           format++;
-          if (i < argc && mrb_nil_p(*sp)) {
+          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
             *ps = NULL;
-            i++; sp++;
+            i++; arg_i++;
             break;
           }
         }
         if (i < argc) {
-          ss = to_str(mrb, *sp++);
+          ss = to_str(mrb, ARGV[arg_i++]);
           *ps = mrb_string_value_cstr(mrb, &ss);
           i++;
@@ -645,13 +742,13 @@
         if (*format == '!') {
           format++;
-          if (i < argc && mrb_nil_p(*sp)) {
+          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
             *pb = 0;
             *pl = 0;
-            i++; sp++;
+            i++; arg_i++;
             break;
           }
         }
         if (i < argc) {
-          aa = to_ary(mrb, *sp++);
+          aa = to_ary(mrb, ARGV[arg_i++]);
           a = mrb_ary_ptr(aa);
           *pb = a->ptr;
@@ -661,4 +758,22 @@
       }
       break;
+    case 'I':
+      {
+        void* *p;
+        mrb_value ss;
+
+        p = va_arg(ap, void**);
+        if (i < argc) {
+          ss = ARGV[arg_i];
+          if (mrb_type(ss) != MRB_TT_ISTRUCT)
+          {
+            mrb_raisef(mrb, E_TYPE_ERROR, "%S is not inline struct", ss);
+          }
+          *p = mrb_istruct_ptr(ss);
+          arg_i++;
+          i++;
+        }
+      }
+      break;
     case 'f':
       {
@@ -667,6 +782,6 @@
         p = va_arg(ap, mrb_float*);
         if (i < argc) {
-          *p = mrb_to_flo(mrb, *sp);
-          sp++;
+          *p = mrb_to_flo(mrb, ARGV[arg_i]);
+          arg_i++;
           i++;
         }
@@ -679,13 +794,13 @@
         p = va_arg(ap, mrb_int*);
         if (i < argc) {
-          switch (mrb_type(*sp)) {
+          switch (mrb_type(ARGV[arg_i])) {
             case MRB_TT_FIXNUM:
-              *p = mrb_fixnum(*sp);
+              *p = mrb_fixnum(ARGV[arg_i]);
               break;
             case MRB_TT_FLOAT:
               {
-                mrb_float f = mrb_float(*sp);
-
-                if (!FIXABLE(f)) {
+                mrb_float f = mrb_float(ARGV[arg_i]);
+
+                if (!FIXABLE_FLOAT(f)) {
                   mrb_raise(mrb, E_RANGE_ERROR, "float too big for int");
                 }
@@ -697,8 +812,8 @@
               break;
             default:
-              *p = mrb_fixnum(mrb_Integer(mrb, *sp));
+              *p = mrb_fixnum(mrb_Integer(mrb, ARGV[arg_i]));
               break;
           }
-          sp++;
+          arg_i++;
           i++;
         }
@@ -710,5 +825,5 @@
 
         if (i < argc) {
-          mrb_value b = *sp++;
+          mrb_value b = ARGV[arg_i++];
           *boolp = mrb_test(b);
           i++;
@@ -724,5 +839,5 @@
           mrb_value ss;
 
-          ss = *sp++;
+          ss = ARGV[arg_i++];
           *symp = to_sym(mrb, ss);
           i++;
@@ -739,12 +854,12 @@
         if (*format == '!') {
           format++;
-          if (i < argc && mrb_nil_p(*sp)) {
+          if (i < argc && mrb_nil_p(ARGV[arg_i])) {
             *datap = 0;
-            i++; sp++;
+            i++; arg_i++;
             break;
           }
         }
         if (i < argc) {
-          *datap = mrb_data_get_ptr(mrb, *sp++, type);
+          *datap = mrb_data_get_ptr(mrb, ARGV[arg_i++], type);
           ++i;
         }
@@ -788,8 +903,8 @@
           *pl = argc-i;
           if (*pl > 0) {
-            *var = sp;
+            *var = ARGV + arg_i;
           }
           i = argc;
-          sp += *pl;
+          arg_i += *pl;
         }
         else {
@@ -804,4 +919,7 @@
     }
   }
+
+#undef ARGV
+
   if (!c && argc > i) {
     mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
@@ -831,5 +949,7 @@
 boot_initmod(mrb_state *mrb, struct RClass *mod)
 {
-  mod->mt = kh_init(mt, mrb);
+  if (!mod->mt) {
+    mod->mt = kh_init(mt, mrb);
+  }
 }
 
@@ -847,5 +967,6 @@
   if (m->tt == MRB_TT_ICLASS) {
     ic->c = m->c;
-  } else {
+  }
+  else {
     ic->c = m;
   }
@@ -873,5 +994,5 @@
         if (p->mt == m->mt) {
           if (!superclass_seen) {
-            ins_pos = p; // move insert point
+            ins_pos = p; /* move insert point */
           }
           goto skip;
@@ -937,22 +1058,4 @@
 
 static mrb_value
-mrb_mod_prepend(mrb_state *mrb, mrb_value klass)
-{
-  mrb_value *argv;
-  mrb_int argc, i;
-
-  mrb_get_args(mrb, "*", &argv, &argc);
-  for (i=0; i<argc; i++) {
-    mrb_check_type(mrb, argv[i], MRB_TT_MODULE);
-  }
-  while (argc--) {
-    mrb_funcall(mrb, argv[argc], "prepend_features", 1, klass);
-    mrb_funcall(mrb, argv[argc], "prepended", 1, klass);
-  }
-
-  return klass;
-}
-
-static mrb_value
 mrb_mod_append_features(mrb_state *mrb, mrb_value mod)
 {
@@ -963,22 +1066,4 @@
   mrb_include_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod));
   return mod;
-}
-
-static mrb_value
-mrb_mod_include(mrb_state *mrb, mrb_value klass)
-{
-  mrb_value *argv;
-  mrb_int argc, i;
-
-  mrb_get_args(mrb, "*", &argv, &argc);
-  for (i=0; i<argc; i++) {
-    mrb_check_type(mrb, argv[i], MRB_TT_MODULE);
-  }
-  while (argc--) {
-    mrb_funcall(mrb, argv[argc], "append_features", 1, klass);
-    mrb_funcall(mrb, argv[argc], "included", 1, klass);
-  }
-
-  return klass;
 }
 
@@ -1076,5 +1161,5 @@
   mrb_value b;
   struct RClass *m = mrb_class_ptr(mod);
-  boot_initmod(mrb, m); // bootstrap a newly initialized module
+  boot_initmod(mrb, m); /* bootstrap a newly initialized module */
   mrb_get_args(mrb, "|&", &b);
   if (!mrb_nil_p(b)) {
@@ -1156,8 +1241,4 @@
   obj = mrb_basic_ptr(v);
   prepare_singleton_class(mrb, obj);
-  if (mrb->c && mrb->c->ci && mrb->c->ci->target_class) {
-    mrb_obj_iv_set(mrb, (struct RObject*)obj->c, mrb_intern_lit(mrb, "__outer__"),
-                   mrb_obj_value(mrb->c->ci->target_class));
-  }
   return mrb_obj_value(obj->c);
 }
@@ -1320,4 +1401,7 @@
 
   if (ttype == 0) ttype = MRB_TT_OBJECT;
+  if (ttype <= MRB_TT_CPTR) {
+    mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of %S", cv);
+  }
   o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c);
   return mrb_obj_value(o);
@@ -1354,8 +1438,11 @@
 {
   mrb_value obj;
+  mrb_sym mid;
 
   obj = mrb_instance_alloc(mrb, mrb_obj_value(c));
-  mrb_funcall_argv(mrb, obj, mrb_intern_lit(mrb, "initialize"), argc, argv);
-
+  mid = mrb_intern_lit(mrb, "initialize");
+  if (!mrb_func_basic_p(mrb, obj, mid, mrb_bob_init)) {
+    mrb_funcall_argv(mrb, obj, mid, argc, argv);
+  }
   return obj;
 }
@@ -1379,4 +1466,5 @@
   mrb_value super, blk;
   mrb_value new_class;
+  mrb_sym mid;
 
   n = mrb_get_args(mrb, "|C&", &super, &blk);
@@ -1385,5 +1473,8 @@
   }
   new_class = mrb_obj_value(mrb_class_new(mrb, mrb_class_ptr(super)));
-  mrb_funcall_with_block(mrb, new_class, mrb_intern_lit(mrb, "initialize"), n, &super, blk);
+  mid = mrb_intern_lit(mrb, "initialize");
+  if (!mrb_func_basic_p(mrb, new_class, mid, mrb_bob_init)) {
+    mrb_funcall_with_block(mrb, new_class, mid, n, &super, blk);
+  }
   mrb_class_inherited(mrb, mrb_class_ptr(super), mrb_class_ptr(new_class));
   return new_class;
@@ -1416,73 +1507,51 @@
 }
 
-void
-mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args)
-{
-  mrb_sym inspect;
-  mrb_value repr;
-
-  inspect = mrb_intern_lit(mrb, "inspect");
-  if (mrb->c->ci > mrb->c->cibase && mrb->c->ci[-1].mid == inspect) {
-    /* method missing in inspect; avoid recursion */
-    repr = mrb_any_to_s(mrb, self);
-  }
-  else if (mrb_respond_to(mrb, self, inspect) && mrb->c->ci - mrb->c->cibase < 64) {
-    repr = mrb_funcall_argv(mrb, self, inspect, 0, 0);
-    if (mrb_string_p(repr) && RSTRING_LEN(repr) > 64) {
-      repr = mrb_any_to_s(mrb, self);
-    }
-  }
-  else {
-    repr = mrb_any_to_s(mrb, self);
-  }
-
-  mrb_no_method_error(mrb, name, args, "undefined method '%S' for %S",
-                      mrb_sym2str(mrb, name), repr);
-}
-
-/* 15.3.1.3.30 */
+/* 15.3.1.3.1  */
+/* 15.3.1.3.10 */
+/* 15.3.1.3.11 */
 /*
  *  call-seq:
- *     obj.method_missing(symbol [, *args] )   -> result
- *
- *  Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.
- *  <i>symbol</i> is the symbol for the method called, and <i>args</i>
- *  are any arguments that were passed to it. By default, the interpreter
- *  raises an error when this method is called. However, it is possible
- *  to override the method to provide more dynamic behavior.
- *  If it is decided that a particular method should not be handled, then
- *  <i>super</i> should be called, so that ancestors can pick up the
- *  missing method.
- *  The example below creates
- *  a class <code>Roman</code>, which responds to methods with names
- *  consisting of roman numerals, returning the corresponding integer
- *  values.
- *
- *     class Roman
- *       def romanToInt(str)
- *         # ...
- *       end
- *       def method_missing(methId)
- *         str = methId.id2name
- *         romanToInt(str)
- *       end
- *     end
- *
- *     r = Roman.new
- *     r.iv      #=> 4
- *     r.xxiii   #=> 23
- *     r.mm      #=> 2000
+ *     obj == other        -> true or false
+ *     obj.equal?(other)   -> true or false
+ *     obj.eql?(other)     -> true or false
+ *
+ *  Equality---At the <code>Object</code> level, <code>==</code> returns
+ *  <code>true</code> only if <i>obj</i> and <i>other</i> are the
+ *  same object. Typically, this method is overridden in descendant
+ *  classes to provide class-specific meaning.
+ *
+ *  Unlike <code>==</code>, the <code>equal?</code> method should never be
+ *  overridden by subclasses: it is used to determine object identity
+ *  (that is, <code>a.equal?(b)</code> iff <code>a</code> is the same
+ *  object as <code>b</code>).
+ *
+ *  The <code>eql?</code> method returns <code>true</code> if
+ *  <i>obj</i> and <i>anObject</i> have the same value. Used by
+ *  <code>Hash</code> to test members for equality.  For objects of
+ *  class <code>Object</code>, <code>eql?</code> is synonymous with
+ *  <code>==</code>. Subclasses normally continue this tradition, but
+ *  there are exceptions. <code>Numeric</code> types, for example,
+ *  perform type conversion across <code>==</code>, but not across
+ *  <code>eql?</code>, so:
+ *
+ *     1 == 1.0     #=> true
+ *     1.eql? 1.0   #=> false
  */
-static mrb_value
-mrb_bob_missing(mrb_state *mrb, mrb_value mod)
-{
-  mrb_sym name;
-  mrb_value *a;
-  mrb_int alen;
-
-  mrb_get_args(mrb, "n*", &name, &a, &alen);
-  mrb_method_missing(mrb, name, mod, mrb_ary_new_from_values(mrb, alen, a));
-  /* not reached */
-  return mrb_nil_value();
+mrb_value
+mrb_obj_equal_m(mrb_state *mrb, mrb_value self)
+{
+  mrb_value arg;
+
+  mrb_get_args(mrb, "o", &arg);
+  return mrb_bool_value(mrb_obj_equal(mrb, self, arg));
+}
+
+static mrb_value
+mrb_obj_not_equal_m(mrb_state *mrb, mrb_value self)
+{
+  mrb_value arg;
+
+  mrb_get_args(mrb, "o", &arg);
+  return mrb_bool_value(!mrb_equal(mrb, self, arg));
 }
 
@@ -1533,5 +1602,5 @@
       return mrb_nil_value();
     }
-    else if (outer && outer != mrb->object_class) {
+    else if (outer && outer != c && outer != mrb->object_class) {
       mrb_value base = mrb_class_path(mrb, outer);
       path = mrb_str_buf_new(mrb, 0);
@@ -1552,7 +1621,9 @@
       path = mrb_str_new(mrb, name, len);
     }
-    mrb_obj_iv_set(mrb, (struct RObject*)c, classpath, path);
-  }
-  return path;
+    if (!MRB_FROZEN_P(c)) {
+      mrb_obj_iv_set(mrb, (struct RObject*)c, classpath, path);
+    }
+  }
+  return mrb_str_dup(mrb, path);
 }
 
@@ -1699,13 +1770,9 @@
     str = mrb_str_new_lit(mrb, "#<Class:");
 
-    switch (mrb_type(v)) {
-      case MRB_TT_CLASS:
-      case MRB_TT_MODULE:
-      case MRB_TT_SCLASS:
-        mrb_str_cat_str(mrb, str, mrb_inspect(mrb, v));
-        break;
-      default:
-        mrb_str_cat_str(mrb, str, mrb_any_to_s(mrb, v));
-        break;
+    if (class_ptr_p(v)) {
+      mrb_str_cat_str(mrb, str, mrb_inspect(mrb, v));
+    }
+    else {
+      mrb_str_cat_str(mrb, str, mrb_any_to_s(mrb, v));
     }
     return mrb_str_cat_lit(mrb, str, ">");
@@ -1786,5 +1853,5 @@
   mrb_get_args(mrb, "*", &argv, &argc);
   while (argc--) {
-    undef_method(mrb, c, mrb_symbol(*argv));
+    undef_method(mrb, c, to_sym(mrb, *argv));
     argv++;
   }
@@ -1798,7 +1865,19 @@
   struct RProc *p;
   mrb_sym mid;
+  mrb_value proc = mrb_undef_value();
   mrb_value blk;
 
-  mrb_get_args(mrb, "n&", &mid, &blk);
+  mrb_get_args(mrb, "n|o&", &mid, &proc, &blk);
+  switch (mrb_type(proc)) {
+    case MRB_TT_PROC:
+      blk = proc;
+      break;
+    case MRB_TT_UNDEF:
+      /* ignored */
+      break;
+    default:
+      mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected Proc)", mrb_obj_value(mrb_obj_class(mrb, proc)));
+      break;
+  }
   if (mrb_nil_p(blk)) {
     mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
@@ -2028,5 +2107,5 @@
   mrb_get_args(mrb, "*", &argv, &argc);
   while (argc--) {
-    remove_method(mrb, mod, mrb_symbol(*argv));
+    remove_method(mrb, mod, to_sym(mrb, *argv));
     argv++;
   }
@@ -2159,5 +2238,5 @@
 
   mrb_get_args(mrb, "*", &argv, &argc);
-  if(argc == 0) {
+  if (argc == 0) {
     /* set MODFUNC SCOPE if implemented */
     return mod;
@@ -2182,4 +2261,9 @@
   return mod;
 }
+
+/* implementation of __id__ */
+mrb_value mrb_obj_id_m(mrb_state *mrb, mrb_value self);
+/* implementation of instance_eval */
+mrb_value mrb_obj_instance_eval(mrb_state*, mrb_value);
 
 void
@@ -2222,5 +2306,9 @@
   mrb_define_method(mrb, bob, "initialize",              mrb_bob_init,             MRB_ARGS_NONE());
   mrb_define_method(mrb, bob, "!",                       mrb_bob_not,              MRB_ARGS_NONE());
-  mrb_define_method(mrb, bob, "method_missing",          mrb_bob_missing,          MRB_ARGS_ANY());  /* 15.3.1.3.30 */
+  mrb_define_method(mrb, bob, "==",                      mrb_obj_equal_m,          MRB_ARGS_REQ(1)); /* 15.3.1.3.1  */
+  mrb_define_method(mrb, bob, "!=",                      mrb_obj_not_equal_m,      MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, bob, "__id__",                  mrb_obj_id_m,             MRB_ARGS_NONE()); /* 15.3.1.3.3  */
+  mrb_define_method(mrb, bob, "__send__",                mrb_f_send,               MRB_ARGS_ANY());  /* 15.3.1.3.4  */
+  mrb_define_method(mrb, bob, "instance_eval",           mrb_obj_instance_eval,    MRB_ARGS_ANY());  /* 15.3.1.3.18 */
 
   mrb_define_class_method(mrb, cls, "new",               mrb_class_new_class,      MRB_ARGS_OPT(1));
@@ -2236,8 +2324,6 @@
   mrb_define_method(mrb, mod, "extend_object",           mrb_mod_extend_object,    MRB_ARGS_REQ(1)); /* 15.2.2.4.25 */
   mrb_define_method(mrb, mod, "extended",                mrb_bob_init,             MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */
-  mrb_define_method(mrb, mod, "prepend",                 mrb_mod_prepend,          MRB_ARGS_ANY());
   mrb_define_method(mrb, mod, "prepended",               mrb_bob_init,             MRB_ARGS_REQ(1));
   mrb_define_method(mrb, mod, "prepend_features",        mrb_mod_prepend_features, MRB_ARGS_REQ(1));
-  mrb_define_method(mrb, mod, "include",                 mrb_mod_include,          MRB_ARGS_ANY());  /* 15.2.2.4.27 */
   mrb_define_method(mrb, mod, "include?",                mrb_mod_include_p,        MRB_ARGS_REQ(1)); /* 15.2.2.4.28 */
   mrb_define_method(mrb, mod, "append_features",         mrb_mod_append_features,  MRB_ARGS_REQ(1)); /* 15.2.2.4.10 */
@@ -2269,5 +2355,5 @@
   mrb_define_method(mrb, mod, "remove_const",            mrb_mod_remove_const,     MRB_ARGS_REQ(1)); /* 15.2.2.4.40 */
   mrb_define_method(mrb, mod, "const_missing",           mrb_mod_const_missing,    MRB_ARGS_REQ(1));
-  mrb_define_method(mrb, mod, "define_method",           mod_define_method,        MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, mod, "define_method",           mod_define_method,        MRB_ARGS_ARG(1,1));
   mrb_define_method(mrb, mod, "class_variables",         mrb_mod_class_variables,  MRB_ARGS_NONE()); /* 15.2.2.4.19 */
   mrb_define_method(mrb, mod, "===",                     mrb_mod_eqq,              MRB_ARGS_REQ(1));
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/codedump.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/codedump.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/codedump.c	(revision 331)
@@ -1,8 +1,8 @@
-#include "mruby.h"
-#include "mruby/irep.h"
-#include "mruby/debug.h"
-#include "mruby/opcode.h"
-#include "mruby/string.h"
-#include "mruby/proc.h"
+#include <mruby.h>
+#include <mruby/irep.h>
+#include <mruby/debug.h>
+#include <mruby/opcode.h>
+#include <mruby/string.h>
+#include <mruby/proc.h>
 
 #ifndef MRB_DISABLE_STDIO
@@ -240,4 +240,5 @@
       switch (GETARG_B(c)) {
       case OP_R_NORMAL:
+        printf("\tnormal\t"); break;
       case OP_R_RETURN:
         printf("\treturn\t"); break;
@@ -246,5 +247,4 @@
       default:
         printf("\tbroken\t"); break;
-        break;
       }
       print_lv(mrb, irep, c, RA);
@@ -260,5 +260,13 @@
 
     case OP_LAMBDA:
-      printf("OP_LAMBDA\tR%d\tI(%+d)\t%d", GETARG_A(c), GETARG_b(c)+1, GETARG_c(c));
+      printf("OP_LAMBDA\tR%d\tI(%+d)\t", GETARG_A(c), GETARG_b(c)+1);
+      switch (GETARG_c(c)) {
+      case OP_L_METHOD:
+        printf("method"); break;
+      case OP_L_BLOCK:
+        printf("block"); break;
+      case OP_L_LAMBDA:
+        printf("lambda"); break;
+      }
       print_lv(mrb, irep, c, RA);
       break;
@@ -324,5 +332,5 @@
       break;
     case OP_EQ:
-      printf("OP_EQ\tR%d\t:%s\t%d\n", GETARG_A(c),
+      printf("OP_EQ\t\tR%d\t:%s\t%d\n", GETARG_A(c),
              mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
              GETARG_C(c));
@@ -410,6 +418,20 @@
       break;
     case OP_RESCUE:
-      printf("OP_RESCUE\tR%d\t\t", GETARG_A(c));
-      print_lv(mrb, irep, c, RA);
+      {
+        int a = GETARG_A(c);
+        int b = GETARG_B(c);
+        int cnt = GETARG_C(c);
+
+        if (b == 0) {
+          printf("OP_RESCUE\tR%d\t\t%s", a, cnt ? "cont" : "");
+          print_lv(mrb, irep, c, RA);
+          break;
+        }
+        else {
+          printf("OP_RESCUE\tR%d\tR%d\t%s", a, b, cnt ? "cont" : "");
+          print_lv(mrb, irep, c, RAB);
+          break;
+        }
+      }
       break;
     case OP_RAISE:
@@ -418,6 +440,5 @@
       break;
     case OP_POPERR:
-      printf("OP_POPERR\t%d\t\t", GETARG_A(c));
-      print_lv(mrb, irep, c, RA);
+      printf("OP_POPERR\t%d\t\t\n", GETARG_A(c));
       break;
     case OP_EPOP:
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/compar.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/compar.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/compar.c	(revision 331)
@@ -5,5 +5,5 @@
 */
 
-#include "mruby.h"
+#include <mruby.h>
 
 void
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/debug.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/debug.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/debug.c	(revision 331)
@@ -1,6 +1,6 @@
 #include <string.h>
-#include "mruby.h"
-#include "mruby/irep.h"
-#include "mruby/debug.h"
+#include <mruby.h>
+#include <mruby/irep.h>
+#include <mruby/debug.h>
 
 static mrb_irep_debug_info_file *
@@ -20,5 +20,6 @@
       ret = it + 1;
       count -= step + 1;
-    } else { count = step; }
+    }
+    else { count = step; }
   }
 
@@ -87,5 +88,6 @@
               ret = it + 1;
               count -= step + 1;
-            } else { count = step; }
+            }
+            else { count = step; }
           }
 
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/dump.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/dump.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/dump.c	(revision 331)
@@ -7,9 +7,9 @@
 #include <string.h>
 #include <limits.h>
-#include "mruby/dump.h"
-#include "mruby/string.h"
-#include "mruby/irep.h"
-#include "mruby/numeric.h"
-#include "mruby/debug.h"
+#include <mruby/dump.h>
+#include <mruby/string.h>
+#include <mruby/irep.h>
+#include <mruby/numeric.h>
+#include <mruby/debug.h>
 
 #define FLAG_BYTEORDER_NATIVE 2
@@ -55,5 +55,5 @@
   uint8_t *cur = buf;
 
-  cur += uint32_to_bin(get_irep_record_size_1(mrb, irep), cur);  /* record size */
+  cur += uint32_to_bin((uint32_t)get_irep_record_size_1(mrb, irep), cur);  /* record size */
   cur += uint16_to_bin((uint16_t)irep->nlocals, cur);  /* number of local variable */
   cur += uint16_to_bin((uint16_t)irep->nregs, cur);  /* number of register variable */
@@ -408,5 +408,6 @@
   if (irep->filename) {
     filename_len = strlen(irep->filename);
-  } else {
+  }
+  else {
     filename_len = 0;
   }
@@ -1060,4 +1061,5 @@
     }
     if (fprintf(fp,
+          "extern const uint8_t %s[];\n"
           "const uint8_t\n"
           "#if defined __GNUC__\n"
@@ -1067,4 +1069,5 @@
           "#endif\n"
           "%s[] = {",
+          initname,
           (uint16_t)MRB_DUMP_ALIGNMENT, (uint16_t)MRB_DUMP_ALIGNMENT, initname) < 0) {
       mrb_free(mrb, bin);
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/enum.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/enum.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/enum.c	(revision 331)
@@ -5,5 +5,5 @@
 */
 
-#include "mruby.h"
+#include <mruby.h>
 
 void
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/error.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/error.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/error.c	(revision 331)
@@ -8,14 +8,14 @@
 #include <stdarg.h>
 #include <stdlib.h>
-#include "mruby.h"
-#include "mruby/array.h"
-#include "mruby/irep.h"
-#include "mruby/proc.h"
-#include "mruby/string.h"
-#include "mruby/variable.h"
-#include "mruby/debug.h"
-#include "mruby/error.h"
-#include "mruby/class.h"
-#include "mruby/throw.h"
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/irep.h>
+#include <mruby/proc.h>
+#include <mruby/string.h>
+#include <mruby/variable.h>
+#include <mruby/debug.h>
+#include <mruby/error.h>
+#include <mruby/class.h>
+#include <mruby/throw.h>
 
 MRB_API mrb_value
@@ -45,6 +45,8 @@
 {
   mrb_value mesg;
-
-  if (mrb_get_args(mrb, "|o", &mesg) == 1) {
+  mrb_int argc;
+  mrb_value *argv;
+
+  if (mrb_get_args(mrb, "|o*", &mesg, &argv, &argc) >= 1) {
     mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "mesg"), mesg);
   }
@@ -61,5 +63,5 @@
  *  return the receiver. Otherwise, create a new
  *  exception object of the same class as the receiver, but with a
- *  message equal to <code>string.to_str</code>.
+ *  message equal to <code>string</code>.
  *
  */
@@ -110,7 +112,5 @@
  *
  * Returns the result of invoking <code>exception.to_s</code>.
- * Normally this returns the exception's message or name. By
- * supplying a to_str method, exceptions are agreeing to
- * be used where Strings are expected.
+ * Normally this returns the exception's message or name.
  */
 
@@ -136,4 +136,5 @@
   mrb_value str, mesg, file, line;
   mrb_bool append_mesg;
+  const char *cname;
 
   mesg = mrb_attr_get(mrb, exc, mrb_intern_lit(mrb, "mesg"));
@@ -147,32 +148,50 @@
   }
 
-  if (!mrb_nil_p(file) && !mrb_nil_p(line)) {
-    str = mrb_str_dup(mrb, file);
-    mrb_str_cat_lit(mrb, str, ":");
-    mrb_str_append(mrb, str, line);
-    mrb_str_cat_lit(mrb, str, ": ");
+  cname = mrb_obj_classname(mrb, exc);
+  str = mrb_str_new_cstr(mrb, cname);
+  if (mrb_string_p(file) && mrb_fixnum_p(line)) {
     if (append_mesg) {
-      mrb_str_cat_str(mrb, str, mesg);
-      mrb_str_cat_lit(mrb, str, " (");
-    }
-    mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc));
-    if (append_mesg) {
-      mrb_str_cat_lit(mrb, str, ")");
-    }
+      str = mrb_format(mrb, "%S:%S:%S (%S)", file, line, mesg, str);
+    }
+    else {
+      str = mrb_format(mrb, "%S:%S:%S", file, line, str);
+    }
+  }
+  else if (append_mesg) {
+    str = mrb_format(mrb, "%S:%S", str, mesg);
+  }
+  return str;
+}
+
+void mrb_keep_backtrace(mrb_state *mrb, mrb_value exc);
+
+static void
+set_backtrace(mrb_state *mrb, mrb_value exc, mrb_value backtrace)
+{
+  if (!mrb_array_p(backtrace)) {
+  type_err:
+    mrb_raise(mrb, E_TYPE_ERROR, "backtrace must be Array of String");
   }
   else {
-    const char *cname = mrb_obj_classname(mrb, exc);
-    str = mrb_str_new_cstr(mrb, cname);
-    mrb_str_cat_lit(mrb, str, ": ");
-    if (append_mesg) {
-      mrb_str_cat_str(mrb, str, mesg);
-    }
-    else {
-      mrb_str_cat_cstr(mrb, str, cname);
-    }
-  }
-  return str;
-}
-
+    const mrb_value *p = RARRAY_PTR(backtrace);
+    const mrb_value *pend = p + RARRAY_LEN(backtrace);
+
+    while (p < pend) {
+      if (!mrb_string_p(*p)) goto type_err;
+      p++;
+    }
+  }
+  mrb_iv_set(mrb, exc, mrb_intern_lit(mrb, "backtrace"), backtrace);
+}
+
+static mrb_value
+exc_set_backtrace(mrb_state *mrb, mrb_value exc)
+{
+  mrb_value backtrace;
+
+  mrb_get_args(mrb, "o", &backtrace);
+  set_backtrace(mrb, exc, backtrace);
+  return backtrace;
+}
 
 static void
@@ -182,5 +201,4 @@
   mrb_code *pc = ci->pc;
 
-  mrb_obj_iv_set(mrb, exc, mrb_intern_lit(mrb, "ciidx"), mrb_fixnum_value((mrb_int)(ci - mrb->c->cibase)));
   while (ci >= mrb->c->cibase) {
     mrb_code *err = ci->err;
@@ -203,11 +221,26 @@
 }
 
+void
+mrb_exc_set(mrb_state *mrb, mrb_value exc)
+{
+  if (mrb_nil_p(exc)) {
+    mrb->exc = 0;
+  }
+  else {
+    mrb->exc = mrb_obj_ptr(exc);
+    if (!mrb->gc.out_of_memory) {
+      exc_debug_info(mrb, mrb->exc);
+      mrb_keep_backtrace(mrb, exc);
+    }
+  }
+}
+
 MRB_API mrb_noreturn void
 mrb_exc_raise(mrb_state *mrb, mrb_value exc)
 {
-  mrb->exc = mrb_obj_ptr(exc);
-  if (!mrb->gc.out_of_memory) {
-    exc_debug_info(mrb, mrb->exc);
-  }
+  if (!mrb_obj_is_kind_of(mrb, exc, mrb->eException_class)) {
+    mrb_raise(mrb, E_TYPE_ERROR, "exception object expected");
+  }
+  mrb_exc_set(mrb, exc);
   if (!mrb->jmp) {
     mrb_p(mrb, exc);
@@ -220,7 +253,5 @@
 mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg)
 {
-  mrb_value mesg;
-  mesg = mrb_str_new_cstr(mrb, msg);
-  mrb_exc_raise(mrb, mrb_exc_new_str(mrb, c, mesg));
+  mrb_exc_raise(mrb, mrb_exc_new_str(mrb, c, mrb_str_new_cstr(mrb, msg)));
 }
 
@@ -232,4 +263,5 @@
   ptrdiff_t size;
   mrb_value ary = mrb_ary_new_capa(mrb, 4);
+  int ai = mrb_gc_arena_save(mrb);
 
   while (*p) {
@@ -255,4 +287,5 @@
       }
     }
+    mrb_gc_arena_restore(mrb, ai);
   }
   if (b == format) {
@@ -261,6 +294,9 @@
   else {
     size = p - b;
-    mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size));
-    return mrb_ary_join(mrb, ary, mrb_str_new(mrb, NULL, 0));
+    if (size > 0) {
+      mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size));
+      mrb_gc_arena_restore(mrb, ai);
+    }
+    return mrb_ary_join(mrb, ary, mrb_nil_value());
   }
 }
@@ -279,14 +315,27 @@
 }
 
+static mrb_noreturn void
+raise_va(mrb_state *mrb, struct RClass *c, const char *fmt, va_list ap, int argc, mrb_value *argv)
+{
+  mrb_value mesg;
+
+  mesg = mrb_vformat(mrb, fmt, ap);
+  if (argv == NULL) {
+    argv = &mesg;
+  }
+  else {
+    argv[0] = mesg;
+  }
+  mrb_exc_raise(mrb, mrb_obj_new(mrb, c, argc+1, argv));
+}
+
 MRB_API mrb_noreturn void
 mrb_raisef(mrb_state *mrb, struct RClass *c, const char *fmt, ...)
 {
   va_list args;
-  mrb_value mesg;
 
   va_start(args, fmt);
-  mesg = mrb_vformat(mrb, fmt, args);
+  raise_va(mrb, c, fmt, args, 0, NULL);
   va_end(args);
-  mrb_exc_raise(mrb, mrb_exc_new_str(mrb, c, mesg));
 }
 
@@ -294,15 +343,11 @@
 mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...)
 {
-  mrb_value exc;
   mrb_value argv[2];
   va_list args;
 
   va_start(args, fmt);
-  argv[0] = mrb_vformat(mrb, fmt, args);
+  argv[1] = mrb_symbol_value(id);
+  raise_va(mrb, E_NAME_ERROR, fmt, args, 1, argv);
   va_end(args);
-
-  argv[1] = mrb_symbol_value(id);
-  exc = mrb_obj_new(mrb, E_NAME_ERROR, 2, argv);
-  mrb_exc_raise(mrb, exc);
 }
 
@@ -338,12 +383,6 @@
 }
 
-static void
-set_backtrace(mrb_state *mrb, mrb_value info, mrb_value bt)
-{
-  mrb_funcall(mrb, info, "set_backtrace", 1, bt);
-}
-
-static mrb_value
-make_exception(mrb_state *mrb, int argc, const mrb_value *argv, mrb_bool isstr)
+MRB_API mrb_value
+mrb_make_exception(mrb_state *mrb, int argc, const mrb_value *argv)
 {
   mrb_value mesg;
@@ -357,10 +396,7 @@
       if (mrb_nil_p(argv[0]))
         break;
-      if (isstr) {
-        mesg = mrb_check_string_type(mrb, argv[0]);
-        if (!mrb_nil_p(mesg)) {
-          mesg = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, mesg);
-          break;
-        }
+      if (mrb_string_p(argv[0])) {
+        mesg = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, argv[0]);
+        break;
       }
       n = 0;
@@ -389,16 +425,10 @@
   if (argc > 0) {
     if (!mrb_obj_is_kind_of(mrb, mesg, mrb->eException_class))
-      mrb_raise(mrb, E_TYPE_ERROR, "exception object expected");
+      mrb_raise(mrb, mrb->eException_class, "exception object expected");
     if (argc > 2)
-        set_backtrace(mrb, mesg, argv[2]);
+      set_backtrace(mrb, mesg, argv[2]);
   }
 
   return mesg;
-}
-
-MRB_API mrb_value
-mrb_make_exception(mrb_state *mrb, int argc, const mrb_value *argv)
-{
-  return make_exception(mrb, argc, argv, TRUE);
 }
 
@@ -428,10 +458,13 @@
 {
   mrb_value exc;
+  mrb_value argv[3];
   va_list ap;
 
   va_start(ap, fmt);
-  exc = mrb_funcall(mrb, mrb_obj_value(E_NOMETHOD_ERROR), "new", 3,
-                    mrb_vformat(mrb, fmt, ap), mrb_symbol_value(id), args);
+  argv[0] = mrb_vformat(mrb, fmt, ap);
+  argv[1] = mrb_symbol_value(id);
+  argv[2] = args;
   va_end(ap);
+  exc = mrb_obj_new(mrb, E_NOMETHOD_ERROR, 3, argv);
   mrb_exc_raise(mrb, exc);
 }
@@ -440,5 +473,5 @@
 mrb_init_exception(mrb_state *mrb)
 {
-  struct RClass *exception, *runtime_error, *script_error;
+  struct RClass *exception, *script_error, *stack_error, *nomem_error;
 
   mrb->eException_class = exception = mrb_define_class(mrb, "Exception", mrb->object_class); /* 15.2.22 */
@@ -451,10 +484,17 @@
   mrb_define_method(mrb, exception, "inspect",         exc_inspect,       MRB_ARGS_NONE());
   mrb_define_method(mrb, exception, "backtrace",       mrb_exc_backtrace, MRB_ARGS_NONE());
+  mrb_define_method(mrb, exception, "set_backtrace",   exc_set_backtrace, MRB_ARGS_REQ(1));
 
   mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */
-  runtime_error = mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class);          /* 15.2.28 */
-  mrb->nomem_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, runtime_error, "Out of memory"));
+  mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class);          /* 15.2.28 */
   script_error = mrb_define_class(mrb, "ScriptError", mrb->eException_class);                /* 15.2.37 */
   mrb_define_class(mrb, "SyntaxError", script_error);                                        /* 15.2.38 */
-  mrb_define_class(mrb, "SystemStackError", exception);
-}
+  stack_error = mrb_define_class(mrb, "SystemStackError", exception);
+  mrb->stack_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, stack_error, "stack level too deep"));
+
+  nomem_error = mrb_define_class(mrb, "NoMemoryError", exception);
+  mrb->nomem_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, nomem_error, "Out of memory"));
+#ifdef MRB_GC_FIXED_ARENA
+  mrb->arena_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, nomem_error, "arena overflow error"));
+#endif
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/error.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/error.h	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/error.h	(revision 331)
@@ -1,3 +1,3 @@
 /* this header file is to be removed soon.
    added for compatibility purpose (1.0.0) */
-#include "mruby/error.h"
+#include <mruby/error.h>
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/etc.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/etc.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/etc.c	(revision 331)
@@ -5,10 +5,10 @@
 */
 
-#include "mruby.h"
-#include "mruby/string.h"
-#include "mruby/data.h"
-#include "mruby/class.h"
-#include "mruby/re.h"
-#include "mruby/irep.h"
+#include <mruby.h>
+#include <mruby/string.h>
+#include <mruby/data.h>
+#include <mruby/class.h>
+#include <mruby/re.h>
+#include <mruby/irep.h>
 
 MRB_API struct RData*
@@ -140,4 +140,5 @@
   case MRB_TT_FILE:
   case MRB_TT_DATA:
+  case MRB_TT_ISTRUCT:
   default:
     return MakeID(mrb_ptr(obj));
@@ -180,5 +181,16 @@
 mrb_regexp_p(mrb_state *mrb, mrb_value v)
 {
-  return mrb_class_defined(mrb, REGEXP_CLASS) && mrb_obj_is_kind_of(mrb, v, mrb_class_get(mrb, REGEXP_CLASS));
+  if (mrb->flags & MRB_STATE_NO_REGEXP) {
+    return FALSE;
+  }
+  if ((mrb->flags & MRB_STATE_REGEXP) || mrb_class_defined(mrb, REGEXP_CLASS)) {
+    mrb->flags |= MRB_STATE_REGEXP;
+    return mrb_obj_is_kind_of(mrb, v, mrb_class_get(mrb, REGEXP_CLASS));
+  }
+  else {
+    mrb->flags |= MRB_STATE_REGEXP;
+    mrb->flags |= MRB_STATE_NO_REGEXP;
+  }
+  return FALSE;
 }
 
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/fmt_fp.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/fmt_fp.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/fmt_fp.c	(revision 331)
@@ -34,6 +34,6 @@
 #include <ctype.h>
 
-#include "mruby.h"
-#include "mruby/string.h"
+#include <mruby.h>
+#include <mruby/string.h>
 
 struct fmt_args {
@@ -157,5 +157,5 @@
     s=buf;
     do {
-      int x=y;
+      int x=(int)y;
       *s++=xdigits[x]|(t&32);
       y=16*(y-x);
@@ -185,5 +185,5 @@
 
   do {
-    *z = y;
+    *z = (uint32_t)y;
     y = 1000000000*(y-*z++);
   } while (y);
@@ -195,5 +195,5 @@
       uint64_t x = ((uint64_t)*d<<sh)+carry;
       *d = x % 1000000000;
-      carry = x / 1000000000;
+      carry = (uint32_t)(x / 1000000000);
     }
     if (carry) *--a = carry;
@@ -254,5 +254,5 @@
   }
   for (; z>a && !z[-1]; z--);
-  
+
   if ((t|32)=='g') {
     if (!p) p++;
@@ -355,5 +355,5 @@
   default:
     return -1;
-  } 
+  }
 }
 
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/gc.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/gc.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/gc.c	(revision 331)
@@ -7,15 +7,16 @@
 #include <string.h>
 #include <stdlib.h>
-#include "mruby.h"
-#include "mruby/array.h"
-#include "mruby/class.h"
-#include "mruby/data.h"
-#include "mruby/hash.h"
-#include "mruby/proc.h"
-#include "mruby/range.h"
-#include "mruby/string.h"
-#include "mruby/variable.h"
-#include "mruby/gc.h"
-#include "mruby/error.h"
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/class.h>
+#include <mruby/data.h>
+#include <mruby/hash.h>
+#include <mruby/proc.h>
+#include <mruby/range.h>
+#include <mruby/string.h>
+#include <mruby/variable.h>
+#include <mruby/gc.h>
+#include <mruby/error.h>
+#include <mruby/throw.h>
 
 /*
@@ -66,5 +67,5 @@
   mruby implementer and C extension library writer must insert a write
   barrier when updating a reference from a field of an object.
-  When updating a reference from a field of object A to object B, 
+  When updating a reference from a field of object A to object B,
   two different types of write barrier are available:
 
@@ -110,5 +111,7 @@
     struct RData data;
     struct RProc proc;
+    struct REnv env;
     struct RException exc;
+    struct RBreak brk;
 #ifdef MRB_WORD_BOXING
     struct RFloat floatv;
@@ -138,5 +141,5 @@
   fprintf(stderr, "gc_invoke: %19.3f\n", gettimeofday_time() - program_invoke_time);\
   fprintf(stderr, "is_generational: %d\n", is_generational(gc));\
-  fprintf(stderr, "is_major_gc: %d\n", is_major_gc(mrb));\
+  fprintf(stderr, "is_major_gc: %d\n", is_major_gc(gc));\
 } while(0)
 
@@ -214,6 +217,8 @@
 
   p2 = mrb_realloc_simple(mrb, p, len);
-  if (!p2 && len) {
+  if (len == 0) return p2;
+  if (p2 == NULL) {
     if (mrb->gc.out_of_memory) {
+      mrb_exc_raise(mrb, mrb_obj_value(mrb->nomem_err));
       /* mrb_panic(mrb); */
     }
@@ -367,5 +372,5 @@
 }
 
-static void obj_free(mrb_state *mrb, struct RBasic *obj);
+static void obj_free(mrb_state *mrb, struct RBasic *obj, int end);
 
 void
@@ -381,5 +386,5 @@
     for (p = objects(tmp), e=p+MRB_HEAP_PAGE_SIZE; p<e; p++) {
       if (p->as.free.tt != MRB_TT_FREE)
-        obj_free(mrb, &p->as.basic);
+        obj_free(mrb, &p->as.basic, TRUE);
     }
     mrb_free(mrb, tmp);
@@ -403,5 +408,5 @@
     /* arena overflow error */
     gc->arena_idx = MRB_GC_ARENA_SIZE - 4; /* force room in arena */
-    mrb_raise(mrb, E_RUNTIME_ERROR, "arena overflow error");
+    mrb_exc_raise(mrb, mrb_obj_value(mrb->arena_err));
   }
 #else
@@ -429,5 +434,5 @@
    Register your object when it's exported to C world,
    without reference from Ruby world, e.g. callback
-   arguments.  Don't forget to remove the obejct using
+   arguments.  Don't forget to remove the object using
    mrb_gc_unregister, otherwise your object will leak.
 */
@@ -453,5 +458,5 @@
   mrb_value table = mrb_gv_get(mrb, root);
   struct RArray *a;
-  mrb_int i, j;
+  mrb_int i;
 
   if (mrb_nil_p(table)) return;
@@ -462,10 +467,11 @@
   a = mrb_ary_ptr(table);
   mrb_ary_modify(mrb, a);
-  for (i=j=0; i<a->len; i++) {
-    if (!mrb_obj_eq(mrb, a->ptr[i], obj)) {
-      a->ptr[j++] = a->ptr[i];
-    }
-  }
-  a->len = j;
+  for (i = 0; i < a->len; i++) {
+    if (mrb_obj_eq(mrb, a->ptr[i], obj)) {
+      a->len--;
+      memmove(&a->ptr[i], &a->ptr[i + 1], (a->len - i) * sizeof(a->ptr[i]));
+      break;
+    }
+  }
 }
 
@@ -476,4 +482,26 @@
   static const RVALUE RVALUE_zero = { { { MRB_TT_FALSE } } };
   mrb_gc *gc = &mrb->gc;
+
+  if (cls) {
+    enum mrb_vtype tt;
+
+    switch (cls->tt) {
+    case MRB_TT_CLASS:
+    case MRB_TT_SCLASS:
+    case MRB_TT_MODULE:
+    case MRB_TT_ENV:
+      break;
+    default:
+      mrb_raise(mrb, E_TYPE_ERROR, "allocation failure");
+    }
+    tt = MRB_INSTANCE_TT(cls);
+    if (tt != MRB_TT_FALSE &&
+        ttype != MRB_TT_SCLASS &&
+        ttype != MRB_TT_ICLASS &&
+        ttype != MRB_TT_ENV &&
+        ttype != tt) {
+      mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %S", mrb_obj_value(cls));
+    }
+  }
 
 #ifdef MRB_GC_STRESS
@@ -520,7 +548,15 @@
   size_t i;
   size_t e;
-
+  mrb_value nil;
+  int nregs;
+
+  if (c->stack == NULL) return;
   e = c->stack - c->stbase;
-  if (c->ci) e += c->ci->nregs;
+  if (c->ci) {
+    nregs = c->ci->argc + 2;
+    if (c->ci->nregs > nregs)
+      nregs = c->ci->nregs;
+    e += nregs;
+  }
   if (c->stbase + e > c->stend) e = c->stend - c->stbase;
   for (i=0; i<e; i++) {
@@ -528,11 +564,11 @@
 
     if (!mrb_immediate_p(v)) {
-      if (mrb_basic_ptr(v)->tt == MRB_TT_FREE) {
-        c->stbase[i] = mrb_nil_value();
-      }
-      else {
-        mrb_gc_mark(mrb, mrb_basic_ptr(v));
-      }
-    }
+      mrb_gc_mark(mrb, mrb_basic_ptr(v));
+    }
+  }
+  e = c->stend - c->stbase;
+  nil = mrb_nil_value();
+  for (; i<e; i++) {
+    c->stbase[i] = nil;
   }
 }
@@ -541,16 +577,13 @@
 mark_context(mrb_state *mrb, struct mrb_context *c)
 {
-  int i, e = 0;
+  int i;
   mrb_callinfo *ci;
 
-  /* mark stack */
+  /* mark VM stack */
   mark_context_stack(mrb, c);
 
-  /* mark VM stack */
+  /* mark call stack */
   if (c->cibase) {
     for (ci = c->cibase; ci <= c->ci; ci++) {
-      if (ci->eidx > e) {
-        e = ci->eidx;
-      }
       mrb_gc_mark(mrb, (struct RBasic*)ci->env);
       mrb_gc_mark(mrb, (struct RBasic*)ci->proc);
@@ -559,10 +592,12 @@
   }
   /* mark ensure stack */
-  for (i=0; i<e; i++) {
+  for (i=0; i<c->esize; i++) {
+    if (c->ensure[i] == NULL) break;
     mrb_gc_mark(mrb, (struct RBasic*)c->ensure[i]);
   }
   /* mark fibers */
-  if (c->prev && c->prev->fib) {
-    mrb_gc_mark(mrb, (struct RBasic*)c->prev->fib);
+  mrb_gc_mark(mrb, (struct RBasic*)c->fib);
+  if (c->prev) {
+    mark_context(mrb, c->prev);
   }
 }
@@ -614,12 +649,15 @@
     {
       struct REnv *e = (struct REnv*)obj;
-
-      if (!MRB_ENV_STACK_SHARED_P(e)) {
-        mrb_int i, len;
-
-        len = MRB_ENV_STACK_LEN(e);
-        for (i=0; i<len; i++) {
-          mrb_gc_mark_value(mrb, e->stack[i]);
+      mrb_int i, len;
+
+      if (MRB_ENV_STACK_SHARED_P(e)) {
+        if (e->cxt.c->fib) {
+          mrb_gc_mark(mrb, (struct RBasic*)e->cxt.c->fib);
         }
+        break;
+      }
+      len = MRB_ENV_STACK_LEN(e);
+      for (i=0; i<len; i++) {
+        mrb_gc_mark_value(mrb, e->stack[i]);
       }
     }
@@ -679,7 +717,7 @@
 
 static void
-obj_free(mrb_state *mrb, struct RBasic *obj)
-{
-  DEBUG(printf("obj_free(%p,tt=%d)\n",obj,obj->tt));
+obj_free(mrb_state *mrb, struct RBasic *obj, int end)
+{
+  DEBUG(fprintf(stderr, "obj_free(%p,tt=%d)\n",obj,obj->tt));
   switch (obj->tt) {
     /* immediate - no mark */
@@ -698,4 +736,7 @@
 
   case MRB_TT_OBJECT:
+    mrb_gc_free_iv(mrb, (struct RObject*)obj);
+    break;
+
   case MRB_TT_EXCEPTION:
     mrb_gc_free_iv(mrb, (struct RObject*)obj);
@@ -716,8 +757,10 @@
       struct REnv *e = (struct REnv*)obj;
 
-      if (!MRB_ENV_STACK_SHARED_P(e)) {
-        mrb_free(mrb, e->stack);
-        e->stack = NULL;
+      if (MRB_ENV_STACK_SHARED_P(e)) {
+        /* cannot be freed */
+        return;
       }
+      mrb_free(mrb, e->stack);
+      e->stack = NULL;
     }
     break;
@@ -727,6 +770,18 @@
       struct mrb_context *c = ((struct RFiber*)obj)->cxt;
 
-      if (c != mrb->root_c)
+      if (!end && c && c != mrb->root_c) {
+        mrb_callinfo *ci = c->ci;
+        mrb_callinfo *ce = c->cibase;
+
+        while (ce <= ci) {
+          struct REnv *e = ci->env;
+          if (e && !is_dead(&mrb->gc, e) &&
+              e->tt == MRB_TT_ENV && MRB_ENV_STACK_SHARED_P(e)) {
+            mrb_env_unshare(mrb, e);
+          }
+          ci--;
+        }
         mrb_free_context(mrb, c);
+      }
     }
     break;
@@ -781,5 +836,5 @@
 root_scan_phase(mrb_state *mrb, mrb_gc *gc)
 {
-  size_t i, e;
+  int i, e;
 
   if (!is_minor_gc(gc)) {
@@ -795,4 +850,24 @@
   /* mark class hierarchy */
   mrb_gc_mark(mrb, (struct RBasic*)mrb->object_class);
+
+  /* mark built-in classes */
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->class_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->module_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->proc_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->string_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->array_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->hash_class);
+
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->float_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->fixnum_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->true_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->false_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->nil_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->symbol_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->kernel_module);
+
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->eException_class);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->eStandardError_class);
+
   /* mark top_self */
   mrb_gc_mark(mrb, (struct RBasic*)mrb->top_self);
@@ -801,11 +876,12 @@
   /* mark pre-allocated exception */
   mrb_gc_mark(mrb, (struct RBasic*)mrb->nomem_err);
-
-  mark_context(mrb, mrb->root_c);
-  if (mrb->root_c->fib) {
-    mrb_gc_mark(mrb, (struct RBasic*)mrb->root_c->fib);
-  }
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->stack_err);
+#ifdef MRB_GC_FIXED_ARENA
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->arena_err);
+#endif
+
+  mark_context(mrb, mrb->c);
   if (mrb->root_c != mrb->c) {
-    mark_context(mrb, mrb->c);
+    mark_context(mrb, mrb->root_c);
   }
 }
@@ -859,5 +935,5 @@
 
       /* mark ensure stack */
-      children += (c->ci) ? c->ci->eidx : 0;
+      children += c->eidx;
 
       /* mark closure */
@@ -920,5 +996,14 @@
 final_marking_phase(mrb_state *mrb, mrb_gc *gc)
 {
-  mark_context_stack(mrb, mrb->root_c);
+  int i, e;
+
+  /* mark arena */
+  for (i=0,e=gc->arena_idx; i<e; i++) {
+    mrb_gc_mark(mrb, gc->arena[i]);
+  }
+  mrb_gc_mark_gv(mrb);
+  mark_context(mrb, mrb->c);
+  mark_context(mrb, mrb->root_c);
+  mrb_gc_mark(mrb, (struct RBasic*)mrb->exc);
   gc_mark_gray_list(mrb, gc);
   mrb_assert(gc->gray_list == NULL);
@@ -958,8 +1043,13 @@
       if (is_dead(gc, &p->as.basic)) {
         if (p->as.basic.tt != MRB_TT_FREE) {
-          obj_free(mrb, &p->as.basic);
-          p->as.free.next = page->freelist;
-          page->freelist = (struct RBasic*)p;
-          freed++;
+          obj_free(mrb, &p->as.basic, FALSE);
+          if (p->as.basic.tt == MRB_TT_FREE) {
+            p->as.free.next = page->freelist;
+            page->freelist = (struct RBasic*)p;
+            freed++;
+          }
+          else {
+            dead_slot = FALSE;
+          }
         }
       }
@@ -967,5 +1057,5 @@
         if (!is_generational(gc))
           paint_partial_white(gc, &p->as.basic); /* next gc target */
-        dead_slot = 0;
+        dead_slot = FALSE;
       }
       p++;
@@ -1080,5 +1170,5 @@
   mrb_gc *gc = &mrb->gc;
 
-  if (gc->disabled) return;
+  if (gc->disabled || gc->iterating) return;
 
   GC_INVOKE_TIME_REPORT("mrb_incremental_gc()");
@@ -1120,5 +1210,5 @@
   mrb_gc *gc = &mrb->gc;
 
-  if (gc->disabled) return;
+  if (gc->disabled || gc->iterating) return;
 
   GC_INVOKE_TIME_REPORT("mrb_full_gc()");
@@ -1357,4 +1447,8 @@
 change_gen_gc_mode(mrb_state *mrb, mrb_gc *gc, mrb_bool enable)
 {
+  if (gc->disabled || gc->iterating) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "generational mode changed when GC disabled");
+    return;
+  }
   if (is_generational(gc) && !enable) {
     clear_all_old(mrb, gc);
@@ -1408,15 +1502,16 @@
 gc_each_objects(mrb_state *mrb, mrb_gc *gc, mrb_each_object_callback *callback, void *data)
 {
-  mrb_heap_page* page = gc->heaps;
-
+  mrb_heap_page* page;
+
+  page = gc->heaps;
   while (page != NULL) {
-    RVALUE *p, *pend;
+    RVALUE *p;
+    int i;
 
     p = objects(page);
-    pend = p + MRB_HEAP_PAGE_SIZE;
-    for (;p < pend; p++) {
-      (*callback)(mrb, &p->as.basic, data);
-    }
-
+    for (i=0; i < MRB_HEAP_PAGE_SIZE; i++) {
+      if ((*callback)(mrb, &p[i].as.basic, data) == MRB_EACH_OBJ_BREAK)
+        return;
+    }
     page = page->next;
   }
@@ -1426,5 +1521,25 @@
 mrb_objspace_each_objects(mrb_state *mrb, mrb_each_object_callback *callback, void *data)
 {
-  gc_each_objects(mrb, &mrb->gc, callback, data);
+  mrb_bool iterating = mrb->gc.iterating;
+
+  mrb->gc.iterating = TRUE;
+  if (iterating) {
+    gc_each_objects(mrb, &mrb->gc, callback, data);
+  }
+  else {
+    struct mrb_jmpbuf *prev_jmp = mrb->jmp;
+    struct mrb_jmpbuf c_jmp;
+
+    MRB_TRY(&c_jmp) {
+      mrb->jmp = &c_jmp;
+      gc_each_objects(mrb, &mrb->gc, callback, data);
+      mrb->jmp = prev_jmp;
+      mrb->gc.iterating = iterating; 
+   } MRB_CATCH(&c_jmp) {
+      mrb->gc.iterating = iterating;
+      mrb->jmp = prev_jmp;
+      MRB_THROW(prev_jmp);
+    } MRB_END_EXC(&c_jmp);
+  }
 }
 
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/hash.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/hash.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/hash.c	(revision 331)
@@ -5,11 +5,11 @@
 */
 
-#include "mruby.h"
-#include "mruby/array.h"
-#include "mruby/class.h"
-#include "mruby/hash.h"
-#include "mruby/khash.h"
-#include "mruby/string.h"
-#include "mruby/variable.h"
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/class.h>
+#include <mruby/hash.h>
+#include <mruby/khash.h>
+#include <mruby/string.h>
+#include <mruby/variable.h>
 
 /* a function to get hash value of a float number */
@@ -92,10 +92,4 @@
 }
 
-typedef struct {
-  mrb_value v;
-  mrb_int n;
-} mrb_hash_value;
-
-KHASH_DECLARE(ht, mrb_value, mrb_hash_value, TRUE)
 KHASH_DEFINE (ht, mrb_value, mrb_hash_value, TRUE, mrb_hash_ht_hash_func, mrb_hash_ht_hash_equal)
 
@@ -105,7 +99,7 @@
 mrb_hash_ht_key(mrb_state *mrb, mrb_value key)
 {
-  if (mrb_string_p(key) && !RSTR_FROZEN_P(mrb_str_ptr(key))) {
+  if (mrb_string_p(key) && !MRB_FROZEN_P(mrb_str_ptr(key))) {
     key = mrb_str_dup(mrb, key);
-    RSTR_SET_FROZEN_FLAG(mrb_str_ptr(key));
+    MRB_SET_FROZEN_FLAG(mrb_str_ptr(key));
   }
   return key;
@@ -147,5 +141,5 @@
 
 MRB_API mrb_value
-mrb_hash_new_capa(mrb_state *mrb, int capa)
+mrb_hash_new_capa(mrb_state *mrb, mrb_int capa)
 {
   struct RHash *h;
@@ -166,4 +160,7 @@
 }
 
+static mrb_value mrb_hash_default(mrb_state *mrb, mrb_value hash);
+static mrb_value hash_default(mrb_state *mrb, mrb_value hash, mrb_value key);
+
 MRB_API mrb_value
 mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key)
@@ -171,4 +168,5 @@
   khash_t(ht) *h = RHASH_TBL(hash);
   khiter_t k;
+  mrb_sym mid;
 
   if (h) {
@@ -178,9 +176,10 @@
   }
 
-  /* not found */
-  if (MRB_RHASH_PROCDEFAULT_P(hash)) {
-    return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key);
-  }
-  return RHASH_IFNONE(hash);
+  mid = mrb_intern_lit(mrb, "default");
+  if (mrb_func_basic_p(mrb, hash, mid, mrb_hash_default)) {
+    return hash_default(mrb, hash, key);
+  }
+  /* xxx mrb_funcall_tailcall(mrb, hash, "default", 1, key); */
+  return mrb_funcall_argv(mrb, hash, mid, 1, &key);
 }
 
@@ -234,4 +233,5 @@
   khash_t(ht) *h, *ret_h;
   khiter_t k, ret_k;
+  mrb_value ifnone, vret;
 
   h = RHASH_TBL(hash);
@@ -239,5 +239,5 @@
   ret->ht = kh_init(ht, mrb);
 
-  if (kh_size(h) > 0) {
+  if (h && kh_size(h) > 0) {
     ret_h = ret->ht;
 
@@ -247,10 +247,22 @@
         ret_k = kh_put(ht, mrb, ret_h, KEY(kh_key(h, k)));
         mrb_gc_arena_restore(mrb, ai);
-        kh_val(ret_h, ret_k) = kh_val(h, k);
+        kh_val(ret_h, ret_k).v = kh_val(h, k).v;
+        kh_val(ret_h, ret_k).n = kh_size(ret_h)-1;
       }
     }
   }
 
-  return mrb_obj_value(ret);
+  if (MRB_RHASH_DEFAULT_P(hash)) {
+    ret->flags |= MRB_HASH_DEFAULT;
+  }
+  if (MRB_RHASH_PROCDEFAULT_P(hash)) {
+    ret->flags |= MRB_HASH_PROC_DEFAULT;
+  }
+  vret = mrb_obj_value(ret);
+  ifnone = RHASH_IFNONE(hash);
+  if (!mrb_nil_p(ifnone)) {
+      mrb_iv_set(mrb, vret, mrb_intern_lit(mrb, "ifnone"), ifnone);
+  }
+  return vret;
 }
 
@@ -275,4 +287,7 @@
 mrb_hash_modify(mrb_state *mrb, mrb_value hash)
 {
+  if (MRB_FROZEN_P(mrb_hash_ptr(hash))) {
+    mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen hash");
+  }
   mrb_hash_tbl(mrb, hash);
 }
@@ -330,5 +345,8 @@
     ifnone = block;
   }
-  mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
+  if (!mrb_nil_p(ifnone)) {
+    RHASH(hash)->flags |= MRB_HASH_DEFAULT;
+    mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
+  }
   return hash;
 }
@@ -357,4 +375,18 @@
 }
 
+static mrb_value
+hash_default(mrb_state *mrb, mrb_value hash, mrb_value key)
+{
+  if (MRB_RHASH_DEFAULT_P(hash)) {
+    if (MRB_RHASH_PROCDEFAULT_P(hash)) {
+      return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key);
+    }
+    else {
+      return RHASH_IFNONE(hash);
+    }
+  }
+  return mrb_nil_value();
+}
+
 /* 15.2.13.4.5  */
 /*
@@ -386,11 +418,14 @@
 
   mrb_get_args(mrb, "|o?", &key, &given);
-  if (MRB_RHASH_PROCDEFAULT_P(hash)) {
-    if (!given) return mrb_nil_value();
-    return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key);
-  }
-  else {
-    return RHASH_IFNONE(hash);
-  }
+  if (MRB_RHASH_DEFAULT_P(hash)) {
+    if (MRB_RHASH_PROCDEFAULT_P(hash)) {
+      if (!given) return mrb_nil_value();
+      return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, key);
+    }
+    else {
+      return RHASH_IFNONE(hash);
+    }
+  }
+  return mrb_nil_value();
 }
 
@@ -424,6 +459,11 @@
   mrb_hash_modify(mrb, hash);
   mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
-  RHASH(hash)->flags &= ~(MRB_HASH_PROC_DEFAULT);
-
+  RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT;
+  if (!mrb_nil_p(ifnone)) {
+    RHASH(hash)->flags |= MRB_HASH_DEFAULT;
+  }
+  else {
+    RHASH(hash)->flags &= ~MRB_HASH_DEFAULT;
+  }
   return ifnone;
 }
@@ -475,5 +515,12 @@
   mrb_hash_modify(mrb, hash);
   mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
-  RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
+  if (!mrb_nil_p(ifnone)) {
+    RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
+    RHASH(hash)->flags |= MRB_HASH_DEFAULT;
+  }
+  else {
+    RHASH(hash)->flags &= ~MRB_HASH_DEFAULT;
+    RHASH(hash)->flags &= ~MRB_HASH_PROC_DEFAULT;
+  }
 
   return ifnone;
@@ -530,4 +577,5 @@
 
   mrb_get_args(mrb, "o", &key);
+  mrb_hash_modify(mrb, self);
   return mrb_hash_delete_key(mrb, self, key);
 }
@@ -568,10 +616,13 @@
   }
 
-  if (MRB_RHASH_PROCDEFAULT_P(hash)) {
-    return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, mrb_nil_value());
-  }
-  else {
-    return RHASH_IFNONE(hash);
-  }
+  if (MRB_RHASH_DEFAULT_P(hash)) {
+    if (MRB_RHASH_PROCDEFAULT_P(hash)) {
+      return mrb_funcall(mrb, RHASH_PROCDEFAULT(hash), "call", 2, hash, mrb_nil_value());
+    }
+    else {
+      return RHASH_IFNONE(hash);
+    }
+  }
+  return mrb_nil_value();
 }
 
@@ -593,4 +644,5 @@
   khash_t(ht) *h = RHASH_TBL(hash);
 
+  mrb_hash_modify(mrb, hash);
   if (h) kh_clear(ht, mrb, h);
   return hash;
@@ -700,4 +752,5 @@
   khash_t(ht) *h = RHASH_TBL(hash);
   khiter_t k;
+  mrb_int end;
   mrb_value ary;
   mrb_value *p;
@@ -705,5 +758,6 @@
   if (!h || kh_size(h) == 0) return mrb_ary_new(mrb);
   ary = mrb_ary_new_capa(mrb, kh_size(h));
-  mrb_ary_set(mrb, ary, kh_size(h)-1, mrb_nil_value());
+  end = kh_size(h)-1;
+  mrb_ary_set(mrb, ary, end, mrb_nil_value());
   p = mrb_ary_ptr(ary)->ptr;
   for (k = kh_begin(h); k != kh_end(h); k++) {
@@ -712,5 +766,10 @@
       mrb_hash_value hv = kh_value(h, k);
 
-      p[hv.n] = kv;
+      if (hv.n <= end) {
+        p[hv.n] = kv;
+      }
+      else {
+        p[end] = kv;
+      }
     }
   }
@@ -731,5 +790,5 @@
  */
 
-static mrb_value
+MRB_API mrb_value
 mrb_hash_values(mrb_state *mrb, mrb_value hash)
 {
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/init.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/init.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/init.c	(revision 331)
@@ -5,5 +5,5 @@
 */
 
-#include "mruby.h"
+#include <mruby.h>
 
 void mrb_init_symtbl(mrb_state*);
@@ -14,7 +14,7 @@
 void mrb_init_enumerable(mrb_state*);
 void mrb_init_symbol(mrb_state*);
+void mrb_init_string(mrb_state*);
 void mrb_init_exception(mrb_state*);
 void mrb_init_proc(mrb_state*);
-void mrb_init_string(mrb_state*);
 void mrb_init_array(mrb_state*);
 void mrb_init_hash(mrb_state*);
@@ -39,7 +39,7 @@
 
   mrb_init_symbol(mrb); DONE;
+  mrb_init_string(mrb); DONE;
   mrb_init_exception(mrb); DONE;
   mrb_init_proc(mrb); DONE;
-  mrb_init_string(mrb); DONE;
   mrb_init_array(mrb); DONE;
   mrb_init_hash(mrb); DONE;
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/kernel.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/kernel.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/kernel.c	(revision 331)
@@ -5,11 +5,13 @@
 */
 
-#include "mruby.h"
-#include "mruby/array.h"
-#include "mruby/class.h"
-#include "mruby/proc.h"
-#include "mruby/string.h"
-#include "mruby/variable.h"
-#include "mruby/error.h"
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/hash.h>
+#include <mruby/class.h>
+#include <mruby/proc.h>
+#include <mruby/string.h>
+#include <mruby/variable.h>
+#include <mruby/error.h>
+#include <mruby/istruct.h>
 
 typedef enum {
@@ -27,11 +29,17 @@
 } mrb_method_flag_t;
 
+MRB_API mrb_bool
+mrb_func_basic_p(mrb_state *mrb, mrb_value obj, mrb_sym mid, mrb_func_t func)
+{
+  struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mid);
+  if (MRB_PROC_CFUNC_P(me) && (me->body.func == func))
+    return TRUE;
+  return FALSE;
+}
+
 static mrb_bool
 mrb_obj_basic_to_s_p(mrb_state *mrb, mrb_value obj)
 {
-  struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mrb_intern_lit(mrb, "to_s"));
-  if (MRB_PROC_CFUNC_P(me) && (me->body.func == mrb_any_to_s))
-    return TRUE;
-  return FALSE;
+  return mrb_func_basic_p(mrb, obj, mrb_intern_lit(mrb, "to_s"), mrb_any_to_s);
 }
 
@@ -57,53 +65,4 @@
   }
   return mrb_any_to_s(mrb, obj);
-}
-
-/* 15.3.1.3.1  */
-/* 15.3.1.3.10 */
-/* 15.3.1.3.11 */
-/*
- *  call-seq:
- *     obj == other        -> true or false
- *     obj.equal?(other)   -> true or false
- *     obj.eql?(other)     -> true or false
- *
- *  Equality---At the <code>Object</code> level, <code>==</code> returns
- *  <code>true</code> only if <i>obj</i> and <i>other</i> are the
- *  same object. Typically, this method is overridden in descendant
- *  classes to provide class-specific meaning.
- *
- *  Unlike <code>==</code>, the <code>equal?</code> method should never be
- *  overridden by subclasses: it is used to determine object identity
- *  (that is, <code>a.equal?(b)</code> iff <code>a</code> is the same
- *  object as <code>b</code>).
- *
- *  The <code>eql?</code> method returns <code>true</code> if
- *  <i>obj</i> and <i>anObject</i> have the same value. Used by
- *  <code>Hash</code> to test members for equality.  For objects of
- *  class <code>Object</code>, <code>eql?</code> is synonymous with
- *  <code>==</code>. Subclasses normally continue this tradition, but
- *  there are exceptions. <code>Numeric</code> types, for example,
- *  perform type conversion across <code>==</code>, but not across
- *  <code>eql?</code>, so:
- *
- *     1 == 1.0     #=> true
- *     1.eql? 1.0   #=> false
- */
-static mrb_value
-mrb_obj_equal_m(mrb_state *mrb, mrb_value self)
-{
-  mrb_value arg;
-
-  mrb_get_args(mrb, "o", &arg);
-  return mrb_bool_value(mrb_obj_equal(mrb, self, arg));
-}
-
-static mrb_value
-mrb_obj_not_equal_m(mrb_state *mrb, mrb_value self)
-{
-  mrb_value arg;
-
-  mrb_get_args(mrb, "o", &arg);
-  return mrb_bool_value(!mrb_equal(mrb, self, arg));
 }
 
@@ -143,5 +102,5 @@
  *  <code>name</code>. Replaces the deprecated <code>Object#id</code>.
  */
-static mrb_value
+mrb_value
 mrb_obj_id_m(mrb_state *mrb, mrb_value self)
 {
@@ -178,36 +137,36 @@
   mrb_callinfo *ci = mrb->c->ci;
   mrb_value *bp;
-  mrb_bool given_p;
 
   bp = ci->stackent + 1;
   ci--;
   if (ci <= mrb->c->cibase) {
-    given_p = FALSE;
-  }
-  else {
-    /* block_given? called within block; check upper scope */
-    if (ci->proc->env) {
-      struct REnv *e = ci->proc->env;
-      mrb_value *sp;
-
-      while (e->c) {
-        e = (struct REnv*)e->c;
-      }
-      sp = e->stack;
-      if (sp) {
-        /* top-level does not have block slot (alway false) */
-        if (sp == mrb->c->stbase)
-          return mrb_false_value();
-        ci = mrb->c->cibase + e->cioff;
-        bp = ci[1].stackent + 1;
-      }
-    }
-    if (ci->argc > 0) {
-      bp += ci->argc;
-    }
-    given_p = !mrb_nil_p(*bp);
-  }
-
-  return mrb_bool_value(given_p);
+    return mrb_false_value();
+  }
+  /* block_given? called within block; check upper scope */
+  if (ci->proc->env) {
+    struct REnv *e = ci->proc->env;
+
+    while (e->c) {
+      e = (struct REnv*)e->c;
+    }
+    /* top-level does not have block slot (always false) */
+    if (e->stack == mrb->c->stbase)
+      return mrb_false_value();
+    if (e->stack && e->cioff < 0) {
+      /* use saved block arg position */
+      bp = &e->stack[-e->cioff];
+      ci = 0;                 /* no callinfo available */
+    }
+    else {
+      ci = e->cxt.c->cibase + e->cioff;
+      bp = ci[1].stackent + 1;
+    }
+  }
+  if (ci && ci->argc > 0) {
+    bp += ci->argc;
+  }
+  if (mrb_nil_p(*bp))
+    return mrb_false_value();
+  return mrb_true_value();
 }
 
@@ -241,9 +200,11 @@
     struct RClass *clone = (struct RClass*)mrb_obj_alloc(mrb, klass->tt, mrb->class_class);
 
-    if ((mrb_type(obj) == MRB_TT_CLASS) || (mrb_type(obj) == MRB_TT_SCLASS)) {
-      clone->c = clone;
-    }
-    else {
+    switch (mrb_type(obj)) {
+    case MRB_TT_CLASS:
+    case MRB_TT_SCLASS:
+      break;
+    default:
       clone->c = mrb_singleton_class_clone(mrb, mrb_obj_value(klass));
+      break;
     }
     clone->super = klass->super;
@@ -283,6 +244,12 @@
     c1->super->flags |= MRB_FLAG_IS_ORIGIN;
   }
-  dc->mt = kh_copy(mt, mrb, sc->mt);
+  if (sc->mt) {
+    dc->mt = kh_copy(mt, mrb, sc->mt);
+  }
+  else {
+    dc->mt = kh_init(mt, mrb);
+  }
   dc->super = sc->super;
+  MRB_SET_INSTANCE_TT(dc, MRB_INSTANCE_TT(sc));
 }
 
@@ -302,4 +269,7 @@
       mrb_iv_copy(mrb, dest, obj);
       break;
+    case MRB_TT_ISTRUCT:
+      mrb_istruct_copy(dest, obj);
+      break;
 
     default:
@@ -441,7 +411,56 @@
   mrb_value *argv;
   mrb_int argc;
+  mrb_value args;
 
   mrb_get_args(mrb, "*", &argv, &argc);
+  args = mrb_ary_new_from_values(mrb, argc, argv);
+  argv = (mrb_value*)RARRAY_PTR(args);
   return mrb_obj_extend(mrb, argc, argv, self);
+}
+
+static mrb_value
+mrb_obj_freeze(mrb_state *mrb, mrb_value self)
+{
+  struct RBasic *b;
+
+  switch (mrb_type(self)) {
+    case MRB_TT_FALSE:
+    case MRB_TT_TRUE:
+    case MRB_TT_FIXNUM:
+    case MRB_TT_SYMBOL:
+    case MRB_TT_FLOAT:
+      return self;
+    default:
+      break;
+  }
+
+  b = mrb_basic_ptr(self);
+  if (!MRB_FROZEN_P(b)) {
+    MRB_SET_FROZEN_FLAG(b);
+  }
+  return self;
+}
+
+static mrb_value
+mrb_obj_frozen(mrb_state *mrb, mrb_value self)
+{
+  struct RBasic *b;
+
+  switch (mrb_type(self)) {
+    case MRB_TT_FALSE:
+    case MRB_TT_TRUE:
+    case MRB_TT_FIXNUM:
+    case MRB_TT_SYMBOL:
+    case MRB_TT_FLOAT:
+      return mrb_true_value();
+    default:
+      break;
+  }
+
+  b = mrb_basic_ptr(self);
+  if (!MRB_FROZEN_P(b)) {
+    return mrb_false_value();
+  }
+  return mrb_true_value();
 }
 
@@ -477,7 +496,4 @@
 }
 
-
-/* implementation of instance_eval */
-mrb_value mrb_obj_instance_eval(mrb_state*, mrb_value);
 
 MRB_API mrb_bool
@@ -723,7 +739,5 @@
 mrb_obj_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj, mrb_method_flag_t flag)
 {
-  if (recur)
-    return mrb_class_instance_method_list(mrb, recur, mrb_class(mrb, obj), 0);
-  return mrb_obj_singleton_methods(mrb, recur, obj);
+  return mrb_class_instance_method_list(mrb, recur, mrb_class(mrb, obj), 0);
 }
 /* 15.3.1.3.31 */
@@ -853,6 +867,6 @@
     break;
   case 1:
-    a[1] = mrb_check_string_type(mrb, a[0]);
-    if (!mrb_nil_p(a[1])) {
+    if (mrb_string_p(a[0])) {
+      a[1] = a[0];
       argc = 2;
       a[0] = mrb_obj_value(E_RUNTIME_ERROR);
@@ -861,5 +875,4 @@
   default:
     exc = mrb_make_exception(mrb, argc, a);
-    mrb_obj_iv_set(mrb, mrb_obj_ptr(exc), mrb_intern_lit(mrb, "lastpc"), mrb_cptr_value(mrb, mrb->c->ci->pc));
     mrb_exc_raise(mrb, exc);
     break;
@@ -905,4 +918,77 @@
 }
 
+void
+mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args)
+{
+  mrb_sym inspect;
+  mrb_value repr;
+
+  inspect = mrb_intern_lit(mrb, "inspect");
+  if (mrb->c->ci > mrb->c->cibase && mrb->c->ci[-1].mid == inspect) {
+    /* method missing in inspect; avoid recursion */
+    repr = mrb_any_to_s(mrb, self);
+  }
+  else if (mrb_respond_to(mrb, self, inspect) && mrb->c->ci - mrb->c->cibase < 16) {
+    repr = mrb_funcall_argv(mrb, self, inspect, 0, 0);
+    if (mrb_string_p(repr) && RSTRING_LEN(repr) > 64) {
+      repr = mrb_any_to_s(mrb, self);
+    }
+  }
+  else {
+    repr = mrb_any_to_s(mrb, self);
+  }
+
+  mrb_no_method_error(mrb, name, args, "undefined method '%S' for %S",
+                      mrb_sym2str(mrb, name), repr);
+}
+
+/* 15.3.1.3.30 */
+/*
+ *  call-seq:
+ *     obj.method_missing(symbol [, *args] )   -> result
+ *
+ *  Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.
+ *  <i>symbol</i> is the symbol for the method called, and <i>args</i>
+ *  are any arguments that were passed to it. By default, the interpreter
+ *  raises an error when this method is called. However, it is possible
+ *  to override the method to provide more dynamic behavior.
+ *  If it is decided that a particular method should not be handled, then
+ *  <i>super</i> should be called, so that ancestors can pick up the
+ *  missing method.
+ *  The example below creates
+ *  a class <code>Roman</code>, which responds to methods with names
+ *  consisting of roman numerals, returning the corresponding integer
+ *  values.
+ *
+ *     class Roman
+ *       def romanToInt(str)
+ *         # ...
+ *       end
+ *       def method_missing(methId)
+ *         str = methId.id2name
+ *         romanToInt(str)
+ *       end
+ *     end
+ *
+ *     r = Roman.new
+ *     r.iv      #=> 4
+ *     r.xxiii   #=> 23
+ *     r.mm      #=> 2000
+ */
+#ifdef MRB_DEFAULT_METHOD_MISSING
+static mrb_value
+mrb_obj_missing(mrb_state *mrb, mrb_value mod)
+{
+  mrb_sym name;
+  mrb_value *a;
+  mrb_int alen;
+
+  mrb_get_args(mrb, "n*", &name, &a, &alen);
+  mrb_method_missing(mrb, name, mod, mrb_ary_new_from_values(mrb, alen, a));
+  /* not reached */
+  return mrb_nil_value();
+}
+#endif
+
 static inline mrb_bool
 basic_obj_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym id, int pub)
@@ -940,5 +1026,8 @@
   else {
     mrb_value tmp;
-    if (!mrb_string_p(mid)) {
+    if (mrb_string_p(mid)) {
+      tmp = mrb_check_intern_str(mrb, mid);
+    }
+    else {
       tmp = mrb_check_string_type(mrb, mid);
       if (mrb_nil_p(tmp)) {
@@ -946,6 +1035,6 @@
         mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", tmp);
       }
-    }
-    tmp = mrb_check_intern_str(mrb, mid);
+      tmp = mrb_check_intern_str(mrb, tmp);
+    }
     if (mrb_nil_p(tmp)) {
       respond_to_p = FALSE;
@@ -963,8 +1052,9 @@
     rtm_id = mrb_intern_lit(mrb, "respond_to_missing?");
     if (basic_obj_respond_to(mrb, self, rtm_id, !priv)) {
-      mrb_value args[2];
+      mrb_value args[2], v;
       args[0] = mid;
       args[1] = mrb_bool_value(priv);
-      return mrb_funcall_argv(mrb, self, rtm_id, 2, args);
+      v = mrb_funcall_argv(mrb, self, rtm_id, 2, args);
+      return mrb_bool_value(mrb_bool(v));
     }
   }
@@ -1051,6 +1141,6 @@
 mrb_local_variables(mrb_state *mrb, mrb_value self)
 {
-  mrb_value ret;
   struct RProc *proc;
+  mrb_value vars;
   struct mrb_irep *irep;
   size_t i;
@@ -1066,8 +1156,8 @@
     return mrb_ary_new(mrb);
   }
-  ret = mrb_ary_new_capa(mrb, irep->nlocals - 1);
+  vars = mrb_hash_new(mrb);
   for (i = 0; i + 1 < irep->nlocals; ++i) {
     if (irep->lv[i].name) {
-      mrb_ary_push(mrb, ret, mrb_symbol_value(irep->lv[i].name));
+      mrb_hash_set(mrb, vars, mrb_symbol_value(irep->lv[i].name), mrb_true_value());
     }
   }
@@ -1076,10 +1166,11 @@
 
     while (e) {
-      if (!MRB_PROC_CFUNC_P(mrb->c->cibase[e->cioff].proc)) {
-        irep = mrb->c->cibase[e->cioff].proc->body.irep;
+      if (MRB_ENV_STACK_SHARED_P(e) &&
+          !MRB_PROC_CFUNC_P(e->cxt.c->cibase[e->cioff].proc)) {
+        irep = e->cxt.c->cibase[e->cioff].proc->body.irep;
         if (irep->lv) {
           for (i = 0; i + 1 < irep->nlocals; ++i) {
             if (irep->lv[i].name) {
-              mrb_ary_push(mrb, ret, mrb_symbol_value(irep->lv[i].name));
+              mrb_hash_set(mrb, vars, mrb_symbol_value(irep->lv[i].name), mrb_true_value());
             }
           }
@@ -1090,7 +1181,8 @@
   }
 
-  return ret;
-}
-
+  return mrb_hash_keys(mrb, vars);
+}
+
+mrb_value mrb_obj_equal_m(mrb_state *mrb, mrb_value);
 void
 mrb_init_kernel(mrb_state *mrb)
@@ -1108,9 +1200,5 @@
   mrb_define_method(mrb, krn, "singleton_class",            mrb_singleton_class,             MRB_ARGS_NONE());
 
-  mrb_define_method(mrb, krn, "==",                         mrb_obj_equal_m,                 MRB_ARGS_REQ(1));    /* 15.3.1.3.1  */
-  mrb_define_method(mrb, krn, "!=",                         mrb_obj_not_equal_m,             MRB_ARGS_REQ(1));
   mrb_define_method(mrb, krn, "===",                        mrb_equal_m,                     MRB_ARGS_REQ(1));    /* 15.3.1.3.2  */
-  mrb_define_method(mrb, krn, "__id__",                     mrb_obj_id_m,                    MRB_ARGS_NONE());    /* 15.3.1.3.3  */
-  mrb_define_method(mrb, krn, "__send__",                   mrb_f_send,                      MRB_ARGS_ANY());     /* 15.3.1.3.4  */
   mrb_define_method(mrb, krn, "block_given?",               mrb_f_block_given_p_m,           MRB_ARGS_NONE());    /* 15.3.1.3.6  */
   mrb_define_method(mrb, krn, "class",                      mrb_obj_class_m,                 MRB_ARGS_NONE());    /* 15.3.1.3.7  */
@@ -1120,9 +1208,10 @@
   mrb_define_method(mrb, krn, "equal?",                     mrb_obj_equal_m,                 MRB_ARGS_REQ(1));    /* 15.3.1.3.11 */
   mrb_define_method(mrb, krn, "extend",                     mrb_obj_extend_m,                MRB_ARGS_ANY());     /* 15.3.1.3.13 */
+  mrb_define_method(mrb, krn, "freeze",                     mrb_obj_freeze,                  MRB_ARGS_NONE());
+  mrb_define_method(mrb, krn, "frozen?",                    mrb_obj_frozen,                  MRB_ARGS_NONE());
   mrb_define_method(mrb, krn, "global_variables",           mrb_f_global_variables,          MRB_ARGS_NONE());    /* 15.3.1.3.14 */
   mrb_define_method(mrb, krn, "hash",                       mrb_obj_hash,                    MRB_ARGS_NONE());    /* 15.3.1.3.15 */
   mrb_define_method(mrb, krn, "initialize_copy",            mrb_obj_init_copy,               MRB_ARGS_REQ(1));    /* 15.3.1.3.16 */
   mrb_define_method(mrb, krn, "inspect",                    mrb_obj_inspect,                 MRB_ARGS_NONE());    /* 15.3.1.3.17 */
-  mrb_define_method(mrb, krn, "instance_eval",              mrb_obj_instance_eval,           MRB_ARGS_ANY());     /* 15.3.1.3.18 */
   mrb_define_method(mrb, krn, "instance_of?",               obj_is_instance_of,              MRB_ARGS_REQ(1));    /* 15.3.1.3.19 */
   mrb_define_method(mrb, krn, "instance_variable_defined?", mrb_obj_ivar_defined,            MRB_ARGS_REQ(1));    /* 15.3.1.3.20 */
@@ -1134,4 +1223,7 @@
   mrb_define_method(mrb, krn, "kind_of?",                   mrb_obj_is_kind_of_m,            MRB_ARGS_REQ(1));    /* 15.3.1.3.26 */
   mrb_define_method(mrb, krn, "local_variables",            mrb_local_variables,             MRB_ARGS_NONE());    /* 15.3.1.3.28 */
+#ifdef MRB_DEFAULT_METHOD_MISSING
+  mrb_define_method(mrb, krn, "method_missing",             mrb_obj_missing,                 MRB_ARGS_ANY());     /* 15.3.1.3.30 */
+#endif
   mrb_define_method(mrb, krn, "methods",                    mrb_obj_methods_m,               MRB_ARGS_OPT(1));    /* 15.3.1.3.31 */
   mrb_define_method(mrb, krn, "nil?",                       mrb_false,                       MRB_ARGS_NONE());    /* 15.3.1.3.32 */
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/load.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/load.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/load.c	(revision 331)
@@ -8,10 +8,10 @@
 #include <stdlib.h>
 #include <string.h>
-#include "mruby/dump.h"
-#include "mruby/irep.h"
-#include "mruby/proc.h"
-#include "mruby/string.h"
-#include "mruby/debug.h"
-#include "mruby/error.h"
+#include <mruby/dump.h>
+#include <mruby/irep.h>
+#include <mruby/proc.h>
+#include <mruby/string.h>
+#include <mruby/debug.h>
+#include <mruby/error.h>
 
 #if SIZE_MAX < UINT32_MAX
@@ -524,5 +524,5 @@
     if (bigendian_p())
       *flags |= FLAG_BYTEORDER_NATIVE;
-    else 
+    else
       *flags |= FLAG_BYTEORDER_BIG;
   }
@@ -545,5 +545,5 @@
 }
 
-MRB_API mrb_irep*
+static mrb_irep*
 read_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags)
 {
@@ -603,5 +603,5 @@
 }
 
-MRB_API mrb_irep*
+mrb_irep*
 mrb_read_irep(mrb_state *mrb, const uint8_t *bin)
 {
@@ -615,8 +615,10 @@
 }
 
+void mrb_exc_set(mrb_state *mrb, mrb_value exc);
+
 static void
 irep_error(mrb_state *mrb)
 {
-  mrb->exc = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, E_SCRIPT_ERROR, "irep load error"));
+  mrb_exc_set(mrb, mrb_exc_new_str_lit(mrb, E_SCRIPT_ERROR, "irep load error"));
 }
 
@@ -634,5 +636,5 @@
   mrb_irep_decref(mrb, irep);
   if (c && c->no_exec) return mrb_obj_value(proc);
-  return mrb_toplevel_run(mrb, proc);
+  return mrb_top_run(mrb, proc, mrb_top_self(mrb), 0);
 }
 
@@ -645,5 +647,5 @@
 #ifndef MRB_DISABLE_STDIO
 
-MRB_API mrb_irep*
+mrb_irep*
 mrb_read_irep_file(mrb_state *mrb, FILE* fp)
 {
@@ -696,5 +698,5 @@
   if (c && c->dump_result) mrb_codedump_all(mrb, proc);
   if (c && c->no_exec) return mrb_obj_value(proc);
-  val = mrb_toplevel_run(mrb, proc);
+  val = mrb_top_run(mrb, proc, mrb_top_self(mrb), 0);
   return val;
 }
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/mruby_core.rake
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/mruby_core.rake	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/mruby_core.rake	(revision 331)
@@ -5,9 +5,9 @@
 
   objs = Dir.glob("#{current_dir}/*.c").map { |f|
-    next nil if cxx_abi_enabled? and f =~ /(error|vm).c$/
+    next nil if cxx_exception_enabled? and f =~ /(error|vm).c$/
     objfile(f.pathmap("#{current_build_dir}/%n"))
   }.compact
 
-  if cxx_abi_enabled?
+  if cxx_exception_enabled?
     objs += %w(vm error).map { |v| compile_as_cxx "#{current_dir}/#{v}.c", "#{current_build_dir}/#{v}.cxx" }
   end
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/numeric.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/numeric.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/numeric.c	(revision 331)
@@ -10,10 +10,12 @@
 #include <stdlib.h>
 
-#include "mruby.h"
-#include "mruby/array.h"
-#include "mruby/numeric.h"
-#include "mruby/string.h"
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/numeric.h>
+#include <mruby/string.h>
+#include <mruby/class.h>
 
 #ifdef MRB_USE_FLOAT
+#define trunc(f) truncf(f)
 #define floor(f) floorf(f)
 #define ceil(f) ceilf(f)
@@ -51,12 +53,30 @@
 {
   mrb_value y;
-  mrb_float d, yv;
-
-  mrb_get_args(mrb, "o", &y);
-  yv = mrb_to_flo(mrb, y);
-  d = pow(mrb_to_flo(mrb, x), yv);
-  if (mrb_fixnum_p(x) && mrb_fixnum_p(y) && FIXABLE(d) && yv > 0 && 
-      (d < 0 || (d > 0 && (mrb_int)d > 0)))
-    return mrb_fixnum_value((mrb_int)d);
+  mrb_float d;
+
+  mrb_get_args(mrb, "o", &y);
+  if (mrb_fixnum_p(x) && mrb_fixnum_p(y)) {
+    /* try ipow() */
+    mrb_int base = mrb_fixnum(x);
+    mrb_int exp = mrb_fixnum(y);
+    mrb_int result = 1;
+
+    if (exp < 0) goto float_pow;
+    for (;;) {
+      if (exp & 1) {
+        if (mrb_int_mul_overflow(result, base, &result)) {
+          goto float_pow;
+        }
+      }
+      exp >>= 1;
+      if (exp == 0) break;
+      if (mrb_int_mul_overflow(base, base, &base)) {
+        goto float_pow;
+      }
+    }
+    return mrb_fixnum_value(result);
+  }
+ float_pow:
+  d = pow(mrb_to_flo(mrb, x), mrb_to_flo(mrb, y));
   return mrb_float_value(mrb, d);
 }
@@ -272,4 +292,126 @@
 }
 
+static int64_t
+value_int64(mrb_state *mrb, mrb_value x)
+{
+  switch (mrb_type(x)) {
+  case MRB_TT_FIXNUM:
+    return (int64_t)mrb_fixnum(x);
+    break;
+  case MRB_TT_FLOAT:
+    return (int64_t)mrb_float(x);
+  default:
+    mrb_raise(mrb, E_TYPE_ERROR, "cannot convert to Integer");
+    break;
+  }
+  /* not reached */
+  return 0;
+}
+
+static mrb_value
+int64_value(mrb_state *mrb, int64_t v)
+{
+  if (FIXABLE(v)) {
+    return mrb_fixnum_value((mrb_int)v);
+  }
+  return mrb_float_value(mrb, (mrb_float)v);
+}
+
+static mrb_value
+flo_rev(mrb_state *mrb, mrb_value x)
+{
+  int64_t v1;
+  mrb_get_args(mrb, "");
+  v1 = (int64_t)mrb_float(x);
+  return int64_value(mrb, ~v1);
+}
+
+static mrb_value
+flo_and(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+  int64_t v1, v2;
+  mrb_get_args(mrb, "o", &y);
+
+  v1 = (int64_t)mrb_float(x);
+  v2 = value_int64(mrb, y);
+  return int64_value(mrb, v1 & v2);
+}
+
+static mrb_value
+flo_or(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+  int64_t v1, v2;
+  mrb_get_args(mrb, "o", &y);
+
+  v1 = (int64_t)mrb_float(x);
+  v2 = value_int64(mrb, y);
+  return int64_value(mrb, v1 | v2);
+}
+
+static mrb_value
+flo_xor(mrb_state *mrb, mrb_value x)
+{
+  mrb_value y;
+  int64_t v1, v2;
+  mrb_get_args(mrb, "o", &y);
+
+  v1 = (int64_t)mrb_float(x);
+  v2 = value_int64(mrb, y);
+  return int64_value(mrb, v1 ^ v2);
+}
+
+static mrb_value
+flo_shift(mrb_state *mrb, mrb_value x, mrb_int width)
+{
+  mrb_float val;
+
+  if (width == 0) {
+    return x;
+  }
+  val = mrb_float(x);
+  if (width < 0) {
+    while (width++) {
+      val /= 2;
+    }
+#if defined(_ISOC99_SOURCE)
+    val = trunc(val);
+#else
+    val = val > 0 ? floor(val) : ceil(val);
+#endif
+    if (val == 0 && mrb_float(x) < 0) {
+      return mrb_fixnum_value(-1);
+    }
+  }
+  else {
+    while (width--) {
+      val *= 2;
+    }
+  }
+  if (FIXABLE_FLOAT(val)) {
+    return mrb_fixnum_value((mrb_int)val);
+  }
+  return mrb_float_value(mrb, val);
+}
+
+static mrb_value
+flo_lshift(mrb_state *mrb, mrb_value x)
+{
+  mrb_int width;
+
+  mrb_get_args(mrb, "i", &width);
+  return flo_shift(mrb, x, -width);
+}
+
+static mrb_value
+flo_rshift(mrb_state *mrb, mrb_value x)
+{
+  mrb_int width;
+
+  mrb_get_args(mrb, "i", &width);
+  return flo_shift(mrb, x, width);
+}
+
 /* 15.2.8.3.18 */
 /*
@@ -285,5 +427,5 @@
   char *c;
   size_t i;
-  int hash;
+  mrb_int hash;
 
   d = (mrb_float)mrb_fixnum(num);
@@ -291,5 +433,5 @@
   if (d == 0) d = 0.0;
   c = (char*)&d;
-  for (hash=0, i=0; i<sizeof(mrb_float);i++) {
+  for (hash=0,i=0; i<sizeof(mrb_float); i++) {
     hash = (hash * 971) ^ (unsigned char)c[i];
   }
@@ -351,4 +493,15 @@
 {
   return mrb_bool_value(isfinite(mrb_float(num)));
+}
+
+void
+mrb_check_num_exact(mrb_state *mrb, mrb_float num)
+{
+  if (isinf(num)) {
+    mrb_raise(mrb, E_FLOATDOMAIN_ERROR, num < 0 ? "-Infinity" : "Infinity");
+  }
+  if (isnan(num)) {
+    mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN");
+  }
 }
 
@@ -371,5 +524,6 @@
   mrb_float f = floor(mrb_float(num));
 
-  if (!FIXABLE(f)) {
+  mrb_check_num_exact(mrb, f);
+  if (!FIXABLE_FLOAT(f)) {
     return mrb_float_value(mrb, f);
   }
@@ -396,5 +550,6 @@
   mrb_float f = ceil(mrb_float(num));
 
-  if (!FIXABLE(f)) {
+  mrb_check_num_exact(mrb, f);
+  if (!FIXABLE_FLOAT(f)) {
     return mrb_float_value(mrb, f);
   }
@@ -443,12 +598,8 @@
   number = mrb_float(num);
 
-  if (isinf(number)) {
-    if (0 < ndigits) return num;
-    else mrb_raise(mrb, E_FLOATDOMAIN_ERROR, number < 0 ? "-Infinity" : "Infinity");
-  }
-  if (isnan(number)) {
-    if (0 < ndigits) return num;
-    else mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN");
-  }
+  if (0 < ndigits && (isinf(number) || isnan(number))) {
+    return num;
+  }
+  mrb_check_num_exact(mrb, number);
 
   f = 1.0;
@@ -506,5 +657,6 @@
   if (f < 0.0) f = ceil(f);
 
-  if (!FIXABLE(f)) {
+  mrb_check_num_exact(mrb, f);
+  if (!FIXABLE_FLOAT(f)) {
     return mrb_float_value(mrb, f);
   }
@@ -542,8 +694,4 @@
 }
 
-/*tests if N*N would overflow*/
-#define SQRT_INT_MAX ((mrb_int)1<<((MRB_INT_BIT-1-MRB_FIXNUM_SHIFT)/2))
-#define FIT_SQRT_INT(n) (((n)<SQRT_INT_MAX)&&((n)>=-SQRT_INT_MAX))
-
 mrb_value
 mrb_fixnum_mul(mrb_state *mrb, mrb_value x, mrb_value y)
@@ -553,16 +701,12 @@
   a = mrb_fixnum(x);
   if (mrb_fixnum_p(y)) {
-    mrb_float c;
-    mrb_int b;
+    mrb_int b, c;
 
     if (a == 0) return x;
     b = mrb_fixnum(y);
-    if (FIT_SQRT_INT(a) && FIT_SQRT_INT(b))
-      return mrb_fixnum_value(a*b);
-    c = a * b;
-    if ((a != 0 && c/a != b) || !FIXABLE(c)) {
-      return mrb_float_value(mrb, (mrb_float)a*(mrb_float)b);
-    }
-    return mrb_fixnum_value((mrb_int)c);
+    if (mrb_int_mul_overflow(a, b, &c)) {
+      return mrb_float_value(mrb, (mrb_float)a * (mrb_float)b);
+    }
+    return mrb_fixnum_value(c);
   }
   return mrb_float_value(mrb, (mrb_float)a * mrb_to_flo(mrb, y));
@@ -747,15 +891,11 @@
 }
 
-static mrb_value
-bit_coerce(mrb_state *mrb, mrb_value x)
-{
-  while (!mrb_fixnum_p(x)) {
-    if (mrb_float_p(x)) {
-      mrb_raise(mrb, E_TYPE_ERROR, "can't convert Float into Integer");
-    }
-    x = mrb_to_int(mrb, x);
-  }
-  return x;
-}
+static mrb_value flo_and(mrb_state *mrb, mrb_value x);
+static mrb_value flo_or(mrb_state *mrb, mrb_value x);
+static mrb_value flo_xor(mrb_state *mrb, mrb_value x);
+#define bit_op(x,y,op1,op2) do {\
+  if (mrb_fixnum_p(y)) return mrb_fixnum_value(mrb_fixnum(x) op2 mrb_fixnum(y));\
+  return flo_ ## op1(mrb, mrb_float_value(mrb, mrb_fixnum(x)));\
+} while(0)
 
 /* 15.2.8.3.9  */
@@ -773,7 +913,5 @@
 
   mrb_get_args(mrb, "o", &y);
-
-  y = bit_coerce(mrb, y);
-  return mrb_fixnum_value(mrb_fixnum(x) & mrb_fixnum(y));
+  bit_op(x, y, and, &);
 }
 
@@ -792,7 +930,5 @@
 
   mrb_get_args(mrb, "o", &y);
-
-  y = bit_coerce(mrb, y);
-  return mrb_fixnum_value(mrb_fixnum(x) | mrb_fixnum(y));
+  bit_op(x, y, or, |);
 }
 
@@ -811,7 +947,5 @@
 
   mrb_get_args(mrb, "o", &y);
-
-  y = bit_coerce(mrb, y);
-  return mrb_fixnum_value(mrb_fixnum(x) ^ mrb_fixnum(y));
+  bit_op(x, y, or, ^);
 }
 
@@ -821,6 +955,24 @@
 lshift(mrb_state *mrb, mrb_int val, mrb_int width)
 {
-  mrb_assert(width > 0);
-  if (width > NUMERIC_SHIFT_WIDTH_MAX) {
+  if (width < 0) {              /* mrb_int overflow */
+    return mrb_float_value(mrb, INFINITY);
+  }
+  if (val > 0) {
+    if ((width > NUMERIC_SHIFT_WIDTH_MAX) ||
+        (val   > (MRB_INT_MAX >> width))) {
+      goto bit_overflow;
+    }
+  }
+  else {
+    if ((width > NUMERIC_SHIFT_WIDTH_MAX) ||
+        (val   < (MRB_INT_MIN >> width))) {
+      goto bit_overflow;
+    }
+  }
+
+  return mrb_fixnum_value(val << width);
+
+bit_overflow:
+  {
     mrb_float f = (mrb_float)val;
     while (width--) {
@@ -829,5 +981,4 @@
     return mrb_float_value(mrb, f);
   }
-  return mrb_fixnum_value(val << width);
 }
 
@@ -835,5 +986,7 @@
 rshift(mrb_int val, mrb_int width)
 {
-  mrb_assert(width > 0);
+  if (width < 0) {              /* mrb_int overflow */
+    return mrb_fixnum_value(0);
+  }
   if (width >= NUMERIC_SHIFT_WIDTH_MAX) {
     if (val < 0) {
@@ -845,13 +998,4 @@
 }
 
-static inline void
-fix_shift_get_width(mrb_state *mrb, mrb_int *width)
-{
-  mrb_value y;
-
-  mrb_get_args(mrb, "o", &y);
-  *width = mrb_fixnum(bit_coerce(mrb, y));
-}
-
 /* 15.2.8.3.12 */
 /*
@@ -867,10 +1011,10 @@
   mrb_int width, val;
 
-  fix_shift_get_width(mrb, &width);
-
+  mrb_get_args(mrb, "i", &width);
   if (width == 0) {
     return x;
   }
   val = mrb_fixnum(x);
+  if (val == 0) return x;
   if (width < 0) {
     return rshift(val, -width);
@@ -892,10 +1036,10 @@
   mrb_int width, val;
 
-  fix_shift_get_width(mrb, &width);
-
+  mrb_get_args(mrb, "i", &width);
   if (width == 0) {
     return x;
   }
   val = mrb_fixnum(x);
+  if (val == 0) return x;
   if (width < 0) {
     return lshift(mrb, val, -width);
@@ -936,5 +1080,5 @@
 mrb_flo_to_fixnum(mrb_state *mrb, mrb_value x)
 {
-  mrb_int z;
+  mrb_int z = 0;
 
   if (!mrb_float_p(x)) {
@@ -951,5 +1095,10 @@
       mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN");
     }
-    z = (mrb_int)d;
+    if (FIXABLE_FLOAT(d)) {
+      z = (mrb_int)d;
+    }
+    else {
+      mrb_raisef(mrb, E_ARGUMENT_ERROR, "number (%S) too big for integer", x);
+    }
   }
   return mrb_fixnum_value(z);
@@ -1150,58 +1299,70 @@
   numeric = mrb_define_class(mrb, "Numeric",  mrb->object_class);                /* 15.2.7 */
 
-  mrb_define_method(mrb, numeric, "**",       num_pow,        MRB_ARGS_REQ(1));
-  mrb_define_method(mrb, numeric, "/",        num_div,        MRB_ARGS_REQ(1));  /* 15.2.8.3.4  */
-  mrb_define_method(mrb, numeric, "quo",      num_div,        MRB_ARGS_REQ(1));  /* 15.2.7.4.5 (x) */
-  mrb_define_method(mrb, numeric, "<=>",      num_cmp,        MRB_ARGS_REQ(1));  /* 15.2.9.3.6  */
+  mrb_define_method(mrb, numeric, "**",       num_pow,         MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, numeric, "/",        num_div,         MRB_ARGS_REQ(1)); /* 15.2.8.3.4  */
+  mrb_define_method(mrb, numeric, "quo",      num_div,         MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */
+  mrb_define_method(mrb, numeric, "<=>",      num_cmp,         MRB_ARGS_REQ(1)); /* 15.2.9.3.6  */
 
   /* Integer Class */
   integer = mrb_define_class(mrb, "Integer",  numeric);                          /* 15.2.8 */
+  MRB_SET_INSTANCE_TT(integer, MRB_TT_FIXNUM);
   mrb_undef_class_method(mrb, integer, "new");
-  mrb_define_method(mrb, integer, "to_i", int_to_i, MRB_ARGS_NONE());            /* 15.2.8.3.24 */
-  mrb_define_method(mrb, integer, "to_int", int_to_i, MRB_ARGS_NONE());
+  mrb_define_method(mrb, integer, "to_i",     int_to_i,        MRB_ARGS_NONE()); /* 15.2.8.3.24 */
+  mrb_define_method(mrb, integer, "to_int",   int_to_i,        MRB_ARGS_NONE());
+  mrb_define_method(mrb, integer, "ceil",     int_to_i,        MRB_ARGS_REQ(1)); /* 15.2.8.3.8 (x) */
+  mrb_define_method(mrb, integer, "floor",    int_to_i,        MRB_ARGS_REQ(1)); /* 15.2.8.3.10 (x) */
+  mrb_define_method(mrb, integer, "round",    int_to_i,        MRB_ARGS_REQ(1)); /* 15.2.8.3.12 (x) */
+  mrb_define_method(mrb, integer, "truncate", int_to_i,        MRB_ARGS_REQ(1)); /* 15.2.8.3.15 (x) */
 
   /* Fixnum Class */
   mrb->fixnum_class = fixnum = mrb_define_class(mrb, "Fixnum", integer);
-  mrb_define_method(mrb, fixnum,  "+",        fix_plus,          MRB_ARGS_REQ(1)); /* 15.2.8.3.1  */
-  mrb_define_method(mrb, fixnum,  "-",        fix_minus,         MRB_ARGS_REQ(1)); /* 15.2.8.3.2  */
-  mrb_define_method(mrb, fixnum,  "*",        fix_mul,           MRB_ARGS_REQ(1)); /* 15.2.8.3.3  */
-  mrb_define_method(mrb, fixnum,  "%",        fix_mod,           MRB_ARGS_REQ(1)); /* 15.2.8.3.5  */
-  mrb_define_method(mrb, fixnum,  "==",       fix_equal,         MRB_ARGS_REQ(1)); /* 15.2.8.3.7  */
-  mrb_define_method(mrb, fixnum,  "~",        fix_rev,           MRB_ARGS_NONE()); /* 15.2.8.3.8  */
-  mrb_define_method(mrb, fixnum,  "&",        fix_and,           MRB_ARGS_REQ(1)); /* 15.2.8.3.9  */
-  mrb_define_method(mrb, fixnum,  "|",        fix_or,            MRB_ARGS_REQ(1)); /* 15.2.8.3.10 */
-  mrb_define_method(mrb, fixnum,  "^",        fix_xor,           MRB_ARGS_REQ(1)); /* 15.2.8.3.11 */
-  mrb_define_method(mrb, fixnum,  "<<",       fix_lshift,        MRB_ARGS_REQ(1)); /* 15.2.8.3.12 */
-  mrb_define_method(mrb, fixnum,  ">>",       fix_rshift,        MRB_ARGS_REQ(1)); /* 15.2.8.3.13 */
-  mrb_define_method(mrb, fixnum,  "eql?",     fix_eql,           MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */
-  mrb_define_method(mrb, fixnum,  "hash",     flo_hash,          MRB_ARGS_NONE()); /* 15.2.8.3.18 */
-  mrb_define_method(mrb, fixnum,  "to_f",     fix_to_f,          MRB_ARGS_NONE()); /* 15.2.8.3.23 */
-  mrb_define_method(mrb, fixnum,  "to_s",     fix_to_s,          MRB_ARGS_NONE()); /* 15.2.8.3.25 */
-  mrb_define_method(mrb, fixnum,  "inspect",  fix_to_s,          MRB_ARGS_NONE());
-  mrb_define_method(mrb, fixnum,  "divmod",   fix_divmod,        MRB_ARGS_REQ(1)); /* 15.2.8.3.30 (x) */
+  mrb_define_method(mrb, fixnum,  "+",        fix_plus,        MRB_ARGS_REQ(1)); /* 15.2.8.3.1  */
+  mrb_define_method(mrb, fixnum,  "-",        fix_minus,       MRB_ARGS_REQ(1)); /* 15.2.8.3.2  */
+  mrb_define_method(mrb, fixnum,  "*",        fix_mul,         MRB_ARGS_REQ(1)); /* 15.2.8.3.3  */
+  mrb_define_method(mrb, fixnum,  "%",        fix_mod,         MRB_ARGS_REQ(1)); /* 15.2.8.3.5  */
+  mrb_define_method(mrb, fixnum,  "==",       fix_equal,       MRB_ARGS_REQ(1)); /* 15.2.8.3.7  */
+  mrb_define_method(mrb, fixnum,  "~",        fix_rev,         MRB_ARGS_NONE()); /* 15.2.8.3.8  */
+  mrb_define_method(mrb, fixnum,  "&",        fix_and,         MRB_ARGS_REQ(1)); /* 15.2.8.3.9  */
+  mrb_define_method(mrb, fixnum,  "|",        fix_or,          MRB_ARGS_REQ(1)); /* 15.2.8.3.10 */
+  mrb_define_method(mrb, fixnum,  "^",        fix_xor,         MRB_ARGS_REQ(1)); /* 15.2.8.3.11 */
+  mrb_define_method(mrb, fixnum,  "<<",       fix_lshift,      MRB_ARGS_REQ(1)); /* 15.2.8.3.12 */
+  mrb_define_method(mrb, fixnum,  ">>",       fix_rshift,      MRB_ARGS_REQ(1)); /* 15.2.8.3.13 */
+  mrb_define_method(mrb, fixnum,  "eql?",     fix_eql,         MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */
+  mrb_define_method(mrb, fixnum,  "hash",     flo_hash,        MRB_ARGS_NONE()); /* 15.2.8.3.18 */
+  mrb_define_method(mrb, fixnum,  "to_f",     fix_to_f,        MRB_ARGS_NONE()); /* 15.2.8.3.23 */
+  mrb_define_method(mrb, fixnum,  "to_s",     fix_to_s,        MRB_ARGS_NONE()); /* 15.2.8.3.25 */
+  mrb_define_method(mrb, fixnum,  "inspect",  fix_to_s,        MRB_ARGS_NONE());
+  mrb_define_method(mrb, fixnum,  "divmod",   fix_divmod,      MRB_ARGS_REQ(1)); /* 15.2.8.3.30 (x) */
 
   /* Float Class */
   mrb->float_class = fl = mrb_define_class(mrb, "Float", numeric);                 /* 15.2.9 */
+  MRB_SET_INSTANCE_TT(fl, MRB_TT_FLOAT);
   mrb_undef_class_method(mrb,  fl, "new");
-  mrb_define_method(mrb, fl,      "+",         flo_plus,         MRB_ARGS_REQ(1)); /* 15.2.9.3.1  */
-  mrb_define_method(mrb, fl,      "-",         flo_minus,        MRB_ARGS_REQ(1)); /* 15.2.9.3.2  */
-  mrb_define_method(mrb, fl,      "*",         flo_mul,          MRB_ARGS_REQ(1)); /* 15.2.9.3.3  */
-  mrb_define_method(mrb, fl,      "%",         flo_mod,          MRB_ARGS_REQ(1)); /* 15.2.9.3.5  */
-  mrb_define_method(mrb, fl,      "==",        flo_eq,           MRB_ARGS_REQ(1)); /* 15.2.9.3.7  */
-  mrb_define_method(mrb, fl,      "ceil",      flo_ceil,         MRB_ARGS_NONE()); /* 15.2.9.3.8  */
-  mrb_define_method(mrb, fl,      "finite?",   flo_finite_p,     MRB_ARGS_NONE()); /* 15.2.9.3.9  */
-  mrb_define_method(mrb, fl,      "floor",     flo_floor,        MRB_ARGS_NONE()); /* 15.2.9.3.10 */
-  mrb_define_method(mrb, fl,      "infinite?", flo_infinite_p,   MRB_ARGS_NONE()); /* 15.2.9.3.11 */
-  mrb_define_method(mrb, fl,      "round",     flo_round,        MRB_ARGS_OPT(1)); /* 15.2.9.3.12 */
-  mrb_define_method(mrb, fl,      "to_f",      flo_to_f,         MRB_ARGS_NONE()); /* 15.2.9.3.13 */
-  mrb_define_method(mrb, fl,      "to_i",      flo_truncate,     MRB_ARGS_NONE()); /* 15.2.9.3.14 */
-  mrb_define_method(mrb, fl,      "to_int",    flo_truncate,     MRB_ARGS_NONE());
-  mrb_define_method(mrb, fl,      "truncate",  flo_truncate,     MRB_ARGS_NONE()); /* 15.2.9.3.15 */
-  mrb_define_method(mrb, fl,      "divmod",    flo_divmod,       MRB_ARGS_REQ(1));
-  mrb_define_method(mrb, fl,      "eql?",      flo_eql,          MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */
-
-  mrb_define_method(mrb, fl,      "to_s",      flo_to_s,         MRB_ARGS_NONE()); /* 15.2.9.3.16(x) */
-  mrb_define_method(mrb, fl,      "inspect",   flo_to_s,         MRB_ARGS_NONE());
-  mrb_define_method(mrb, fl,      "nan?",      flo_nan_p,        MRB_ARGS_NONE());
+  mrb_define_method(mrb, fl,      "+",         flo_plus,       MRB_ARGS_REQ(1)); /* 15.2.9.3.1  */
+  mrb_define_method(mrb, fl,      "-",         flo_minus,      MRB_ARGS_REQ(1)); /* 15.2.9.3.2  */
+  mrb_define_method(mrb, fl,      "*",         flo_mul,        MRB_ARGS_REQ(1)); /* 15.2.9.3.3  */
+  mrb_define_method(mrb, fl,      "%",         flo_mod,        MRB_ARGS_REQ(1)); /* 15.2.9.3.5  */
+  mrb_define_method(mrb, fl,      "==",        flo_eq,         MRB_ARGS_REQ(1)); /* 15.2.9.3.7  */
+  mrb_define_method(mrb, fl,      "~",         flo_rev,        MRB_ARGS_NONE());
+  mrb_define_method(mrb, fl,      "&",         flo_and,        MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, fl,      "|",         flo_or,         MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, fl,      "^",         flo_xor,        MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, fl,      ">>",        flo_lshift,     MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, fl,      "<<",        flo_rshift,     MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, fl,      "ceil",      flo_ceil,       MRB_ARGS_NONE()); /* 15.2.9.3.8  */
+  mrb_define_method(mrb, fl,      "finite?",   flo_finite_p,   MRB_ARGS_NONE()); /* 15.2.9.3.9  */
+  mrb_define_method(mrb, fl,      "floor",     flo_floor,      MRB_ARGS_NONE()); /* 15.2.9.3.10 */
+  mrb_define_method(mrb, fl,      "infinite?", flo_infinite_p, MRB_ARGS_NONE()); /* 15.2.9.3.11 */
+  mrb_define_method(mrb, fl,      "round",     flo_round,      MRB_ARGS_OPT(1)); /* 15.2.9.3.12 */
+  mrb_define_method(mrb, fl,      "to_f",      flo_to_f,       MRB_ARGS_NONE()); /* 15.2.9.3.13 */
+  mrb_define_method(mrb, fl,      "to_i",      flo_truncate,   MRB_ARGS_NONE()); /* 15.2.9.3.14 */
+  mrb_define_method(mrb, fl,      "to_int",    flo_truncate,   MRB_ARGS_NONE());
+  mrb_define_method(mrb, fl,      "truncate",  flo_truncate,   MRB_ARGS_NONE()); /* 15.2.9.3.15 */
+  mrb_define_method(mrb, fl,      "divmod",    flo_divmod,     MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, fl,      "eql?",      flo_eql,        MRB_ARGS_REQ(1)); /* 15.2.8.3.16 */
+
+  mrb_define_method(mrb, fl,      "to_s",      flo_to_s,       MRB_ARGS_NONE()); /* 15.2.9.3.16(x) */
+  mrb_define_method(mrb, fl,      "inspect",   flo_to_s,       MRB_ARGS_NONE());
+  mrb_define_method(mrb, fl,      "nan?",      flo_nan_p,      MRB_ARGS_NONE());
 
 #ifdef INFINITY
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/object.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/object.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/object.c	(revision 331)
@@ -5,8 +5,9 @@
 */
 
-#include "mruby.h"
-#include "mruby/class.h"
-#include "mruby/numeric.h"
-#include "mruby/string.h"
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/numeric.h>
+#include <mruby/string.h>
+#include <mruby/class.h>
 
 MRB_API mrb_bool
@@ -266,4 +267,5 @@
 
   mrb->nil_class   = n = mrb_define_class(mrb, "NilClass",   mrb->object_class);
+  MRB_SET_INSTANCE_TT(n, MRB_TT_TRUE);
   mrb_undef_class_method(mrb, n, "new");
   mrb_define_method(mrb, n, "&",    false_and,      MRB_ARGS_REQ(1));  /* 15.2.4.3.1  */
@@ -275,4 +277,5 @@
 
   mrb->true_class  = t = mrb_define_class(mrb, "TrueClass",  mrb->object_class);
+  MRB_SET_INSTANCE_TT(t, MRB_TT_TRUE);
   mrb_undef_class_method(mrb, t, "new");
   mrb_define_method(mrb, t, "&",    true_and,       MRB_ARGS_REQ(1));  /* 15.2.5.3.1  */
@@ -283,4 +286,5 @@
 
   mrb->false_class = f = mrb_define_class(mrb, "FalseClass", mrb->object_class);
+  MRB_SET_INSTANCE_TT(f, MRB_TT_TRUE);
   mrb_undef_class_method(mrb, f, "new");
   mrb_define_method(mrb, f, "&",    false_and,      MRB_ARGS_REQ(1));  /* 15.2.6.3.1  */
@@ -349,5 +353,5 @@
   mrb_value v;
 
-  if (mrb_type(val) == type && type != MRB_TT_DATA) return val;
+  if (mrb_type(val) == type && type != MRB_TT_DATA && type != MRB_TT_ISTRUCT) return val;
   v = convert_type(mrb, val, tname, method, FALSE);
   if (mrb_nil_p(v) || mrb_type(v) != type) return mrb_nil_value();
@@ -381,5 +385,5 @@
 /*    {MRB_TT_NODE,  "Node"}, */ /* internal use: syntax tree node */
 /*    {MRB_TT_UNDEF,  "undef"}, */ /* internal use: #undef; should not happen */
-    {-1,  0}
+  {MRB_TT_MAXDEFINE,  0}
 };
 
@@ -391,5 +395,5 @@
 
   xt = mrb_type(x);
-  if ((xt != t) || (xt == MRB_TT_DATA)) {
+  if ((xt != t) || (xt == MRB_TT_DATA) || (xt == MRB_TT_ISTRUCT)) {
     while (type->type < MRB_TT_MAXDEFINE) {
       if (type->type == t) {
@@ -441,5 +445,5 @@
   mrb_str_cat_cstr(mrb, str, cname);
   mrb_str_cat_lit(mrb, str, ":");
-  mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(obj)));
+  mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_ptr(obj)));
   mrb_str_cat_lit(mrb, str, ">");
 
@@ -482,4 +486,5 @@
     case MRB_TT_CLASS:
     case MRB_TT_ICLASS:
+    case MRB_TT_SCLASS:
       break;
 
@@ -530,6 +535,9 @@
     case MRB_TT_FLOAT:
       if (base != 0) goto arg_error;
-      if (FIXABLE(mrb_float(val))) {
-        break;
+      else {
+        mrb_float f = mrb_float(val);
+        if (FIXABLE_FLOAT(f)) {
+          break;
+        }
       }
       return mrb_flo_to_fixnum(mrb, val);
@@ -549,4 +557,5 @@
     tmp = mrb_check_string_type(mrb, val);
     if (!mrb_nil_p(tmp)) {
+      val = tmp;
       goto string_conv;
     }
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/opcode.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/opcode.h	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/opcode.h	(revision 331)
@@ -1,2 +1,2 @@
 /* this header file is to be removed soon. */
-#include "mruby/opcode.h"
+#include <mruby/opcode.h>
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/pool.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/pool.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/pool.c	(revision 331)
@@ -8,5 +8,5 @@
 #include <stdint.h>
 #include <string.h>
-#include "mruby.h"
+#include <mruby.h>
 
 /* configuration section */
@@ -14,5 +14,9 @@
 /* or undef it if alignment does not matter */
 #ifndef POOL_ALIGNMENT
+#if INTPTR_MAX == INT64_MAX
+#define POOL_ALIGNMENT 8
+#else
 #define POOL_ALIGNMENT 4
+#endif
 #endif
 /* page size of memory pool */
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/print.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/print.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/print.c	(revision 331)
@@ -5,7 +5,7 @@
 */
 
-#include "mruby.h"
-#include "mruby/string.h"
-#include "mruby/variable.h"
+#include <mruby.h>
+#include <mruby/string.h>
+#include <mruby/variable.h>
 
 #ifndef MRB_DISABLE_STDIO
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/proc.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/proc.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/proc.c	(revision 331)
@@ -5,8 +5,8 @@
 */
 
-#include "mruby.h"
-#include "mruby/class.h"
-#include "mruby/proc.h"
-#include "mruby/opcode.h"
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/proc.h>
+#include <mruby/opcode.h>
 
 static mrb_code call_iseq[] = {
@@ -42,5 +42,5 @@
   e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->c->ci->proc->env);
   MRB_SET_ENV_STACK_LEN(e, nlocals);
-  e->mid = mrb->c->ci->mid;
+  e->cxt.c = mrb->c;
   e->cioff = mrb->c->ci - mrb->c->cibase;
   e->stack = mrb->c->stack;
@@ -62,4 +62,5 @@
   }
   p->env = e;
+  mrb_field_write_barrier(mrb, (struct RBasic *)p, (struct RBasic *)p->env);
 }
 
@@ -136,10 +137,10 @@
 }
 
-MRB_API void
+void
 mrb_proc_copy(struct RProc *a, struct RProc *b)
 {
   a->flags = b->flags;
   a->body = b->body;
-  if (!MRB_PROC_CFUNC_P(a)) {
+  if (!MRB_PROC_CFUNC_P(a) && a->body.irep) {
     a->body.irep->refcnt++;
   }
@@ -149,7 +150,9 @@
 
 static mrb_value
-mrb_proc_initialize(mrb_state *mrb, mrb_value self)
+mrb_proc_s_new(mrb_state *mrb, mrb_value proc_class)
 {
   mrb_value blk;
+  mrb_value proc;
+  struct RProc *p;
 
   mrb_get_args(mrb, "&", &blk);
@@ -158,8 +161,9 @@
     mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block");
   }
-  else {
-    mrb_proc_copy(mrb_proc_ptr(self), mrb_proc_ptr(blk));
-  }
-  return self;
+  p = (struct RProc *)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb_class_ptr(proc_class));
+  mrb_proc_copy(p, mrb_proc_ptr(blk));
+  proc = mrb_obj_value(p);
+  mrb_funcall_with_block(mrb, proc, mrb_intern_lit(mrb, "initialize"), 0, NULL, blk);
+  return proc;
 }
 
@@ -189,10 +193,4 @@
 }
 
-mrb_code*
-mrb_proc_iseq(mrb_state *mrb, struct RProc *p)
-{
-  return p->body.irep->iseq;
-}
-
 /* 15.2.17.4.2 */
 static mrb_value
@@ -200,5 +198,6 @@
 {
   struct RProc *p = mrb_proc_ptr(self);
-  mrb_code *iseq = mrb_proc_iseq(mrb, p);
+  struct mrb_irep *irep;
+  mrb_code *iseq;
   mrb_aspec aspec;
   int ma, op, ra, pa, arity;
@@ -209,4 +208,10 @@
   }
 
+  irep = p->body.irep;
+  if (!irep) {
+    return mrb_fixnum_value(0);
+  }
+
+  iseq = irep->iseq;
   /* arity is depend on OP_ENTER */
   if (GET_OPCODE(*iseq) != OP_ENTER) {
@@ -267,6 +272,7 @@
   call_irep->iseq = call_iseq;
   call_irep->ilen = 1;
-
-  mrb_define_method(mrb, mrb->proc_class, "initialize", mrb_proc_initialize, MRB_ARGS_NONE());
+  call_irep->nregs = 2;         /* receiver and block */
+
+  mrb_define_class_method(mrb, mrb->proc_class, "new", mrb_proc_s_new, MRB_ARGS_ANY());
   mrb_define_method(mrb, mrb->proc_class, "initialize_copy", mrb_proc_init_copy, MRB_ARGS_REQ(1));
   mrb_define_method(mrb, mrb->proc_class, "arity", mrb_proc_arity, MRB_ARGS_NONE());
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/range.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/range.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/range.c	(revision 331)
@@ -5,11 +5,22 @@
 */
 
-#include "mruby.h"
-#include "mruby/class.h"
-#include "mruby/range.h"
-#include "mruby/string.h"
-#include "mruby/array.h"
+#include <mruby.h>
+#include <mruby/class.h>
+#include <mruby/range.h>
+#include <mruby/string.h>
+#include <mruby/array.h>
 
 #define RANGE_CLASS (mrb_class_get(mrb, "Range"))
+
+MRB_API struct RRange*
+mrb_range_ptr(mrb_state *mrb, mrb_value v)
+{
+  struct RRange *r = (struct RRange*)mrb_ptr(v);
+
+  if (r->edges == NULL) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized range");
+  }
+  return r;
+}
 
 static void
@@ -58,5 +69,5 @@
 mrb_range_beg(mrb_state *mrb, mrb_value range)
 {
-  struct RRange *r = mrb_range_ptr(range);
+  struct RRange *r = mrb_range_ptr(mrb, range);
 
   return r->edges->beg;
@@ -77,5 +88,5 @@
 mrb_range_end(mrb_state *mrb, mrb_value range)
 {
-  struct RRange *r = mrb_range_ptr(range);
+  struct RRange *r = mrb_range_ptr(mrb, range);
 
   return r->edges->end;
@@ -91,5 +102,5 @@
 mrb_range_excl(mrb_state *mrb, mrb_value range)
 {
-  struct RRange *r = mrb_range_ptr(range);
+  struct RRange *r = mrb_range_ptr(mrb, range);
 
   return mrb_bool_value(r->excl);
@@ -99,5 +110,5 @@
 range_init(mrb_state *mrb, mrb_value range, mrb_value beg, mrb_value end, mrb_bool exclude_end)
 {
-  struct RRange *r = mrb_range_ptr(range);
+  struct RRange *r = mrb_range_raw_ptr(range);
 
   range_check(mrb, beg, end);
@@ -130,4 +141,7 @@
   }
   /* Ranges are immutable, so that they should be initialized only once. */
+  if (mrb_range_raw_ptr(range)->edges) {
+    mrb_name_error(mrb, mrb_intern_lit(mrb, "initialize"), "`initialize' called twice");
+  }
   range_init(mrb, range, beg, end, exclusive);
   return range;
@@ -153,5 +167,5 @@
   struct RRange *rr;
   struct RRange *ro;
-  mrb_value obj;
+  mrb_value obj, v1, v2;
 
   mrb_get_args(mrb, "o", &obj);
@@ -162,9 +176,9 @@
   }
 
-  rr = mrb_range_ptr(range);
-  ro = mrb_range_ptr(obj);
-  if (!mrb_bool(mrb_funcall(mrb, rr->edges->beg, "==", 1, ro->edges->beg)) ||
-      !mrb_bool(mrb_funcall(mrb, rr->edges->end, "==", 1, ro->edges->end)) ||
-      rr->excl != ro->excl) {
+  rr = mrb_range_ptr(mrb, range);
+  ro = mrb_range_ptr(mrb, obj);
+  v1 = mrb_funcall(mrb, rr->edges->beg, "==", 1, ro->edges->beg);
+  v2 = mrb_funcall(mrb, rr->edges->end, "==", 1, ro->edges->end);
+  if (!mrb_bool(v1) || !mrb_bool(v2) || rr->excl != ro->excl) {
     return mrb_false_value();
   }
@@ -220,5 +234,5 @@
 {
   mrb_value val;
-  struct RRange *r = mrb_range_ptr(range);
+  struct RRange *r = mrb_range_ptr(mrb, range);
   mrb_value beg, end;
   mrb_bool include_p;
@@ -228,18 +242,19 @@
   beg = r->edges->beg;
   end = r->edges->end;
-  include_p = r_le(mrb, beg, val) && /* beg <= val */
-              ((r->excl && r_gt(mrb, end, val)) || /* end >  val */
-              (r_ge(mrb, end, val))); /* end >= val */
+  include_p = r_le(mrb, beg, val) &&           /* beg <= val */
+              (r->excl ? r_gt(mrb, end, val)   /* end >  val */
+                       : r_ge(mrb, end, val)); /* end >= val */
 
   return mrb_bool_value(include_p);
 }
 
-static mrb_bool
-range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc)
+MRB_API mrb_int
+mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc)
 {
   mrb_int beg, end;
-  struct RRange *r = mrb_range_ptr(range);
-
-  if (mrb_type(range) != MRB_TT_RANGE) return FALSE;
+  struct RRange *r;
+
+  if (mrb_type(range) != MRB_TT_RANGE) return 0;
+  r = mrb_range_ptr(mrb, range);
 
   beg = mrb_int(mrb, r->edges->beg);
@@ -248,9 +263,9 @@
   if (beg < 0) {
     beg += len;
-    if (beg < 0) return FALSE;
+    if (beg < 0) return 2;
   }
 
   if (trunc) {
-    if (beg > len) return FALSE;
+    if (beg > len) return 2;
     if (end > len) end = len;
   }
@@ -264,11 +279,5 @@
   *begp = beg;
   *lenp = len;
-  return TRUE;
-}
-
-MRB_API mrb_bool
-mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len)
-{
-  return range_beg_len(mrb, range, begp, lenp, len, TRUE);
+  return 1;
 }
 
@@ -285,5 +294,5 @@
 {
   mrb_value str, str2;
-  struct RRange *r = mrb_range_ptr(range);
+  struct RRange *r = mrb_range_ptr(mrb, range);
 
   str  = mrb_obj_as_string(mrb, r->edges->beg);
@@ -310,5 +319,5 @@
 {
   mrb_value str, str2;
-  struct RRange *r = mrb_range_ptr(range);
+  struct RRange *r = mrb_range_ptr(mrb, range);
 
   str  = mrb_inspect(mrb, r->edges->beg);
@@ -350,6 +359,6 @@
   if (mrb_type(obj) != MRB_TT_RANGE) return mrb_false_value();
 
-  r = mrb_range_ptr(range);
-  o = mrb_range_ptr(obj);
+  r = mrb_range_ptr(mrb, range);
+  o = mrb_range_ptr(mrb, obj);
   if (!mrb_eql(mrb, r->edges->beg, o->edges->beg) ||
       !mrb_eql(mrb, r->edges->end, o->edges->end) ||
@@ -374,5 +383,5 @@
   }
 
-  r = mrb_range_ptr(src);
+  r = mrb_range_ptr(mrb, src);
   range_init(mrb, copy, r->edges->beg, r->edges->end, r->excl);
 
@@ -391,5 +400,5 @@
       mrb_ary_push(mrb, result, func(mrb, obj, mrb_fixnum(argv[i])));
     }
-    else if (range_beg_len(mrb, argv[i], &beg, &len, olen, FALSE)) {
+    else if (mrb_range_beg_len(mrb, argv[i], &beg, &len, olen, FALSE) == 1) {
       mrb_int const end = olen < beg + len ? olen : beg + len;
       for (j = beg; j < end; ++j) {
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/state.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/state.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/state.c	(revision 331)
@@ -7,9 +7,9 @@
 #include <stdlib.h>
 #include <string.h>
-#include "mruby.h"
-#include "mruby/irep.h"
-#include "mruby/variable.h"
-#include "mruby/debug.h"
-#include "mruby/string.h"
+#include <mruby.h>
+#include <mruby/irep.h>
+#include <mruby/variable.h>
+#include <mruby/debug.h>
+#include <mruby/string.h>
 
 void mrb_init_core(mrb_state*);
@@ -142,5 +142,5 @@
   if (!(irep->flags & MRB_ISEQ_NO_FREE))
     mrb_free(mrb, irep->iseq);
-  for (i=0; i<irep->plen; i++) {
+  if (irep->pool) for (i=0; i<irep->plen; i++) {
     if (mrb_type(irep->pool[i]) == MRB_TT_STRING) {
       mrb_gc_free_str(mrb, RSTRING(irep->pool[i]));
@@ -160,5 +160,7 @@
   mrb_free(mrb, irep->reps);
   mrb_free(mrb, irep->lv);
-  mrb_free(mrb, (void *)irep->filename);
+  if (irep->own_filename) {
+    mrb_free(mrb, (void *)irep->filename);
+  }
   mrb_free(mrb, irep->lines);
   mrb_debug_info_free(mrb, irep->debug_info);
@@ -216,4 +218,6 @@
 }
 
+void mrb_free_backtrace(mrb_state *mrb);
+
 MRB_API void
 mrb_free_context(mrb_state *mrb, struct mrb_context *c)
@@ -259,4 +263,5 @@
   *irep = mrb_irep_zero;
   irep->refcnt = 1;
+  irep->own_filename = FALSE;
 
   return irep;
@@ -287,5 +292,6 @@
   if (mrb->atexit_stack_len == 0) {
     mrb->atexit_stack = (mrb_atexit_func*)mrb_malloc(mrb, stack_size);
-  } else {
+  }
+  else {
     mrb->atexit_stack = (mrb_atexit_func*)mrb_realloc(mrb, mrb->atexit_stack, stack_size);
   }
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/string.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/string.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/string.c	(revision 331)
@@ -4,4 +4,8 @@
 ** See Copyright Notice in mruby.h
 */
+
+#ifdef _MSC_VER
+# define _CRT_NONSTDC_NO_DEPRECATE
+#endif
 
 #include <float.h>
@@ -10,10 +14,10 @@
 #include <stdlib.h>
 #include <string.h>
-#include "mruby.h"
-#include "mruby/array.h"
-#include "mruby/class.h"
-#include "mruby/range.h"
-#include "mruby/string.h"
-#include "mruby/re.h"
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/class.h>
+#include <mruby/range.h>
+#include <mruby/string.h>
+#include <mruby/re.h>
 
 typedef struct mrb_shared_string {
@@ -60,5 +64,6 @@
       memcpy(s->as.ary, p, len);
     }
-  } else {
+  }
+  else {
     if (len >= MRB_INT_MAX) {
       mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
@@ -115,7 +120,10 @@
 }
 
-static inline void
-resize_capa(mrb_state *mrb, struct RString *s, mrb_int capacity)
-{
+static void
+resize_capa(mrb_state *mrb, struct RString *s, size_t capacity)
+{
+#if SIZE_MAX > MRB_INT_MAX
+    mrb_assert(capacity < MRB_INT_MAX);
+#endif
   if (RSTR_EMBED_P(s)) {
     if (RSTRING_EMBED_LEN_MAX < capacity) {
@@ -126,10 +134,10 @@
       s->as.heap.ptr = tmp;
       s->as.heap.len = len;
-      s->as.heap.aux.capa = capacity;
+      s->as.heap.aux.capa = (mrb_int)capacity;
     }
   }
   else {
-    s->as.heap.ptr = (char *)mrb_realloc(mrb, RSTR_PTR(s), capacity+1);
-    s->as.heap.aux.capa = capacity;
+    s->as.heap.ptr = (char*)mrb_realloc(mrb, RSTR_PTR(s), capacity+1);
+    s->as.heap.aux.capa = (mrb_int)capacity;
   }
 }
@@ -148,20 +156,24 @@
   }
 
-  if (RSTR_EMBED_P(s))
-    capa = RSTRING_EMBED_LEN_MAX;
-  else
-    capa = s->as.heap.aux.capa;
-
-  if (RSTR_LEN(s) >= MRB_INT_MAX - (mrb_int)len) {
+  capa = RSTR_CAPA(s);
+  if (capa <= RSTRING_EMBED_LEN_MAX)
+    capa = RSTRING_EMBED_LEN_MAX+1;
+
+  total = RSTR_LEN(s)+len;
+  if (total >= MRB_INT_MAX) {
+  size_error:
     mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
   }
-  total = RSTR_LEN(s)+len;
   if (capa <= total) {
     while (total > capa) {
-      if (capa + 1 >= MRB_INT_MAX / 2) {
-        capa = (total + 4095) / 4096;
-        break;
-      }
-      capa = (capa + 1) * 2;
+      if (capa <= MRB_INT_MAX / 2) {
+        capa *= 2;
+      }
+      else {
+        capa = total;
+      }
+    }
+    if (capa < total || capa > MRB_INT_MAX) {
+      goto size_error;
     }
     resize_capa(mrb, s, capa);
@@ -270,4 +282,7 @@
   char* p = RSTRING_PTR(str);
   char* e = p;
+  if (RSTRING(str)->flags & MRB_STR_NO_UTF) {
+    return RSTRING_LEN(str);
+  }
   e += len < 0 ? RSTRING_LEN(str) : len;
   while (p<e) {
@@ -275,4 +290,7 @@
     total++;
   }
+  if (RSTRING_LEN(str) == total) {
+    RSTRING(str)->flags |= MRB_STR_NO_UTF;
+  }
   return total;
 }
@@ -303,15 +321,18 @@
 
   for (b=i=0; b<bi; i++) {
-    n = utf8len(p, p+bi);
+    n = utf8len_codepage[(unsigned char)*p];
     b += n;
     p += n;
   }
+  if (b != bi) return -1;
   return i;
 }
 
+#define BYTES_ALIGN_CHECK(pos) if (pos < 0) return mrb_nil_value();
 #else
 #define RSTRING_CHAR_LEN(s) RSTRING_LEN(s)
 #define chars2bytes(p, off, ci) (ci)
 #define bytes2chars(p, bi) (bi)
+#define BYTES_ALIGN_CHECK(pos)
 #endif
 
@@ -349,10 +370,10 @@
   }
   else if (m == 1) {
-    const unsigned char *ys = y, *ye = ys + n;
-    for (; y < ye; ++y) {
-      if (*x == *y)
-        return y - ys;
-    }
-    return -1;
+    const unsigned char *ys = (const unsigned char *)memchr(y, *x, n);
+
+    if (ys)
+      return ys - y;
+    else
+      return -1;
   }
   return mrb_memsearch_qs((const unsigned char *)x0, m, (const unsigned char *)y0, n);
@@ -404,5 +425,5 @@
 
   orig = mrb_str_ptr(str);
-  if (RSTR_EMBED_P(orig)) {
+  if (RSTR_EMBED_P(orig) || RSTR_LEN(orig) == 0) {
     s = str_new(mrb, orig->as.ary+beg, len);
   }
@@ -450,5 +471,5 @@
     if (beg < 0) return mrb_nil_value();
   }
-  if (beg + len > clen)
+  if (len > clen - beg)
     len = clen - beg;
   if (len <= 0) {
@@ -489,5 +510,5 @@
 check_frozen(mrb_state *mrb, struct RString *s)
 {
-  if (RSTR_FROZEN_P(s)) {
+  if (MRB_FROZEN_P(s)) {
     mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen string");
   }
@@ -500,4 +521,7 @@
 
   check_frozen(mrb, s1);
+  if (s1 == s2) return mrb_obj_value(s1);
+  s1->flags &= ~MRB_STR_NO_UTF;
+  s1->flags |= s2->flags&MRB_STR_NO_UTF;
   len = RSTR_LEN(s2);
   if (RSTR_SHARED_P(s1)) {
@@ -646,8 +670,9 @@
 {
   check_frozen(mrb, s);
+  s->flags &= ~MRB_STR_NO_UTF;
   if (RSTR_SHARED_P(s)) {
     mrb_shared_string *shared = s->as.heap.aux.shared;
 
-    if (shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) {
+    if (shared->nofree == 0 && shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) {
       s->as.heap.ptr = shared->ptr;
       s->as.heap.aux.capa = shared->len;
@@ -661,11 +686,18 @@
       p = RSTR_PTR(s);
       len = s->as.heap.len;
-      ptr = (char *)mrb_malloc(mrb, (size_t)len + 1);
+      if (len < RSTRING_EMBED_LEN_MAX) {
+        RSTR_SET_EMBED_FLAG(s);
+        RSTR_SET_EMBED_LEN(s, len);
+        ptr = RSTR_PTR(s);
+      }
+      else {
+        ptr = (char *)mrb_malloc(mrb, (size_t)len + 1);
+        s->as.heap.ptr = ptr;
+        s->as.heap.aux.capa = len;
+      }
       if (p) {
         memcpy(ptr, p, len);
       }
       ptr[len] = '\0';
-      s->as.heap.ptr = ptr;
-      s->as.heap.aux.capa = len;
       str_decref(mrb, shared);
     }
@@ -675,23 +707,21 @@
   if (RSTR_NOFREE_P(s)) {
     char *p = s->as.heap.ptr;
-
-    s->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)s->as.heap.len+1);
+    mrb_int len = s->as.heap.len;
+
+    RSTR_UNSET_NOFREE_FLAG(s);
+    if (len < RSTRING_EMBED_LEN_MAX) {
+      RSTR_SET_EMBED_FLAG(s);
+      RSTR_SET_EMBED_LEN(s, len);
+    }
+    else {
+      s->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1);
+      s->as.heap.aux.capa = len;
+    }
     if (p) {
-      memcpy(RSTR_PTR(s), p, s->as.heap.len);
-    }
-    RSTR_PTR(s)[s->as.heap.len] = '\0';
-    s->as.heap.aux.capa = s->as.heap.len;
-    RSTR_UNSET_NOFREE_FLAG(s);
+      memcpy(RSTR_PTR(s), p, len);
+    }
+    RSTR_PTR(s)[len] = '\0';
     return;
   }
-}
-
-static mrb_value
-mrb_str_freeze(mrb_state *mrb, mrb_value str)
-{
-  struct RString *s = mrb_str_ptr(str);
-
-  RSTR_SET_FROZEN_FLAG(s);
-  return str;
 }
 
@@ -747,6 +777,12 @@
   }
   s2 = mrb_str_ptr(other);
+  if (RSTR_LEN(s2) == 0) {
+    return;
+  }
   len = RSTR_LEN(s1) + RSTR_LEN(s2);
 
+  if (len < 0 || len >= MRB_INT_MAX) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
+  }
   if (RSTRING_CAPA(self) < len) {
     resize_capa(mrb, s1, len);
@@ -932,6 +968,6 @@
       mrb_value tmp = mrb_funcall(mrb, str2, "<=>", 1, str1);
 
-      if (mrb_nil_p(tmp)) return mrb_nil_value();
-      if (!mrb_fixnum(tmp)) {
+      if (!mrb_nil_p(tmp)) return mrb_nil_value();
+      if (!mrb_fixnum_p(tmp)) {
         return mrb_funcall(mrb, mrb_fixnum_value(0), "-", 1, tmp);
       }
@@ -1014,4 +1050,11 @@
 }
 
+MRB_API mrb_int
+mrb_string_value_len(mrb_state *mrb, mrb_value ptr)
+{
+  mrb_value str = mrb_str_to_str(mrb, ptr);
+  return RSTRING_LEN(str);
+}
+
 void
 mrb_noregexp(mrb_state *mrb, mrb_value self)
@@ -1059,20 +1102,23 @@
 
     case MRB_TT_RANGE:
-      /* check if indx is Range */
-      {
-        mrb_int beg, len;
-
-        len = RSTRING_CHAR_LEN(str);
-        if (mrb_range_beg_len(mrb, indx, &beg, &len, len)) {
-          return str_subseq(mrb, str, beg, len);
-        }
-        else {
-          return mrb_nil_value();
-        }
-      }
-    case MRB_TT_FLOAT:
+      goto range_arg;
+
     default:
       indx = mrb_Integer(mrb, indx);
       if (mrb_nil_p(indx)) {
+      range_arg:
+        {
+          mrb_int beg, len;
+
+          len = RSTRING_CHAR_LEN(str);
+          switch (mrb_range_beg_len(mrb, indx, &beg, &len, len, TRUE)) {
+          case 1:
+            return str_subseq(mrb, str, beg, len);
+          case 2:
+            return mrb_nil_value();
+          default:
+            break;
+          }
+        }
         mrb_raise(mrb, E_TYPE_ERROR, "can't convert to Fixnum");
       }
@@ -1131,6 +1177,9 @@
   argc = mrb_get_args(mrb, "o|o", &a1, &a2);
   if (argc == 2) {
+    mrb_int n1, n2;
+
     mrb_regexp_check(mrb, a1);
-    return str_substr(mrb, str, mrb_fixnum(a1), mrb_fixnum(a2));
+    mrb_get_args(mrb, "ii", &n1, &n2);
+    return str_substr(mrb, str, n1, n2);
   }
   if (argc != 1) {
@@ -1215,9 +1264,11 @@
   mrb_int rslen;
   mrb_int len;
+  mrb_int argc;
   struct RString *s = mrb_str_ptr(str);
 
   mrb_str_modify(mrb, s);
+  argc = mrb_get_args(mrb, "|S", &rs);
   len = RSTR_LEN(s);
-  if (mrb_get_args(mrb, "|S", &rs) == 0) {
+  if (argc == 0) {
     if (len == 0) return mrb_nil_value();
   smart_chomp:
@@ -1510,20 +1561,10 @@
 mrb_str_include(mrb_state *mrb, mrb_value self)
 {
-  mrb_int i;
   mrb_value str2;
-  mrb_bool include_p;
-
-  mrb_get_args(mrb, "o", &str2);
-  if (mrb_fixnum_p(str2)) {
-    include_p = (memchr(RSTRING_PTR(self), mrb_fixnum(str2), RSTRING_LEN(self)) != NULL);
-  }
-  else {
-    str2 = mrb_str_to_str(mrb, str2);
-    i = str_index(mrb, self, str2, 0);
-
-    include_p = (i != -1);
-  }
-
-  return mrb_bool_value(include_p);
+
+  mrb_get_args(mrb, "S", &str2);
+  if (str_index(mrb, self, str2, 0) < 0)
+    return mrb_bool_value(FALSE);
+  return mrb_bool_value(TRUE);
 }
 
@@ -1559,6 +1600,5 @@
   mrb_get_args(mrb, "*", &argv, &argc);
   if (argc == 2) {
-    pos = mrb_fixnum(argv[1]);
-    sub = argv[0];
+    mrb_get_args(mrb, "oi", &sub, &pos);
   }
   else {
@@ -1577,5 +1617,5 @@
     }
   }
-  if (pos >= clen) return mrb_nil_value();
+  if (pos > clen) return mrb_nil_value();
   pos = chars2bytes(str, 0, pos);
 
@@ -1598,4 +1638,5 @@
   if (pos == -1) return mrb_nil_value();
   pos = bytes2chars(RSTRING_PTR(str), pos);
+  BYTES_ALIGN_CHECK(pos);
   return mrb_fixnum_value(pos);
 }
@@ -1633,7 +1674,9 @@
   mrb_value str2;
 
-  if (mrb_get_args(mrb, "|S", &str2) == 1) {
-    str_replace(mrb, mrb_str_ptr(self), mrb_str_ptr(str2));
-  }
+  if (mrb_get_args(mrb, "|S", &str2) == 0) {
+    struct RString *s = str_new(mrb, 0, 0);
+    str2 = mrb_obj_value(s);
+  }
+  str_replace(mrb, mrb_str_ptr(self), mrb_str_ptr(str2));
   return self;
 }
@@ -1743,5 +1786,5 @@
     mrb_str_modify(mrb, mrb_str_ptr(str));
     len = RSTRING_LEN(str);
-    buf = mrb_malloc(mrb, (size_t)len);
+    buf = (char*)mrb_malloc(mrb, (size_t)len);
     p = buf;
     e = buf + len;
@@ -1824,12 +1867,9 @@
   mrb_int argc;
   mrb_value sub;
-  mrb_value vpos;
   mrb_int pos, len = RSTRING_CHAR_LEN(str);
 
   mrb_get_args(mrb, "*", &argv, &argc);
   if (argc == 2) {
-    sub = argv[0];
-    vpos = argv[1];
-    pos = mrb_fixnum(vpos);
+    mrb_get_args(mrb, "oi", &sub, &pos);
     if (pos < 0) {
       pos += len;
@@ -1849,5 +1889,4 @@
   }
   pos = chars2bytes(str, 0, pos);
-  len = chars2bytes(str, pos, len);
   mrb_regexp_check(mrb, sub);
 
@@ -1867,4 +1906,5 @@
       if (pos >= 0) {
         pos = bytes2chars(RSTRING_PTR(str), pos);
+        BYTES_ALIGN_CHECK(pos);
         return mrb_fixnum_value(pos);
       }
@@ -1922,8 +1962,9 @@
   mrb_value spat = mrb_nil_value();
   enum {awk, string, regexp} split_type = string;
-  long i = 0, lim_p;
+  mrb_int i = 0;
   mrb_int beg;
   mrb_int end;
   mrb_int lim = 0;
+  mrb_bool lim_p;
   mrb_value result, tmp;
 
@@ -1998,5 +2039,6 @@
         end = mrb_memsearch(RSTRING_PTR(spat), pat_len, RSTRING_PTR(str)+idx, str_len - idx);
         if (end < 0) break;
-      } else {
+      }
+      else {
         end = chars2bytes(str, idx, 1);
       }
@@ -2031,9 +2073,10 @@
 
 MRB_API mrb_value
-mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck)
-{
-  const char *p;
+mrb_str_len_to_inum(mrb_state *mrb, const char *str, size_t len, int base, int badcheck)
+{
+  const char *p = str;
+  const char *pend = str + len;
   char sign = 1;
-  int c, uscore;
+  int c;
   uint64_t n = 0;
   mrb_int val;
@@ -2045,24 +2088,21 @@
      -1)
 
-  if (!str) {
+  if (!p) {
     if (badcheck) goto bad;
     return mrb_fixnum_value(0);
   }
-  while (ISSPACE(*str)) str++;
-
-  if (str[0] == '+') {
-    str++;
-  }
-  else if (str[0] == '-') {
-    str++;
+  while (p<pend && ISSPACE(*p))
+    p++;
+
+  if (p[0] == '+') {
+    p++;
+  }
+  else if (p[0] == '-') {
+    p++;
     sign = 0;
   }
-  if (str[0] == '+' || str[0] == '-') {
-    if (badcheck) goto bad;
-    return mrb_fixnum_value(0);
-  }
   if (base <= 0) {
-    if (str[0] == '0') {
-      switch (str[1]) {
+    if (p[0] == '0') {
+      switch (p[1]) {
         case 'x': case 'X':
           base = 16;
@@ -2079,4 +2119,5 @@
         default:
           base = 8;
+          break;
       }
     }
@@ -2090,6 +2131,6 @@
   switch (base) {
     case 2:
-      if (str[0] == '0' && (str[1] == 'b'||str[1] == 'B')) {
-        str += 2;
+      if (p[0] == '0' && (p[1] == 'b'||p[1] == 'B')) {
+        p += 2;
       }
       break;
@@ -2097,18 +2138,18 @@
       break;
     case 8:
-      if (str[0] == '0' && (str[1] == 'o'||str[1] == 'O')) {
-        str += 2;
+      if (p[0] == '0' && (p[1] == 'o'||p[1] == 'O')) {
+        p += 2;
       }
     case 4: case 5: case 6: case 7:
       break;
     case 10:
-      if (str[0] == '0' && (str[1] == 'd'||str[1] == 'D')) {
-        str += 2;
+      if (p[0] == '0' && (p[1] == 'd'||p[1] == 'D')) {
+        p += 2;
       }
     case 9: case 11: case 12: case 13: case 14: case 15:
       break;
     case 16:
-      if (str[0] == '0' && (str[1] == 'x'||str[1] == 'X')) {
-        str += 2;
+      if (p[0] == '0' && (p[1] == 'x'||p[1] == 'X')) {
+        p += 2;
       }
       break;
@@ -2119,57 +2160,79 @@
       break;
   } /* end of switch (base) { */
-  if (*str == '0') {    /* squeeze preceding 0s */
-    uscore = 0;
-    while ((c = *++str) == '0' || c == '_') {
-      if (c == '_') {
-        if (++uscore >= 2)
-          break;
-      }
-      else
-        uscore = 0;
-    }
-    if (!(c = *str) || ISSPACE(c)) --str;
-  }
-  c = *str;
-  c = conv_digit(c);
-  if (c < 0 || c >= base) {
+  if (p>=pend) {
     if (badcheck) goto bad;
     return mrb_fixnum_value(0);
   }
-
-  uscore = 0;
-  for (p=str;*p;p++) {
+  if (*p == '0') {    /* squeeze preceding 0s */
+    p++;
+    while (p<pend) {
+      c = *p++;
+      if (c == '_') {
+        if (p<pend && *p == '_') {
+          if (badcheck) goto bad;
+          break;
+        }
+        continue;
+      }
+      if (c != '0') {
+        p--;
+        break;
+      }
+    }
+    if (*(p - 1) == '0')
+      p--;
+  }
+  if (p == pend) {
+    if (badcheck) goto bad;
+    return mrb_fixnum_value(0);
+  }
+  for ( ;p<pend;p++) {
     if (*p == '_') {
-      if (uscore == 0) {
-        uscore++;
+      p++;
+      if (p==pend) {
+        if (badcheck) goto bad;
         continue;
       }
-      if (badcheck) goto bad;
-      break;
-    }
-    uscore = 0;
+      if (*p == '_') {
+        if (badcheck) goto bad;
+        break;
+      }
+    }
+    if (badcheck && *p == '\0') {
+      goto nullbyte;
+    }
     c = conv_digit(*p);
     if (c < 0 || c >= base) {
-      if (badcheck) goto bad;
       break;
     }
     n *= base;
     n += c;
-    if (n > MRB_INT_MAX) {
-      mrb_raisef(mrb, E_ARGUMENT_ERROR, "string (%S) too big for integer", mrb_str_new_cstr(mrb, str));
-    }
-  }
-  val = n;
+    if (n > (uint64_t)MRB_INT_MAX + (sign ? 0 : 1)) {
+      mrb_raisef(mrb, E_ARGUMENT_ERROR, "string (%S) too big for integer",
+                 mrb_str_new(mrb, str, pend-str));
+    }
+  }
+  val = (mrb_int)n;
   if (badcheck) {
     if (p == str) goto bad; /* no number */
-    while (*p && ISSPACE(*p)) p++;
-    if (*p) goto bad;           /* trailing garbage */
+    while (p<pend && ISSPACE(*p)) p++;
+    if (p<pend) goto bad;       /* trailing garbage */
   }
 
   return mrb_fixnum_value(sign ? val : -val);
-bad:
-  mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for number(%S)", mrb_str_new_cstr(mrb, str));
+ nullbyte:
+  mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte");
+  /* not reached */
+ bad:
+  mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for number(%S)",
+             mrb_inspect(mrb, mrb_str_new(mrb, str, pend-str)));
   /* not reached */
   return mrb_fixnum_value(0);
+}
+
+MRB_API mrb_value
+mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck)
+{
+  return mrb_str_len_to_inum(mrb, str, strlen(str), base, badcheck);
 }
 
@@ -2183,4 +2246,8 @@
 
   if (!p || p[len] != '\0') {
+    if (MRB_FROZEN_P(ps)) {
+      *ptr = str = mrb_str_dup(mrb, str);
+      ps = mrb_str_ptr(str);
+    }
     mrb_str_modify(mrb, ps);
     return RSTR_PTR(ps);
@@ -2195,19 +2262,7 @@
   mrb_int len;
 
-  if (badcheck) {
-    /* Raises if the string contains a null character (the badcheck) */
-    s = mrb_string_value_cstr(mrb, &str);
-  }
-  else {
-    s = mrb_string_value_ptr(mrb, str);
-  }
-  if (s) {
-    len = RSTRING_LEN(str);
-    if (s[len]) {    /* no sentinel somehow */
-      struct RString *temp_str = str_new(mrb, s, len);
-      s = RSTR_PTR(temp_str);
-    }
-  }
-  return mrb_cstr_to_inum(mrb, s, base, badcheck);
+  s = mrb_string_value_ptr(mrb, str);
+  len = RSTRING_LEN(str);
+  return mrb_str_len_to_inum(mrb, s, len, base, badcheck);
 }
 
@@ -2260,5 +2315,5 @@
     return 0.0;
   }
-  d = strtod(p, &end);
+  d = mrb_float_read(p, &end);
   if (p == end) {
     if (badcheck) {
@@ -2298,5 +2353,5 @@
     }
 
-    d = strtod(p, &end);
+    d = mrb_float_read(p, &end);
     if (badcheck) {
       if (!end || p == end) goto bad;
@@ -2603,5 +2658,5 @@
 #endif
     c = *p;
-    if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p, pend))) {
+    if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p+1, pend))) {
       buf[0] = '\\'; buf[1] = c;
       mrb_str_cat(mrb, result, buf, 2);
@@ -2689,6 +2744,6 @@
   mrb_define_method(mrb, s, "chomp",           mrb_str_chomp,           MRB_ARGS_ANY());  /* 15.2.10.5.9  */
   mrb_define_method(mrb, s, "chomp!",          mrb_str_chomp_bang,      MRB_ARGS_ANY());  /* 15.2.10.5.10 */
-  mrb_define_method(mrb, s, "chop",            mrb_str_chop,            MRB_ARGS_REQ(1)); /* 15.2.10.5.11 */
-  mrb_define_method(mrb, s, "chop!",           mrb_str_chop_bang,       MRB_ARGS_REQ(1)); /* 15.2.10.5.12 */
+  mrb_define_method(mrb, s, "chop",            mrb_str_chop,            MRB_ARGS_NONE()); /* 15.2.10.5.11 */
+  mrb_define_method(mrb, s, "chop!",           mrb_str_chop_bang,       MRB_ARGS_NONE()); /* 15.2.10.5.12 */
   mrb_define_method(mrb, s, "downcase",        mrb_str_downcase,        MRB_ARGS_NONE()); /* 15.2.10.5.13 */
   mrb_define_method(mrb, s, "downcase!",       mrb_str_downcase_bang,   MRB_ARGS_NONE()); /* 15.2.10.5.14 */
@@ -2720,5 +2775,248 @@
   mrb_define_method(mrb, s, "inspect",         mrb_str_inspect,         MRB_ARGS_NONE()); /* 15.2.10.5.46(x) */
   mrb_define_method(mrb, s, "bytes",           mrb_str_bytes,           MRB_ARGS_NONE());
-
-  mrb_define_method(mrb, s, "freeze",          mrb_str_freeze,          MRB_ARGS_NONE());
-}
+}
+
+/*
+ *	Source code for the "strtod" library procedure.
+ *
+ * Copyright (c) 1988-1993 The Regents of the University of California.
+ * Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies.  The University of California
+ * makes no representations about the suitability of this
+ * software for any purpose.  It is provided "as is" without
+ * express or implied warranty.
+ *
+ * RCS: @(#) $Id$
+ */
+
+#include <ctype.h>
+#include <errno.h>
+
+static const int maxExponent = 511; /* Largest possible base 10 exponent.  Any
+                                     * exponent larger than this will already
+                                     * produce underflow or overflow, so there's
+                                     * no need to worry about additional digits.
+                                     */
+static const double powersOf10[] = {/* Table giving binary powers of 10.  Entry */
+    10.,                            /* is 10^2^i.  Used to convert decimal */
+    100.,			    /* exponents into floating-point numbers. */
+    1.0e4,
+    1.0e8,
+    1.0e16,
+    1.0e32,
+    1.0e64,
+    1.0e128,
+    1.0e256
+};
+
+MRB_API double
+mrb_float_read(const char *string, char **endPtr)
+/*  const char *string;		   A decimal ASCII floating-point number,
+				 * optionally preceded by white space.
+				 * Must have form "-I.FE-X", where I is the
+				 * integer part of the mantissa, F is the
+				 * fractional part of the mantissa, and X
+				 * is the exponent.  Either of the signs
+				 * may be "+", "-", or omitted.  Either I
+				 * or F may be omitted, or both.  The decimal
+				 * point isn't necessary unless F is present.
+				 * The "E" may actually be an "e".  E and X
+				 * may both be omitted (but not just one).
+				 */
+/*  char **endPtr;		   If non-NULL, store terminating character's
+				 * address here. */
+{
+    int sign, expSign = FALSE;
+    double fraction, dblExp;
+    const double *d;
+    register const char *p;
+    register int c;
+    int exp = 0;		/* Exponent read from "EX" field. */
+    int fracExp = 0;		/* Exponent that derives from the fractional
+				 * part.  Under normal circumstatnces, it is
+				 * the negative of the number of digits in F.
+				 * However, if I is very long, the last digits
+				 * of I get dropped (otherwise a long I with a
+				 * large negative exponent could cause an
+				 * unnecessary overflow on I alone).  In this
+				 * case, fracExp is incremented one for each
+				 * dropped digit. */
+    int mantSize;		/* Number of digits in mantissa. */
+    int decPt;			/* Number of mantissa digits BEFORE decimal
+				 * point. */
+    const char *pExp;		/* Temporarily holds location of exponent
+				 * in string. */
+
+    /*
+     * Strip off leading blanks and check for a sign.
+     */
+
+    p = string;
+    while (isspace(*p)) {
+	p += 1;
+    }
+    if (*p == '-') {
+	sign = TRUE;
+	p += 1;
+    }
+    else {
+	if (*p == '+') {
+	    p += 1;
+	}
+	sign = FALSE;
+    }
+
+    /*
+     * Count the number of digits in the mantissa (including the decimal
+     * point), and also locate the decimal point.
+     */
+
+    decPt = -1;
+    for (mantSize = 0; ; mantSize += 1)
+    {
+	c = *p;
+	if (!isdigit(c)) {
+	    if ((c != '.') || (decPt >= 0)) {
+		break;
+	    }
+	    decPt = mantSize;
+	}
+	p += 1;
+    }
+
+    /*
+     * Now suck up the digits in the mantissa.  Use two integers to
+     * collect 9 digits each (this is faster than using floating-point).
+     * If the mantissa has more than 18 digits, ignore the extras, since
+     * they can't affect the value anyway.
+     */
+
+    pExp  = p;
+    p -= mantSize;
+    if (decPt < 0) {
+	decPt = mantSize;
+    }
+    else {
+	mantSize -= 1;			/* One of the digits was the point. */
+    }
+    if (mantSize > 18) {
+	if (decPt - 18 > 29999) {
+	    fracExp = 29999;
+	}
+        else {
+	    fracExp = decPt - 18;
+	}
+	mantSize = 18;
+    }
+    else {
+	fracExp = decPt - mantSize;
+    }
+    if (mantSize == 0) {
+	fraction = 0.0;
+	p = string;
+	goto done;
+    }
+    else {
+	int frac1, frac2;
+	frac1 = 0;
+	for ( ; mantSize > 9; mantSize -= 1)
+	{
+	    c = *p;
+	    p += 1;
+	    if (c == '.') {
+		c = *p;
+		p += 1;
+	    }
+	    frac1 = 10*frac1 + (c - '0');
+	}
+	frac2 = 0;
+	for (; mantSize > 0; mantSize -= 1)
+	{
+	    c = *p;
+	    p += 1;
+	    if (c == '.') {
+		c = *p;
+		p += 1;
+	    }
+	    frac2 = 10*frac2 + (c - '0');
+	}
+	fraction = (1.0e9 * frac1) + frac2;
+    }
+
+    /*
+     * Skim off the exponent.
+     */
+
+    p = pExp;
+    if ((*p == 'E') || (*p == 'e')) {
+	p += 1;
+	if (*p == '-') {
+	    expSign = TRUE;
+	    p += 1;
+	}
+        else {
+	    if (*p == '+') {
+		p += 1;
+	    }
+	    expSign = FALSE;
+	}
+	while (isdigit(*p)) {
+	    exp = exp * 10 + (*p - '0');
+	    if (exp > 19999) {
+		exp = 19999;
+	    }
+	    p += 1;
+	}
+    }
+    if (expSign) {
+	exp = fracExp - exp;
+    }
+    else {
+	exp = fracExp + exp;
+    }
+
+    /*
+     * Generate a floating-point number that represents the exponent.
+     * Do this by processing the exponent one bit at a time to combine
+     * many powers of 2 of 10. Then combine the exponent with the
+     * fraction.
+     */
+
+    if (exp < 0) {
+	expSign = TRUE;
+	exp = -exp;
+    }
+    else {
+	expSign = FALSE;
+    }
+    if (exp > maxExponent) {
+	exp = maxExponent;
+	errno = ERANGE;
+    }
+    dblExp = 1.0;
+    for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
+	if (exp & 01) {
+	    dblExp *= *d;
+	}
+    }
+    if (expSign) {
+	fraction /= dblExp;
+    }
+    else {
+	fraction *= dblExp;
+    }
+
+done:
+    if (endPtr != NULL) {
+	*endPtr = (char *) p;
+    }
+
+    if (sign) {
+	return -fraction;
+    }
+    return fraction;
+}
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/symbol.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/symbol.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/symbol.c	(revision 331)
@@ -7,8 +7,9 @@
 #include <limits.h>
 #include <string.h>
-#include "mruby.h"
-#include "mruby/khash.h"
-#include "mruby/string.h"
-#include "mruby/dump.h"
+#include <mruby.h>
+#include <mruby/khash.h>
+#include <mruby/string.h>
+#include <mruby/dump.h>
+#include <mruby/class.h>
 
 /* ------------------------------------------------------ */
@@ -355,5 +356,7 @@
       break;
     case '!':
-      if (*++m == '=') ++m;
+      switch (*++m) {
+        case '=': case '~': ++m;
+      }
       break;
     case '+': case '-':
@@ -480,4 +483,6 @@
 
   mrb->symbol_class = sym = mrb_define_class(mrb, "Symbol", mrb->object_class);                 /* 15.2.11 */
+  MRB_SET_INSTANCE_TT(sym, MRB_TT_SYMBOL);
+  mrb_undef_class_method(mrb,  sym, "new");
 
   mrb_define_method(mrb, sym, "===",             sym_equal,      MRB_ARGS_REQ(1));              /* 15.2.11.3.1  */
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/value_array.h
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/value_array.h	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/value_array.h	(revision 331)
@@ -2,5 +2,5 @@
 #define MRB_VALUE_ARRAY_H__
 
-#include "mruby.h"
+#include <mruby.h>
 
 static inline void
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/variable.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/variable.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/variable.c	(revision 331)
@@ -5,9 +5,9 @@
 */
 
-#include "mruby.h"
-#include "mruby/array.h"
-#include "mruby/class.h"
-#include "mruby/proc.h"
-#include "mruby/string.h"
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/class.h>
+#include <mruby/proc.h>
+#include <mruby/string.h>
 
 typedef int (iv_foreach_func)(mrb_state*,mrb_sym,mrb_value,void*);
@@ -45,5 +45,5 @@
   iv_tbl *t;
 
-  t = mrb_malloc(mrb, sizeof(iv_tbl));
+  t = (iv_tbl*)mrb_malloc(mrb, sizeof(iv_tbl));
   t->size = 0;
   t->rootseg =  NULL;
@@ -103,5 +103,5 @@
   }
 
-  seg = mrb_malloc(mrb, sizeof(segment));
+  seg = (segment*)mrb_malloc(mrb, sizeof(segment));
   if (!seg) return;
   seg->next = NULL;
@@ -283,5 +283,5 @@
 #else
 
-#include "mruby/khash.h"
+#include <mruby/khash.h>
 
 #ifndef MRB_IVHASH_INIT_SIZE
@@ -490,4 +490,7 @@
   iv_tbl *t = obj->iv;
 
+  if (MRB_FROZEN_P(obj)) {
+    mrb_raisef(mrb, E_RUNTIME_ERROR, "can't modify frozen %S", mrb_obj_value(obj));
+  }
   if (!t) {
     t = obj->iv = iv_new(mrb);
@@ -757,15 +760,17 @@
 
 MRB_API mrb_value
-mrb_mod_cv_get(mrb_state *mrb, struct RClass * c, mrb_sym sym)
+mrb_mod_cv_get(mrb_state *mrb, struct RClass *c, mrb_sym sym)
 {
   struct RClass * cls = c;
   mrb_value v;
+  int given = FALSE;
 
   while (c) {
     if (c->iv && iv_get(mrb, c->iv, sym, &v)) {
-      return v;
+      given = TRUE;
     }
     c = c->super;
   }
+  if (given) return v;
   if (cls && cls->tt == MRB_TT_SCLASS) {
     mrb_value klass;
@@ -774,11 +779,13 @@
                            mrb_intern_lit(mrb, "__attached__"));
     c = mrb_class_ptr(klass);
-    if (c->tt == MRB_TT_CLASS) {
+    if (c->tt == MRB_TT_CLASS || c->tt == MRB_TT_MODULE) {
+      given = FALSE;
       while (c) {
         if (c->iv && iv_get(mrb, c->iv, sym, &v)) {
-          return v;
+          given = TRUE;
         }
         c = c->super;
       }
+      if (given) return v;
     }
   }
@@ -813,10 +820,30 @@
   }
 
-  if (!cls->iv) {
-    cls->iv = iv_new(mrb);
-  }
-
-  mrb_write_barrier(mrb, (struct RBasic*)cls);
-  iv_put(mrb, cls->iv, sym, v);
+  if (cls && cls->tt == MRB_TT_SCLASS) {
+    mrb_value klass;
+
+    klass = mrb_obj_iv_get(mrb, (struct RObject*)cls,
+                           mrb_intern_lit(mrb, "__attached__"));
+    switch (mrb_type(klass)) {
+    case MRB_TT_CLASS:
+    case MRB_TT_MODULE:
+    case MRB_TT_SCLASS:
+      c = mrb_class_ptr(klass);
+      break;
+    default:
+      c = cls;
+      break;
+    }
+  }
+  else{
+    c = cls;
+  }
+
+  if (!c->iv) {
+    c->iv = iv_new(mrb);
+  }
+
+  mrb_write_barrier(mrb, (struct RBasic*)c);
+  iv_put(mrb, c->iv, sym, v);
 }
 
@@ -927,12 +954,12 @@
       return v;
     }
-    if (c->tt == MRB_TT_SCLASS) {
+    c2 = c;
+    while (c2 && c2->tt == MRB_TT_SCLASS) {
       mrb_value klass;
-      klass = mrb_obj_iv_get(mrb, (struct RObject *)c,
+      klass = mrb_obj_iv_get(mrb, (struct RObject *)c2,
                              mrb_intern_lit(mrb, "__attached__"));
       c2 = mrb_class_ptr(klass);
-      if (c2->tt == MRB_TT_CLASS)
-        c = c2;
-    }
+    }
+    if (c2->tt == MRB_TT_CLASS || c2->tt == MRB_TT_MODULE) c = c2;
     c2 = c;
     for (;;) {
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/version.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/version.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/version.c	(revision 331)
@@ -1,4 +1,4 @@
-#include "mruby.h"
-#include "mruby/variable.h"
+#include <mruby.h>
+#include <mruby/variable.h>
 
 void
@@ -10,5 +10,5 @@
   mrb_define_global_const(mrb, "RUBY_ENGINE", mrb_str_new_lit(mrb, MRUBY_RUBY_ENGINE));
   mrb_define_global_const(mrb, "RUBY_ENGINE_VERSION", mruby_version);
-  mrb_define_global_const(mrb, "MRUBY_VERSION", mrb_str_new_lit(mrb, MRUBY_VERSION));
+  mrb_define_global_const(mrb, "MRUBY_VERSION", mruby_version);
   mrb_define_global_const(mrb, "MRUBY_RELEASE_NO", mrb_fixnum_value(MRUBY_RELEASE_NO));
   mrb_define_global_const(mrb, "MRUBY_RELEASE_DATE", mrb_str_new_lit(mrb, MRUBY_RELEASE_DATE));
Index: EcnlProtoTool/trunk/mruby-1.3.0/src/vm.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/src/vm.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/src/vm.c	(revision 331)
@@ -8,20 +8,20 @@
 #include <stdarg.h>
 #include <math.h>
-#include "mruby.h"
-#include "mruby/array.h"
-#include "mruby/class.h"
-#include "mruby/hash.h"
-#include "mruby/irep.h"
-#include "mruby/numeric.h"
-#include "mruby/proc.h"
-#include "mruby/range.h"
-#include "mruby/string.h"
-#include "mruby/variable.h"
-#include "mruby/error.h"
-#include "mruby/opcode.h"
+#include <mruby.h>
+#include <mruby/array.h>
+#include <mruby/class.h>
+#include <mruby/hash.h>
+#include <mruby/irep.h>
+#include <mruby/numeric.h>
+#include <mruby/proc.h>
+#include <mruby/range.h>
+#include <mruby/string.h>
+#include <mruby/variable.h>
+#include <mruby/error.h>
+#include <mruby/opcode.h>
 #include "value_array.h"
-#include "mruby/throw.h"
-
-#ifdef MRB_DISABLE_STDIO
+#include <mruby/throw.h>
+
+#ifndef MRB_DISABLE_STDIO
 #if defined(__cplusplus)
 extern "C" {
@@ -36,7 +36,20 @@
 #define CALLINFO_INIT_SIZE 32
 
+#ifndef ENSURE_STACK_INIT_SIZE
+#define ENSURE_STACK_INIT_SIZE 16
+#endif
+
+#ifndef RESCUE_STACK_INIT_SIZE
+#define RESCUE_STACK_INIT_SIZE 16
+#endif
+
 /* Define amount of linear stack growth. */
 #ifndef MRB_STACK_GROWTH
 #define MRB_STACK_GROWTH 128
+#endif
+
+/* Maximum mrb_funcall() depth. Should be set lower on memory constrained systems. */
+#ifndef MRB_FUNCALL_DEPTH_MAX
+#define MRB_FUNCALL_DEPTH_MAX 512
 #endif
 
@@ -54,4 +67,8 @@
 
 #define ARENA_RESTORE(mrb,ai) (mrb)->gc.arena_idx = (ai)
+
+#define CALL_MAXARGS 127
+
+void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args);
 
 static inline void
@@ -99,5 +116,5 @@
 
 static inline void
-envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase)
+envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t size)
 {
   mrb_callinfo *ci = mrb->c->cibase;
@@ -106,5 +123,8 @@
   while (ci <= mrb->c->ci) {
     struct REnv *e = ci->env;
-    if (e && MRB_ENV_STACK_SHARED_P(e)) {
+    mrb_value *st;
+
+    if (e && MRB_ENV_STACK_SHARED_P(e) &&
+        (st = e->stack) && oldbase <= st && st < oldbase+size) {
       ptrdiff_t off = e->stack - oldbase;
 
@@ -116,22 +136,16 @@
 }
 
-static inline void
-init_new_stack_space(mrb_state *mrb, int room, int keep)
-{
-  if (room > keep) {
-    /* do not leave uninitialized malloc region */
-    stack_clear(&(mrb->c->stack[keep]), room - keep);
-  }
-}
-
 /** def rec ; $deep =+ 1 ; if $deep > 1000 ; return 0 ; end ; rec ; end  */
 
 static void
-stack_extend_alloc(mrb_state *mrb, int room, int keep)
+stack_extend_alloc(mrb_state *mrb, int room)
 {
   mrb_value *oldbase = mrb->c->stbase;
-  int size = mrb->c->stend - mrb->c->stbase;
-  int off = mrb->c->stack - mrb->c->stbase;
-
+  mrb_value *newstack;
+  size_t oldsize = mrb->c->stend - mrb->c->stbase;
+  size_t size = oldsize;
+  size_t off = mrb->c->stack - mrb->c->stbase;
+
+  if (off > size) size = off;
 #ifdef MRB_STACK_EXTEND_DOUBLING
   if (room <= size)
@@ -149,24 +163,27 @@
 #endif
 
-  mrb->c->stbase = (mrb_value *)mrb_realloc(mrb, mrb->c->stbase, sizeof(mrb_value) * size);
+  newstack = (mrb_value *)mrb_realloc(mrb, mrb->c->stbase, sizeof(mrb_value) * size);
+  if (newstack == NULL) {
+    mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
+  }
+  stack_clear(&(newstack[oldsize]), size - oldsize);
+  envadjust(mrb, oldbase, newstack, size);
+  mrb->c->stbase = newstack;
   mrb->c->stack = mrb->c->stbase + off;
   mrb->c->stend = mrb->c->stbase + size;
-  envadjust(mrb, oldbase, mrb->c->stbase);
 
   /* Raise an exception if the new stack size will be too large,
      to prevent infinite recursion. However, do this only after resizing the stack, so mrb_raise has stack space to work with. */
   if (size > MRB_STACK_MAX) {
-    init_new_stack_space(mrb, room, keep);
-    mrb_raise(mrb, E_SYSSTACK_ERROR, "stack level too deep. (limit=" MRB_STRINGIZE(MRB_STACK_MAX) ")");
+    mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
   }
 }
 
 static inline void
-stack_extend(mrb_state *mrb, int room, int keep)
+stack_extend(mrb_state *mrb, int room)
 {
   if (mrb->c->stack + room >= mrb->c->stend) {
-    stack_extend_alloc(mrb, room, keep);
-  }
-  init_new_stack_space(mrb, room, keep);
+    stack_extend_alloc(mrb, room);
+  }
 }
 
@@ -188,6 +205,6 @@
   int cioff = e->cioff;
 
-  if (MRB_ENV_STACK_SHARED_P(e) && mrb->c->cibase[cioff].proc &&
-      MRB_PROC_STRICT_P(mrb->c->cibase[cioff].proc)) {
+  if (MRB_ENV_STACK_SHARED_P(e) && e->cxt.c->cibase[cioff].proc &&
+      MRB_PROC_STRICT_P(e->cxt.c->cibase[cioff].proc)) {
     return TRUE;
   }
@@ -210,4 +227,5 @@
 #define CI_ACC_SKIP    -1
 #define CI_ACC_DIRECT  -2
+#define CI_ACC_RESUMED -3
 
 static mrb_callinfo*
@@ -217,5 +235,4 @@
   mrb_callinfo *ci = c->ci;
 
-  int eidx = ci->eidx;
   int ridx = ci->ridx;
 
@@ -228,5 +245,5 @@
   }
   ci = ++c->ci;
-  ci->eidx = eidx;
+  ci->epos = mrb->c->eidx;
   ci->ridx = ridx;
   ci->env = 0;
@@ -234,6 +251,31 @@
   ci->err = 0;
   ci->proc = 0;
+  ci->acc = 0;
 
   return ci;
+}
+
+MRB_API void
+mrb_env_unshare(mrb_state *mrb, struct REnv *e)
+{
+  size_t len = (size_t)MRB_ENV_STACK_LEN(e);
+  ptrdiff_t cioff = e->cioff;
+  mrb_value *p;
+
+  if (!MRB_ENV_STACK_SHARED_P(e)) return;
+  if (e->cxt.c != mrb->c) return;
+  if (e->cioff == 0 && e->cxt.c == mrb->root_c) return;
+  MRB_ENV_UNSHARE_STACK(e);
+  if (!e->c) {
+    /* save block argument position (negated) */
+    e->cioff = -e->cxt.c->cibase[cioff].argc-1;
+  }
+  e->cxt.mid = e->cxt.c->cibase[cioff].mid;
+  p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len);
+  if (len > 0) {
+    stack_copy(p, e->stack, len);
+  }
+  e->stack = p;
+  mrb_write_barrier(mrb, (struct RBasic *)e);
 }
 
@@ -242,20 +284,14 @@
 {
   struct mrb_context *c = mrb->c;
-
-  if (c->ci->env) {
-    struct REnv *e = c->ci->env;
-    size_t len = (size_t)MRB_ENV_STACK_LEN(e);
-    mrb_value *p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len);
-
-    MRB_ENV_UNSHARE_STACK(e);
-    if (len > 0) {
-      stack_copy(p, e->stack, len);
-    }
-    e->stack = p;
-    mrb_write_barrier(mrb, (struct RBasic *)e);
-  }
+  struct REnv *env = c->ci->env;
 
   c->ci--;
-}
+
+  if (env) {
+    mrb_env_unshare(mrb, env);
+  }
+}
+
+void mrb_exc_set(mrb_state *mrb, mrb_value exc);
 
 static void
@@ -263,13 +299,18 @@
 {
   struct RProc *p;
-  mrb_callinfo *ci;
+  mrb_callinfo *ci = mrb->c->ci;
   mrb_value *self = mrb->c->stack;
   struct RObject *exc;
+  ptrdiff_t cioff;
+  int ai = mrb_gc_arena_save(mrb);
 
   if (i<0) return;
+  if (ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
+    mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
+  }
   p = mrb->c->ensure[i];
   if (!p) return;
-  if (mrb->c->ci->eidx > i)
-    mrb->c->ci->eidx = i;
+  mrb->c->ensure[i] = NULL;
+  cioff = ci - mrb->c->cibase;
   ci = cipush(mrb);
   ci->stackent = mrb->c->stack;
@@ -282,7 +323,11 @@
   mrb->c->stack = mrb->c->stack + ci[-1].nregs;
   exc = mrb->exc; mrb->exc = 0;
+  if (exc) {
+    mrb_gc_protect(mrb, mrb_obj_value(exc));
+  }
   mrb_run(mrb, p, *self);
-  mrb->c->ensure[i] = NULL;
+  mrb->c->ci = mrb->c->cibase + cioff;
   if (!mrb->exc) mrb->exc = exc;
+  mrb_gc_arena_restore(mrb, ai);
 }
 
@@ -335,9 +380,9 @@
     }
     MRB_END_EXC(&c_jmp);
+    mrb->jmp = 0;
   }
   else {
     struct RProc *p;
     struct RClass *c;
-    mrb_sym undef = 0;
     mrb_callinfo *ci;
     int n;
@@ -354,8 +399,17 @@
     p = mrb_method_search_vm(mrb, &c, mid);
     if (!p) {
-      undef = mid;
-      mid = mrb_intern_lit(mrb, "method_missing");
-      p = mrb_method_search_vm(mrb, &c, mid);
-      n++; argc++;
+      mrb_sym missing = mrb_intern_lit(mrb, "method_missing");
+      mrb_value args = mrb_ary_new_from_values(mrb, argc, argv);
+      p = mrb_method_search_vm(mrb, &c, missing);
+      if (!p) {
+        mrb_method_missing(mrb, mid, self, args);
+      }
+      mrb_ary_unshift(mrb, args, mrb_symbol_value(mid));
+      stack_extend(mrb, n+2);
+      mrb->c->stack[n+1] = args;
+      argc = -1;
+    }
+    if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
+      mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
     }
     ci = cipush(mrb);
@@ -371,9 +425,17 @@
     if (MRB_PROC_CFUNC_P(p)) {
       ci->nregs = argc + 2;
-      stack_extend(mrb, ci->nregs, 0);
+      stack_extend(mrb, ci->nregs);
+    }
+    else if (argc >= CALL_MAXARGS) {
+      mrb_value args = mrb_ary_new_from_values(mrb, argc, argv);
+      stack_extend(mrb, ci->nregs);
+      mrb->c->stack[1] = args;
+      ci->argc = -1;
+      argc = 1;
     }
     else {
-      ci->nregs = p->body.irep->nregs + n;
-      stack_extend(mrb, ci->nregs, argc+2);
+      if (argc < 0) argc = 1;
+      ci->nregs = p->body.irep->nregs + argc;
+      stack_extend(mrb, ci->nregs);
     }
     if (voff >= 0) {
@@ -381,11 +443,5 @@
     }
     mrb->c->stack[0] = self;
-    if (undef) {
-      mrb->c->stack[1] = mrb_symbol_value(undef);
-      if (argc > 1) {
-        stack_copy(mrb->c->stack+2, argv, argc-1);
-      }
-    }
-    else if (argc > 0) {
+    if (ci->argc > 0) {
       stack_copy(mrb->c->stack+1, argv, argc);
     }
@@ -414,4 +470,33 @@
 {
   return mrb_funcall_with_block(mrb, self, mid, argc, argv, mrb_nil_value());
+}
+
+mrb_value
+mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p)
+{
+  mrb_callinfo *ci = mrb->c->ci;
+
+  mrb->c->stack[0] = self;
+  ci->proc = p;
+  ci->target_class = p->target_class;
+  if (MRB_PROC_CFUNC_P(p)) {
+    return p->body.func(mrb, self);
+  }
+  if (ci->argc < 0) {
+    stack_extend(mrb, (p->body.irep->nregs < 3) ? 3 : p->body.irep->nregs);
+  }
+  else {
+    stack_extend(mrb, p->body.irep->nregs);
+  }
+
+  ci->nregs = p->body.irep->nregs;
+  ci = cipush(mrb);
+  ci->nregs = 0;
+  ci->target_class = 0;
+  ci->pc = p->body.irep->iseq;
+  ci->stackent = mrb->c->stack;
+  ci->acc = 0;
+
+  return self;
 }
 
@@ -446,4 +531,9 @@
 
   mrb_get_args(mrb, "n*&", &name, &argv, &argc, &block);
+  ci = mrb->c->ci;
+  if (ci->acc < 0) {
+  funcall:
+    return mrb_funcall_with_block(mrb, self, name, argc, argv, block);
+  }
 
   c = mrb_class(mrb, self);
@@ -451,11 +541,9 @@
 
   if (!p) {                     /* call method_mising */
-    return mrb_funcall_with_block(mrb, self, name, argc, argv, block);
-  }
-
-  ci = mrb->c->ci;
+    goto funcall;
+  }
+
   ci->mid = name;
   ci->target_class = c;
-  ci->proc = p;
   regs = mrb->c->stack+1;
   /* remove first symbol from arguments */
@@ -470,24 +558,5 @@
   }
 
-  if (MRB_PROC_CFUNC_P(p)) {
-    return p->body.func(mrb, self);
-  }
-
-  if (ci->argc < 0) {
-    stack_extend(mrb, (p->body.irep->nregs < 3) ? 3 : p->body.irep->nregs, 3);
-  }
-  else {
-    stack_extend(mrb, p->body.irep->nregs, ci->argc+2);
-  }
-
-  ci->nregs = p->body.irep->nregs;
-  ci = cipush(mrb);
-  ci->nregs = 0;
-  ci->target_class = 0;
-  ci->pc = p->body.irep->iseq;
-  ci->stackent = mrb->c->stack;
-  ci->acc = 0;
-
-  return self;
+  return mrb_exec_irep(mrb, self, p);
 }
 
@@ -497,4 +566,5 @@
   struct RProc *p;
   mrb_callinfo *ci;
+  mrb_int max = 3;
 
   if (mrb_nil_p(blk)) {
@@ -503,13 +573,25 @@
   ci = mrb->c->ci;
   if (ci->acc == CI_ACC_DIRECT) {
-    return mrb_yield_with_class(mrb, blk, 0, 0, self, c);
+    ci->target_class = c;
+    return mrb_yield_cont(mrb, blk, self, 1, &self);
   }
   ci->target_class = c;
   p = mrb_proc_ptr(blk);
   ci->proc = p;
+  ci->argc = 1;
+  ci->mid = ci[-1].mid;
   if (MRB_PROC_CFUNC_P(p)) {
+    stack_extend(mrb, 3);
+    mrb->c->stack[0] = self;
+    mrb->c->stack[1] = self;
+    mrb->c->stack[2] = mrb_nil_value();
     return p->body.func(mrb, self);
   }
   ci->nregs = p->body.irep->nregs;
+  if (max < ci->nregs) max = ci->nregs;
+  stack_extend(mrb, max);
+  mrb->c->stack[0] = self;
+  mrb->c->stack[1] = self;
+  mrb->c->stack[2] = mrb_nil_value();
   ci = cipush(mrb);
   ci->nregs = 0;
@@ -600,4 +682,7 @@
     mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
   }
+  if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
+    mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
+  }
   p = mrb_proc_ptr(b);
   ci = cipush(mrb);
@@ -611,9 +696,9 @@
   if (MRB_PROC_CFUNC_P(p)) {
     ci->nregs = argc + 2;
-    stack_extend(mrb, ci->nregs, 0);
+    stack_extend(mrb, ci->nregs);
   }
   else {
     ci->nregs = p->body.irep->nregs;
-    stack_extend(mrb, ci->nregs, argc+2);
+    stack_extend(mrb, ci->nregs);
   }
 
@@ -627,9 +712,11 @@
     val = p->body.func(mrb, self);
     mrb->c->stack = mrb->c->ci->stackent;
-    cipop(mrb);
   }
   else {
+    int cioff = mrb->c->ci - mrb->c->cibase;
     val = mrb_run(mrb, p, self);
-  }
+    mrb->c->ci = mrb->c->cibase + cioff;
+  }
+  cipop(mrb);
   return val;
 }
@@ -649,4 +736,40 @@
 
   return mrb_yield_with_class(mrb, b, 1, &arg, p->env->stack[0], p->target_class);
+}
+
+mrb_value
+mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const mrb_value *argv)
+{
+  struct RProc *p;
+  mrb_callinfo *ci;
+
+  if (mrb_nil_p(b)) {
+    mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
+  }
+  if (mrb_type(b) != MRB_TT_PROC) {
+    mrb_raise(mrb, E_TYPE_ERROR, "not a block");
+  }
+
+  p = mrb_proc_ptr(b);
+  ci = mrb->c->ci;
+
+  stack_extend(mrb, 3);
+  mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv);
+  mrb->c->stack[2] = mrb_nil_value();
+  ci->argc = -1;
+  return mrb_exec_irep(mrb, self, p);
+}
+
+static struct RBreak*
+break_new(mrb_state *mrb, struct RProc *p, mrb_value val)
+{
+  struct RBreak *brk;
+
+  brk = (struct RBreak*)mrb_obj_alloc(mrb, MRB_TT_BREAK, NULL);
+  brk->iv = NULL;
+  brk->proc = p;
+  brk->val = val;
+
+  return brk;
 }
 
@@ -670,5 +793,5 @@
   mrb_str_cat(mrb, msg, kind_str[kind], kind_str_len[kind]);
   exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg);
-  mrb->exc = mrb_obj_ptr(exc);
+  mrb_exc_set(mrb, exc);
 }
 
@@ -678,16 +801,23 @@
   mrb_value exc;
   mrb_value str;
-
+  mrb_int argc = mrb->c->ci->argc;
+
+  if (argc < 0) {
+    mrb_value args = mrb->c->stack[1];
+    if (mrb_array_p(args)) {
+      argc = RARRAY_LEN(args);
+    }
+  }
   if (mrb->c->ci->mid) {
     str = mrb_format(mrb, "'%S': wrong number of arguments (%S for %S)",
                   mrb_sym2str(mrb, mrb->c->ci->mid),
-                  mrb_fixnum_value(mrb->c->ci->argc), mrb_fixnum_value(num));
+                  mrb_fixnum_value(argc), mrb_fixnum_value(num));
   }
   else {
     str = mrb_format(mrb, "wrong number of arguments (%S for %S)",
-                  mrb_fixnum_value(mrb->c->ci->argc), mrb_fixnum_value(num));
+                     mrb_fixnum_value(argc), mrb_fixnum_value(num));
   }
   exc = mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str);
-  mrb->exc = mrb_obj_ptr(exc);
+  mrb_exc_set(mrb, exc);
 }
 
@@ -700,4 +830,11 @@
 #endif
 
+#ifdef MRB_BYTECODE_DECODE_OPTION
+#define BYTECODE_DECODER(x) ((mrb)->bytecode_decoder)?(mrb)->bytecode_decoder((mrb), (x)):(x)
+#else
+#define BYTECODE_DECODER(x) (x)
+#endif
+
+
 #if defined __GNUC__ || defined __clang__ || defined __INTEL_COMPILER
 #define DIRECT_THREADED
@@ -706,5 +843,5 @@
 #ifndef DIRECT_THREADED
 
-#define INIT_DISPATCH for (;;) { i = *pc; CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (GET_OPCODE(i)) {
+#define INIT_DISPATCH for (;;) { i = BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (GET_OPCODE(i)) {
 #define CASE(op) case op:
 #define NEXT pc++; break
@@ -716,6 +853,6 @@
 #define INIT_DISPATCH JUMP; return mrb_nil_value();
 #define CASE(op) L_ ## op:
-#define NEXT i=*++pc; CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)]
-#define JUMP i=*pc; CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)]
+#define NEXT i=BYTECODE_DECODER(*++pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)]
+#define JUMP i=BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)]
 
 #define END_DISPATCH
@@ -723,17 +860,41 @@
 #endif
 
-#define CALL_MAXARGS 127
-
-void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args);
-
 MRB_API mrb_value
-mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep)
+mrb_vm_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep)
+{
+  mrb_irep *irep = proc->body.irep;
+  mrb_value result;
+  struct mrb_context *c = mrb->c;
+  int cioff = c->ci - c->cibase;
+  unsigned int nregs = irep->nregs;
+
+  if (!c->stack) {
+    stack_init(mrb);
+  }
+  if (stack_keep > nregs)
+    nregs = stack_keep;
+  stack_extend(mrb, nregs);
+  stack_clear(c->stack + stack_keep, nregs - stack_keep);
+  c->stack[0] = self;
+  result = mrb_vm_exec(mrb, proc, irep->iseq);
+  if (c->ci - c->cibase > cioff) {
+    c->ci = c->cibase + cioff;
+  }
+  if (mrb->c != c) {
+    if (mrb->c->fib) {
+      mrb_write_barrier(mrb, (struct RBasic*)mrb->c->fib);
+    }
+    mrb->c = c;
+  }
+  return result;
+}
+
+MRB_API mrb_value
+mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc)
 {
   /* mrb_assert(mrb_proc_cfunc_p(proc)) */
   mrb_irep *irep = proc->body.irep;
-  mrb_code *pc = irep->iseq;
   mrb_value *pool = irep->pool;
   mrb_sym *syms = irep->syms;
-  mrb_value *regs = NULL;
   mrb_code i;
   int ai = mrb_gc_arena_save(mrb);
@@ -773,16 +934,13 @@
   if (exc_catched) {
     exc_catched = FALSE;
+    if (mrb->exc && mrb->exc->tt == MRB_TT_BREAK)
+      goto L_BREAK;
     goto L_RAISE;
   }
   mrb->jmp = &c_jmp;
-  if (!mrb->c->stack) {
-    stack_init(mrb);
-  }
-  stack_extend(mrb, irep->nregs, stack_keep);
   mrb->c->ci->proc = proc;
   mrb->c->ci->nregs = irep->nregs;
-  regs = mrb->c->stack;
-  regs[0] = self;
-
+
+#define regs (mrb->c->stack)
   INIT_DISPATCH {
     CASE(OP_NOP) {
@@ -793,5 +951,7 @@
     CASE(OP_MOVE) {
       /* A B    R(A) := R(B) */
-      regs[GETARG_A(i)] = regs[GETARG_B(i)];
+      int a = GETARG_A(i);
+      int b = GETARG_B(i);
+      regs[a] = regs[b];
       NEXT;
     }
@@ -799,5 +959,15 @@
     CASE(OP_LOADL) {
       /* A Bx   R(A) := Pool(Bx) */
-      regs[GETARG_A(i)] = pool[GETARG_Bx(i)];
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+#ifdef MRB_WORD_BOXING
+      mrb_value val = pool[bx];
+      if (mrb_float_p(val)) {
+        val = mrb_float_value(mrb, mrb_float(val));
+      }
+      regs[a] = val;
+#else
+      regs[a] = pool[bx];
+#endif
       NEXT;
     }
@@ -811,5 +981,7 @@
     CASE(OP_LOADSYM) {
       /* A Bx   R(A) := Syms(Bx) */
-      SET_SYM_VALUE(regs[GETARG_A(i)], syms[GETARG_Bx(i)]);
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      SET_SYM_VALUE(regs[a], syms[bx]);
       NEXT;
     }
@@ -817,5 +989,6 @@
     CASE(OP_LOADSELF) {
       /* A      R(A) := self */
-      regs[GETARG_A(i)] = regs[0];
+      int a = GETARG_A(i);
+      regs[a] = regs[0];
       NEXT;
     }
@@ -823,5 +996,6 @@
     CASE(OP_LOADT) {
       /* A      R(A) := true */
-      SET_TRUE_VALUE(regs[GETARG_A(i)]);
+      int a = GETARG_A(i);
+      SET_TRUE_VALUE(regs[a]);
       NEXT;
     }
@@ -829,5 +1003,6 @@
     CASE(OP_LOADF) {
       /* A      R(A) := false */
-      SET_FALSE_VALUE(regs[GETARG_A(i)]);
+      int a = GETARG_A(i);
+      SET_FALSE_VALUE(regs[a]);
       NEXT;
     }
@@ -835,11 +1010,16 @@
     CASE(OP_GETGLOBAL) {
       /* A Bx   R(A) := getglobal(Syms(Bx)) */
-      regs[GETARG_A(i)] = mrb_gv_get(mrb, syms[GETARG_Bx(i)]);
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_value val = mrb_gv_get(mrb, syms[bx]);
+      regs[a] = val;
       NEXT;
     }
 
     CASE(OP_SETGLOBAL) {
-      /* setglobal(Syms(Bx), R(A)) */
-      mrb_gv_set(mrb, syms[GETARG_Bx(i)], regs[GETARG_A(i)]);
+      /* A Bx   setglobal(Syms(Bx), R(A)) */
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_gv_set(mrb, syms[bx], regs[a]);
       NEXT;
     }
@@ -847,5 +1027,8 @@
     CASE(OP_GETSPECIAL) {
       /* A Bx   R(A) := Special[Bx] */
-      regs[GETARG_A(i)] = mrb_vm_special_get(mrb, GETARG_Bx(i));
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_value val = mrb_vm_special_get(mrb, bx);
+      regs[a] = val;
       NEXT;
     }
@@ -853,5 +1036,7 @@
     CASE(OP_SETSPECIAL) {
       /* A Bx   Special[Bx] := R(A) */
-      mrb_vm_special_set(mrb, GETARG_Bx(i), regs[GETARG_A(i)]);
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_vm_special_set(mrb, bx, regs[a]);
       NEXT;
     }
@@ -859,11 +1044,16 @@
     CASE(OP_GETIV) {
       /* A Bx   R(A) := ivget(Bx) */
-      regs[GETARG_A(i)] = mrb_vm_iv_get(mrb, syms[GETARG_Bx(i)]);
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_value val = mrb_vm_iv_get(mrb, syms[bx]);
+      regs[a] = val;
       NEXT;
     }
 
     CASE(OP_SETIV) {
-      /* ivset(Syms(Bx),R(A)) */
-      mrb_vm_iv_set(mrb, syms[GETARG_Bx(i)], regs[GETARG_A(i)]);
+      /* A Bx   ivset(Syms(Bx),R(A)) */
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_vm_iv_set(mrb, syms[bx], regs[a]);
       NEXT;
     }
@@ -871,13 +1061,19 @@
     CASE(OP_GETCV) {
       /* A Bx   R(A) := cvget(Syms(Bx)) */
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_value val;
       ERR_PC_SET(mrb, pc);
-      regs[GETARG_A(i)] = mrb_vm_cv_get(mrb, syms[GETARG_Bx(i)]);
+      val = mrb_vm_cv_get(mrb, syms[bx]);
       ERR_PC_CLR(mrb);
+      regs[a] = val;
       NEXT;
     }
 
     CASE(OP_SETCV) {
-      /* cvset(Syms(Bx),R(A)) */
-      mrb_vm_cv_set(mrb, syms[GETARG_Bx(i)], regs[GETARG_A(i)]);
+      /* A Bx   cvset(Syms(Bx),R(A)) */
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_vm_cv_set(mrb, syms[bx], regs[a]);
       NEXT;
     }
@@ -886,10 +1082,12 @@
       /* A Bx    R(A) := constget(Syms(Bx)) */
       mrb_value val;
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_sym sym = syms[bx];
 
       ERR_PC_SET(mrb, pc);
-      val = mrb_vm_const_get(mrb, syms[GETARG_Bx(i)]);
+      val = mrb_vm_const_get(mrb, sym);
       ERR_PC_CLR(mrb);
-      regs = mrb->c->stack;
-      regs[GETARG_A(i)] = val;
+      regs[a] = val;
       NEXT;
     }
@@ -897,5 +1095,7 @@
     CASE(OP_SETCONST) {
       /* A Bx   constset(Syms(Bx),R(A)) */
-      mrb_vm_const_set(mrb, syms[GETARG_Bx(i)], regs[GETARG_A(i)]);
+      int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
+      mrb_vm_const_set(mrb, syms[bx], regs[a]);
       NEXT;
     }
@@ -905,9 +1105,9 @@
       mrb_value val;
       int a = GETARG_A(i);
+      int bx = GETARG_Bx(i);
 
       ERR_PC_SET(mrb, pc);
-      val = mrb_const_get(mrb, regs[a], syms[GETARG_Bx(i)]);
+      val = mrb_const_get(mrb, regs[a], syms[bx]);
       ERR_PC_CLR(mrb);
-      regs = mrb->c->stack;
       regs[a] = val;
       NEXT;
@@ -917,6 +1117,6 @@
       /* A Bx    R(A+1)::Syms(Bx) := R(A) */
       int a = GETARG_A(i);
-
-      mrb_const_set(mrb, regs[a+1], syms[GETARG_Bx(i)], regs[a]);
+      int bx = GETARG_Bx(i);
+      mrb_const_set(mrb, regs[a+1], syms[bx], regs[a]);
       NEXT;
     }
@@ -924,8 +1124,9 @@
     CASE(OP_GETUPVAR) {
       /* A B C  R(A) := uvget(B,C) */
-      mrb_value *regs_a = regs + GETARG_A(i);
-      int up = GETARG_C(i);
-
-      struct REnv *e = uvenv(mrb, up);
+      int a = GETARG_A(i);
+      int b = GETARG_B(i);
+      int c = GETARG_C(i);
+      mrb_value *regs_a = regs + a;
+      struct REnv *e = uvenv(mrb, c);
 
       if (!e) {
@@ -933,6 +1134,5 @@
       }
       else {
-        int idx = GETARG_B(i);
-        *regs_a = e->stack[idx];
+        *regs_a = e->stack[b];
       }
       NEXT;
@@ -941,13 +1141,17 @@
     CASE(OP_SETUPVAR) {
       /* A B C  uvset(B,C,R(A)) */
-      int up = GETARG_C(i);
-
-      struct REnv *e = uvenv(mrb, up);
+      int a = GETARG_A(i);
+      int b = GETARG_B(i);
+      int c = GETARG_C(i);
+
+      struct REnv *e = uvenv(mrb, c);
 
       if (e) {
-        mrb_value *regs_a = regs + GETARG_A(i);
-        int idx = GETARG_B(i);
-        e->stack[idx] = *regs_a;
-        mrb_write_barrier(mrb, (struct RBasic*)e);
+        mrb_value *regs_a = regs + a;
+
+        if (b < MRB_ENV_STACK_LEN(e)) {
+          e->stack[b] = *regs_a;
+          mrb_write_barrier(mrb, (struct RBasic*)e);
+        }
       }
       NEXT;
@@ -956,5 +1160,6 @@
     CASE(OP_JMP) {
       /* sBx    pc+=sBx */
-      pc += GETARG_sBx(i);
+      int sbx = GETARG_sBx(i);
+      pc += sbx;
       JUMP;
     }
@@ -962,6 +1167,8 @@
     CASE(OP_JMPIF) {
       /* A sBx  if R(A) pc+=sBx */
-      if (mrb_test(regs[GETARG_A(i)])) {
-        pc += GETARG_sBx(i);
+      int a = GETARG_A(i);
+      int sbx = GETARG_sBx(i);
+      if (mrb_test(regs[a])) {
+        pc += sbx;
         JUMP;
       }
@@ -971,6 +1178,8 @@
     CASE(OP_JMPNOT) {
       /* A sBx  if !R(A) pc+=sBx */
-      if (!mrb_test(regs[GETARG_A(i)])) {
-        pc += GETARG_sBx(i);
+      int a = GETARG_A(i);
+      int sbx = GETARG_sBx(i);
+      if (!mrb_test(regs[a])) {
+        pc += sbx;
         JUMP;
       }
@@ -980,17 +1189,52 @@
     CASE(OP_ONERR) {
       /* sBx    pc+=sBx on exception */
+      int sbx = GETARG_sBx(i);
       if (mrb->c->rsize <= mrb->c->ci->ridx) {
-        if (mrb->c->rsize == 0) mrb->c->rsize = 16;
+        if (mrb->c->rsize == 0) mrb->c->rsize = RESCUE_STACK_INIT_SIZE;
         else mrb->c->rsize *= 2;
         mrb->c->rescue = (mrb_code **)mrb_realloc(mrb, mrb->c->rescue, sizeof(mrb_code*) * mrb->c->rsize);
       }
-      mrb->c->rescue[mrb->c->ci->ridx++] = pc + GETARG_sBx(i);
+      mrb->c->rescue[mrb->c->ci->ridx++] = pc + sbx;
       NEXT;
     }
 
     CASE(OP_RESCUE) {
-      /* A      R(A) := exc; clear(exc) */
-      SET_OBJ_VALUE(regs[GETARG_A(i)], mrb->exc);
-      mrb->exc = 0;
+      /* A B    R(A) := exc; clear(exc); R(B) := matched (bool) */
+      int a = GETARG_A(i);
+      int b = GETARG_B(i);
+      int c = GETARG_C(i);
+      mrb_value exc;
+
+      if (c == 0) {
+        exc = mrb_obj_value(mrb->exc);
+        mrb->exc = 0;
+      }
+      else {           /* continued; exc taken from R(A) */
+        exc = regs[a];
+      }
+      if (b != 0) {
+        mrb_value e = regs[b];
+        struct RClass *ec;
+
+        switch (mrb_type(e)) {
+        case MRB_TT_CLASS:
+        case MRB_TT_MODULE:
+          break;
+        default:
+          {
+            mrb_value exc;
+
+            exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR,
+                  "class or module required for rescue clause");
+            mrb_exc_set(mrb, exc);
+            goto L_RAISE;
+          }
+        }
+        ec = mrb_class_ptr(e);
+        regs[b] = mrb_bool_value(mrb_obj_is_kind_of(mrb, exc, ec));
+      }
+      if (a != 0 && c == 0) {
+        regs[a] = exc;
+      }
       NEXT;
     }
@@ -1008,5 +1252,7 @@
     CASE(OP_RAISE) {
       /* A      raise(R(A)) */
-      mrb->exc = mrb_obj_ptr(regs[GETARG_A(i)]);
+      int a = GETARG_A(i);
+
+      mrb_exc_set(mrb, regs[a]);
       goto L_RAISE;
     }
@@ -1014,14 +1260,16 @@
     CASE(OP_EPUSH) {
       /* Bx     ensure_push(SEQ[Bx]) */
+      int bx = GETARG_Bx(i);
       struct RProc *p;
 
-      p = mrb_closure_new(mrb, irep->reps[GETARG_Bx(i)]);
+      p = mrb_closure_new(mrb, irep->reps[bx]);
       /* push ensure_stack */
-      if (mrb->c->esize <= mrb->c->ci->eidx) {
-        if (mrb->c->esize == 0) mrb->c->esize = 16;
+      if (mrb->c->esize <= mrb->c->eidx+1) {
+        if (mrb->c->esize == 0) mrb->c->esize = ENSURE_STACK_INIT_SIZE;
         else mrb->c->esize *= 2;
         mrb->c->ensure = (struct RProc **)mrb_realloc(mrb, mrb->c->ensure, sizeof(struct RProc*) * mrb->c->esize);
       }
-      mrb->c->ensure[mrb->c->ci->eidx++] = p;
+      mrb->c->ensure[mrb->c->eidx++] = p;
+      mrb->c->ensure[mrb->c->eidx] = NULL;
       ARENA_RESTORE(mrb, ai);
       NEXT;
@@ -1032,8 +1280,8 @@
       int a = GETARG_A(i);
       mrb_callinfo *ci = mrb->c->ci;
-      int n, eidx = ci->eidx;
-
-      for (n=0; n<a && (ci == mrb->c->cibase || eidx > ci[-1].eidx); n++) {
-        ecall(mrb, --eidx);
+      int n, epos = ci->epos;
+
+      for (n=0; n<a && mrb->c->eidx > epos; n++) {
+        ecall(mrb, --mrb->c->eidx);
         ARENA_RESTORE(mrb, ai);
       }
@@ -1061,15 +1309,34 @@
       struct RProc *m;
       struct RClass *c;
-      mrb_callinfo *ci;
+      mrb_callinfo *ci = mrb->c->ci;
       mrb_value recv, result;
       mrb_sym mid = syms[GETARG_B(i)];
+      int bidx;
+      mrb_value blk;
 
       recv = regs[a];
+      if (n == CALL_MAXARGS) {
+        bidx = a+2;
+      }
+      else {
+        bidx = a+n+1;
+      }
       if (GET_OPCODE(i) != OP_SENDB) {
-        if (n == CALL_MAXARGS) {
-          SET_NIL_VALUE(regs[a+2]);
-        }
-        else {
-          SET_NIL_VALUE(regs[a+n+1]);
+        if (bidx >= ci->nregs) {
+          stack_extend(mrb, bidx+1);
+          ci->nregs = bidx+1;
+        }
+        SET_NIL_VALUE(regs[bidx]);
+        blk = mrb_nil_value();
+      }
+      else {
+        blk = regs[bidx];
+        if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) {
+          if (bidx >= ci->nregs) {
+            stack_extend(mrb, bidx+1);
+            ci->nregs = bidx+1;
+          }
+          result = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc");
+          blk = regs[bidx] = result;
         }
       }
@@ -1090,14 +1357,17 @@
             args = mrb_ary_new_from_values(mrb, n, regs+a+1);
           }
+          ERR_PC_SET(mrb, pc);
           mrb_method_missing(mrb, mid, recv, args);
         }
         mid = missing;
-        if (n == CALL_MAXARGS) {
-          mrb_ary_unshift(mrb, regs[a+1], sym);
-        }
-        else {
-          value_move(regs+a+2, regs+a+1, ++n);
-          regs[a+1] = sym;
-        }
+        if (n != CALL_MAXARGS) {
+          if (a+2 >= irep->nregs) {
+            stack_extend(mrb, a+3);
+          }
+          regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1);
+          regs[a+2] = blk;
+          n = CALL_MAXARGS;
+        }
+        mrb_ary_unshift(mrb, regs[a+1], sym);
       }
 
@@ -1125,11 +1395,23 @@
         }
         result = m->body.func(mrb, recv);
-        mrb->c->stack[0] = result;
         mrb_gc_arena_restore(mrb, ai);
         if (mrb->exc) goto L_RAISE;
-        /* pop stackpos */
         ci = mrb->c->ci;
+        if (GET_OPCODE(i) == OP_SENDB) {
+          if (mrb_type(blk) == MRB_TT_PROC) {
+            struct RProc *p = mrb_proc_ptr(blk);
+
+            if (p && !MRB_PROC_STRICT_P(p) && p->env == ci[-1].env) {
+              p->flags |= MRB_PROC_ORPHAN;
+            }
+          }
+        }
         if (!ci->target_class) { /* return from context modifying method (resume/yield) */
-          if (!MRB_PROC_CFUNC_P(ci[-1].proc)) {
+          if (ci->acc == CI_ACC_RESUMED) {
+            mrb->jmp = prev_jmp;
+            return result;
+          }
+          else {
+            mrb_assert(!MRB_PROC_CFUNC_P(ci[-1].proc));
             proc = ci[-1].proc;
             irep = proc->body.irep;
@@ -1138,5 +1420,7 @@
           }
         }
-        regs = mrb->c->stack = ci->stackent;
+        mrb->c->stack[0] = result;
+        /* pop stackpos */
+        mrb->c->stack = ci->stackent;
         pc = ci->pc;
         cipop(mrb);
@@ -1152,11 +1436,10 @@
         if (n == CALL_MAXARGS) {
           ci->argc = -1;
-          stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs, 3);
+          stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs);
         }
         else {
           ci->argc = n;
-          stack_extend(mrb, irep->nregs,  n+2);
-        }
-        regs = mrb->c->stack;
+          stack_extend(mrb, irep->nregs);
+        }
         pc = irep->iseq;
         JUMP;
@@ -1166,4 +1449,5 @@
     CASE(OP_FSEND) {
       /* A B C  R(A) := fcall(R(A),Syms(B),R(A+1),... ,R(A+C-1)) */
+      /* not implemented yet */
       NEXT;
     }
@@ -1180,7 +1464,13 @@
       ci->proc = m;
       if (m->env) {
-        if (m->env->mid) {
-          ci->mid = m->env->mid;
-        }
+        mrb_sym mid;
+
+        if (MRB_ENV_STACK_SHARED_P(m->env)) {
+          mid = m->env->cxt.c->cibase[m->env->cioff].mid;
+        }
+        else {
+          mid = m->env->cxt.mid;
+        }
+        if (mid) ci->mid = mid;
         if (!m->env->stack) {
           m->env->stack = mrb->c->stack;
@@ -1195,5 +1485,5 @@
         /* pop stackpos */
         ci = mrb->c->ci;
-        regs = mrb->c->stack = ci->stackent;
+        mrb->c->stack = ci->stackent;
         regs[ci->acc] = recv;
         pc = ci->pc;
@@ -1215,12 +1505,16 @@
         syms = irep->syms;
         ci->nregs = irep->nregs;
+        stack_extend(mrb, irep->nregs);
         if (ci->argc < 0) {
-          stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs, 3);
-        }
-        else {
-          stack_extend(mrb, irep->nregs, ci->argc+2);
-        }
-        regs = mrb->c->stack;
-        regs[0] = m->env->stack[0];
+          if (irep->nregs > 3) {
+            stack_clear(regs+3, irep->nregs-3);
+          }
+        }
+        else if (ci->argc+2 < irep->nregs) {
+          stack_clear(regs+ci->argc+2, irep->nregs-ci->argc-2);
+        }
+        if (m->env) {
+          regs[0] = m->env->stack[0];
+        }
         pc = irep->iseq;
         JUMP;
@@ -1237,10 +1531,12 @@
       int a = GETARG_A(i);
       int n = GETARG_C(i);
-
-      if (mid == 0) {
+      mrb_value blk;
+      int bidx;
+
+      if (mid == 0 || !ci->target_class) {
         mrb_value exc;
 
         exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method");
-        mrb->exc = mrb_obj_ptr(exc);
+        mrb_exc_set(mrb, exc);
         goto L_RAISE;
       }
@@ -1249,6 +1545,23 @@
       m = mrb_method_search_vm(mrb, &c, mid);
       if (!m) {
-        mid = mrb_intern_lit(mrb, "method_missing");
-        m = mrb_method_search_vm(mrb, &c, mid);
+        mrb_sym missing = mrb_intern_lit(mrb, "method_missing");
+        m = mrb_method_search_vm(mrb, &c, missing);
+        if (!m) {
+          mrb_value args;
+
+          if (n == CALL_MAXARGS) {
+            args = regs[a+1];
+          }
+          else {
+            args = mrb_ary_new_from_values(mrb, n, regs+a+1);
+          }
+          ERR_PC_SET(mrb, pc);
+          mrb_method_missing(mrb, mid, recv, args);
+        }
+        mid = missing;
+        if (n == CALL_MAXARGS-1) {
+          regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1);
+          n++;
+        }
         if (n == CALL_MAXARGS) {
           mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid));
@@ -1258,4 +1571,22 @@
           SET_SYM_VALUE(regs[a+1], ci->mid);
         }
+      }
+
+      if (n == CALL_MAXARGS) {
+        bidx = a+2;
+      }
+      else {
+        bidx = a+n+1;
+      }
+      blk = regs[bidx];
+      if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) {
+        mrb_value result;
+
+        if (bidx >= ci->nregs) {
+          stack_extend(mrb, bidx+1);
+          ci->nregs = bidx+1;
+        }
+        result = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc");
+        regs[bidx] = result;
       }
 
@@ -1265,4 +1596,6 @@
       ci->proc = m;
       ci->stackent = mrb->c->stack;
+      ci->target_class = c;
+      ci->pc = pc + 1;
       if (n == CALL_MAXARGS) {
         ci->argc = -1;
@@ -1271,6 +1604,4 @@
         ci->argc = n;
       }
-      ci->target_class = c;
-      ci->pc = pc + 1;
 
       /* prepare stack */
@@ -1279,4 +1610,6 @@
 
       if (MRB_PROC_CFUNC_P(m)) {
+        mrb_value v;
+
         if (n == CALL_MAXARGS) {
           ci->nregs = 3;
@@ -1285,11 +1618,27 @@
           ci->nregs = n + 2;
         }
-        mrb->c->stack[0] = m->body.func(mrb, recv);
+        v = m->body.func(mrb, recv);
         mrb_gc_arena_restore(mrb, ai);
         if (mrb->exc) goto L_RAISE;
+        ci = mrb->c->ci;
+        if (!ci->target_class) { /* return from context modifying method (resume/yield) */
+          if (ci->acc == CI_ACC_RESUMED) {
+            mrb->jmp = prev_jmp;
+            return v;
+          }
+          else {
+            mrb_assert(!MRB_PROC_CFUNC_P(ci[-1].proc));
+            proc = ci[-1].proc;
+            irep = proc->body.irep;
+            pool = irep->pool;
+            syms = irep->syms;
+          }
+        }
+        mrb->c->stack[0] = v;
         /* pop stackpos */
-        regs = mrb->c->stack = mrb->c->ci->stackent;
+        mrb->c->stack = ci->stackent;
+        pc = ci->pc;
         cipop(mrb);
-        NEXT;
+        JUMP;
       }
       else {
@@ -1304,10 +1653,9 @@
         ci->nregs = irep->nregs;
         if (n == CALL_MAXARGS) {
-          stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs, 3);
+          stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs);
         }
         else {
-          stack_extend(mrb, irep->nregs, ci->argc+2);
-        }
-        regs = mrb->c->stack;
+          stack_extend(mrb, irep->nregs);
+        }
         pc = irep->iseq;
         JUMP;
@@ -1325,14 +1673,16 @@
       mrb_value *stack;
 
+      if (mrb->c->ci->mid == 0 || mrb->c->ci->target_class == NULL) {
+        mrb_value exc;
+
+      L_NOSUPER:
+        exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method");
+        mrb_exc_set(mrb, exc);
+        goto L_RAISE;
+      }
       if (lv == 0) stack = regs + 1;
       else {
         struct REnv *e = uvenv(mrb, lv-1);
-        if (!e) {
-          mrb_value exc;
-
-          exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method");
-          mrb->exc = mrb_obj_ptr(exc);
-          goto L_RAISE;
-        }
+        if (!e) goto L_NOSUPER;
         stack = e->stack + 1;
       }
@@ -1388,7 +1738,4 @@
       mrb_value *blk = &argv[argc < 0 ? 1 : argc];
 
-      if (!mrb_nil_p(*blk) && mrb_type(*blk) != MRB_TT_PROC) {
-        *blk = mrb_convert_type(mrb, *blk, MRB_TT_PROC, "Proc", "to_proc");
-      }
       if (argc < 0) {
         struct RArray *ary = mrb_ary_ptr(regs[1]);
@@ -1410,5 +1757,4 @@
         argv = mrb_ary_ptr(argv[0])->ptr;
       }
-      mrb->c->ci->argc = len;
       if (argc < len) {
         int mlen = m2;
@@ -1424,6 +1770,12 @@
           value_move(&regs[1], argv, argc-mlen); /* m1 + o */
         }
+        if (argc < m1) {
+          stack_clear(&regs[argc+1], m1-argc);
+        }
         if (mlen) {
           value_move(&regs[len-m2+1], &argv[argc-mlen], mlen);
+        }
+        if (mlen < m2) {
+          stack_clear(&regs[len-m2+mlen+1], m2-mlen);
         }
         if (r) {
@@ -1454,4 +1806,9 @@
         pc += o + 1;
       }
+      mrb->c->ci->argc = len;
+      /* clear local (but non-argument) variables */
+      if (irep->nlocals-len-2 > 0) {
+        stack_clear(&regs[len+2], irep->nlocals-len-2);
+      }
       JUMP;
     }
@@ -1474,32 +1831,51 @@
     CASE(OP_RETURN) {
       /* A B     return R(A) (B=normal,in-block return/break) */
+      mrb_callinfo *ci;
+
+      ci = mrb->c->ci;
+      if (ci->mid) {
+        mrb_value blk;
+
+        if (ci->argc < 0) {
+          blk = regs[2];
+        }
+        else {
+          blk = regs[ci->argc+1];
+        }
+        if (mrb_type(blk) == MRB_TT_PROC) {
+          struct RProc *p = mrb_proc_ptr(blk);
+
+          if (!MRB_PROC_STRICT_P(proc) &&
+              ci > mrb->c->cibase && p->env == ci[-1].env) {
+            p->flags |= MRB_PROC_ORPHAN;
+          }
+        }
+      }
+
       if (mrb->exc) {
-        mrb_callinfo *ci;
-        int eidx;
+        mrb_callinfo *ci0;
+        mrb_value *stk;
 
       L_RAISE:
-        ci = mrb->c->ci;
-        mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern_lit(mrb, "lastpc"), mrb_cptr_value(mrb, pc));
-        mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern_lit(mrb, "ciidx"), mrb_fixnum_value(ci - mrb->c->cibase));
-        eidx = ci->eidx;
+        ci0 = ci = mrb->c->ci;
         if (ci == mrb->c->cibase) {
-          if (ci->ridx == 0) goto L_STOP;
+          if (ci->ridx == 0) goto L_FTOP;
           goto L_RESCUE;
         }
+        stk = mrb->c->stack;
         while (ci[0].ridx == ci[-1].ridx) {
           cipop(mrb);
-          ci = mrb->c->ci;
-          mrb->c->stack = ci[1].stackent;
-          if (ci[1].acc == CI_ACC_SKIP && prev_jmp) {
+          mrb->c->stack = ci->stackent;
+          if (ci->acc == CI_ACC_SKIP && prev_jmp) {
             mrb->jmp = prev_jmp;
             MRB_THROW(prev_jmp);
           }
+          ci = mrb->c->ci;
           if (ci == mrb->c->cibase) {
-            while (eidx > 0) {
-              ecall(mrb, --eidx);
-            }
+            mrb->c->stack = stk;
             if (ci->ridx == 0) {
+            L_FTOP:             /* fiber top */
               if (mrb->c == mrb->root_c) {
-                regs = mrb->c->stack = mrb->c->stbase;
+                mrb->c->stack = mrb->c->stbase;
                 goto L_STOP;
               }
@@ -1507,4 +1883,7 @@
                 struct mrb_context *c = mrb->c;
 
+                if (c->fib) {
+                  mrb_write_barrier(mrb, (struct RBasic*)c->fib);
+                }
                 mrb->c = c->prev;
                 c->prev = NULL;
@@ -1516,6 +1895,7 @@
           /* call ensure only when we skip this callinfo */
           if (ci[0].ridx == ci[-1].ridx) {
-            while (eidx > ci[-1].eidx) {
-              ecall(mrb, --eidx);
+            while (mrb->c->eidx > ci->epos) {
+              ecall(mrb, --mrb->c->eidx);
+              ci = mrb->c->ci;
             }
           }
@@ -1527,32 +1907,49 @@
         pool = irep->pool;
         syms = irep->syms;
-        regs = mrb->c->stack = ci[1].stackent;
+        if (ci != ci0) {
+          mrb->c->stack = ci[1].stackent;
+        }
+        stack_extend(mrb, irep->nregs);
         pc = mrb->c->rescue[--ci->ridx];
       }
       else {
-        mrb_callinfo *ci = mrb->c->ci;
-        int acc, eidx = mrb->c->ci->eidx;
-        mrb_value v = regs[GETARG_A(i)];
-
+        int acc;
+        mrb_value v;
+
+        v = regs[GETARG_A(i)];
+        mrb_gc_protect(mrb, v);
         switch (GETARG_B(i)) {
         case OP_R_RETURN:
           /* Fall through to OP_R_NORMAL otherwise */
-          if (proc->env && !MRB_PROC_STRICT_P(proc)) {
+          if (ci->acc >=0 && proc->env && !MRB_PROC_STRICT_P(proc)) {
             struct REnv *e = top_env(mrb, proc);
-
-            if (!MRB_ENV_STACK_SHARED_P(e)) {
+            mrb_callinfo *ce;
+
+            if (!MRB_ENV_STACK_SHARED_P(e) || e->cxt.c != mrb->c) {
               localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
               goto L_RAISE;
             }
-            ci = mrb->c->cibase + e->cioff;
-            if (ci == mrb->c->cibase) {
+            
+            ce = mrb->c->cibase + e->cioff;
+            while (ci >= ce) {
+              if (ci->env) {
+                mrb_env_unshare(mrb, ci->env);
+              }
+              if (ci->acc < 0) {
+                localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
+                goto L_RAISE;
+              }
+              ci--;
+            }
+            if (ce == mrb->c->cibase) {
               localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
               goto L_RAISE;
             }
             mrb->c->stack = mrb->c->ci->stackent;
-            mrb->c->ci = ci;
+            mrb->c->ci = ce;
             break;
           }
         case OP_R_NORMAL:
+        NORMAL_RETURN:
           if (ci == mrb->c->cibase) {
             if (!mrb->c->prev) { /* toplevel return */
@@ -1562,6 +1959,9 @@
             if (mrb->c->prev->ci == mrb->c->prev->cibase) {
               mrb_value exc = mrb_exc_new_str_lit(mrb, E_FIBER_ERROR, "double resume");
-              mrb->exc = mrb_obj_ptr(exc);
+              mrb_exc_set(mrb, exc);
               goto L_RAISE;
+            }
+            while (mrb->c->eidx > 0) {
+              ecall(mrb, --mrb->c->eidx);
             }
             /* automatic yield at the end */
@@ -1573,7 +1973,16 @@
           break;
         case OP_R_BREAK:
+          if (MRB_PROC_STRICT_P(proc)) goto NORMAL_RETURN;
+          if (MRB_PROC_ORPHAN_P(proc)) { 
+            mrb_value exc;
+
+          L_BREAK_ERROR:
+            exc = mrb_exc_new_str_lit(mrb, E_LOCALJUMP_ERROR,
+                                      "break from proc-closure");
+            mrb_exc_set(mrb, exc);
+            goto L_RAISE;
+          }
           if (!proc->env || !MRB_ENV_STACK_SHARED_P(proc->env)) {
-            localjump_error(mrb, LOCALJUMP_ERROR_BREAK);
-            goto L_RAISE;
+            goto L_BREAK_ERROR;
           }
           /* break from fiber block */
@@ -1581,14 +1990,37 @@
             struct mrb_context *c = mrb->c;
 
+            while (mrb->c->eidx > 0) {
+              ecall(mrb, --mrb->c->eidx);
+            }
             mrb->c = c->prev;
             c->prev = NULL;
-          }
-          ci = mrb->c->ci;
+            ci = mrb->c->ci;
+          }
+          if (ci->acc < 0) {
+            while (mrb->c->eidx > mrb->c->ci->epos) {
+              ecall(mrb, --mrb->c->eidx);
+            }
+            ARENA_RESTORE(mrb, ai);
+            mrb->c->vmexec = FALSE;
+            mrb->exc = (struct RObject*)break_new(mrb, proc, v);
+            mrb->jmp = prev_jmp;
+            MRB_THROW(prev_jmp);
+          }
+          if (FALSE) {
+          L_BREAK:
+            v = ((struct RBreak*)mrb->exc)->val;
+            proc = ((struct RBreak*)mrb->exc)->proc;
+            mrb->exc = NULL;
+            ci = mrb->c->ci;
+          }
           mrb->c->stack = ci->stackent;
           mrb->c->ci = mrb->c->cibase + proc->env->cioff + 1;
           while (ci > mrb->c->ci) {
+            if (ci->env) {
+              mrb_env_unshare(mrb, ci->env);
+            }
             if (ci[-1].acc == CI_ACC_SKIP) {
               mrb->c->ci = ci;
-              break;
+              goto L_BREAK_ERROR;
             }
             ci--;
@@ -1599,16 +2031,24 @@
           break;
         }
-        while (eidx > mrb->c->ci[-1].eidx) {
-          ecall(mrb, --eidx);
-        }
-        cipop(mrb);
-        acc = ci->acc;
-        pc = ci->pc;
-        regs = mrb->c->stack = ci->stackent;
-        if (acc == CI_ACC_SKIP) {
+        while (mrb->c->eidx > mrb->c->ci->epos) {
+          ecall(mrb, --mrb->c->eidx);
+        }
+        if (mrb->c->vmexec && !mrb->c->ci->target_class) {
+          ARENA_RESTORE(mrb, ai);
+          mrb->c->vmexec = FALSE;
           mrb->jmp = prev_jmp;
           return v;
         }
-        DEBUG(printf("from :%s\n", mrb_sym2name(mrb, ci->mid)));
+        ci = mrb->c->ci;
+        acc = ci->acc;
+        mrb->c->stack = ci->stackent;
+        cipop(mrb);
+        if (acc == CI_ACC_SKIP || acc == CI_ACC_DIRECT) {
+          ARENA_RESTORE(mrb, ai);
+          mrb->jmp = prev_jmp;
+          return v;
+        }
+        pc = ci->pc;
+        DEBUG(fprintf(stderr, "from :%s\n", mrb_sym2name(mrb, ci->mid)));
         proc = mrb->c->ci->proc;
         irep = proc->body.irep;
@@ -1617,4 +2057,5 @@
 
         regs[acc] = v;
+        ARENA_RESTORE(mrb, ai);
       }
       JUMP;
@@ -1636,7 +2077,19 @@
       if (!m) {
         mrb_value sym = mrb_symbol_value(mid);
-
-        mid = mrb_intern_lit(mrb, "method_missing");
-        m = mrb_method_search_vm(mrb, &c, mid);
+        mrb_sym missing = mrb_intern_lit(mrb, "method_missing");
+        m = mrb_method_search_vm(mrb, &c, missing);
+        if (!m) {
+          mrb_value args;
+
+          if (n == CALL_MAXARGS) {
+            args = regs[a+1];
+          }
+          else {
+            args = mrb_ary_new_from_values(mrb, n, regs+a+1);
+          }
+          ERR_PC_SET(mrb, pc);
+          mrb_method_missing(mrb, mid, recv, args);
+        }
+        mid = missing;
         if (n == CALL_MAXARGS) {
           mrb_ary_unshift(mrb, regs[a+1], sym);
@@ -1663,5 +2116,6 @@
 
       if (MRB_PROC_CFUNC_P(m)) {
-        mrb->c->stack[0] = m->body.func(mrb, recv);
+        mrb_value v = m->body.func(mrb, recv);
+        mrb->c->stack[0] = v;
         mrb_gc_arena_restore(mrb, ai);
         goto L_RETURN;
@@ -1673,10 +2127,9 @@
         syms = irep->syms;
         if (ci->argc < 0) {
-          stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs, 3);
+          stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs);
         }
         else {
-          stack_extend(mrb, irep->nregs, ci->argc+2);
-        }
-        regs = mrb->c->stack;
+          stack_extend(mrb, irep->nregs);
+        }
         pc = irep->iseq;
       }
@@ -1697,9 +2150,14 @@
       else {
         struct REnv *e = uvenv(mrb, lv-1);
-        if (!e) {
+        if (!e || e->cioff == 0 ||
+            (!MRB_ENV_STACK_SHARED_P(e) && e->cxt.mid == 0)) {
           localjump_error(mrb, LOCALJUMP_ERROR_YIELD);
           goto L_RAISE;
         }
         stack = e->stack + 1;
+      }
+      if (mrb_nil_p(stack[m1+r+m2])) {
+        localjump_error(mrb, LOCALJUMP_ERROR_YIELD);
+        goto L_RAISE;
       }
       regs[a] = stack[m1+r+m2];
@@ -1833,23 +2291,13 @@
       case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
         {
-          mrb_value z;
-
-          z = mrb_fixnum_mul(mrb, regs[a], regs[a+1]);
-
-          switch (mrb_type(z)) {
-          case MRB_TT_FIXNUM:
-            {
-              SET_INT_VALUE(regs[a], mrb_fixnum(z));
-            }
+          mrb_int x, y, z;
+
+          x = mrb_fixnum(regs[a]);
+          y = mrb_fixnum(regs[a+1]);
+          if (mrb_int_mul_overflow(x, y, &z)) {
+            SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * (mrb_float)y);
             break;
-          case MRB_TT_FLOAT:
-            {
-              SET_FLOAT_VALUE(mrb, regs[a], mrb_float(z));
-            }
-            break;
-          default:
-            /* cannot happen */
-            break;
-          }
+          }
+          SET_INT_VALUE(regs[a], z);
         }
         break;
@@ -1936,5 +2384,6 @@
 #ifdef MRB_NAN_BOXING
       if (isnan(mrb_float(regs[a]))) {
-        regs[a] = mrb_float_value(mrb, mrb_float(regs[a]));
+        mrb_value v = mrb_float_value(mrb, mrb_float(regs[a]));
+        regs[a] = v;
       }
 #endif
@@ -2089,5 +2538,9 @@
     CASE(OP_ARRAY) {
       /* A B C          R(A) := ary_new(R(B),R(B+1)..R(B+C)) */
-      regs[GETARG_A(i)] = mrb_ary_new_from_values(mrb, GETARG_C(i), &regs[GETARG_B(i)]);
+      int a = GETARG_A(i);
+      int b = GETARG_B(i);
+      int c = GETARG_C(i);
+      mrb_value v = mrb_ary_new_from_values(mrb, c, &regs[b]);
+      regs[a] = v;
       ARENA_RESTORE(mrb, ai);
       NEXT;
@@ -2096,6 +2549,8 @@
     CASE(OP_ARYCAT) {
       /* A B            mrb_ary_concat(R(A),R(B)) */
-      mrb_ary_concat(mrb, regs[GETARG_A(i)],
-                     mrb_ary_splat(mrb, regs[GETARG_B(i)]));
+      int a = GETARG_A(i);
+      int b = GETARG_B(i);
+      mrb_value splat = mrb_ary_splat(mrb, regs[b]);
+      mrb_ary_concat(mrb, regs[a], splat);
       ARENA_RESTORE(mrb, ai);
       NEXT;
@@ -2104,5 +2559,7 @@
     CASE(OP_ARYPUSH) {
       /* A B            R(A).push(R(B)) */
-      mrb_ary_push(mrb, regs[GETARG_A(i)], regs[GETARG_B(i)]);
+      int a = GETARG_A(i);
+      int b = GETARG_B(i);
+      mrb_ary_push(mrb, regs[a], regs[b]);
       NEXT;
     }
@@ -2111,10 +2568,11 @@
       /* A B C          R(A) := R(B)[C] */
       int a = GETARG_A(i);
+      int b = GETARG_B(i);
       int c = GETARG_C(i);
-      mrb_value v = regs[GETARG_B(i)];
+      mrb_value v = regs[b];
 
       if (!mrb_array_p(v)) {
         if (c == 0) {
-          regs[GETARG_A(i)] = v;
+          regs[a] = v;
         }
         else {
@@ -2123,5 +2581,6 @@
       }
       else {
-        regs[GETARG_A(i)] = mrb_ary_ref(mrb, v, c);
+        v = mrb_ary_ref(mrb, v, c);
+        regs[a] = v;
       }
       NEXT;
@@ -2130,5 +2589,8 @@
     CASE(OP_ASET) {
       /* A B C          R(B)[C] := R(A) */
-      mrb_ary_set(mrb, regs[GETARG_B(i)], GETARG_C(i), regs[GETARG_A(i)]);
+      int a = GETARG_A(i);
+      int b = GETARG_B(i);
+      int c = GETARG_C(i);
+      mrb_ary_set(mrb, regs[b], c, regs[a]);
       NEXT;
     }
@@ -2140,5 +2602,4 @@
       int pre  = GETARG_B(i);
       int post = GETARG_C(i);
-
       struct RArray *ary;
       int len, idx;
@@ -2150,5 +2611,6 @@
       len = ary->len;
       if (len > pre + post) {
-        regs[a++] = mrb_ary_new_from_values(mrb, len - pre - post, ary->ptr+pre);
+        v = mrb_ary_new_from_values(mrb, len - pre - post, ary->ptr+pre);
+        regs[a++] = v;
         while (post--) {
           regs[a++] = ary->ptr[len-post-1];
@@ -2156,5 +2618,6 @@
       }
       else {
-        regs[a++] = mrb_ary_new_capa(mrb, 0);
+        v = mrb_ary_new_capa(mrb, 0);
+        regs[a++] = v;
         for (idx=0; idx+pre<len; idx++) {
           regs[a+idx] = ary->ptr[pre+idx];
@@ -2171,5 +2634,6 @@
     CASE(OP_STRING) {
       /* A Bx           R(A) := str_new(Lit(Bx)) */
-      regs[GETARG_A(i)] = mrb_str_dup(mrb, pool[GETARG_Bx(i)]);
+      mrb_value str = mrb_str_dup(mrb, pool[GETARG_Bx(i)]);
+      regs[GETARG_A(i)] = str;
       ARENA_RESTORE(mrb, ai);
       NEXT;
@@ -2179,5 +2643,4 @@
       /* A B    R(A).concat(R(B)) */
       mrb_str_concat(mrb, regs[GETARG_A(i)], regs[GETARG_B(i)]);
-      regs = mrb->c->stack;
       NEXT;
     }
@@ -2224,5 +2687,5 @@
     CASE(OP_CLASS) {
       /* A B    R(A) := newclass(R(A),Syms(B),R(A+1)) */
-      struct RClass *c = 0;
+      struct RClass *c = 0, *baseclass;
       int a = GETARG_A(i);
       mrb_value base, super;
@@ -2232,5 +2695,8 @@
       super = regs[a+1];
       if (mrb_nil_p(base)) {
-        base = mrb_obj_value(mrb->c->ci->target_class);
+        baseclass = mrb->c->ci->proc->target_class;
+        if (!baseclass) baseclass = mrb->c->ci->target_class;
+
+        base = mrb_obj_value(baseclass);
       }
       c = mrb_vm_define_class(mrb, base, super, id);
@@ -2242,5 +2708,5 @@
     CASE(OP_MODULE) {
       /* A B            R(A) := newmodule(R(A),Syms(B)) */
-      struct RClass *c = 0;
+      struct RClass *c = 0, *baseclass;
       int a = GETARG_A(i);
       mrb_value base;
@@ -2249,5 +2715,8 @@
       base = regs[a];
       if (mrb_nil_p(base)) {
-        base = mrb_obj_value(mrb->c->ci->target_class);
+        baseclass = mrb->c->ci->proc->target_class;
+        if (!baseclass) baseclass = mrb->c->ci->target_class;
+
+        base = mrb_obj_value(baseclass);
       }
       c = mrb_vm_define_module(mrb, base, id);
@@ -2263,4 +2732,8 @@
       mrb_value recv = regs[a];
       struct RProc *p;
+
+      /* prepare closure */
+      p = mrb_closure_new(mrb, irep->reps[GETARG_Bx(i)]);
+      p->c = NULL;
 
       /* prepare stack */
@@ -2276,28 +2749,16 @@
       mrb->c->stack += a;
 
-      p = mrb_proc_new(mrb, irep->reps[GETARG_Bx(i)]);
+      /* setup closure */
       p->target_class = ci->target_class;
       ci->proc = p;
 
-      if (MRB_PROC_CFUNC_P(p)) {
-        ci->nregs = 0;
-        mrb->c->stack[0] = p->body.func(mrb, recv);
-        mrb_gc_arena_restore(mrb, ai);
-        if (mrb->exc) goto L_RAISE;
-        /* pop stackpos */
-        regs = mrb->c->stack = mrb->c->ci->stackent;
-        cipop(mrb);
-        NEXT;
-      }
-      else {
-        irep = p->body.irep;
-        pool = irep->pool;
-        syms = irep->syms;
-        stack_extend(mrb, irep->nregs, 1);
-        ci->nregs = irep->nregs;
-        regs = mrb->c->stack;
-        pc = irep->iseq;
-        JUMP;
-      }
+      irep = p->body.irep;
+      pool = irep->pool;
+      syms = irep->syms;
+      stack_extend(mrb, irep->nregs);
+      stack_clear(regs+1, irep->nregs-1);
+      ci->nregs = irep->nregs;
+      pc = irep->iseq;
+      JUMP;
     }
 
@@ -2324,5 +2785,5 @@
       if (!mrb->c->ci->target_class) {
         mrb_value exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, "no target class or module");
-        mrb->exc = mrb_obj_ptr(exc);
+        mrb_exc_set(mrb, exc);
         goto L_RAISE;
       }
@@ -2334,5 +2795,6 @@
       /* A B C  R(A) := range_new(R(B),R(B+1),C) */
       int b = GETARG_B(i);
-      regs[GETARG_A(i)] = mrb_range_new(mrb, regs[b], regs[b+1], GETARG_C(i));
+      mrb_value val = mrb_range_new(mrb, regs[b], regs[b+1], GETARG_C(i));
+      regs[GETARG_A(i)] = val;
       ARENA_RESTORE(mrb, ai);
       NEXT;
@@ -2357,8 +2819,8 @@
     L_STOP:
       {
-        int eidx_stop = mrb->c->ci == mrb->c->cibase ? 0 : mrb->c->ci[-1].eidx;
-        int eidx = mrb->c->ci->eidx;
-        while (eidx > eidx_stop) {
-          ecall(mrb, --eidx);
+        int epos = mrb->c->ci->epos;
+
+        while (mrb->c->eidx > epos) {
+          ecall(mrb, --mrb->c->eidx);
         }
       }
@@ -2382,9 +2844,10 @@
         exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg);
       }
-      mrb->exc = mrb_obj_ptr(exc);
+      mrb_exc_set(mrb, exc);
       goto L_RAISE;
     }
   }
   END_DISPATCH;
+#undef regs
 
   }
@@ -2399,21 +2862,31 @@
 mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
 {
-  return mrb_context_run(mrb, proc, self, mrb->c->ci->argc + 2); /* argc + 2 (receiver and block) */
+  if (mrb->c->ci->argc < 0) {
+    return mrb_vm_run(mrb, proc, self, 3); /* receiver, args and block) */
+  }
+  else {
+    return mrb_vm_run(mrb, proc, self, mrb->c->ci->argc + 2); /* argc + 2 (receiver and block) */
+  }
 }
 
 MRB_API mrb_value
-mrb_toplevel_run_keep(mrb_state *mrb, struct RProc *proc, unsigned int stack_keep)
+mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep)
 {
   mrb_callinfo *ci;
   mrb_value v;
 
-  if (!mrb->c->cibase || mrb->c->ci == mrb->c->cibase) {
-    return mrb_context_run(mrb, proc, mrb_top_self(mrb), stack_keep);
+  if (!mrb->c->cibase) {
+    return mrb_vm_run(mrb, proc, self, stack_keep);
+  }
+  if (mrb->c->ci == mrb->c->cibase) {
+    mrb->c->ci->env = NULL;
+    return mrb_vm_run(mrb, proc, self, stack_keep);
   }
   ci = cipush(mrb);
+  ci->mid = 0;
   ci->nregs = 1;   /* protect the receiver */
   ci->acc = CI_ACC_SKIP;
   ci->target_class = mrb->object_class;
-  v = mrb_context_run(mrb, proc, mrb_top_self(mrb), stack_keep);
+  v = mrb_vm_run(mrb, proc, self, stack_keep);
   cipop(mrb);
 
@@ -2421,7 +2894,11 @@
 }
 
-MRB_API mrb_value
-mrb_toplevel_run(mrb_state *mrb, struct RProc *proc)
-{
-  return mrb_toplevel_run_keep(mrb, proc, 0);
-}
+#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus)
+# if !defined(MRB_ENABLE_CXX_ABI)
+} /* end of extern "C" */
+# endif
+mrb_int mrb_jmpbuf::jmpbuf_id = 0;
+# if !defined(MRB_ENABLE_CXX_ABI)
+extern "C" {
+# endif
+#endif
