Ignore:
Timestamp:
Jul 9, 2020, 8:51:43 AM (4 years ago)
Author:
coas-nagasima
Message:

mrubyを2.1.1に更新

Location:
EcnlProtoTool/trunk/mruby-2.1.1
Files:
1 edited
1 moved

Legend:

Unmodified
Added
Removed
  • EcnlProtoTool/trunk/mruby-2.1.1/src/vm.c

    r331 r439  
    77#include <stddef.h>
    88#include <stdarg.h>
     9#ifndef MRB_WITHOUT_FLOAT
    910#include <math.h>
     11#endif
    1012#include <mruby.h>
    1113#include <mruby/array.h>
     
    2325#include <mruby/throw.h>
    2426
    25 #ifndef MRB_DISABLE_STDIO
     27#ifdef MRB_DISABLE_STDIO
    2628#if defined(__cplusplus)
    2729extern "C" {
     
    5254#ifndef MRB_FUNCALL_DEPTH_MAX
    5355#define MRB_FUNCALL_DEPTH_MAX 512
     56#endif
     57
     58/* Maximum depth of ecall() recursion. */
     59#ifndef MRB_ECALL_DEPTH_MAX
     60#define MRB_ECALL_DEPTH_MAX 512
    5461#endif
    5562
     
    6673#endif
    6774
    68 #define ARENA_RESTORE(mrb,ai) (mrb)->gc.arena_idx = (ai)
     75
     76#ifndef MRB_GC_FIXED_ARENA
     77static void
     78mrb_gc_arena_shrink(mrb_state *mrb, int idx)
     79{
     80  mrb_gc *gc = &mrb->gc;
     81  int capa = gc->arena_capa;
     82
     83  if (idx < capa / 4) {
     84    capa >>= 2;
     85    if (capa < MRB_GC_ARENA_SIZE) {
     86      capa = MRB_GC_ARENA_SIZE;
     87    }
     88    if (capa != gc->arena_capa) {
     89      gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*capa);
     90      gc->arena_capa = capa;
     91    }
     92  }
     93}
     94#else
     95#define mrb_gc_arena_shrink(mrb,idx)
     96#endif
    6997
    7098#define CALL_MAXARGS 127
     
    116144
    117145static inline void
    118 envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t size)
     146envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize)
    119147{
    120148  mrb_callinfo *ci = mrb->c->cibase;
     
    126154
    127155    if (e && MRB_ENV_STACK_SHARED_P(e) &&
    128         (st = e->stack) && oldbase <= st && st < oldbase+size) {
     156        (st = e->stack) && oldbase <= st && st < oldbase+oldsize) {
    129157      ptrdiff_t off = e->stack - oldbase;
    130158
    131159      e->stack = newbase + off;
    132160    }
     161
     162    if (ci->proc && MRB_PROC_ENV_P(ci->proc) && ci->env != MRB_PROC_ENV(ci->proc)) {
     163      e = MRB_PROC_ENV(ci->proc);
     164
     165      if (e && MRB_ENV_STACK_SHARED_P(e) &&
     166          (st = e->stack) && oldbase <= st && st < oldbase+oldsize) {
     167        ptrdiff_t off = e->stack - oldbase;
     168
     169        e->stack = newbase + off;
     170      }
     171    }
     172
    133173    ci->stackent = newbase + (ci->stackent - oldbase);
    134174    ci++;
     
    139179
    140180static void
    141 stack_extend_alloc(mrb_state *mrb, int room)
     181stack_extend_alloc(mrb_state *mrb, mrb_int room)
    142182{
    143183  mrb_value *oldbase = mrb->c->stbase;
     
    149189  if (off > size) size = off;
    150190#ifdef MRB_STACK_EXTEND_DOUBLING
    151   if (room <= size)
     191  if ((size_t)room <= size)
    152192    size *= 2;
    153193  else
     
    168208  }
    169209  stack_clear(&(newstack[oldsize]), size - oldsize);
    170   envadjust(mrb, oldbase, newstack, size);
     210  envadjust(mrb, oldbase, newstack, oldsize);
    171211  mrb->c->stbase = newstack;
    172212  mrb->c->stack = mrb->c->stbase + off;
     
    180220}
    181221
    182 static inline void
    183 stack_extend(mrb_state *mrb, int room)
     222MRB_API void
     223mrb_stack_extend(mrb_state *mrb, mrb_int room)
    184224{
    185225  if (mrb->c->stack + room >= mrb->c->stend) {
     
    191231uvenv(mrb_state *mrb, int up)
    192232{
    193   struct REnv *e = mrb->c->ci->proc->env;
     233  struct RProc *proc = mrb->c->ci->proc;
     234  struct REnv *e;
    194235
    195236  while (up--) {
    196     if (!e) return NULL;
    197     e = (struct REnv*)e->c;
    198   }
    199   return e;
    200 }
    201 
    202 static inline mrb_bool
    203 is_strict(mrb_state *mrb, struct REnv *e)
    204 {
    205   int cioff = e->cioff;
    206 
    207   if (MRB_ENV_STACK_SHARED_P(e) && e->cxt.c->cibase[cioff].proc &&
    208       MRB_PROC_STRICT_P(e->cxt.c->cibase[cioff].proc)) {
    209     return TRUE;
    210   }
    211   return FALSE;
    212 }
    213 
    214 static inline struct REnv*
    215 top_env(mrb_state *mrb, struct RProc *proc)
    216 {
    217   struct REnv *e = proc->env;
    218 
    219   if (is_strict(mrb, e)) return e;
    220   while (e->c) {
    221     e = (struct REnv*)e->c;
    222     if (is_strict(mrb, e)) return e;
    223   }
    224   return e;
     237    proc = proc->upper;
     238    if (!proc) return NULL;
     239  }
     240  e = MRB_PROC_ENV(proc);
     241  if (e) return e;              /* proc has enclosed env */
     242  else {
     243    mrb_callinfo *ci = mrb->c->ci;
     244    mrb_callinfo *cb = mrb->c->cibase;
     245
     246    while (cb <= ci) {
     247      if (ci->proc == proc) {
     248        return ci->env;
     249      }
     250      ci--;
     251    }
     252  }
     253  return NULL;
     254}
     255
     256static inline struct RProc*
     257top_proc(mrb_state *mrb, struct RProc *proc)
     258{
     259  while (proc->upper) {
     260    if (MRB_PROC_SCOPE_P(proc) || MRB_PROC_STRICT_P(proc))
     261      return proc;
     262    proc = proc->upper;
     263  }
     264  return proc;
    225265}
    226266
     
    229269#define CI_ACC_RESUMED -3
    230270
    231 static mrb_callinfo*
     271static inline mrb_callinfo*
    232272cipush(mrb_state *mrb)
    233273{
    234274  struct mrb_context *c = mrb->c;
     275  static const mrb_callinfo ci_zero = { 0 };
    235276  mrb_callinfo *ci = c->ci;
    236277
     
    245286  }
    246287  ci = ++c->ci;
     288  *ci = ci_zero;
    247289  ci->epos = mrb->c->eidx;
    248290  ci->ridx = ridx;
    249   ci->env = 0;
    250   ci->pc = 0;
    251   ci->err = 0;
    252   ci->proc = 0;
    253   ci->acc = 0;
    254291
    255292  return ci;
    256293}
    257294
    258 MRB_API void
     295void
    259296mrb_env_unshare(mrb_state *mrb, struct REnv *e)
    260297{
    261   size_t len = (size_t)MRB_ENV_STACK_LEN(e);
    262   ptrdiff_t cioff = e->cioff;
    263   mrb_value *p;
    264 
    265   if (!MRB_ENV_STACK_SHARED_P(e)) return;
    266   if (e->cxt.c != mrb->c) return;
    267   if (e->cioff == 0 && e->cxt.c == mrb->root_c) return;
    268   MRB_ENV_UNSHARE_STACK(e);
    269   if (!e->c) {
    270     /* save block argument position (negated) */
    271     e->cioff = -e->cxt.c->cibase[cioff].argc-1;
    272   }
    273   e->cxt.mid = e->cxt.c->cibase[cioff].mid;
    274   p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len);
    275   if (len > 0) {
    276     stack_copy(p, e->stack, len);
    277   }
    278   e->stack = p;
    279   mrb_write_barrier(mrb, (struct RBasic *)e);
    280 }
    281 
    282 static void
     298  if (e == NULL) return;
     299  else {
     300    size_t len = (size_t)MRB_ENV_STACK_LEN(e);
     301    mrb_value *p;
     302
     303    if (!MRB_ENV_STACK_SHARED_P(e)) return;
     304    if (e->cxt != mrb->c) return;
     305    if (e == mrb->c->cibase->env) return; /* for mirb */
     306    p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len);
     307    if (len > 0) {
     308      stack_copy(p, e->stack, len);
     309    }
     310    e->stack = p;
     311    MRB_ENV_UNSHARE_STACK(e);
     312    mrb_write_barrier(mrb, (struct RBasic *)e);
     313  }
     314}
     315
     316static inline void
    283317cipop(mrb_state *mrb)
    284318{
     
    287321
    288322  c->ci--;
    289 
    290   if (env) {
    291     mrb_env_unshare(mrb, env);
    292   }
     323  if (env) mrb_env_unshare(mrb, env);
    293324}
    294325
     
    296327
    297328static void
    298 ecall(mrb_state *mrb, int i)
     329ecall(mrb_state *mrb)
    299330{
    300331  struct RProc *p;
    301   mrb_callinfo *ci = mrb->c->ci;
    302   mrb_value *self = mrb->c->stack;
     332  struct mrb_context *c = mrb->c;
     333  mrb_callinfo *ci = c->ci;
    303334  struct RObject *exc;
     335  struct REnv *env;
    304336  ptrdiff_t cioff;
    305337  int ai = mrb_gc_arena_save(mrb);
     338  uint16_t i = --c->eidx;
     339  int nregs;
    306340
    307341  if (i<0) return;
    308   if (ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
     342  /* restrict total call depth of ecall() */
     343  if (++mrb->ecall_nest > MRB_ECALL_DEPTH_MAX) {
    309344    mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
    310345  }
    311   p = mrb->c->ensure[i];
     346  p = c->ensure[i];
    312347  if (!p) return;
    313   mrb->c->ensure[i] = NULL;
    314   cioff = ci - mrb->c->cibase;
     348  mrb_assert(!MRB_PROC_CFUNC_P(p));
     349  c->ensure[i] = NULL;
     350  nregs = p->upper->body.irep->nregs;
     351  if (ci->proc && !MRB_PROC_CFUNC_P(ci->proc) &&
     352      ci->proc->body.irep->nregs > nregs) {
     353    nregs = ci->proc->body.irep->nregs;
     354  }
     355  cioff = ci - c->cibase;
    315356  ci = cipush(mrb);
    316357  ci->stackent = mrb->c->stack;
     
    319360  ci->argc = 0;
    320361  ci->proc = p;
    321   ci->nregs = p->body.irep->nregs;
    322   ci->target_class = p->target_class;
    323   mrb->c->stack = mrb->c->stack + ci[-1].nregs;
     362  ci->target_class = MRB_PROC_TARGET_CLASS(p);
     363  env = MRB_PROC_ENV(p);
     364  mrb_assert(env);
     365  c->stack += nregs;
    324366  exc = mrb->exc; mrb->exc = 0;
    325367  if (exc) {
    326368    mrb_gc_protect(mrb, mrb_obj_value(exc));
    327369  }
    328   mrb_run(mrb, p, *self);
    329   mrb->c->ci = mrb->c->cibase + cioff;
     370  if (mrb->c->fib) {
     371    mrb_gc_protect(mrb, mrb_obj_value(mrb->c->fib));
     372  }
     373  mrb_run(mrb, p, env->stack[0]);
     374  mrb->c = c;
     375  c->ci = c->cibase + cioff;
    330376  if (!mrb->exc) mrb->exc = exc;
    331377  mrb_gc_arena_restore(mrb, ai);
     378  mrb->ecall_nest--;
    332379}
    333380
     
    356403}
    357404
     405static int
     406ci_nregs(mrb_callinfo *ci)
     407{
     408  struct RProc *p;
     409  int n = 0;
     410
     411  if (!ci) return 3;
     412  p = ci->proc;
     413  if (!p) {
     414    if (ci->argc < 0) return 3;
     415    return ci->argc+2;
     416  }
     417  if (!MRB_PROC_CFUNC_P(p) && p->body.irep) {
     418    n = p->body.irep->nregs;
     419  }
     420  if (ci->argc < 0) {
     421    if (n < 3) n = 3; /* self + args + blk */
     422  }
     423  if (ci->argc > n) {
     424    n = ci->argc + 2; /* self + blk */
     425  }
     426  return n;
     427}
     428
    358429MRB_API mrb_value
    359430mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, const mrb_value *argv, mrb_value blk)
    360431{
    361432  mrb_value val;
     433  int ai = mrb_gc_arena_save(mrb);
    362434
    363435  if (!mrb->jmp) {
     
    383455  }
    384456  else {
    385     struct RProc *p;
     457    mrb_method_t m;
    386458    struct RClass *c;
    387459    mrb_callinfo *ci;
    388     int n;
     460    int n = ci_nregs(mrb->c->ci);
    389461    ptrdiff_t voff = -1;
    390462
     
    392464      stack_init(mrb);
    393465    }
    394     n = mrb->c->ci->nregs;
    395466    if (argc < 0) {
    396       mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%S)", mrb_fixnum_value(argc));
     467      mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%i)", argc);
    397468    }
    398469    c = mrb_class(mrb, self);
    399     p = mrb_method_search_vm(mrb, &c, mid);
    400     if (!p) {
     470    m = mrb_method_search_vm(mrb, &c, mid);
     471    if (MRB_METHOD_UNDEF_P(m)) {
    401472      mrb_sym missing = mrb_intern_lit(mrb, "method_missing");
    402473      mrb_value args = mrb_ary_new_from_values(mrb, argc, argv);
    403       p = mrb_method_search_vm(mrb, &c, missing);
    404       if (!p) {
     474      m = mrb_method_search_vm(mrb, &c, missing);
     475      if (MRB_METHOD_UNDEF_P(m)) {
    405476        mrb_method_missing(mrb, mid, self, args);
    406477      }
    407478      mrb_ary_unshift(mrb, args, mrb_symbol_value(mid));
    408       stack_extend(mrb, n+2);
     479      mrb_stack_extend(mrb, n+2);
    409480      mrb->c->stack[n+1] = args;
    410481      argc = -1;
     
    415486    ci = cipush(mrb);
    416487    ci->mid = mid;
    417     ci->proc = p;
    418488    ci->stackent = mrb->c->stack;
    419     ci->argc = argc;
     489    ci->argc = (int)argc;
    420490    ci->target_class = c;
    421491    mrb->c->stack = mrb->c->stack + n;
     492    if (argc < 0) argc = 1;
    422493    if (mrb->c->stbase <= argv && argv < mrb->c->stend) {
    423494      voff = argv - mrb->c->stbase;
    424495    }
    425     if (MRB_PROC_CFUNC_P(p)) {
    426       ci->nregs = argc + 2;
    427       stack_extend(mrb, ci->nregs);
    428     }
    429     else if (argc >= CALL_MAXARGS) {
     496    if (argc >= CALL_MAXARGS) {
    430497      mrb_value args = mrb_ary_new_from_values(mrb, argc, argv);
    431       stack_extend(mrb, ci->nregs);
     498
    432499      mrb->c->stack[1] = args;
    433500      ci->argc = -1;
    434501      argc = 1;
    435502    }
    436     else {
    437       if (argc < 0) argc = 1;
    438       ci->nregs = p->body.irep->nregs + argc;
    439       stack_extend(mrb, ci->nregs);
     503    mrb_stack_extend(mrb, argc + 2);
     504    if (MRB_METHOD_PROC_P(m)) {
     505      struct RProc *p = MRB_METHOD_PROC(m);
     506
     507      ci->proc = p;
     508      if (!MRB_PROC_CFUNC_P(p)) {
     509        mrb_stack_extend(mrb, p->body.irep->nregs + argc);
     510      }
    440511    }
    441512    if (voff >= 0) {
     
    448519    mrb->c->stack[argc+1] = blk;
    449520
    450     if (MRB_PROC_CFUNC_P(p)) {
    451       int ai = mrb_gc_arena_save(mrb);
    452 
     521    if (MRB_METHOD_CFUNC_P(m)) {
    453522      ci->acc = CI_ACC_DIRECT;
    454       val = p->body.func(mrb, self);
     523      val = MRB_METHOD_CFUNC(m)(mrb, self);
    455524      mrb->c->stack = mrb->c->ci->stackent;
    456525      cipop(mrb);
    457       mrb_gc_arena_restore(mrb, ai);
    458526    }
    459527    else {
    460528      ci->acc = CI_ACC_SKIP;
    461       val = mrb_run(mrb, p, self);
    462     }
    463   }
     529      val = mrb_run(mrb, MRB_METHOD_PROC(m), self);
     530    }
     531  }
     532  mrb_gc_arena_restore(mrb, ai);
    464533  mrb_gc_protect(mrb, val);
    465534  return val;
     
    476545{
    477546  mrb_callinfo *ci = mrb->c->ci;
     547  int keep, nregs;
    478548
    479549  mrb->c->stack[0] = self;
    480550  ci->proc = p;
    481   ci->target_class = p->target_class;
    482551  if (MRB_PROC_CFUNC_P(p)) {
    483     return p->body.func(mrb, self);
    484   }
    485   if (ci->argc < 0) {
    486     stack_extend(mrb, (p->body.irep->nregs < 3) ? 3 : p->body.irep->nregs);
     552    return MRB_PROC_CFUNC(p)(mrb, self);
     553  }
     554  nregs = p->body.irep->nregs;
     555  if (ci->argc < 0) keep = 3;
     556  else keep = ci->argc + 2;
     557  if (nregs < keep) {
     558    mrb_stack_extend(mrb, keep);
    487559  }
    488560  else {
    489     stack_extend(mrb, p->body.irep->nregs);
    490   }
    491 
    492   ci->nregs = p->body.irep->nregs;
     561    mrb_stack_extend(mrb, nregs);
     562    stack_clear(mrb->c->stack+keep, nregs-keep);
     563  }
     564
    493565  ci = cipush(mrb);
    494   ci->nregs = 0;
    495566  ci->target_class = 0;
    496567  ci->pc = p->body.irep->iseq;
     
    520591 *     k.send :hello, "gentle", "readers"   #=> "Hello gentle readers"
    521592 */
    522 MRB_API mrb_value
     593mrb_value
    523594mrb_f_send(mrb_state *mrb, mrb_value self)
    524595{
     
    526597  mrb_value block, *argv, *regs;
    527598  mrb_int argc, i, len;
    528   struct RProc *p;
     599  mrb_method_t m;
    529600  struct RClass *c;
    530601  mrb_callinfo *ci;
     
    538609
    539610  c = mrb_class(mrb, self);
    540   p = mrb_method_search_vm(mrb, &c, name);
    541 
    542   if (!p) {                     /* call method_mising */
     611  m = mrb_method_search_vm(mrb, &c, name);
     612  if (MRB_METHOD_UNDEF_P(m)) {            /* call method_mising */
    543613    goto funcall;
    544614  }
     
    558628  }
    559629
    560   return mrb_exec_irep(mrb, self, p);
     630  if (MRB_METHOD_CFUNC_P(m)) {
     631    if (MRB_METHOD_PROC_P(m)) {
     632      ci->proc = MRB_METHOD_PROC(m);
     633    }
     634    return MRB_METHOD_CFUNC(m)(mrb, self);
     635  }
     636  return mrb_exec_irep(mrb, self, MRB_METHOD_PROC(m));
    561637}
    562638
     
    566642  struct RProc *p;
    567643  mrb_callinfo *ci;
    568   mrb_int max = 3;
     644  int nregs;
    569645
    570646  if (mrb_nil_p(blk)) {
     
    582658  ci->mid = ci[-1].mid;
    583659  if (MRB_PROC_CFUNC_P(p)) {
    584     stack_extend(mrb, 3);
     660    mrb_stack_extend(mrb, 3);
    585661    mrb->c->stack[0] = self;
    586662    mrb->c->stack[1] = self;
    587663    mrb->c->stack[2] = mrb_nil_value();
    588     return p->body.func(mrb, self);
    589   }
    590   ci->nregs = p->body.irep->nregs;
    591   if (max < ci->nregs) max = ci->nregs;
    592   stack_extend(mrb, max);
     664    return MRB_PROC_CFUNC(p)(mrb, self);
     665  }
     666  nregs = p->body.irep->nregs;
     667  if (nregs < 3) nregs = 3;
     668  mrb_stack_extend(mrb, nregs);
    593669  mrb->c->stack[0] = self;
    594670  mrb->c->stack[1] = self;
    595   mrb->c->stack[2] = mrb_nil_value();
     671  stack_clear(mrb->c->stack+2, nregs-2);
    596672  ci = cipush(mrb);
    597   ci->nregs = 0;
    598673  ci->target_class = 0;
    599674  ci->pc = p->body.irep->iseq;
     
    659734  case MRB_TT_SYMBOL:
    660735  case MRB_TT_FIXNUM:
     736#ifndef MRB_WITHOUT_FLOAT
    661737  case MRB_TT_FLOAT:
     738#endif
    662739    c = 0;
    663740    break;
     
    676753  mrb_sym mid = mrb->c->ci->mid;
    677754  mrb_callinfo *ci;
    678   int n = mrb->c->ci->nregs;
    679755  mrb_value val;
     756  int n;
    680757
    681758  if (mrb_nil_p(b)) {
    682759    mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
    683760  }
    684   if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
     761  ci = mrb->c->ci;
     762  n = ci_nregs(ci);
     763  if (ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
    685764    mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
    686765  }
     
    690769  ci->proc = p;
    691770  ci->stackent = mrb->c->stack;
    692   ci->argc = argc;
     771  ci->argc = (int)argc;
    693772  ci->target_class = c;
    694773  ci->acc = CI_ACC_SKIP;
     774  n = MRB_PROC_CFUNC_P(p) ? (int)(argc+2) : p->body.irep->nregs;
    695775  mrb->c->stack = mrb->c->stack + n;
    696   if (MRB_PROC_CFUNC_P(p)) {
    697     ci->nregs = argc + 2;
    698     stack_extend(mrb, ci->nregs);
    699   }
    700   else {
    701     ci->nregs = p->body.irep->nregs;
    702     stack_extend(mrb, ci->nregs);
    703   }
     776  mrb_stack_extend(mrb, n);
    704777
    705778  mrb->c->stack[0] = self;
     
    710783
    711784  if (MRB_PROC_CFUNC_P(p)) {
    712     val = p->body.func(mrb, self);
     785    val = MRB_PROC_CFUNC(p)(mrb, self);
    713786    mrb->c->stack = mrb->c->ci->stackent;
     787    cipop(mrb);
    714788  }
    715789  else {
    716     int cioff = mrb->c->ci - mrb->c->cibase;
    717790    val = mrb_run(mrb, p, self);
    718     mrb->c->ci = mrb->c->cibase + cioff;
    719   }
    720   cipop(mrb);
     791  }
    721792  return val;
    722793}
     
    727798  struct RProc *p = mrb_proc_ptr(b);
    728799
    729   return mrb_yield_with_class(mrb, b, argc, argv, p->env->stack[0], p->target_class);
     800  return mrb_yield_with_class(mrb, b, argc, argv, MRB_PROC_ENV(p)->stack[0], MRB_PROC_TARGET_CLASS(p));
    730801}
    731802
     
    735806  struct RProc *p = mrb_proc_ptr(b);
    736807
    737   return mrb_yield_with_class(mrb, b, 1, &arg, p->env->stack[0], p->target_class);
     808  return mrb_yield_with_class(mrb, b, 1, &arg, MRB_PROC_ENV(p)->stack[0], MRB_PROC_TARGET_CLASS(p));
    738809}
    739810
     
    747818    mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
    748819  }
    749   if (mrb_type(b) != MRB_TT_PROC) {
     820  if (!mrb_proc_p(b)) {
    750821    mrb_raise(mrb, E_TYPE_ERROR, "not a block");
    751822  }
     
    754825  ci = mrb->c->ci;
    755826
    756   stack_extend(mrb, 3);
     827  mrb_stack_extend(mrb, 3);
    757828  mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv);
    758829  mrb->c->stack[2] = mrb_nil_value();
     
    767838
    768839  brk = (struct RBreak*)mrb_obj_alloc(mrb, MRB_TT_BREAK, NULL);
    769   brk->iv = NULL;
    770   brk->proc = p;
    771   brk->val = val;
     840  mrb_break_proc_set(brk, p);
     841  mrb_break_value_set(brk, val);
    772842
    773843  return brk;
     
    789859  mrb_value exc;
    790860
    791   msg = mrb_str_buf_new(mrb, sizeof(lead) + 7);
     861  msg = mrb_str_new_capa(mrb, sizeof(lead) + 7);
    792862  mrb_str_cat(mrb, msg, lead, sizeof(lead) - 1);
    793863  mrb_str_cat(mrb, msg, kind_str[kind], kind_str_len[kind]);
     
    810880  }
    811881  if (mrb->c->ci->mid) {
    812     str = mrb_format(mrb, "'%S': wrong number of arguments (%S for %S)",
    813                   mrb_sym2str(mrb, mrb->c->ci->mid),
    814                   mrb_fixnum_value(argc), mrb_fixnum_value(num));
     882    str = mrb_format(mrb, "'%n': wrong number of arguments (%i for %i)",
     883                     mrb->c->ci->mid, argc, num);
    815884  }
    816885  else {
    817     str = mrb_format(mrb, "wrong number of arguments (%S for %S)",
    818                      mrb_fixnum_value(argc), mrb_fixnum_value(num));
     886    str = mrb_format(mrb, "wrong number of arguments (%i for %i)", argc, num);
    819887  }
    820888  exc = mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str);
     
    822890}
    823891
    824 #define ERR_PC_SET(mrb, pc) mrb->c->ci->err = pc;
    825 #define ERR_PC_CLR(mrb)     mrb->c->ci->err = 0;
     892#define ERR_PC_SET(mrb) mrb->c->ci->err = pc0;
     893#define ERR_PC_CLR(mrb) mrb->c->ci->err = 0;
    826894#ifdef MRB_ENABLE_DEBUG_HOOK
    827895#define CODE_FETCH_HOOK(mrb, irep, pc, regs) if ((mrb)->code_fetch_hook) (mrb)->code_fetch_hook((mrb), (irep), (pc), (regs));
     
    836904#endif
    837905
    838 
     906#ifndef MRB_DISABLE_DIRECT_THREADING
    839907#if defined __GNUC__ || defined __clang__ || defined __INTEL_COMPILER
    840908#define DIRECT_THREADED
    841909#endif
     910#endif /* ifndef MRB_DISABLE_DIRECT_THREADING */
    842911
    843912#ifndef DIRECT_THREADED
    844913
    845 #define INIT_DISPATCH for (;;) { i = BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (GET_OPCODE(i)) {
    846 #define CASE(op) case op:
    847 #define NEXT pc++; break
    848 #define JUMP break
     914#define INIT_DISPATCH for (;;) { insn = BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (insn) {
     915#define CASE(insn,ops) case insn: pc0=pc++; FETCH_ ## ops ();; L_ ## insn ## _BODY:
     916#define NEXT break
     917#define JUMP NEXT
    849918#define END_DISPATCH }}
    850919
     
    852921
    853922#define INIT_DISPATCH JUMP; return mrb_nil_value();
    854 #define CASE(op) L_ ## op:
    855 #define NEXT i=BYTECODE_DECODER(*++pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)]
    856 #define JUMP i=BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)]
     923#define CASE(insn,ops) L_ ## insn: pc0=pc++; FETCH_ ## ops (); L_ ## insn ## _BODY:
     924#define NEXT insn=BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[insn]
     925#define JUMP NEXT
    857926
    858927#define END_DISPATCH
     
    866935  mrb_value result;
    867936  struct mrb_context *c = mrb->c;
    868   int cioff = c->ci - c->cibase;
     937  ptrdiff_t cioff = c->ci - c->cibase;
    869938  unsigned int nregs = irep->nregs;
    870939
     
    874943  if (stack_keep > nregs)
    875944    nregs = stack_keep;
    876   stack_extend(mrb, nregs);
     945  mrb_stack_extend(mrb, nregs);
    877946  stack_clear(c->stack + stack_keep, nregs - stack_keep);
    878947  c->stack[0] = self;
    879948  result = mrb_vm_exec(mrb, proc, irep->iseq);
    880   if (c->ci - c->cibase > cioff) {
    881     c->ci = c->cibase + cioff;
    882   }
    883949  if (mrb->c != c) {
    884950    if (mrb->c->fib) {
     
    887953    mrb->c = c;
    888954  }
     955  else if (c->ci - c->cibase > cioff) {
     956    c->ci = c->cibase + cioff;
     957  }
    889958  return result;
    890959}
    891960
     961static mrb_bool
     962check_target_class(mrb_state *mrb)
     963{
     964  if (!mrb->c->ci->target_class) {
     965    mrb_value exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, "no target class or module");
     966    mrb_exc_set(mrb, exc);
     967    return FALSE;
     968  }
     969  return TRUE;
     970}
     971
     972void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self);
     973
    892974MRB_API mrb_value
    893 mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc)
    894 {
    895   /* mrb_assert(mrb_proc_cfunc_p(proc)) */
     975mrb_vm_exec(mrb_state *mrb, struct RProc *proc, const mrb_code *pc)
     976{
     977  /* mrb_assert(MRB_PROC_CFUNC_P(proc)) */
     978  const mrb_code *pc0 = pc;
    896979  mrb_irep *irep = proc->body.irep;
    897980  mrb_value *pool = irep->pool;
    898981  mrb_sym *syms = irep->syms;
    899   mrb_code i;
     982  mrb_code insn;
    900983  int ai = mrb_gc_arena_save(mrb);
    901984  struct mrb_jmpbuf *prev_jmp = mrb->jmp;
    902985  struct mrb_jmpbuf c_jmp;
     986  uint32_t a;
     987  uint16_t b;
     988  uint8_t c;
     989  mrb_sym mid;
    903990
    904991#ifdef DIRECT_THREADED
    905992  static void *optable[] = {
    906     &&L_OP_NOP, &&L_OP_MOVE,
    907     &&L_OP_LOADL, &&L_OP_LOADI, &&L_OP_LOADSYM, &&L_OP_LOADNIL,
    908     &&L_OP_LOADSELF, &&L_OP_LOADT, &&L_OP_LOADF,
    909     &&L_OP_GETGLOBAL, &&L_OP_SETGLOBAL, &&L_OP_GETSPECIAL, &&L_OP_SETSPECIAL,
    910     &&L_OP_GETIV, &&L_OP_SETIV, &&L_OP_GETCV, &&L_OP_SETCV,
    911     &&L_OP_GETCONST, &&L_OP_SETCONST, &&L_OP_GETMCNST, &&L_OP_SETMCNST,
    912     &&L_OP_GETUPVAR, &&L_OP_SETUPVAR,
    913     &&L_OP_JMP, &&L_OP_JMPIF, &&L_OP_JMPNOT,
    914     &&L_OP_ONERR, &&L_OP_RESCUE, &&L_OP_POPERR, &&L_OP_RAISE, &&L_OP_EPUSH, &&L_OP_EPOP,
    915     &&L_OP_SEND, &&L_OP_SENDB, &&L_OP_FSEND,
    916     &&L_OP_CALL, &&L_OP_SUPER, &&L_OP_ARGARY, &&L_OP_ENTER,
    917     &&L_OP_KARG, &&L_OP_KDICT, &&L_OP_RETURN, &&L_OP_TAILCALL, &&L_OP_BLKPUSH,
    918     &&L_OP_ADD, &&L_OP_ADDI, &&L_OP_SUB, &&L_OP_SUBI, &&L_OP_MUL, &&L_OP_DIV,
    919     &&L_OP_EQ, &&L_OP_LT, &&L_OP_LE, &&L_OP_GT, &&L_OP_GE,
    920     &&L_OP_ARRAY, &&L_OP_ARYCAT, &&L_OP_ARYPUSH, &&L_OP_AREF, &&L_OP_ASET, &&L_OP_APOST,
    921     &&L_OP_STRING, &&L_OP_STRCAT, &&L_OP_HASH,
    922     &&L_OP_LAMBDA, &&L_OP_RANGE, &&L_OP_OCLASS,
    923     &&L_OP_CLASS, &&L_OP_MODULE, &&L_OP_EXEC,
    924     &&L_OP_METHOD, &&L_OP_SCLASS, &&L_OP_TCLASS,
    925     &&L_OP_DEBUG, &&L_OP_STOP, &&L_OP_ERR,
     993#define OPCODE(x,_) &&L_OP_ ## x,
     994#include "mruby/ops.h"
     995#undef OPCODE
    926996  };
    927997#endif
     
    9341004  if (exc_catched) {
    9351005    exc_catched = FALSE;
     1006    mrb_gc_arena_restore(mrb, ai);
    9361007    if (mrb->exc && mrb->exc->tt == MRB_TT_BREAK)
    9371008      goto L_BREAK;
     
    9401011  mrb->jmp = &c_jmp;
    9411012  mrb->c->ci->proc = proc;
    942   mrb->c->ci->nregs = irep->nregs;
    9431013
    9441014#define regs (mrb->c->stack)
    9451015  INIT_DISPATCH {
    946     CASE(OP_NOP) {
     1016    CASE(OP_NOP, Z) {
    9471017      /* do nothing */
    9481018      NEXT;
    9491019    }
    9501020
    951     CASE(OP_MOVE) {
    952       /* A B    R(A) := R(B) */
    953       int a = GETARG_A(i);
    954       int b = GETARG_B(i);
     1021    CASE(OP_MOVE, BB) {
    9551022      regs[a] = regs[b];
    9561023      NEXT;
    9571024    }
    9581025
    959     CASE(OP_LOADL) {
    960       /* A Bx   R(A) := Pool(Bx) */
    961       int a = GETARG_A(i);
    962       int bx = GETARG_Bx(i);
     1026    CASE(OP_LOADL, BB) {
    9631027#ifdef MRB_WORD_BOXING
    964       mrb_value val = pool[bx];
     1028      mrb_value val = pool[b];
     1029#ifndef MRB_WITHOUT_FLOAT
    9651030      if (mrb_float_p(val)) {
    9661031        val = mrb_float_value(mrb, mrb_float(val));
    9671032      }
     1033#endif
    9681034      regs[a] = val;
    9691035#else
    970       regs[a] = pool[bx];
    971 #endif
    972       NEXT;
    973     }
    974 
    975     CASE(OP_LOADI) {
    976       /* A sBx  R(A) := sBx */
    977       SET_INT_VALUE(regs[GETARG_A(i)], GETARG_sBx(i));
    978       NEXT;
    979     }
    980 
    981     CASE(OP_LOADSYM) {
    982       /* A Bx   R(A) := Syms(Bx) */
    983       int a = GETARG_A(i);
    984       int bx = GETARG_Bx(i);
    985       SET_SYM_VALUE(regs[a], syms[bx]);
    986       NEXT;
    987     }
    988 
    989     CASE(OP_LOADSELF) {
    990       /* A      R(A) := self */
    991       int a = GETARG_A(i);
     1036      regs[a] = pool[b];
     1037#endif
     1038      NEXT;
     1039    }
     1040
     1041    CASE(OP_LOADI, BB) {
     1042      SET_INT_VALUE(regs[a], b);
     1043      NEXT;
     1044    }
     1045
     1046    CASE(OP_LOADINEG, BB) {
     1047      SET_INT_VALUE(regs[a], -b);
     1048      NEXT;
     1049    }
     1050
     1051    CASE(OP_LOADI__1,B) goto L_LOADI;
     1052    CASE(OP_LOADI_0,B) goto L_LOADI;
     1053    CASE(OP_LOADI_1,B) goto L_LOADI;
     1054    CASE(OP_LOADI_2,B) goto L_LOADI;
     1055    CASE(OP_LOADI_3,B) goto L_LOADI;
     1056    CASE(OP_LOADI_4,B) goto L_LOADI;
     1057    CASE(OP_LOADI_5,B) goto L_LOADI;
     1058    CASE(OP_LOADI_6,B) goto L_LOADI;
     1059    CASE(OP_LOADI_7, B) {
     1060    L_LOADI:
     1061      SET_INT_VALUE(regs[a], (mrb_int)insn - (mrb_int)OP_LOADI_0);
     1062      NEXT;
     1063    }
     1064
     1065    CASE(OP_LOADSYM, BB) {
     1066      SET_SYM_VALUE(regs[a], syms[b]);
     1067      NEXT;
     1068    }
     1069
     1070    CASE(OP_LOADNIL, B) {
     1071      SET_NIL_VALUE(regs[a]);
     1072      NEXT;
     1073    }
     1074
     1075    CASE(OP_LOADSELF, B) {
    9921076      regs[a] = regs[0];
    9931077      NEXT;
    9941078    }
    9951079
    996     CASE(OP_LOADT) {
    997       /* A      R(A) := true */
    998       int a = GETARG_A(i);
     1080    CASE(OP_LOADT, B) {
    9991081      SET_TRUE_VALUE(regs[a]);
    10001082      NEXT;
    10011083    }
    10021084
    1003     CASE(OP_LOADF) {
    1004       /* A      R(A) := false */
    1005       int a = GETARG_A(i);
     1085    CASE(OP_LOADF, B) {
    10061086      SET_FALSE_VALUE(regs[a]);
    10071087      NEXT;
    10081088    }
    10091089
    1010     CASE(OP_GETGLOBAL) {
    1011       /* A Bx   R(A) := getglobal(Syms(Bx)) */
    1012       int a = GETARG_A(i);
    1013       int bx = GETARG_Bx(i);
    1014       mrb_value val = mrb_gv_get(mrb, syms[bx]);
     1090    CASE(OP_GETGV, BB) {
     1091      mrb_value val = mrb_gv_get(mrb, syms[b]);
    10151092      regs[a] = val;
    10161093      NEXT;
    10171094    }
    10181095
    1019     CASE(OP_SETGLOBAL) {
    1020       /* A Bx   setglobal(Syms(Bx), R(A)) */
    1021       int a = GETARG_A(i);
    1022       int bx = GETARG_Bx(i);
    1023       mrb_gv_set(mrb, syms[bx], regs[a]);
    1024       NEXT;
    1025     }
    1026 
    1027     CASE(OP_GETSPECIAL) {
    1028       /* A Bx   R(A) := Special[Bx] */
    1029       int a = GETARG_A(i);
    1030       int bx = GETARG_Bx(i);
    1031       mrb_value val = mrb_vm_special_get(mrb, bx);
     1096    CASE(OP_SETGV, BB) {
     1097      mrb_gv_set(mrb, syms[b], regs[a]);
     1098      NEXT;
     1099    }
     1100
     1101    CASE(OP_GETSV, BB) {
     1102      mrb_value val = mrb_vm_special_get(mrb, b);
    10321103      regs[a] = val;
    10331104      NEXT;
    10341105    }
    10351106
    1036     CASE(OP_SETSPECIAL) {
    1037       /* A Bx   Special[Bx] := R(A) */
    1038       int a = GETARG_A(i);
    1039       int bx = GETARG_Bx(i);
    1040       mrb_vm_special_set(mrb, bx, regs[a]);
    1041       NEXT;
    1042     }
    1043 
    1044     CASE(OP_GETIV) {
    1045       /* A Bx   R(A) := ivget(Bx) */
    1046       int a = GETARG_A(i);
    1047       int bx = GETARG_Bx(i);
    1048       mrb_value val = mrb_vm_iv_get(mrb, syms[bx]);
    1049       regs[a] = val;
    1050       NEXT;
    1051     }
    1052 
    1053     CASE(OP_SETIV) {
    1054       /* A Bx   ivset(Syms(Bx),R(A)) */
    1055       int a = GETARG_A(i);
    1056       int bx = GETARG_Bx(i);
    1057       mrb_vm_iv_set(mrb, syms[bx], regs[a]);
    1058       NEXT;
    1059     }
    1060 
    1061     CASE(OP_GETCV) {
    1062       /* A Bx   R(A) := cvget(Syms(Bx)) */
    1063       int a = GETARG_A(i);
    1064       int bx = GETARG_Bx(i);
     1107    CASE(OP_SETSV, BB) {
     1108      mrb_vm_special_set(mrb, b, regs[a]);
     1109      NEXT;
     1110    }
     1111
     1112    CASE(OP_GETIV, BB) {
     1113      regs[a] = mrb_iv_get(mrb, regs[0], syms[b]);
     1114      NEXT;
     1115    }
     1116
     1117    CASE(OP_SETIV, BB) {
     1118      mrb_iv_set(mrb, regs[0], syms[b], regs[a]);
     1119      NEXT;
     1120    }
     1121
     1122    CASE(OP_GETCV, BB) {
    10651123      mrb_value val;
    1066       ERR_PC_SET(mrb, pc);
    1067       val = mrb_vm_cv_get(mrb, syms[bx]);
     1124      ERR_PC_SET(mrb);
     1125      val = mrb_vm_cv_get(mrb, syms[b]);
    10681126      ERR_PC_CLR(mrb);
    10691127      regs[a] = val;
     
    10711129    }
    10721130
    1073     CASE(OP_SETCV) {
    1074       /* A Bx   cvset(Syms(Bx),R(A)) */
    1075       int a = GETARG_A(i);
    1076       int bx = GETARG_Bx(i);
    1077       mrb_vm_cv_set(mrb, syms[bx], regs[a]);
    1078       NEXT;
    1079     }
    1080 
    1081     CASE(OP_GETCONST) {
    1082       /* A Bx    R(A) := constget(Syms(Bx)) */
     1131    CASE(OP_SETCV, BB) {
     1132      mrb_vm_cv_set(mrb, syms[b], regs[a]);
     1133      NEXT;
     1134    }
     1135
     1136    CASE(OP_GETCONST, BB) {
    10831137      mrb_value val;
    1084       int a = GETARG_A(i);
    1085       int bx = GETARG_Bx(i);
    1086       mrb_sym sym = syms[bx];
    1087 
    1088       ERR_PC_SET(mrb, pc);
     1138      mrb_sym sym = syms[b];
     1139
     1140      ERR_PC_SET(mrb);
    10891141      val = mrb_vm_const_get(mrb, sym);
    10901142      ERR_PC_CLR(mrb);
     
    10931145    }
    10941146
    1095     CASE(OP_SETCONST) {
    1096       /* A Bx   constset(Syms(Bx),R(A)) */
    1097       int a = GETARG_A(i);
    1098       int bx = GETARG_Bx(i);
    1099       mrb_vm_const_set(mrb, syms[bx], regs[a]);
    1100       NEXT;
    1101     }
    1102 
    1103     CASE(OP_GETMCNST) {
    1104       /* A Bx   R(A) := R(A)::Syms(Bx) */
     1147    CASE(OP_SETCONST, BB) {
     1148      mrb_vm_const_set(mrb, syms[b], regs[a]);
     1149      NEXT;
     1150    }
     1151
     1152    CASE(OP_GETMCNST, BB) {
    11051153      mrb_value val;
    1106       int a = GETARG_A(i);
    1107       int bx = GETARG_Bx(i);
    1108 
    1109       ERR_PC_SET(mrb, pc);
    1110       val = mrb_const_get(mrb, regs[a], syms[bx]);
     1154
     1155      ERR_PC_SET(mrb);
     1156      val = mrb_const_get(mrb, regs[a], syms[b]);
    11111157      ERR_PC_CLR(mrb);
    11121158      regs[a] = val;
     
    11141160    }
    11151161
    1116     CASE(OP_SETMCNST) {
    1117       /* A Bx    R(A+1)::Syms(Bx) := R(A) */
    1118       int a = GETARG_A(i);
    1119       int bx = GETARG_Bx(i);
    1120       mrb_const_set(mrb, regs[a+1], syms[bx], regs[a]);
    1121       NEXT;
    1122     }
    1123 
    1124     CASE(OP_GETUPVAR) {
    1125       /* A B C  R(A) := uvget(B,C) */
    1126       int a = GETARG_A(i);
    1127       int b = GETARG_B(i);
    1128       int c = GETARG_C(i);
     1162    CASE(OP_SETMCNST, BB) {
     1163      mrb_const_set(mrb, regs[a+1], syms[b], regs[a]);
     1164      NEXT;
     1165    }
     1166
     1167    CASE(OP_GETUPVAR, BBB) {
    11291168      mrb_value *regs_a = regs + a;
    11301169      struct REnv *e = uvenv(mrb, c);
    11311170
    1132       if (!e) {
     1171      if (e && b < MRB_ENV_STACK_LEN(e)) {
     1172        *regs_a = e->stack[b];
     1173      }
     1174      else {
    11331175        *regs_a = mrb_nil_value();
    11341176      }
    1135       else {
    1136         *regs_a = e->stack[b];
    1137       }
    1138       NEXT;
    1139     }
    1140 
    1141     CASE(OP_SETUPVAR) {
    1142       /* A B C  uvset(B,C,R(A)) */
    1143       int a = GETARG_A(i);
    1144       int b = GETARG_B(i);
    1145       int c = GETARG_C(i);
    1146 
     1177      NEXT;
     1178    }
     1179
     1180    CASE(OP_SETUPVAR, BBB) {
    11471181      struct REnv *e = uvenv(mrb, c);
    11481182
     
    11581192    }
    11591193
    1160     CASE(OP_JMP) {
    1161       /* sBx    pc+=sBx */
    1162       int sbx = GETARG_sBx(i);
    1163       pc += sbx;
     1194    CASE(OP_JMP, S) {
     1195      pc = irep->iseq+a;
    11641196      JUMP;
    11651197    }
    1166 
    1167     CASE(OP_JMPIF) {
    1168       /* A sBx  if R(A) pc+=sBx */
    1169       int a = GETARG_A(i);
    1170       int sbx = GETARG_sBx(i);
     1198    CASE(OP_JMPIF, BS) {
    11711199      if (mrb_test(regs[a])) {
    1172         pc += sbx;
     1200        pc = irep->iseq+b;
    11731201        JUMP;
    11741202      }
    11751203      NEXT;
    11761204    }
    1177 
    1178     CASE(OP_JMPNOT) {
    1179       /* A sBx  if !R(A) pc+=sBx */
    1180       int a = GETARG_A(i);
    1181       int sbx = GETARG_sBx(i);
     1205    CASE(OP_JMPNOT, BS) {
    11821206      if (!mrb_test(regs[a])) {
    1183         pc += sbx;
     1207        pc = irep->iseq+b;
    11841208        JUMP;
    11851209      }
    11861210      NEXT;
    11871211    }
    1188 
    1189     CASE(OP_ONERR) {
    1190       /* sBx    pc+=sBx on exception */
    1191       int sbx = GETARG_sBx(i);
     1212    CASE(OP_JMPNIL, BS) {
     1213      if (mrb_nil_p(regs[a])) {
     1214        pc = irep->iseq+b;
     1215        JUMP;
     1216      }
     1217      NEXT;
     1218    }
     1219
     1220    CASE(OP_ONERR, S) {
     1221      /* check rescue stack */
     1222      if (mrb->c->ci->ridx == UINT16_MAX-1) {
     1223        mrb_value exc = mrb_exc_new_str_lit(mrb, E_RUNTIME_ERROR, "too many nested rescues");
     1224        mrb_exc_set(mrb, exc);
     1225        goto L_RAISE;
     1226      }
     1227      /* expand rescue stack */
    11921228      if (mrb->c->rsize <= mrb->c->ci->ridx) {
    11931229        if (mrb->c->rsize == 0) mrb->c->rsize = RESCUE_STACK_INIT_SIZE;
    1194         else mrb->c->rsize *= 2;
    1195         mrb->c->rescue = (mrb_code **)mrb_realloc(mrb, mrb->c->rescue, sizeof(mrb_code*) * mrb->c->rsize);
    1196       }
    1197       mrb->c->rescue[mrb->c->ci->ridx++] = pc + sbx;
    1198       NEXT;
    1199     }
    1200 
    1201     CASE(OP_RESCUE) {
    1202       /* A B    R(A) := exc; clear(exc); R(B) := matched (bool) */
    1203       int a = GETARG_A(i);
    1204       int b = GETARG_B(i);
    1205       int c = GETARG_C(i);
    1206       mrb_value exc;
    1207 
    1208       if (c == 0) {
    1209         exc = mrb_obj_value(mrb->exc);
    1210         mrb->exc = 0;
    1211       }
    1212       else {           /* continued; exc taken from R(A) */
    1213         exc = regs[a];
    1214       }
    1215       if (b != 0) {
    1216         mrb_value e = regs[b];
    1217         struct RClass *ec;
    1218 
    1219         switch (mrb_type(e)) {
    1220         case MRB_TT_CLASS:
    1221         case MRB_TT_MODULE:
    1222           break;
    1223         default:
    1224           {
    1225             mrb_value exc;
    1226 
    1227             exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR,
    1228                   "class or module required for rescue clause");
    1229             mrb_exc_set(mrb, exc);
    1230             goto L_RAISE;
    1231           }
    1232         }
    1233         ec = mrb_class_ptr(e);
    1234         regs[b] = mrb_bool_value(mrb_obj_is_kind_of(mrb, exc, ec));
    1235       }
    1236       if (a != 0 && c == 0) {
    1237         regs[a] = exc;
    1238       }
    1239       NEXT;
    1240     }
    1241 
    1242     CASE(OP_POPERR) {
    1243       /* A      A.times{rescue_pop()} */
    1244       int a = GETARG_A(i);
    1245 
    1246       while (a--) {
    1247         mrb->c->ci->ridx--;
    1248       }
    1249       NEXT;
    1250     }
    1251 
    1252     CASE(OP_RAISE) {
    1253       /* A      raise(R(A)) */
    1254       int a = GETARG_A(i);
    1255 
     1230        else {
     1231          mrb->c->rsize *= 2;
     1232          if (mrb->c->rsize <= mrb->c->ci->ridx) {
     1233            mrb->c->rsize = UINT16_MAX;
     1234          }
     1235        }
     1236        mrb->c->rescue = (uint16_t*)mrb_realloc(mrb, mrb->c->rescue, sizeof(uint16_t)*mrb->c->rsize);
     1237      }
     1238      /* push rescue stack */
     1239      mrb->c->rescue[mrb->c->ci->ridx++] = a;
     1240      NEXT;
     1241    }
     1242
     1243    CASE(OP_EXCEPT, B) {
     1244      mrb_value exc = mrb_obj_value(mrb->exc);
     1245      mrb->exc = 0;
     1246      regs[a] = exc;
     1247      NEXT;
     1248    }
     1249    CASE(OP_RESCUE, BB) {
     1250      mrb_value exc = regs[a];  /* exc on stack */
     1251      mrb_value e = regs[b];
     1252      struct RClass *ec;
     1253
     1254      switch (mrb_type(e)) {
     1255      case MRB_TT_CLASS:
     1256      case MRB_TT_MODULE:
     1257        break;
     1258      default:
     1259        {
     1260          mrb_value exc;
     1261
     1262          exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR,
     1263                                    "class or module required for rescue clause");
     1264          mrb_exc_set(mrb, exc);
     1265          goto L_RAISE;
     1266        }
     1267      }
     1268      ec = mrb_class_ptr(e);
     1269      regs[b] = mrb_bool_value(mrb_obj_is_kind_of(mrb, exc, ec));
     1270      NEXT;
     1271    }
     1272
     1273    CASE(OP_POPERR, B) {
     1274      mrb->c->ci->ridx -= a;
     1275      NEXT;
     1276    }
     1277
     1278    CASE(OP_RAISE, B) {
    12561279      mrb_exc_set(mrb, regs[a]);
    12571280      goto L_RAISE;
    12581281    }
    12591282
    1260     CASE(OP_EPUSH) {
    1261       /* Bx     ensure_push(SEQ[Bx]) */
    1262       int bx = GETARG_Bx(i);
     1283    CASE(OP_EPUSH, B) {
    12631284      struct RProc *p;
    12641285
    1265       p = mrb_closure_new(mrb, irep->reps[bx]);
    1266       /* push ensure_stack */
     1286      p = mrb_closure_new(mrb, irep->reps[a]);
     1287      /* check ensure stack */
     1288      if (mrb->c->eidx == UINT16_MAX-1) {
     1289        mrb_value exc = mrb_exc_new_str_lit(mrb, E_RUNTIME_ERROR, "too many nested ensures");
     1290        mrb_exc_set(mrb, exc);
     1291        goto L_RAISE;
     1292      }
     1293      /* expand ensure stack */
    12671294      if (mrb->c->esize <= mrb->c->eidx+1) {
    12681295        if (mrb->c->esize == 0) mrb->c->esize = ENSURE_STACK_INIT_SIZE;
    1269         else mrb->c->esize *= 2;
    1270         mrb->c->ensure = (struct RProc **)mrb_realloc(mrb, mrb->c->ensure, sizeof(struct RProc*) * mrb->c->esize);
    1271       }
     1296        else {
     1297          mrb->c->esize *= 2;
     1298          if (mrb->c->esize <= mrb->c->eidx) {
     1299            mrb->c->esize = UINT16_MAX;
     1300          }
     1301        }
     1302        mrb->c->ensure = (struct RProc**)mrb_realloc(mrb, mrb->c->ensure, sizeof(struct RProc*)*mrb->c->esize);
     1303      }
     1304      /* push ensure stack */
    12721305      mrb->c->ensure[mrb->c->eidx++] = p;
    12731306      mrb->c->ensure[mrb->c->eidx] = NULL;
    1274       ARENA_RESTORE(mrb, ai);
    1275       NEXT;
    1276     }
    1277 
    1278     CASE(OP_EPOP) {
    1279       /* A      A.times{ensure_pop().call} */
    1280       int a = GETARG_A(i);
     1307      mrb_gc_arena_restore(mrb, ai);
     1308      NEXT;
     1309    }
     1310
     1311    CASE(OP_EPOP, B) {
    12811312      mrb_callinfo *ci = mrb->c->ci;
    1282       int n, epos = ci->epos;
    1283 
    1284       for (n=0; n<a && mrb->c->eidx > epos; n++) {
    1285         ecall(mrb, --mrb->c->eidx);
    1286         ARENA_RESTORE(mrb, ai);
    1287       }
    1288       NEXT;
    1289     }
    1290 
    1291     CASE(OP_LOADNIL) {
    1292       /* A     R(A) := nil */
    1293       int a = GETARG_A(i);
    1294 
    1295       SET_NIL_VALUE(regs[a]);
    1296       NEXT;
    1297     }
    1298 
    1299     CASE(OP_SENDB) {
    1300       /* A B C  R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C),&R(A+C+1))*/
    1301       /* fall through */
     1313      unsigned int n, epos = ci->epos;
     1314      mrb_value self = regs[0];
     1315      struct RClass *target_class = ci->target_class;
     1316
     1317      if (mrb->c->eidx <= epos) {
     1318        NEXT;
     1319      }
     1320
     1321      if (a > (int)mrb->c->eidx - epos)
     1322        a = mrb->c->eidx - epos;
     1323      for (n=0; n<a; n++) {
     1324        int nregs = irep->nregs;
     1325
     1326        proc = mrb->c->ensure[epos+n];
     1327        mrb->c->ensure[epos+n] = NULL;
     1328        if (proc == NULL) continue;
     1329        irep = proc->body.irep;
     1330        ci = cipush(mrb);
     1331        ci->mid = ci[-1].mid;
     1332        ci->argc = 0;
     1333        ci->proc = proc;
     1334        ci->stackent = mrb->c->stack;
     1335        ci->target_class = target_class;
     1336        ci->pc = pc;
     1337        ci->acc = nregs;
     1338        mrb->c->stack += ci->acc;
     1339        mrb_stack_extend(mrb, irep->nregs);
     1340        regs[0] = self;
     1341        pc = irep->iseq;
     1342      }
     1343      pool = irep->pool;
     1344      syms = irep->syms;
     1345      mrb->c->eidx = epos;
     1346      JUMP;
     1347    }
     1348
     1349    CASE(OP_SENDV, BB) {
     1350      c = CALL_MAXARGS;
     1351      goto L_SEND;
    13021352    };
    13031353
    1304   L_SEND:
    1305     CASE(OP_SEND) {
    1306       /* A B C  R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C)) */
    1307       int a = GETARG_A(i);
    1308       int n = GETARG_C(i);
    1309       struct RProc *m;
    1310       struct RClass *c;
     1354    CASE(OP_SENDVB, BB) {
     1355      c = CALL_MAXARGS;
     1356      goto L_SENDB;
     1357    };
     1358
     1359    CASE(OP_SEND, BBB)
     1360    L_SEND:
     1361    {
     1362      /* push nil after arguments */
     1363      int bidx = (c == CALL_MAXARGS) ? a+2 : a+c+1;
     1364      SET_NIL_VALUE(regs[bidx]);
     1365      goto L_SENDB;
     1366    };
     1367    L_SEND_SYM:
     1368    {
     1369      /* push nil after arguments */
     1370      int bidx = (c == CALL_MAXARGS) ? a+2 : a+c+1;
     1371      SET_NIL_VALUE(regs[bidx]);
     1372      goto L_SENDB_SYM;
     1373    };
     1374
     1375    CASE(OP_SENDB, BBB)
     1376    L_SENDB:
     1377    mid = syms[b];
     1378    L_SENDB_SYM:
     1379    {
     1380      int argc = (c == CALL_MAXARGS) ? -1 : c;
     1381      int bidx = (argc < 0) ? a+2 : a+c+1;
     1382      mrb_method_t m;
     1383      struct RClass *cls;
    13111384      mrb_callinfo *ci = mrb->c->ci;
    1312       mrb_value recv, result;
    1313       mrb_sym mid = syms[GETARG_B(i)];
    1314       int bidx;
    1315       mrb_value blk;
     1385      mrb_value recv, blk;
     1386
     1387      mrb_assert(bidx < irep->nregs);
    13161388
    13171389      recv = regs[a];
    1318       if (n == CALL_MAXARGS) {
    1319         bidx = a+2;
    1320       }
    1321       else {
    1322         bidx = a+n+1;
    1323       }
    1324       if (GET_OPCODE(i) != OP_SENDB) {
    1325         if (bidx >= ci->nregs) {
    1326           stack_extend(mrb, bidx+1);
    1327           ci->nregs = bidx+1;
    1328         }
    1329         SET_NIL_VALUE(regs[bidx]);
    1330         blk = mrb_nil_value();
    1331       }
    1332       else {
    1333         blk = regs[bidx];
    1334         if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) {
    1335           if (bidx >= ci->nregs) {
    1336             stack_extend(mrb, bidx+1);
    1337             ci->nregs = bidx+1;
    1338           }
    1339           result = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc");
    1340           blk = regs[bidx] = result;
    1341         }
    1342       }
    1343       c = mrb_class(mrb, recv);
    1344       m = mrb_method_search_vm(mrb, &c, mid);
    1345       if (!m) {
    1346         mrb_value sym = mrb_symbol_value(mid);
     1390      blk = regs[bidx];
     1391      if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) {
     1392        blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc");
     1393        /* The stack might have been reallocated during mrb_convert_type(),
     1394           see #3622 */
     1395        regs[bidx] = blk;
     1396      }
     1397      cls = mrb_class(mrb, recv);
     1398      m = mrb_method_search_vm(mrb, &cls, mid);
     1399      if (MRB_METHOD_UNDEF_P(m)) {
    13471400        mrb_sym missing = mrb_intern_lit(mrb, "method_missing");
    1348 
    1349         m = mrb_method_search_vm(mrb, &c, missing);
    1350         if (!m) {
    1351           mrb_value args;
    1352 
    1353           if (n == CALL_MAXARGS) {
    1354             args = regs[a+1];
    1355           }
    1356           else {
    1357             args = mrb_ary_new_from_values(mrb, n, regs+a+1);
    1358           }
    1359           ERR_PC_SET(mrb, pc);
     1401        m = mrb_method_search_vm(mrb, &cls, missing);
     1402        if (MRB_METHOD_UNDEF_P(m) || (missing == mrb->c->ci->mid && mrb_obj_eq(mrb, regs[0], recv))) {
     1403          mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, c, regs+a+1);
     1404          ERR_PC_SET(mrb);
    13601405          mrb_method_missing(mrb, mid, recv, args);
    13611406        }
     1407        if (argc >= 0) {
     1408          if (a+2 >= irep->nregs) {
     1409            mrb_stack_extend(mrb, a+3);
     1410          }
     1411          regs[a+1] = mrb_ary_new_from_values(mrb, c, regs+a+1);
     1412          regs[a+2] = blk;
     1413          argc = -1;
     1414        }
     1415        mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(mid));
    13621416        mid = missing;
    1363         if (n != CALL_MAXARGS) {
    1364           if (a+2 >= irep->nregs) {
    1365             stack_extend(mrb, a+3);
    1366           }
    1367           regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1);
    1368           regs[a+2] = blk;
    1369           n = CALL_MAXARGS;
    1370         }
    1371         mrb_ary_unshift(mrb, regs[a+1], sym);
    13721417      }
    13731418
     
    13751420      ci = cipush(mrb);
    13761421      ci->mid = mid;
    1377       ci->proc = m;
    13781422      ci->stackent = mrb->c->stack;
    1379       ci->target_class = c;
    1380 
    1381       ci->pc = pc + 1;
     1423      ci->target_class = cls;
     1424      ci->argc = argc;
     1425
     1426      ci->pc = pc;
    13821427      ci->acc = a;
    13831428
     
    13851430      mrb->c->stack += a;
    13861431
    1387       if (MRB_PROC_CFUNC_P(m)) {
    1388         if (n == CALL_MAXARGS) {
    1389           ci->argc = -1;
    1390           ci->nregs = 3;
     1432      if (MRB_METHOD_CFUNC_P(m)) {
     1433        if (MRB_METHOD_PROC_P(m)) {
     1434          struct RProc *p = MRB_METHOD_PROC(m);
     1435
     1436          ci->proc = p;
     1437          recv = p->body.func(mrb, recv);
     1438        }
     1439        else if (MRB_METHOD_NOARG_P(m) &&
     1440                 (argc > 0 || (argc == -1 && RARRAY_LEN(regs[1]) != 0))) {
     1441          argnum_error(mrb, 0);
     1442          goto L_RAISE;
    13911443        }
    13921444        else {
    1393           ci->argc = n;
    1394           ci->nregs = n + 2;
    1395         }
    1396         result = m->body.func(mrb, recv);
     1445          recv = MRB_METHOD_FUNC(m)(mrb, recv);
     1446        }
    13971447        mrb_gc_arena_restore(mrb, ai);
     1448        mrb_gc_arena_shrink(mrb, ai);
    13981449        if (mrb->exc) goto L_RAISE;
    13991450        ci = mrb->c->ci;
    1400         if (GET_OPCODE(i) == OP_SENDB) {
    1401           if (mrb_type(blk) == MRB_TT_PROC) {
    1402             struct RProc *p = mrb_proc_ptr(blk);
    1403 
    1404             if (p && !MRB_PROC_STRICT_P(p) && p->env == ci[-1].env) {
    1405               p->flags |= MRB_PROC_ORPHAN;
    1406             }
     1451        if (mrb_proc_p(blk)) {
     1452          struct RProc *p = mrb_proc_ptr(blk);
     1453          if (p && !MRB_PROC_STRICT_P(p) && MRB_PROC_ENV(p) == ci[-1].env) {
     1454            p->flags |= MRB_PROC_ORPHAN;
    14071455          }
    14081456        }
     
    14101458          if (ci->acc == CI_ACC_RESUMED) {
    14111459            mrb->jmp = prev_jmp;
    1412             return result;
     1460            return recv;
    14131461          }
    14141462          else {
     
    14201468          }
    14211469        }
    1422         mrb->c->stack[0] = result;
     1470        mrb->c->stack[0] = recv;
    14231471        /* pop stackpos */
    14241472        mrb->c->stack = ci->stackent;
     
    14291477      else {
    14301478        /* setup environment for calling method */
    1431         proc = mrb->c->ci->proc = m;
    1432         irep = m->body.irep;
     1479        proc = ci->proc = MRB_METHOD_PROC(m);
     1480        irep = proc->body.irep;
    14331481        pool = irep->pool;
    14341482        syms = irep->syms;
    1435         ci->nregs = irep->nregs;
    1436         if (n == CALL_MAXARGS) {
    1437           ci->argc = -1;
    1438           stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs);
    1439         }
    1440         else {
    1441           ci->argc = n;
    1442           stack_extend(mrb, irep->nregs);
    1443         }
     1483        mrb_stack_extend(mrb, (argc < 0 && irep->nregs < 3) ? 3 : irep->nregs);
    14441484        pc = irep->iseq;
    14451485        JUMP;
     
    14471487    }
    14481488
    1449     CASE(OP_FSEND) {
    1450       /* A B C  R(A) := fcall(R(A),Syms(B),R(A+1),... ,R(A+C-1)) */
    1451       /* not implemented yet */
    1452       NEXT;
    1453     }
    1454 
    1455     CASE(OP_CALL) {
    1456       /* A      R(A) := self.call(frame.argc, frame.argv) */
     1489    CASE(OP_CALL, Z) {
    14571490      mrb_callinfo *ci;
    14581491      mrb_value recv = mrb->c->stack[0];
     
    14611494      /* replace callinfo */
    14621495      ci = mrb->c->ci;
    1463       ci->target_class = m->target_class;
     1496      ci->target_class = MRB_PROC_TARGET_CLASS(m);
    14641497      ci->proc = m;
    1465       if (m->env) {
    1466         mrb_sym mid;
    1467 
    1468         if (MRB_ENV_STACK_SHARED_P(m->env)) {
    1469           mid = m->env->cxt.c->cibase[m->env->cioff].mid;
    1470         }
    1471         else {
    1472           mid = m->env->cxt.mid;
    1473         }
    1474         if (mid) ci->mid = mid;
    1475         if (!m->env->stack) {
    1476           m->env->stack = mrb->c->stack;
     1498      if (MRB_PROC_ENV_P(m)) {
     1499        struct REnv *e = MRB_PROC_ENV(m);
     1500
     1501        ci->mid = e->mid;
     1502        if (!e->stack) {
     1503          e->stack = mrb->c->stack;
    14771504        }
    14781505      }
     
    14801507      /* prepare stack */
    14811508      if (MRB_PROC_CFUNC_P(m)) {
    1482         recv = m->body.func(mrb, recv);
     1509        recv = MRB_PROC_CFUNC(m)(mrb, recv);
    14831510        mrb_gc_arena_restore(mrb, ai);
     1511        mrb_gc_arena_shrink(mrb, ai);
    14841512        if (mrb->exc) goto L_RAISE;
    14851513        /* pop stackpos */
     
    15001528        if (!irep) {
    15011529          mrb->c->stack[0] = mrb_nil_value();
    1502           goto L_RETURN;
     1530          a = 0;
     1531          c = OP_R_NORMAL;
     1532          goto L_OP_RETURN_BODY;
    15031533        }
    15041534        pool = irep->pool;
    15051535        syms = irep->syms;
    1506         ci->nregs = irep->nregs;
    1507         stack_extend(mrb, irep->nregs);
     1536        mrb_stack_extend(mrb, irep->nregs);
    15081537        if (ci->argc < 0) {
    15091538          if (irep->nregs > 3) {
     
    15141543          stack_clear(regs+ci->argc+2, irep->nregs-ci->argc-2);
    15151544        }
    1516         if (m->env) {
    1517           regs[0] = m->env->stack[0];
     1545        if (MRB_PROC_ENV_P(m)) {
     1546          regs[0] = MRB_PROC_ENV(m)->stack[0];
    15181547        }
    15191548        pc = irep->iseq;
     
    15221551    }
    15231552
    1524     CASE(OP_SUPER) {
    1525       /* A C  R(A) := super(R(A+1),... ,R(A+C+1)) */
    1526       mrb_value recv;
     1553    CASE(OP_SUPER, BB) {
     1554      int argc = (b == CALL_MAXARGS) ? -1 : b;
     1555      int bidx = (argc < 0) ? a+2 : a+b+1;
     1556      mrb_method_t m;
     1557      struct RClass *cls;
    15271558      mrb_callinfo *ci = mrb->c->ci;
    1528       struct RProc *m;
    1529       struct RClass *c;
     1559      mrb_value recv, blk;
     1560      struct RProc *p = ci->proc;
    15301561      mrb_sym mid = ci->mid;
    1531       int a = GETARG_A(i);
    1532       int n = GETARG_C(i);
    1533       mrb_value blk;
    1534       int bidx;
    1535 
    1536       if (mid == 0 || !ci->target_class) {
    1537         mrb_value exc;
    1538 
    1539         exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method");
     1562      struct RClass* target_class = MRB_PROC_TARGET_CLASS(p);
     1563
     1564      if (MRB_PROC_ENV_P(p) && p->e.env->mid && p->e.env->mid != mid) { /* alias support */
     1565        mid = p->e.env->mid;    /* restore old mid */
     1566      }
     1567      mrb_assert(bidx < irep->nregs);
     1568
     1569      if (mid == 0 || !target_class) {
     1570        mrb_value exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method");
    15401571        mrb_exc_set(mrb, exc);
    15411572        goto L_RAISE;
    15421573      }
     1574      if (target_class->tt == MRB_TT_MODULE) {
     1575        target_class = ci->target_class;
     1576        if (target_class->tt != MRB_TT_ICLASS) {
     1577          mrb_value exc = mrb_exc_new_str_lit(mrb, E_RUNTIME_ERROR, "superclass info lost [mruby limitations]");
     1578          mrb_exc_set(mrb, exc);
     1579          goto L_RAISE;
     1580        }
     1581      }
    15431582      recv = regs[0];
    1544       c = mrb->c->ci->target_class->super;
    1545       m = mrb_method_search_vm(mrb, &c, mid);
    1546       if (!m) {
     1583      if (!mrb_obj_is_kind_of(mrb, recv, target_class)) {
     1584        mrb_value exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR,
     1585                                            "self has wrong type to call super in this context");
     1586        mrb_exc_set(mrb, exc);
     1587        goto L_RAISE;
     1588      }
     1589      blk = regs[bidx];
     1590      if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) {
     1591        blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc");
     1592        /* The stack or ci stack might have been reallocated during
     1593           mrb_convert_type(), see #3622 and #3784 */
     1594        regs[bidx] = blk;
     1595        ci = mrb->c->ci;
     1596      }
     1597      cls = target_class->super;
     1598      m = mrb_method_search_vm(mrb, &cls, mid);
     1599      if (MRB_METHOD_UNDEF_P(m)) {
    15471600        mrb_sym missing = mrb_intern_lit(mrb, "method_missing");
    1548         m = mrb_method_search_vm(mrb, &c, missing);
    1549         if (!m) {
    1550           mrb_value args;
    1551 
    1552           if (n == CALL_MAXARGS) {
    1553             args = regs[a+1];
    1554           }
    1555           else {
    1556             args = mrb_ary_new_from_values(mrb, n, regs+a+1);
    1557           }
    1558           ERR_PC_SET(mrb, pc);
     1601
     1602        if (mid != missing) {
     1603          cls = mrb_class(mrb, recv);
     1604        }
     1605        m = mrb_method_search_vm(mrb, &cls, missing);
     1606        if (MRB_METHOD_UNDEF_P(m)) {
     1607          mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, b, regs+a+1);
     1608          ERR_PC_SET(mrb);
    15591609          mrb_method_missing(mrb, mid, recv, args);
    15601610        }
    15611611        mid = missing;
    1562         if (n == CALL_MAXARGS-1) {
    1563           regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1);
    1564           n++;
    1565         }
    1566         if (n == CALL_MAXARGS) {
    1567           mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid));
    1568         }
    1569         else {
    1570           value_move(regs+a+2, regs+a+1, ++n);
    1571           SET_SYM_VALUE(regs[a+1], ci->mid);
    1572         }
    1573       }
    1574 
    1575       if (n == CALL_MAXARGS) {
    1576         bidx = a+2;
    1577       }
    1578       else {
    1579         bidx = a+n+1;
    1580       }
    1581       blk = regs[bidx];
    1582       if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) {
    1583         mrb_value result;
    1584 
    1585         if (bidx >= ci->nregs) {
    1586           stack_extend(mrb, bidx+1);
    1587           ci->nregs = bidx+1;
    1588         }
    1589         result = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc");
    1590         regs[bidx] = result;
     1612        if (argc >= 0) {
     1613          if (a+2 >= irep->nregs) {
     1614            mrb_stack_extend(mrb, a+3);
     1615          }
     1616          regs[a+1] = mrb_ary_new_from_values(mrb, b, regs+a+1);
     1617          regs[a+2] = blk;
     1618          argc = -1;
     1619        }
     1620        mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid));
    15911621      }
    15921622
     
    15941624      ci = cipush(mrb);
    15951625      ci->mid = mid;
    1596       ci->proc = m;
    15971626      ci->stackent = mrb->c->stack;
    1598       ci->target_class = c;
    1599       ci->pc = pc + 1;
    1600       if (n == CALL_MAXARGS) {
    1601         ci->argc = -1;
    1602       }
    1603       else {
    1604         ci->argc = n;
    1605       }
     1627      ci->target_class = cls;
     1628      ci->pc = pc;
     1629      ci->argc = argc;
    16061630
    16071631      /* prepare stack */
     
    16091633      mrb->c->stack[0] = recv;
    16101634
    1611       if (MRB_PROC_CFUNC_P(m)) {
     1635      if (MRB_METHOD_CFUNC_P(m)) {
    16121636        mrb_value v;
    16131637
    1614         if (n == CALL_MAXARGS) {
    1615           ci->nregs = 3;
    1616         }
    1617         else {
    1618           ci->nregs = n + 2;
    1619         }
    1620         v = m->body.func(mrb, recv);
     1638        if (MRB_METHOD_PROC_P(m)) {
     1639          ci->proc = MRB_METHOD_PROC(m);
     1640        }
     1641        v = MRB_METHOD_CFUNC(m)(mrb, recv);
    16211642        mrb_gc_arena_restore(mrb, ai);
    16221643        if (mrb->exc) goto L_RAISE;
     
    16471668
    16481669        /* setup environment for calling method */
    1649         ci->proc = m;
    1650         irep = m->body.irep;
     1670        proc = ci->proc = MRB_METHOD_PROC(m);
     1671        irep = proc->body.irep;
    16511672        pool = irep->pool;
    16521673        syms = irep->syms;
    1653         ci->nregs = irep->nregs;
    1654         if (n == CALL_MAXARGS) {
    1655           stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs);
    1656         }
    1657         else {
    1658           stack_extend(mrb, irep->nregs);
    1659         }
     1674        mrb_stack_extend(mrb, (argc < 0 && irep->nregs < 3) ? 3 : irep->nregs);
    16601675        pc = irep->iseq;
    16611676        JUMP;
     
    16631678    }
    16641679
    1665     CASE(OP_ARGARY) {
    1666       /* A Bx   R(A) := argument array (16=6:1:5:4) */
    1667       int a = GETARG_A(i);
    1668       int bx = GETARG_Bx(i);
    1669       int m1 = (bx>>10)&0x3f;
    1670       int r  = (bx>>9)&0x1;
    1671       int m2 = (bx>>4)&0x1f;
    1672       int lv = (bx>>0)&0xf;
     1680    CASE(OP_ARGARY, BS) {
     1681      int m1 = (b>>11)&0x3f;
     1682      int r  = (b>>10)&0x1;
     1683      int m2 = (b>>5)&0x1f;
     1684      int kd = (b>>4)&0x1;
     1685      int lv = (b>>0)&0xf;
    16731686      mrb_value *stack;
    16741687
     
    16851698        struct REnv *e = uvenv(mrb, lv-1);
    16861699        if (!e) goto L_NOSUPER;
     1700        if (MRB_ENV_STACK_LEN(e) <= m1+r+m2+kd+1)
     1701          goto L_NOSUPER;
    16871702        stack = e->stack + 1;
    16881703      }
    16891704      if (r == 0) {
    1690         regs[a] = mrb_ary_new_from_values(mrb, m1+m2, stack);
     1705        regs[a] = mrb_ary_new_from_values(mrb, m1+m2+kd, stack);
    16911706      }
    16921707      else {
     
    16981713          struct RArray *ary = mrb_ary_ptr(stack[m1]);
    16991714
    1700           pp = ary->ptr;
    1701           len = ary->len;
    1702         }
    1703         regs[a] = mrb_ary_new_capa(mrb, m1+len+m2);
     1715          pp = ARY_PTR(ary);
     1716          len = (int)ARY_LEN(ary);
     1717        }
     1718        regs[a] = mrb_ary_new_capa(mrb, m1+len+m2+kd);
    17041719        rest = mrb_ary_ptr(regs[a]);
    17051720        if (m1 > 0) {
    1706           stack_copy(rest->ptr, stack, m1);
     1721          stack_copy(ARY_PTR(rest), stack, m1);
    17071722        }
    17081723        if (len > 0) {
    1709           stack_copy(rest->ptr+m1, pp, len);
     1724          stack_copy(ARY_PTR(rest)+m1, pp, len);
    17101725        }
    17111726        if (m2 > 0) {
    1712           stack_copy(rest->ptr+m1+len, stack+m1+1, m2);
    1713         }
    1714         rest->len = m1+len+m2;
     1727          stack_copy(ARY_PTR(rest)+m1+len, stack+m1+1, m2);
     1728        }
     1729        if (kd) {
     1730          stack_copy(ARY_PTR(rest)+m1+len+m2, stack+m1+m2+1, kd);
     1731        }
     1732        ARY_SET_LEN(rest, m1+len+m2+kd);
    17151733      }
    17161734      regs[a+1] = stack[m1+r+m2];
    1717       ARENA_RESTORE(mrb, ai);
    1718       NEXT;
    1719     }
    1720 
    1721     CASE(OP_ENTER) {
    1722       /* Ax             arg setup according to flags (23=5:5:1:5:5:1:1) */
    1723       /* number of optional arguments times OP_JMP should follow */
    1724       mrb_aspec ax = GETARG_Ax(i);
    1725       int m1 = MRB_ASPEC_REQ(ax);
    1726       int o  = MRB_ASPEC_OPT(ax);
    1727       int r  = MRB_ASPEC_REST(ax);
    1728       int m2 = MRB_ASPEC_POST(ax);
     1735      mrb_gc_arena_restore(mrb, ai);
     1736      NEXT;
     1737    }
     1738
     1739    CASE(OP_ENTER, W) {
     1740      int m1 = MRB_ASPEC_REQ(a);
     1741      int o  = MRB_ASPEC_OPT(a);
     1742      int r  = MRB_ASPEC_REST(a);
     1743      int m2 = MRB_ASPEC_POST(a);
     1744      int kd = (MRB_ASPEC_KEY(a) > 0 || MRB_ASPEC_KDICT(a))? 1 : 0;
    17291745      /* unused
    1730       int k  = MRB_ASPEC_KEY(ax);
    1731       int kd = MRB_ASPEC_KDICT(ax);
    1732       int b  = MRB_ASPEC_BLOCK(ax);
     1746      int b  = MRB_ASPEC_BLOCK(a);
    17331747      */
    17341748      int argc = mrb->c->ci->argc;
    17351749      mrb_value *argv = regs+1;
    1736       mrb_value *argv0 = argv;
    1737       int len = m1 + o + r + m2;
     1750      mrb_value * const argv0 = argv;
     1751      int const len = m1 + o + r + m2;
     1752      int const blk_pos = len + kd + 1;
    17381753      mrb_value *blk = &argv[argc < 0 ? 1 : argc];
    1739 
     1754      mrb_value kdict;
     1755      int kargs = kd;
     1756
     1757      /* arguments is passed with Array */
    17401758      if (argc < 0) {
    17411759        struct RArray *ary = mrb_ary_ptr(regs[1]);
    1742         argv = ary->ptr;
    1743         argc = ary->len;
     1760        argv = ARY_PTR(ary);
     1761        argc = (int)ARY_LEN(ary);
    17441762        mrb_gc_protect(mrb, regs[1]);
    17451763      }
     1764
     1765      /* strict argument check */
    17461766      if (mrb->c->ci->proc && MRB_PROC_STRICT_P(mrb->c->ci->proc)) {
    1747         if (argc >= 0) {
    1748           if (argc < m1 + m2 || (r == 0 && argc > len)) {
     1767        if (argc < m1 + m2 || (r == 0 && argc > len + kd)) {
     1768          argnum_error(mrb, m1+m2);
     1769          goto L_RAISE;
     1770        }
     1771      }
     1772      /* extract first argument array to arguments */
     1773      else if (len > 1 && argc == 1 && mrb_array_p(argv[0])) {
     1774        mrb_gc_protect(mrb, argv[0]);
     1775        argc = (int)RARRAY_LEN(argv[0]);
     1776        argv = RARRAY_PTR(argv[0]);
     1777      }
     1778
     1779      if (kd) {
     1780        /* check last arguments is hash if method takes keyword arguments */
     1781        if (argc == m1+m2) {
     1782          kdict = mrb_hash_new(mrb);
     1783          kargs = 0;
     1784        }
     1785        else {
     1786          if (argv && argc > 0 && mrb_hash_p(argv[argc-1])) {
     1787            kdict = argv[argc-1];
     1788            mrb_hash_check_kdict(mrb, kdict);
     1789          }
     1790          else if (r || argc <= m1+m2+o
     1791                   || !(mrb->c->ci->proc && MRB_PROC_STRICT_P(mrb->c->ci->proc))) {
     1792            kdict = mrb_hash_new(mrb);
     1793            kargs = 0;
     1794          }
     1795          else {
    17491796            argnum_error(mrb, m1+m2);
    17501797            goto L_RAISE;
    17511798          }
    1752         }
    1753       }
    1754       else if (len > 1 && argc == 1 && mrb_array_p(argv[0])) {
    1755         mrb_gc_protect(mrb, argv[0]);
    1756         argc = mrb_ary_ptr(argv[0])->len;
    1757         argv = mrb_ary_ptr(argv[0])->ptr;
    1758       }
    1759       if (argc < len) {
     1799          if (MRB_ASPEC_KEY(a) > 0) {
     1800            kdict = mrb_hash_dup(mrb, kdict);
     1801          }
     1802        }
     1803      }
     1804
     1805      /* no rest arguments */
     1806      if (argc-kargs < len) {
    17601807        int mlen = m2;
    17611808        if (argc < m1+m2) {
    1762           if (m1 < argc)
    1763             mlen = argc - m1;
    1764           else
    1765             mlen = 0;
    1766         }
    1767         regs[len+1] = *blk; /* move block */
    1768         SET_NIL_VALUE(regs[argc+1]);
     1809          mlen = m1 < argc ? argc - m1 : 0;
     1810        }
     1811        regs[blk_pos] = *blk; /* move block */
     1812        if (kd) regs[len + 1] = kdict;
     1813
     1814        /* copy mandatory and optional arguments */
    17691815        if (argv0 != argv) {
    17701816          value_move(&regs[1], argv, argc-mlen); /* m1 + o */
     
    17731819          stack_clear(&regs[argc+1], m1-argc);
    17741820        }
     1821        /* copy post mandatory arguments */
    17751822        if (mlen) {
    17761823          value_move(&regs[len-m2+1], &argv[argc-mlen], mlen);
     
    17791826          stack_clear(&regs[len-m2+mlen+1], m2-mlen);
    17801827        }
     1828        /* initalize rest arguments with empty Array */
    17811829        if (r) {
    17821830          regs[m1+o+1] = mrb_ary_new_capa(mrb, 0);
    17831831        }
    1784         if (o == 0 || argc < m1+m2) pc++;
    1785         else
    1786           pc += argc - m1 - m2 + 1;
     1832        /* skip initailizer of passed arguments */
     1833        if (o > 0 && argc-kargs > m1+m2)
     1834          pc += (argc - kargs - m1 - m2)*3;
    17871835      }
    17881836      else {
    17891837        int rnum = 0;
    17901838        if (argv0 != argv) {
    1791           regs[len+1] = *blk; /* move block */
     1839          regs[blk_pos] = *blk; /* move block */
     1840          if (kd) regs[len + 1] = kdict;
    17921841          value_move(&regs[1], argv, m1+o);
    17931842        }
    17941843        if (r) {
    1795           rnum = argc-m1-o-m2;
    1796           regs[m1+o+1] = mrb_ary_new_from_values(mrb, rnum, argv+m1+o);
     1844          mrb_value ary;
     1845
     1846          rnum = argc-m1-o-m2-kargs;
     1847          ary = mrb_ary_new_from_values(mrb, rnum, argv+m1+o);
     1848          regs[m1+o+1] = ary;
    17971849        }
    17981850        if (m2) {
     
    18021854        }
    18031855        if (argv0 == argv) {
    1804           regs[len+1] = *blk; /* move block */
    1805         }
    1806         pc += o + 1;
    1807       }
    1808       mrb->c->ci->argc = len;
     1856          regs[blk_pos] = *blk; /* move block */
     1857          if (kd) regs[len + 1] = kdict;
     1858        }
     1859        pc += o*3;
     1860      }
     1861
     1862      /* format arguments for generated code */
     1863      mrb->c->ci->argc = len + kd;
     1864
    18091865      /* clear local (but non-argument) variables */
    1810       if (irep->nlocals-len-2 > 0) {
    1811         stack_clear(&regs[len+2], irep->nlocals-len-2);
     1866      if (irep->nlocals-blk_pos-1 > 0) {
     1867        stack_clear(&regs[blk_pos+1], irep->nlocals-blk_pos-1);
    18121868      }
    18131869      JUMP;
    18141870    }
    18151871
    1816     CASE(OP_KARG) {
    1817       /* A B C          R(A) := kdict[Syms(B)]; if C kdict.rm(Syms(B)) */
    1818       /* if C == 2; raise unless kdict.empty? */
    1819       /* OP_JMP should follow to skip init code */
    1820       NEXT;
    1821     }
    1822 
    1823     CASE(OP_KDICT) {
    1824       /* A C            R(A) := kdict */
    1825       NEXT;
    1826     }
    1827 
     1872    CASE(OP_KARG, BB) {
     1873      mrb_value k = mrb_symbol_value(syms[b]);
     1874      mrb_value kdict = regs[mrb->c->ci->argc];
     1875
     1876      if (!mrb_hash_p(kdict) || !mrb_hash_key_p(mrb, kdict, k)) {
     1877        mrb_value str = mrb_format(mrb, "missing keyword: %v", k);
     1878        mrb_exc_set(mrb, mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str));
     1879        goto L_RAISE;
     1880      }
     1881      regs[a] = mrb_hash_get(mrb, kdict, k);
     1882      mrb_hash_delete_key(mrb, kdict, k);
     1883      NEXT;
     1884    }
     1885
     1886    CASE(OP_KEY_P, BB) {
     1887      mrb_value k = mrb_symbol_value(syms[b]);
     1888      mrb_value kdict = regs[mrb->c->ci->argc];
     1889      mrb_bool key_p = FALSE;
     1890
     1891      if (mrb_hash_p(kdict)) {
     1892        key_p = mrb_hash_key_p(mrb, kdict, k);
     1893      }
     1894      regs[a] = mrb_bool_value(key_p);
     1895      NEXT;
     1896    }
     1897
     1898    CASE(OP_KEYEND, Z) {
     1899      mrb_value kdict = regs[mrb->c->ci->argc];
     1900
     1901      if (mrb_hash_p(kdict) && !mrb_hash_empty_p(mrb, kdict)) {
     1902        mrb_value keys = mrb_hash_keys(mrb, kdict);
     1903        mrb_value key1 = RARRAY_PTR(keys)[0];
     1904        mrb_value str = mrb_format(mrb, "unknown keyword: %v", key1);
     1905        mrb_exc_set(mrb, mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str));
     1906        goto L_RAISE;
     1907      }
     1908      NEXT;
     1909    }
     1910
     1911    CASE(OP_BREAK, B) {
     1912      c = OP_R_BREAK;
     1913      goto L_RETURN;
     1914    }
     1915    CASE(OP_RETURN_BLK, B) {
     1916      c = OP_R_RETURN;
     1917      goto L_RETURN;
     1918    }
     1919    CASE(OP_RETURN, B)
     1920    c = OP_R_NORMAL;
    18281921    L_RETURN:
    1829       i = MKOP_AB(OP_RETURN, GETARG_A(i), OP_R_NORMAL);
    1830       /* fall through */
    1831     CASE(OP_RETURN) {
    1832       /* A B     return R(A) (B=normal,in-block return/break) */
    1833       mrb_callinfo *ci;
     1922    {
     1923       mrb_callinfo *ci;
     1924
     1925#define ecall_adjust() do {\
     1926  ptrdiff_t cioff = ci - mrb->c->cibase;\
     1927  ecall(mrb);\
     1928  ci = mrb->c->cibase + cioff;\
     1929} while (0)
    18341930
    18351931      ci = mrb->c->ci;
     
    18431939          blk = regs[ci->argc+1];
    18441940        }
    1845         if (mrb_type(blk) == MRB_TT_PROC) {
     1941        if (mrb_proc_p(blk)) {
    18461942          struct RProc *p = mrb_proc_ptr(blk);
    18471943
    1848           if (!MRB_PROC_STRICT_P(proc) &&
    1849               ci > mrb->c->cibase && p->env == ci[-1].env) {
     1944          if (!MRB_PROC_STRICT_P(p) &&
     1945              ci > mrb->c->cibase && MRB_PROC_ENV(p) == ci[-1].env) {
    18501946            p->flags |= MRB_PROC_ORPHAN;
    18511947          }
     
    18551951      if (mrb->exc) {
    18561952        mrb_callinfo *ci0;
    1857         mrb_value *stk;
    18581953
    18591954      L_RAISE:
     
    18631958          goto L_RESCUE;
    18641959        }
    1865         stk = mrb->c->stack;
    18661960        while (ci[0].ridx == ci[-1].ridx) {
    18671961          cipop(mrb);
     
    18731967          ci = mrb->c->ci;
    18741968          if (ci == mrb->c->cibase) {
    1875             mrb->c->stack = stk;
    18761969            if (ci->ridx == 0) {
    18771970            L_FTOP:             /* fiber top */
     
    18831976                struct mrb_context *c = mrb->c;
    18841977
    1885                 if (c->fib) {
    1886                   mrb_write_barrier(mrb, (struct RBasic*)c->fib);
     1978                while (c->eidx > ci->epos) {
     1979                  ecall_adjust();
    18871980                }
     1981                c->status = MRB_FIBER_TERMINATED;
    18881982                mrb->c = c->prev;
    18891983                c->prev = NULL;
     
    18961990          if (ci[0].ridx == ci[-1].ridx) {
    18971991            while (mrb->c->eidx > ci->epos) {
    1898               ecall(mrb, --mrb->c->eidx);
    1899               ci = mrb->c->ci;
     1992              ecall_adjust();
    19001993            }
    19011994          }
     
    19072000        pool = irep->pool;
    19082001        syms = irep->syms;
    1909         if (ci != ci0) {
     2002        if (ci < ci0) {
    19102003          mrb->c->stack = ci[1].stackent;
    19112004        }
    1912         stack_extend(mrb, irep->nregs);
    1913         pc = mrb->c->rescue[--ci->ridx];
     2005        mrb_stack_extend(mrb, irep->nregs);
     2006        pc = irep->iseq+mrb->c->rescue[--ci->ridx];
    19142007      }
    19152008      else {
    19162009        int acc;
    19172010        mrb_value v;
    1918 
    1919         v = regs[GETARG_A(i)];
     2011        struct RProc *dst;
     2012
     2013        ci = mrb->c->ci;
     2014        v = regs[a];
    19202015        mrb_gc_protect(mrb, v);
    1921         switch (GETARG_B(i)) {
     2016        switch (c) {
    19222017        case OP_R_RETURN:
    19232018          /* Fall through to OP_R_NORMAL otherwise */
    1924           if (ci->acc >=0 && proc->env && !MRB_PROC_STRICT_P(proc)) {
    1925             struct REnv *e = top_env(mrb, proc);
    1926             mrb_callinfo *ce;
    1927 
    1928             if (!MRB_ENV_STACK_SHARED_P(e) || e->cxt.c != mrb->c) {
    1929               localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
    1930               goto L_RAISE;
     2019          if (ci->acc >=0 && MRB_PROC_ENV_P(proc) && !MRB_PROC_STRICT_P(proc)) {
     2020            mrb_callinfo *cibase = mrb->c->cibase;
     2021            dst = top_proc(mrb, proc);
     2022
     2023            if (MRB_PROC_ENV_P(dst)) {
     2024              struct REnv *e = MRB_PROC_ENV(dst);
     2025
     2026              if (!MRB_ENV_STACK_SHARED_P(e) || (e->cxt && e->cxt != mrb->c)) {
     2027                localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
     2028                goto L_RAISE;
     2029              }
    19312030            }
    1932            
    1933             ce = mrb->c->cibase + e->cioff;
    1934             while (ci >= ce) {
    1935               if (ci->env) {
    1936                 mrb_env_unshare(mrb, ci->env);
    1937               }
     2031            while (cibase <= ci && ci->proc != dst) {
    19382032              if (ci->acc < 0) {
    19392033                localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
     
    19422036              ci--;
    19432037            }
    1944             if (ce == mrb->c->cibase) {
     2038            if (ci <= cibase) {
    19452039              localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
    19462040              goto L_RAISE;
    19472041            }
    1948             mrb->c->stack = mrb->c->ci->stackent;
    1949             mrb->c->ci = ce;
    19502042            break;
    19512043          }
     2044          /* fallthrough */
    19522045        case OP_R_NORMAL:
    19532046        NORMAL_RETURN:
    19542047          if (ci == mrb->c->cibase) {
    1955             if (!mrb->c->prev) { /* toplevel return */
    1956               localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
    1957               goto L_RAISE;
     2048            struct mrb_context *c = mrb->c;
     2049
     2050            if (!c->prev) { /* toplevel return */
     2051              regs[irep->nlocals] = v;
     2052              goto L_STOP;
    19582053            }
    1959             if (mrb->c->prev->ci == mrb->c->prev->cibase) {
     2054            if (c->prev->ci == c->prev->cibase) {
    19602055              mrb_value exc = mrb_exc_new_str_lit(mrb, E_FIBER_ERROR, "double resume");
    19612056              mrb_exc_set(mrb, exc);
    19622057              goto L_RAISE;
    19632058            }
    1964             while (mrb->c->eidx > 0) {
    1965               ecall(mrb, --mrb->c->eidx);
     2059            while (c->eidx > 0) {
     2060              ecall(mrb);
    19662061            }
    19672062            /* automatic yield at the end */
    1968             mrb->c->status = MRB_FIBER_TERMINATED;
    1969             mrb->c = mrb->c->prev;
     2063            c->status = MRB_FIBER_TERMINATED;
     2064            mrb->c = c->prev;
     2065            c->prev = NULL;
    19702066            mrb->c->status = MRB_FIBER_RUNNING;
    1971           }
    1972           ci = mrb->c->ci;
     2067            ci = mrb->c->ci;
     2068          }
    19732069          break;
    19742070        case OP_R_BREAK:
    19752071          if (MRB_PROC_STRICT_P(proc)) goto NORMAL_RETURN;
    1976           if (MRB_PROC_ORPHAN_P(proc)) { 
     2072          if (MRB_PROC_ORPHAN_P(proc)) {
    19772073            mrb_value exc;
    19782074
     
    19832079            goto L_RAISE;
    19842080          }
    1985           if (!proc->env || !MRB_ENV_STACK_SHARED_P(proc->env)) {
     2081          if (!MRB_PROC_ENV_P(proc) || !MRB_ENV_STACK_SHARED_P(MRB_PROC_ENV(proc))) {
    19862082            goto L_BREAK_ERROR;
    19872083          }
     2084          else {
     2085            struct REnv *e = MRB_PROC_ENV(proc);
     2086
     2087            if (e->cxt != mrb->c) {
     2088              goto L_BREAK_ERROR;
     2089            }
     2090          }
     2091          while (mrb->c->eidx > mrb->c->ci->epos) {
     2092            ecall_adjust();
     2093          }
    19882094          /* break from fiber block */
    1989           if (mrb->c->ci == mrb->c->cibase && mrb->c->ci->pc) {
     2095          if (ci == mrb->c->cibase && ci->pc) {
    19902096            struct mrb_context *c = mrb->c;
    19912097
    1992             while (mrb->c->eidx > 0) {
    1993               ecall(mrb, --mrb->c->eidx);
    1994             }
    19952098            mrb->c = c->prev;
    19962099            c->prev = NULL;
     
    19982101          }
    19992102          if (ci->acc < 0) {
    2000             while (mrb->c->eidx > mrb->c->ci->epos) {
    2001               ecall(mrb, --mrb->c->eidx);
    2002             }
    2003             ARENA_RESTORE(mrb, ai);
     2103            mrb_gc_arena_restore(mrb, ai);
    20042104            mrb->c->vmexec = FALSE;
    20052105            mrb->exc = (struct RObject*)break_new(mrb, proc, v);
     
    20092109          if (FALSE) {
    20102110          L_BREAK:
    2011             v = ((struct RBreak*)mrb->exc)->val;
    2012             proc = ((struct RBreak*)mrb->exc)->proc;
     2111            v = mrb_break_value_get((struct RBreak*)mrb->exc);
     2112            proc = mrb_break_proc_get((struct RBreak*)mrb->exc);
    20132113            mrb->exc = NULL;
    20142114            ci = mrb->c->ci;
    20152115          }
    20162116          mrb->c->stack = ci->stackent;
    2017           mrb->c->ci = mrb->c->cibase + proc->env->cioff + 1;
    2018           while (ci > mrb->c->ci) {
    2019             if (ci->env) {
    2020               mrb_env_unshare(mrb, ci->env);
    2021             }
     2117          proc = proc->upper;
     2118          while (mrb->c->cibase < ci &&  ci[-1].proc != proc) {
    20222119            if (ci[-1].acc == CI_ACC_SKIP) {
    2023               mrb->c->ci = ci;
     2120              while (ci < mrb->c->ci) {
     2121                cipop(mrb);
     2122              }
    20242123              goto L_BREAK_ERROR;
    20252124            }
    20262125            ci--;
     2126          }
     2127          if (ci == mrb->c->cibase) {
     2128            goto L_BREAK_ERROR;
    20272129          }
    20282130          break;
     
    20312133          break;
    20322134        }
    2033         while (mrb->c->eidx > mrb->c->ci->epos) {
    2034           ecall(mrb, --mrb->c->eidx);
    2035         }
    2036         if (mrb->c->vmexec && !mrb->c->ci->target_class) {
    2037           ARENA_RESTORE(mrb, ai);
     2135        while (ci < mrb->c->ci) {
     2136          cipop(mrb);
     2137        }
     2138        ci[0].ridx = ci[-1].ridx;
     2139        while (mrb->c->eidx > ci->epos) {
     2140          ecall_adjust();
     2141        }
     2142        if (mrb->c->vmexec && !ci->target_class) {
     2143          mrb_gc_arena_restore(mrb, ai);
    20382144          mrb->c->vmexec = FALSE;
    20392145          mrb->jmp = prev_jmp;
    20402146          return v;
    20412147        }
    2042         ci = mrb->c->ci;
    20432148        acc = ci->acc;
    20442149        mrb->c->stack = ci->stackent;
    20452150        cipop(mrb);
    20462151        if (acc == CI_ACC_SKIP || acc == CI_ACC_DIRECT) {
    2047           ARENA_RESTORE(mrb, ai);
     2152          mrb_gc_arena_restore(mrb, ai);
    20482153          mrb->jmp = prev_jmp;
    20492154          return v;
    20502155        }
    20512156        pc = ci->pc;
    2052         DEBUG(fprintf(stderr, "from :%s\n", mrb_sym2name(mrb, ci->mid)));
     2157        ci = mrb->c->ci;
     2158        DEBUG(fprintf(stderr, "from :%s\n", mrb_sym_name(mrb, ci->mid)));
    20532159        proc = mrb->c->ci->proc;
    20542160        irep = proc->body.irep;
     
    20572163
    20582164        regs[acc] = v;
    2059         ARENA_RESTORE(mrb, ai);
     2165        mrb_gc_arena_restore(mrb, ai);
    20602166      }
    20612167      JUMP;
    20622168    }
    20632169
    2064     CASE(OP_TAILCALL) {
    2065       /* A B C  return call(R(A),Syms(B),R(A+1),... ,R(A+C+1)) */
    2066       int a = GETARG_A(i);
    2067       int n = GETARG_C(i);
    2068       struct RProc *m;
    2069       struct RClass *c;
    2070       mrb_callinfo *ci;
    2071       mrb_value recv;
    2072       mrb_sym mid = syms[GETARG_B(i)];
    2073 
    2074       recv = regs[a];
    2075       c = mrb_class(mrb, recv);
    2076       m = mrb_method_search_vm(mrb, &c, mid);
    2077       if (!m) {
    2078         mrb_value sym = mrb_symbol_value(mid);
    2079         mrb_sym missing = mrb_intern_lit(mrb, "method_missing");
    2080         m = mrb_method_search_vm(mrb, &c, missing);
    2081         if (!m) {
    2082           mrb_value args;
    2083 
    2084           if (n == CALL_MAXARGS) {
    2085             args = regs[a+1];
    2086           }
    2087           else {
    2088             args = mrb_ary_new_from_values(mrb, n, regs+a+1);
    2089           }
    2090           ERR_PC_SET(mrb, pc);
    2091           mrb_method_missing(mrb, mid, recv, args);
    2092         }
    2093         mid = missing;
    2094         if (n == CALL_MAXARGS) {
    2095           mrb_ary_unshift(mrb, regs[a+1], sym);
    2096         }
    2097         else {
    2098           value_move(regs+a+2, regs+a+1, ++n);
    2099           regs[a+1] = sym;
    2100         }
    2101       }
    2102 
    2103       /* replace callinfo */
    2104       ci = mrb->c->ci;
    2105       ci->mid = mid;
    2106       ci->target_class = c;
    2107       if (n == CALL_MAXARGS) {
    2108         ci->argc = -1;
    2109       }
    2110       else {
    2111         ci->argc = n;
    2112       }
    2113 
    2114       /* move stack */
    2115       value_move(mrb->c->stack, &regs[a], ci->argc+1);
    2116 
    2117       if (MRB_PROC_CFUNC_P(m)) {
    2118         mrb_value v = m->body.func(mrb, recv);
    2119         mrb->c->stack[0] = v;
    2120         mrb_gc_arena_restore(mrb, ai);
    2121         goto L_RETURN;
    2122       }
    2123       else {
    2124         /* setup environment for calling method */
    2125         irep = m->body.irep;
    2126         pool = irep->pool;
    2127         syms = irep->syms;
    2128         if (ci->argc < 0) {
    2129           stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs);
    2130         }
    2131         else {
    2132           stack_extend(mrb, irep->nregs);
    2133         }
    2134         pc = irep->iseq;
    2135       }
    2136       JUMP;
    2137     }
    2138 
    2139     CASE(OP_BLKPUSH) {
    2140       /* A Bx   R(A) := block (16=6:1:5:4) */
    2141       int a = GETARG_A(i);
    2142       int bx = GETARG_Bx(i);
    2143       int m1 = (bx>>10)&0x3f;
    2144       int r  = (bx>>9)&0x1;
    2145       int m2 = (bx>>4)&0x1f;
    2146       int lv = (bx>>0)&0xf;
     2170    CASE(OP_BLKPUSH, BS) {
     2171      int m1 = (b>>11)&0x3f;
     2172      int r  = (b>>10)&0x1;
     2173      int m2 = (b>>5)&0x1f;
     2174      int kd = (b>>4)&0x1;
     2175      int lv = (b>>0)&0xf;
    21472176      mrb_value *stack;
    21482177
     
    21502179      else {
    21512180        struct REnv *e = uvenv(mrb, lv-1);
    2152         if (!e || e->cioff == 0 ||
    2153             (!MRB_ENV_STACK_SHARED_P(e) && e->cxt.mid == 0)) {
     2181        if (!e || (!MRB_ENV_STACK_SHARED_P(e) && e->mid == 0) ||
     2182            MRB_ENV_STACK_LEN(e) <= m1+r+m2+1) {
    21542183          localjump_error(mrb, LOCALJUMP_ERROR_YIELD);
    21552184          goto L_RAISE;
     
    21612190        goto L_RAISE;
    21622191      }
    2163       regs[a] = stack[m1+r+m2];
     2192      regs[a] = stack[m1+r+m2+kd];
    21642193      NEXT;
    21652194    }
    21662195
    21672196#define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff))
    2168 #define OP_MATH_BODY(op,v1,v2) do {\
    2169   v1(regs[a]) = v1(regs[a]) op v2(regs[a+1]);\
    2170 } while(0)
    2171 
    2172     CASE(OP_ADD) {
    2173       /* A B C  R(A) := R(A)+R(A+1) (Syms[B]=:+,C=1)*/
    2174       int a = GETARG_A(i);
     2197#define OP_MATH(op_name)                                                    \
     2198  /* need to check if op is overridden */                                   \
     2199  switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {                  \
     2200    OP_MATH_CASE_FIXNUM(op_name);                                           \
     2201    OP_MATH_CASE_FLOAT(op_name, fixnum, float);                             \
     2202    OP_MATH_CASE_FLOAT(op_name, float,  fixnum);                            \
     2203    OP_MATH_CASE_FLOAT(op_name, float,  float);                             \
     2204    OP_MATH_CASE_STRING_##op_name();                                        \
     2205    default:                                                                \
     2206      c = 1;                                                                \
     2207      mid = mrb_intern_lit(mrb, MRB_STRINGIZE(OP_MATH_OP_##op_name));       \
     2208      goto L_SEND_SYM;                                                      \
     2209  }                                                                         \
     2210  NEXT;
     2211#define OP_MATH_CASE_FIXNUM(op_name)                                        \
     2212  case TYPES2(MRB_TT_FIXNUM, MRB_TT_FIXNUM):                                \
     2213    {                                                                       \
     2214      mrb_int x = mrb_fixnum(regs[a]), y = mrb_fixnum(regs[a+1]), z;        \
     2215      if (mrb_int_##op_name##_overflow(x, y, &z))                           \
     2216        OP_MATH_OVERFLOW_INT(op_name, x, y, z);                             \
     2217      else                                                                  \
     2218        SET_INT_VALUE(regs[a], z);                                          \
     2219    }                                                                       \
     2220    break
     2221#ifdef MRB_WITHOUT_FLOAT
     2222#define OP_MATH_CASE_FLOAT(op_name, t1, t2) (void)0
     2223#define OP_MATH_OVERFLOW_INT(op_name, x, y, z) SET_INT_VALUE(regs[a], z)
     2224#else
     2225#define OP_MATH_CASE_FLOAT(op_name, t1, t2)                                     \
     2226  case TYPES2(OP_MATH_TT_##t1, OP_MATH_TT_##t2):                                \
     2227    {                                                                           \
     2228      mrb_float z = mrb_##t1(regs[a]) OP_MATH_OP_##op_name mrb_##t2(regs[a+1]); \
     2229      SET_FLOAT_VALUE(mrb, regs[a], z);                                         \
     2230    }                                                                           \
     2231    break
     2232#define OP_MATH_OVERFLOW_INT(op_name, x, y, z) \
     2233  SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x OP_MATH_OP_##op_name (mrb_float)y)
     2234#endif
     2235#define OP_MATH_CASE_STRING_add()                                           \
     2236  case TYPES2(MRB_TT_STRING, MRB_TT_STRING):                                \
     2237    regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]);                        \
     2238    mrb_gc_arena_restore(mrb, ai);                                          \
     2239    break
     2240#define OP_MATH_CASE_STRING_sub() (void)0
     2241#define OP_MATH_CASE_STRING_mul() (void)0
     2242#define OP_MATH_OP_add +
     2243#define OP_MATH_OP_sub -
     2244#define OP_MATH_OP_mul *
     2245#define OP_MATH_TT_fixnum MRB_TT_FIXNUM
     2246#define OP_MATH_TT_float  MRB_TT_FLOAT
     2247
     2248    CASE(OP_ADD, B) {
     2249      OP_MATH(add);
     2250    }
     2251
     2252    CASE(OP_SUB, B) {
     2253      OP_MATH(sub);
     2254    }
     2255
     2256    CASE(OP_MUL, B) {
     2257      OP_MATH(mul);
     2258    }
     2259
     2260    CASE(OP_DIV, B) {
     2261#ifndef MRB_WITHOUT_FLOAT
     2262      double x, y, f;
     2263#endif
    21752264
    21762265      /* need to check if op is overridden */
    21772266      switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
    21782267      case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
    2179         {
    2180           mrb_int x, y, z;
    2181           mrb_value *regs_a = regs + a;
    2182 
    2183           x = mrb_fixnum(regs_a[0]);
    2184           y = mrb_fixnum(regs_a[1]);
    2185           if (mrb_int_add_overflow(x, y, &z)) {
    2186             SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x + (mrb_float)y);
    2187             break;
    2188           }
    2189           SET_INT_VALUE(regs[a], z);
    2190         }
    2191         break;
    2192       case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
    2193         {
    2194           mrb_int x = mrb_fixnum(regs[a]);
    2195           mrb_float y = mrb_float(regs[a+1]);
    2196           SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + y);
    2197         }
    2198         break;
    2199       case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
    2200 #ifdef MRB_WORD_BOXING
    2201         {
    2202           mrb_float x = mrb_float(regs[a]);
    2203           mrb_int y = mrb_fixnum(regs[a+1]);
    2204           SET_FLOAT_VALUE(mrb, regs[a], x + y);
    2205         }
    2206 #else
    2207         OP_MATH_BODY(+,mrb_float,mrb_fixnum);
    2208 #endif
    2209         break;
    2210       case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
    2211 #ifdef MRB_WORD_BOXING
    2212         {
    2213           mrb_float x = mrb_float(regs[a]);
    2214           mrb_float y = mrb_float(regs[a+1]);
    2215           SET_FLOAT_VALUE(mrb, regs[a], x + y);
    2216         }
    2217 #else
    2218         OP_MATH_BODY(+,mrb_float,mrb_float);
    2219 #endif
    2220         break;
    2221       case TYPES2(MRB_TT_STRING,MRB_TT_STRING):
    2222         regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]);
    2223         break;
    2224       default:
    2225         goto L_SEND;
    2226       }
    2227       ARENA_RESTORE(mrb, ai);
    2228       NEXT;
    2229     }
    2230 
    2231     CASE(OP_SUB) {
    2232       /* A B C  R(A) := R(A)-R(A+1) (Syms[B]=:-,C=1)*/
    2233       int a = GETARG_A(i);
    2234 
    2235       /* need to check if op is overridden */
    2236       switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
    2237       case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
    2238         {
    2239           mrb_int x, y, z;
    2240 
    2241           x = mrb_fixnum(regs[a]);
    2242           y = mrb_fixnum(regs[a+1]);
    2243           if (mrb_int_sub_overflow(x, y, &z)) {
    2244             SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)y);
    2245             break;
    2246           }
    2247           SET_INT_VALUE(regs[a], z);
    2248         }
    2249         break;
    2250       case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
    2251         {
    2252           mrb_int x = mrb_fixnum(regs[a]);
    2253           mrb_float y = mrb_float(regs[a+1]);
    2254           SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - y);
    2255         }
    2256         break;
    2257       case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
    2258 #ifdef MRB_WORD_BOXING
    2259         {
    2260           mrb_float x = mrb_float(regs[a]);
    2261           mrb_int y = mrb_fixnum(regs[a+1]);
    2262           SET_FLOAT_VALUE(mrb, regs[a], x - y);
    2263         }
    2264 #else
    2265         OP_MATH_BODY(-,mrb_float,mrb_fixnum);
    2266 #endif
    2267         break;
    2268       case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
    2269 #ifdef MRB_WORD_BOXING
    2270         {
    2271           mrb_float x = mrb_float(regs[a]);
    2272           mrb_float y = mrb_float(regs[a+1]);
    2273           SET_FLOAT_VALUE(mrb, regs[a], x - y);
    2274         }
    2275 #else
    2276         OP_MATH_BODY(-,mrb_float,mrb_float);
    2277 #endif
    2278         break;
    2279       default:
    2280         goto L_SEND;
    2281       }
    2282       NEXT;
    2283     }
    2284 
    2285     CASE(OP_MUL) {
    2286       /* A B C  R(A) := R(A)*R(A+1) (Syms[B]=:*,C=1)*/
    2287       int a = GETARG_A(i);
    2288 
    2289       /* need to check if op is overridden */
    2290       switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
    2291       case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
    2292         {
    2293           mrb_int x, y, z;
    2294 
    2295           x = mrb_fixnum(regs[a]);
    2296           y = mrb_fixnum(regs[a+1]);
    2297           if (mrb_int_mul_overflow(x, y, &z)) {
    2298             SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * (mrb_float)y);
    2299             break;
    2300           }
    2301           SET_INT_VALUE(regs[a], z);
    2302         }
    2303         break;
    2304       case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
    2305         {
    2306           mrb_int x = mrb_fixnum(regs[a]);
    2307           mrb_float y = mrb_float(regs[a+1]);
    2308           SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * y);
    2309         }
    2310         break;
    2311       case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
    2312 #ifdef MRB_WORD_BOXING
    2313         {
    2314           mrb_float x = mrb_float(regs[a]);
    2315           mrb_int y = mrb_fixnum(regs[a+1]);
    2316           SET_FLOAT_VALUE(mrb, regs[a], x * y);
    2317         }
    2318 #else
    2319         OP_MATH_BODY(*,mrb_float,mrb_fixnum);
    2320 #endif
    2321         break;
    2322       case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
    2323 #ifdef MRB_WORD_BOXING
    2324         {
    2325           mrb_float x = mrb_float(regs[a]);
    2326           mrb_float y = mrb_float(regs[a+1]);
    2327           SET_FLOAT_VALUE(mrb, regs[a], x * y);
    2328         }
    2329 #else
    2330         OP_MATH_BODY(*,mrb_float,mrb_float);
    2331 #endif
    2332         break;
    2333       default:
    2334         goto L_SEND;
    2335       }
    2336       NEXT;
    2337     }
    2338 
    2339     CASE(OP_DIV) {
    2340       /* A B C  R(A) := R(A)/R(A+1) (Syms[B]=:/,C=1)*/
    2341       int a = GETARG_A(i);
    2342 
    2343       /* need to check if op is overridden */
    2344       switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
    2345       case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
     2268#ifdef MRB_WITHOUT_FLOAT
    23462269        {
    23472270          mrb_int x = mrb_fixnum(regs[a]);
    23482271          mrb_int y = mrb_fixnum(regs[a+1]);
    2349           SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x / (mrb_float)y);
    2350         }
     2272          SET_INT_VALUE(regs[a], y ? x / y : 0);
     2273        }
     2274        break;
     2275#else
     2276        x = (mrb_float)mrb_fixnum(regs[a]);
     2277        y = (mrb_float)mrb_fixnum(regs[a+1]);
    23512278        break;
    23522279      case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):
    2353         {
    2354           mrb_int x = mrb_fixnum(regs[a]);
    2355           mrb_float y = mrb_float(regs[a+1]);
    2356           SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x / y);
    2357         }
     2280        x = (mrb_float)mrb_fixnum(regs[a]);
     2281        y = mrb_float(regs[a+1]);
    23582282        break;
    23592283      case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):
    2360 #ifdef MRB_WORD_BOXING
    2361         {
    2362           mrb_float x = mrb_float(regs[a]);
    2363           mrb_int y = mrb_fixnum(regs[a+1]);
    2364           SET_FLOAT_VALUE(mrb, regs[a], x / y);
    2365         }
    2366 #else
    2367         OP_MATH_BODY(/,mrb_float,mrb_fixnum);
    2368 #endif
     2284        x = mrb_float(regs[a]);
     2285        y = (mrb_float)mrb_fixnum(regs[a+1]);
    23692286        break;
    23702287      case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):
    2371 #ifdef MRB_WORD_BOXING
    2372         {
    2373           mrb_float x = mrb_float(regs[a]);
    2374           mrb_float y = mrb_float(regs[a+1]);
    2375           SET_FLOAT_VALUE(mrb, regs[a], x / y);
    2376         }
     2288        x = mrb_float(regs[a]);
     2289        y = mrb_float(regs[a+1]);
     2290        break;
     2291#endif
     2292      default:
     2293        c = 1;
     2294        mid = mrb_intern_lit(mrb, "/");
     2295        goto L_SEND_SYM;
     2296      }
     2297
     2298#ifndef MRB_WITHOUT_FLOAT
     2299      if (y == 0) {
     2300        if (x > 0) f = INFINITY;
     2301        else if (x < 0) f = -INFINITY;
     2302        else /* if (x == 0) */ f = NAN;
     2303      }
     2304      else {
     2305        f = x / y;
     2306      }
     2307      SET_FLOAT_VALUE(mrb, regs[a], f);
     2308#endif
     2309      NEXT;
     2310    }
     2311
     2312#define OP_MATHI(op_name)                                                   \
     2313  /* need to check if op is overridden */                                   \
     2314  switch (mrb_type(regs[a])) {                                              \
     2315    OP_MATHI_CASE_FIXNUM(op_name);                                          \
     2316    OP_MATHI_CASE_FLOAT(op_name);                                           \
     2317    default:                                                                \
     2318      SET_INT_VALUE(regs[a+1], b);                                          \
     2319      c = 1;                                                                \
     2320      mid = mrb_intern_lit(mrb, MRB_STRINGIZE(OP_MATH_OP_##op_name));       \
     2321      goto L_SEND_SYM;                                                      \
     2322  }                                                                         \
     2323  NEXT;
     2324#define OP_MATHI_CASE_FIXNUM(op_name)                                       \
     2325  case MRB_TT_FIXNUM:                                                       \
     2326    {                                                                       \
     2327      mrb_int x = mrb_fixnum(regs[a]), y = (mrb_int)b, z;                   \
     2328      if (mrb_int_##op_name##_overflow(x, y, &z))                           \
     2329        OP_MATH_OVERFLOW_INT(op_name, x, y, z);                             \
     2330      else                                                                  \
     2331        SET_INT_VALUE(regs[a], z);                                          \
     2332    }                                                                       \
     2333    break
     2334#ifdef MRB_WITHOUT_FLOAT
     2335#define OP_MATHI_CASE_FLOAT(op_name) (void)0
    23772336#else
    2378         OP_MATH_BODY(/,mrb_float,mrb_float);
    2379 #endif
    2380         break;
    2381       default:
    2382         goto L_SEND;
    2383       }
    2384 #ifdef MRB_NAN_BOXING
    2385       if (isnan(mrb_float(regs[a]))) {
    2386         mrb_value v = mrb_float_value(mrb, mrb_float(regs[a]));
    2387         regs[a] = v;
    2388       }
    2389 #endif
    2390       NEXT;
    2391     }
    2392 
    2393     CASE(OP_ADDI) {
    2394       /* A B C  R(A) := R(A)+C (Syms[B]=:+)*/
    2395       int a = GETARG_A(i);
    2396 
    2397       /* need to check if + is overridden */
    2398       switch (mrb_type(regs[a])) {
    2399       case MRB_TT_FIXNUM:
    2400         {
    2401           mrb_int x = mrb_fixnum(regs[a]);
    2402           mrb_int y = GETARG_C(i);
    2403           mrb_int z;
    2404 
    2405           if (mrb_int_add_overflow(x, y, &z)) {
    2406             SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + (mrb_float)y);
    2407             break;
    2408           }
    2409           SET_INT_VALUE(regs[a], z);
    2410         }
    2411         break;
    2412       case MRB_TT_FLOAT:
    2413 #ifdef MRB_WORD_BOXING
    2414         {
    2415           mrb_float x = mrb_float(regs[a]);
    2416           SET_FLOAT_VALUE(mrb, regs[a], x + GETARG_C(i));
    2417         }
     2337#define OP_MATHI_CASE_FLOAT(op_name)                                        \
     2338  case MRB_TT_FLOAT:                                                        \
     2339    {                                                                       \
     2340      mrb_float z = mrb_float(regs[a]) OP_MATH_OP_##op_name b;              \
     2341      SET_FLOAT_VALUE(mrb, regs[a], z);                                     \
     2342    }                                                                       \
     2343    break
     2344#endif
     2345
     2346    CASE(OP_ADDI, BB) {
     2347      OP_MATHI(add);
     2348    }
     2349
     2350    CASE(OP_SUBI, BB) {
     2351      OP_MATHI(sub);
     2352    }
     2353
     2354#define OP_CMP_BODY(op,v1,v2) (v1(regs[a]) op v2(regs[a+1]))
     2355
     2356#ifdef MRB_WITHOUT_FLOAT
     2357#define OP_CMP(op) do {\
     2358  int result;\
     2359  /* need to check if - is overridden */\
     2360  switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {\
     2361  case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):\
     2362    result = OP_CMP_BODY(op,mrb_fixnum,mrb_fixnum);\
     2363    break;\
     2364  default:\
     2365    c = 1;\
     2366    mid = mrb_intern_lit(mrb, # op);\
     2367    goto L_SEND_SYM;\
     2368  }\
     2369  if (result) {\
     2370    SET_TRUE_VALUE(regs[a]);\
     2371  }\
     2372  else {\
     2373    SET_FALSE_VALUE(regs[a]);\
     2374  }\
     2375} while(0)
    24182376#else
    2419         mrb_float(regs[a]) += GETARG_C(i);
    2420 #endif
    2421         break;
    2422       default:
    2423         SET_INT_VALUE(regs[a+1], GETARG_C(i));
    2424         i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1);
    2425         goto L_SEND;
    2426       }
    2427       NEXT;
    2428     }
    2429 
    2430     CASE(OP_SUBI) {
    2431       /* A B C  R(A) := R(A)-C (Syms[B]=:-)*/
    2432       int a = GETARG_A(i);
    2433       mrb_value *regs_a = regs + a;
    2434 
    2435       /* need to check if + is overridden */
    2436       switch (mrb_type(regs_a[0])) {
    2437       case MRB_TT_FIXNUM:
    2438         {
    2439           mrb_int x = mrb_fixnum(regs_a[0]);
    2440           mrb_int y = GETARG_C(i);
    2441           mrb_int z;
    2442 
    2443           if (mrb_int_sub_overflow(x, y, &z)) {
    2444             SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x - (mrb_float)y);
    2445           }
    2446           else {
    2447             SET_INT_VALUE(regs_a[0], z);
    2448           }
    2449         }
    2450         break;
    2451       case MRB_TT_FLOAT:
    2452 #ifdef MRB_WORD_BOXING
    2453         {
    2454           mrb_float x = mrb_float(regs[a]);
    2455           SET_FLOAT_VALUE(mrb, regs[a], x - GETARG_C(i));
    2456         }
    2457 #else
    2458         mrb_float(regs_a[0]) -= GETARG_C(i);
    2459 #endif
    2460         break;
    2461       default:
    2462         SET_INT_VALUE(regs_a[1], GETARG_C(i));
    2463         i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1);
    2464         goto L_SEND;
    2465       }
    2466       NEXT;
    2467     }
    2468 
    2469 #define OP_CMP_BODY(op,v1,v2) (v1(regs[a]) op v2(regs[a+1]))
    2470 
    24712377#define OP_CMP(op) do {\
    24722378  int result;\
     
    24862392    break;\
    24872393  default:\
    2488     goto L_SEND;\
     2394    c = 1;\
     2395    mid = mrb_intern_lit(mrb, # op);\
     2396    goto L_SEND_SYM;\
    24892397  }\
    24902398  if (result) {\
     
    24952403  }\
    24962404} while(0)
    2497 
    2498     CASE(OP_EQ) {
    2499       /* A B C  R(A) := R(A)==R(A+1) (Syms[B]=:==,C=1)*/
    2500       int a = GETARG_A(i);
     2405#endif
     2406
     2407    CASE(OP_EQ, B) {
    25012408      if (mrb_obj_eq(mrb, regs[a], regs[a+1])) {
    25022409        SET_TRUE_VALUE(regs[a]);
     
    25082415    }
    25092416
    2510     CASE(OP_LT) {
    2511       /* A B C  R(A) := R(A)<R(A+1) (Syms[B]=:<,C=1)*/
    2512       int a = GETARG_A(i);
     2417    CASE(OP_LT, B) {
    25132418      OP_CMP(<);
    25142419      NEXT;
    25152420    }
    25162421
    2517     CASE(OP_LE) {
    2518       /* A B C  R(A) := R(A)<=R(A+1) (Syms[B]=:<=,C=1)*/
    2519       int a = GETARG_A(i);
     2422    CASE(OP_LE, B) {
    25202423      OP_CMP(<=);
    25212424      NEXT;
    25222425    }
    25232426
    2524     CASE(OP_GT) {
    2525       /* A B C  R(A) := R(A)>R(A+1) (Syms[B]=:>,C=1)*/
    2526       int a = GETARG_A(i);
     2427    CASE(OP_GT, B) {
    25272428      OP_CMP(>);
    25282429      NEXT;
    25292430    }
    25302431
    2531     CASE(OP_GE) {
    2532       /* A B C  R(A) := R(A)>=R(A+1) (Syms[B]=:>=,C=1)*/
    2533       int a = GETARG_A(i);
     2432    CASE(OP_GE, B) {
    25342433      OP_CMP(>=);
    25352434      NEXT;
    25362435    }
    25372436
    2538     CASE(OP_ARRAY) {
    2539       /* A B C          R(A) := ary_new(R(B),R(B+1)..R(B+C)) */
    2540       int a = GETARG_A(i);
    2541       int b = GETARG_B(i);
    2542       int c = GETARG_C(i);
     2437    CASE(OP_ARRAY, BB) {
     2438      mrb_value v = mrb_ary_new_from_values(mrb, b, &regs[a]);
     2439      regs[a] = v;
     2440      mrb_gc_arena_restore(mrb, ai);
     2441      NEXT;
     2442    }
     2443    CASE(OP_ARRAY2, BBB) {
    25432444      mrb_value v = mrb_ary_new_from_values(mrb, c, &regs[b]);
    25442445      regs[a] = v;
    2545       ARENA_RESTORE(mrb, ai);
    2546       NEXT;
    2547     }
    2548 
    2549     CASE(OP_ARYCAT) {
    2550       /* A B            mrb_ary_concat(R(A),R(B)) */
    2551       int a = GETARG_A(i);
    2552       int b = GETARG_B(i);
    2553       mrb_value splat = mrb_ary_splat(mrb, regs[b]);
    2554       mrb_ary_concat(mrb, regs[a], splat);
    2555       ARENA_RESTORE(mrb, ai);
    2556       NEXT;
    2557     }
    2558 
    2559     CASE(OP_ARYPUSH) {
    2560       /* A B            R(A).push(R(B)) */
    2561       int a = GETARG_A(i);
    2562       int b = GETARG_B(i);
    2563       mrb_ary_push(mrb, regs[a], regs[b]);
    2564       NEXT;
    2565     }
    2566 
    2567     CASE(OP_AREF) {
    2568       /* A B C          R(A) := R(B)[C] */
    2569       int a = GETARG_A(i);
    2570       int b = GETARG_B(i);
    2571       int c = GETARG_C(i);
     2446      mrb_gc_arena_restore(mrb, ai);
     2447      NEXT;
     2448    }
     2449
     2450    CASE(OP_ARYCAT, B) {
     2451      mrb_value splat = mrb_ary_splat(mrb, regs[a+1]);
     2452      if (mrb_nil_p(regs[a])) {
     2453        regs[a] = splat;
     2454      }
     2455      else {
     2456        mrb_ary_concat(mrb, regs[a], splat);
     2457      }
     2458      mrb_gc_arena_restore(mrb, ai);
     2459      NEXT;
     2460    }
     2461
     2462    CASE(OP_ARYPUSH, B) {
     2463      mrb_ary_push(mrb, regs[a], regs[a+1]);
     2464      NEXT;
     2465    }
     2466
     2467    CASE(OP_ARYDUP, B) {
     2468      mrb_value ary = regs[a];
     2469      if (mrb_array_p(ary)) {
     2470        ary = mrb_ary_new_from_values(mrb, RARRAY_LEN(ary), RARRAY_PTR(ary));
     2471      }
     2472      else {
     2473        ary = mrb_ary_new_from_values(mrb, 1, &ary);
     2474      }
     2475      regs[a] = ary;
     2476      NEXT;
     2477    }
     2478
     2479    CASE(OP_AREF, BBB) {
    25722480      mrb_value v = regs[b];
    25732481
     
    25872495    }
    25882496
    2589     CASE(OP_ASET) {
    2590       /* A B C          R(B)[C] := R(A) */
    2591       int a = GETARG_A(i);
    2592       int b = GETARG_B(i);
    2593       int c = GETARG_C(i);
     2497    CASE(OP_ASET, BBB) {
    25942498      mrb_ary_set(mrb, regs[b], c, regs[a]);
    25952499      NEXT;
    25962500    }
    25972501
    2598     CASE(OP_APOST) {
    2599       /* A B C  *R(A),R(A+1)..R(A+C) := R(A) */
    2600       int a = GETARG_A(i);
     2502    CASE(OP_APOST, BBB) {
    26012503      mrb_value v = regs[a];
    2602       int pre  = GETARG_B(i);
    2603       int post = GETARG_C(i);
     2504      int pre  = b;
     2505      int post = c;
    26042506      struct RArray *ary;
    26052507      int len, idx;
     
    26092511      }
    26102512      ary = mrb_ary_ptr(v);
    2611       len = ary->len;
     2513      len = (int)ARY_LEN(ary);
    26122514      if (len > pre + post) {
    2613         v = mrb_ary_new_from_values(mrb, len - pre - post, ary->ptr+pre);
     2515        v = mrb_ary_new_from_values(mrb, len - pre - post, ARY_PTR(ary)+pre);
    26142516        regs[a++] = v;
    26152517        while (post--) {
    2616           regs[a++] = ary->ptr[len-post-1];
     2518          regs[a++] = ARY_PTR(ary)[len-post-1];
    26172519        }
    26182520      }
     
    26212523        regs[a++] = v;
    26222524        for (idx=0; idx+pre<len; idx++) {
    2623           regs[a+idx] = ary->ptr[pre+idx];
     2525          regs[a+idx] = ARY_PTR(ary)[pre+idx];
    26242526        }
    26252527        while (idx < post) {
     
    26282530        }
    26292531      }
    2630       ARENA_RESTORE(mrb, ai);
    2631       NEXT;
    2632     }
    2633 
    2634     CASE(OP_STRING) {
    2635       /* A Bx           R(A) := str_new(Lit(Bx)) */
    2636       mrb_value str = mrb_str_dup(mrb, pool[GETARG_Bx(i)]);
    2637       regs[GETARG_A(i)] = str;
    2638       ARENA_RESTORE(mrb, ai);
    2639       NEXT;
    2640     }
    2641 
    2642     CASE(OP_STRCAT) {
    2643       /* A B    R(A).concat(R(B)) */
    2644       mrb_str_concat(mrb, regs[GETARG_A(i)], regs[GETARG_B(i)]);
    2645       NEXT;
    2646     }
    2647 
    2648     CASE(OP_HASH) {
    2649       /* A B C   R(A) := hash_new(R(B),R(B+1)..R(B+C)) */
    2650       int b = GETARG_B(i);
    2651       int c = GETARG_C(i);
    2652       int lim = b+c*2;
    2653       mrb_value hash = mrb_hash_new_capa(mrb, c);
    2654 
    2655       while (b < lim) {
    2656         mrb_hash_set(mrb, hash, regs[b], regs[b+1]);
    2657         b+=2;
    2658       }
    2659       regs[GETARG_A(i)] = hash;
    2660       ARENA_RESTORE(mrb, ai);
    2661       NEXT;
    2662     }
    2663 
    2664     CASE(OP_LAMBDA) {
    2665       /* A b c  R(A) := lambda(SEQ[b],c) (b:c = 14:2) */
     2532      mrb_gc_arena_restore(mrb, ai);
     2533      NEXT;
     2534    }
     2535
     2536    CASE(OP_INTERN, B) {
     2537      mrb_sym sym = mrb_intern_str(mrb, regs[a]);
     2538
     2539      regs[a] = mrb_symbol_value(sym);
     2540      mrb_gc_arena_restore(mrb, ai);
     2541      NEXT;
     2542    }
     2543
     2544    CASE(OP_STRING, BB) {
     2545      mrb_value str = mrb_str_dup(mrb, pool[b]);
     2546
     2547      regs[a] = str;
     2548      mrb_gc_arena_restore(mrb, ai);
     2549      NEXT;
     2550    }
     2551
     2552    CASE(OP_STRCAT, B) {
     2553      mrb_str_concat(mrb, regs[a], regs[a+1]);
     2554      NEXT;
     2555    }
     2556
     2557    CASE(OP_HASH, BB) {
     2558      mrb_value hash = mrb_hash_new_capa(mrb, b);
     2559      int i;
     2560      int lim = a+b*2;
     2561
     2562      for (i=a; i<lim; i+=2) {
     2563        mrb_hash_set(mrb, hash, regs[i], regs[i+1]);
     2564      }
     2565      regs[a] = hash;
     2566      mrb_gc_arena_restore(mrb, ai);
     2567      NEXT;
     2568    }
     2569
     2570    CASE(OP_HASHADD, BB) {
     2571      mrb_value hash;
     2572      int i;
     2573      int lim = a+b*2+1;
     2574
     2575      hash = mrb_ensure_hash_type(mrb, regs[a]);
     2576      for (i=a+1; i<lim; i+=2) {
     2577        mrb_hash_set(mrb, hash, regs[i], regs[i+1]);
     2578      }
     2579      mrb_gc_arena_restore(mrb, ai);
     2580      NEXT;
     2581    }
     2582    CASE(OP_HASHCAT, B) {
     2583      mrb_value hash = mrb_ensure_hash_type(mrb, regs[a]);
     2584
     2585      mrb_hash_merge(mrb, hash, regs[a+1]);
     2586      mrb_gc_arena_restore(mrb, ai);
     2587      NEXT;
     2588    }
     2589
     2590    CASE(OP_LAMBDA, BB)
     2591    c = OP_L_LAMBDA;
     2592    L_MAKE_LAMBDA:
     2593    {
    26662594      struct RProc *p;
    2667       int c = GETARG_c(i);
     2595      mrb_irep *nirep = irep->reps[b];
    26682596
    26692597      if (c & OP_L_CAPTURE) {
    2670         p = mrb_closure_new(mrb, irep->reps[GETARG_b(i)]);
     2598        p = mrb_closure_new(mrb, nirep);
    26712599      }
    26722600      else {
    2673         p = mrb_proc_new(mrb, irep->reps[GETARG_b(i)]);
     2601        p = mrb_proc_new(mrb, nirep);
     2602        p->flags |= MRB_PROC_SCOPE;
    26742603      }
    26752604      if (c & OP_L_STRICT) p->flags |= MRB_PROC_STRICT;
    2676       regs[GETARG_A(i)] = mrb_obj_value(p);
    2677       ARENA_RESTORE(mrb, ai);
    2678       NEXT;
    2679     }
    2680 
    2681     CASE(OP_OCLASS) {
    2682       /* A      R(A) := ::Object */
    2683       regs[GETARG_A(i)] = mrb_obj_value(mrb->object_class);
    2684       NEXT;
    2685     }
    2686 
    2687     CASE(OP_CLASS) {
    2688       /* A B    R(A) := newclass(R(A),Syms(B),R(A+1)) */
     2605      regs[a] = mrb_obj_value(p);
     2606      mrb_gc_arena_restore(mrb, ai);
     2607      NEXT;
     2608    }
     2609    CASE(OP_BLOCK, BB) {
     2610      c = OP_L_BLOCK;
     2611      goto L_MAKE_LAMBDA;
     2612    }
     2613    CASE(OP_METHOD, BB) {
     2614      c = OP_L_METHOD;
     2615      goto L_MAKE_LAMBDA;
     2616    }
     2617
     2618    CASE(OP_RANGE_INC, B) {
     2619      mrb_value val = mrb_range_new(mrb, regs[a], regs[a+1], FALSE);
     2620      regs[a] = val;
     2621      mrb_gc_arena_restore(mrb, ai);
     2622      NEXT;
     2623    }
     2624
     2625    CASE(OP_RANGE_EXC, B) {
     2626      mrb_value val = mrb_range_new(mrb, regs[a], regs[a+1], TRUE);
     2627      regs[a] = val;
     2628      mrb_gc_arena_restore(mrb, ai);
     2629      NEXT;
     2630    }
     2631
     2632    CASE(OP_OCLASS, B) {
     2633      regs[a] = mrb_obj_value(mrb->object_class);
     2634      NEXT;
     2635    }
     2636
     2637    CASE(OP_CLASS, BB) {
    26892638      struct RClass *c = 0, *baseclass;
    2690       int a = GETARG_A(i);
    26912639      mrb_value base, super;
    2692       mrb_sym id = syms[GETARG_B(i)];
     2640      mrb_sym id = syms[b];
    26932641
    26942642      base = regs[a];
    26952643      super = regs[a+1];
    26962644      if (mrb_nil_p(base)) {
    2697         baseclass = mrb->c->ci->proc->target_class;
    2698         if (!baseclass) baseclass = mrb->c->ci->target_class;
    2699 
     2645        baseclass = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc);
    27002646        base = mrb_obj_value(baseclass);
    27012647      }
    27022648      c = mrb_vm_define_class(mrb, base, super, id);
    27032649      regs[a] = mrb_obj_value(c);
    2704       ARENA_RESTORE(mrb, ai);
    2705       NEXT;
    2706     }
    2707 
    2708     CASE(OP_MODULE) {
    2709       /* A B            R(A) := newmodule(R(A),Syms(B)) */
    2710       struct RClass *c = 0, *baseclass;
    2711       int a = GETARG_A(i);
     2650      mrb_gc_arena_restore(mrb, ai);
     2651      NEXT;
     2652    }
     2653
     2654    CASE(OP_MODULE, BB) {
     2655      struct RClass *cls = 0, *baseclass;
    27122656      mrb_value base;
    2713       mrb_sym id = syms[GETARG_B(i)];
     2657      mrb_sym id = syms[b];
    27142658
    27152659      base = regs[a];
    27162660      if (mrb_nil_p(base)) {
    2717         baseclass = mrb->c->ci->proc->target_class;
    2718         if (!baseclass) baseclass = mrb->c->ci->target_class;
    2719 
     2661        baseclass = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc);
    27202662        base = mrb_obj_value(baseclass);
    27212663      }
    2722       c = mrb_vm_define_module(mrb, base, id);
    2723       regs[a] = mrb_obj_value(c);
    2724       ARENA_RESTORE(mrb, ai);
    2725       NEXT;
    2726     }
    2727 
    2728     CASE(OP_EXEC) {
    2729       /* A Bx   R(A) := blockexec(R(A),SEQ[Bx]) */
    2730       int a = GETARG_A(i);
     2664      cls = mrb_vm_define_module(mrb, base, id);
     2665      regs[a] = mrb_obj_value(cls);
     2666      mrb_gc_arena_restore(mrb, ai);
     2667      NEXT;
     2668    }
     2669
     2670    CASE(OP_EXEC, BB) {
    27312671      mrb_callinfo *ci;
    27322672      mrb_value recv = regs[a];
    27332673      struct RProc *p;
     2674      mrb_irep *nirep = irep->reps[b];
    27342675
    27352676      /* prepare closure */
    2736       p = mrb_closure_new(mrb, irep->reps[GETARG_Bx(i)]);
     2677      p = mrb_proc_new(mrb, nirep);
    27372678      p->c = NULL;
    2738 
    2739       /* prepare stack */
     2679      mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)proc);
     2680      MRB_PROC_SET_TARGET_CLASS(p, mrb_class_ptr(recv));
     2681      p->flags |= MRB_PROC_SCOPE;
     2682
     2683      /* prepare call stack */
    27402684      ci = cipush(mrb);
    2741       ci->pc = pc + 1;
     2685      ci->pc = pc;
    27422686      ci->acc = a;
    27432687      ci->mid = 0;
     
    27492693      mrb->c->stack += a;
    27502694
    2751       /* setup closure */
    2752       p->target_class = ci->target_class;
     2695      /* setup block to call */
    27532696      ci->proc = p;
    27542697
     
    27562699      pool = irep->pool;
    27572700      syms = irep->syms;
    2758       stack_extend(mrb, irep->nregs);
     2701      mrb_stack_extend(mrb, irep->nregs);
    27592702      stack_clear(regs+1, irep->nregs-1);
    2760       ci->nregs = irep->nregs;
    27612703      pc = irep->iseq;
    27622704      JUMP;
    27632705    }
    27642706
    2765     CASE(OP_METHOD) {
    2766       /* A B            R(A).newmethod(Syms(B),R(A+1)) */
    2767       int a = GETARG_A(i);
    2768       struct RClass *c = mrb_class_ptr(regs[a]);
     2707    CASE(OP_DEF, BB) {
     2708      struct RClass *target = mrb_class_ptr(regs[a]);
    27692709      struct RProc *p = mrb_proc_ptr(regs[a+1]);
    2770 
    2771       mrb_define_method_raw(mrb, c, syms[GETARG_B(i)], p);
    2772       ARENA_RESTORE(mrb, ai);
    2773       NEXT;
    2774     }
    2775 
    2776     CASE(OP_SCLASS) {
    2777       /* A B    R(A) := R(B).singleton_class */
    2778       regs[GETARG_A(i)] = mrb_singleton_class(mrb, regs[GETARG_B(i)]);
    2779       ARENA_RESTORE(mrb, ai);
    2780       NEXT;
    2781     }
    2782 
    2783     CASE(OP_TCLASS) {
    2784       /* A      R(A) := target_class */
    2785       if (!mrb->c->ci->target_class) {
    2786         mrb_value exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, "no target class or module");
    2787         mrb_exc_set(mrb, exc);
    2788         goto L_RAISE;
    2789       }
    2790       regs[GETARG_A(i)] = mrb_obj_value(mrb->c->ci->target_class);
    2791       NEXT;
    2792     }
    2793 
    2794     CASE(OP_RANGE) {
    2795       /* A B C  R(A) := range_new(R(B),R(B+1),C) */
    2796       int b = GETARG_B(i);
    2797       mrb_value val = mrb_range_new(mrb, regs[b], regs[b+1], GETARG_C(i));
    2798       regs[GETARG_A(i)] = val;
    2799       ARENA_RESTORE(mrb, ai);
    2800       NEXT;
    2801     }
    2802 
    2803     CASE(OP_DEBUG) {
    2804       /* A B C    debug print R(A),R(B),R(C) */
     2710      mrb_method_t m;
     2711
     2712      MRB_METHOD_FROM_PROC(m, p);
     2713      mrb_define_method_raw(mrb, target, syms[b], m);
     2714      mrb_gc_arena_restore(mrb, ai);
     2715      NEXT;
     2716    }
     2717
     2718    CASE(OP_SCLASS, B) {
     2719      regs[a] = mrb_singleton_class(mrb, regs[a]);
     2720      mrb_gc_arena_restore(mrb, ai);
     2721      NEXT;
     2722    }
     2723
     2724    CASE(OP_TCLASS, B) {
     2725      if (!check_target_class(mrb)) goto L_RAISE;
     2726      regs[a] = mrb_obj_value(mrb->c->ci->target_class);
     2727      NEXT;
     2728    }
     2729
     2730    CASE(OP_ALIAS, BB) {
     2731      struct RClass *target;
     2732
     2733      if (!check_target_class(mrb)) goto L_RAISE;
     2734      target = mrb->c->ci->target_class;
     2735      mrb_alias_method(mrb, target, syms[a], syms[b]);
     2736      NEXT;
     2737    }
     2738    CASE(OP_UNDEF, B) {
     2739      struct RClass *target;
     2740
     2741      if (!check_target_class(mrb)) goto L_RAISE;
     2742      target = mrb->c->ci->target_class;
     2743      mrb_undef_method_id(mrb, target, syms[a]);
     2744      NEXT;
     2745    }
     2746
     2747    CASE(OP_DEBUG, Z) {
     2748      FETCH_BBB();
    28052749#ifdef MRB_ENABLE_DEBUG_HOOK
    28062750      mrb->debug_op_hook(mrb, irep, pc, regs);
    28072751#else
    28082752#ifndef MRB_DISABLE_STDIO
    2809       printf("OP_DEBUG %d %d %d\n", GETARG_A(i), GETARG_B(i), GETARG_C(i));
     2753      printf("OP_DEBUG %d %d %d\n", a, b, c);
    28102754#else
    28112755      abort();
     
    28152759    }
    28162760
    2817     CASE(OP_STOP) {
     2761    CASE(OP_ERR, B) {
     2762      mrb_value msg = mrb_str_dup(mrb, pool[a]);
     2763      mrb_value exc;
     2764
     2765      exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg);
     2766      ERR_PC_SET(mrb);
     2767      mrb_exc_set(mrb, exc);
     2768      goto L_RAISE;
     2769    }
     2770
     2771    CASE(OP_EXT1, Z) {
     2772      insn = READ_B();
     2773      switch (insn) {
     2774#define OPCODE(insn,ops) case OP_ ## insn: FETCH_ ## ops ## _1(); goto L_OP_ ## insn ## _BODY;
     2775#include "mruby/ops.h"
     2776#undef OPCODE
     2777      }
     2778      pc--;
     2779      NEXT;
     2780    }
     2781    CASE(OP_EXT2, Z) {
     2782      insn = READ_B();
     2783      switch (insn) {
     2784#define OPCODE(insn,ops) case OP_ ## insn: FETCH_ ## ops ## _2(); goto L_OP_ ## insn ## _BODY;
     2785#include "mruby/ops.h"
     2786#undef OPCODE
     2787      }
     2788      pc--;
     2789      NEXT;
     2790    }
     2791    CASE(OP_EXT3, Z) {
     2792      uint8_t insn = READ_B();
     2793      switch (insn) {
     2794#define OPCODE(insn,ops) case OP_ ## insn: FETCH_ ## ops ## _3(); goto L_OP_ ## insn ## _BODY;
     2795#include "mruby/ops.h"
     2796#undef OPCODE
     2797      }
     2798      pc--;
     2799      NEXT;
     2800    }
     2801
     2802    CASE(OP_STOP, Z) {
    28182803      /*        stop VM */
    28192804    L_STOP:
    2820       {
    2821         int epos = mrb->c->ci->epos;
    2822 
    2823         while (mrb->c->eidx > epos) {
    2824           ecall(mrb, --mrb->c->eidx);
    2825         }
    2826       }
     2805      while (mrb->c->eidx > 0) {
     2806        ecall(mrb);
     2807      }
     2808      mrb->c->cibase->ridx = 0;
    28272809      ERR_PC_CLR(mrb);
    28282810      mrb->jmp = prev_jmp;
     
    28322814      return regs[irep->nlocals];
    28332815    }
    2834 
    2835     CASE(OP_ERR) {
    2836       /* Bx     raise RuntimeError with message Lit(Bx) */
    2837       mrb_value msg = mrb_str_dup(mrb, pool[GETARG_Bx(i)]);
    2838       mrb_value exc;
    2839 
    2840       if (GETARG_A(i) == 0) {
    2841         exc = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, msg);
    2842       }
    2843       else {
    2844         exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg);
    2845       }
    2846       mrb_exc_set(mrb, exc);
    2847       goto L_RAISE;
    2848     }
    28492816  }
    28502817  END_DISPATCH;
    28512818#undef regs
    2852 
    28532819  }
    28542820  MRB_CATCH(&c_jmp) {
     
    28842850  }
    28852851  ci = cipush(mrb);
     2852  ci->stackent = mrb->c->stack;
    28862853  ci->mid = 0;
    2887   ci->nregs = 1;   /* protect the receiver */
    28882854  ci->acc = CI_ACC_SKIP;
    28892855  ci->target_class = mrb->object_class;
    28902856  v = mrb_vm_run(mrb, proc, self, stack_keep);
    2891   cipop(mrb);
    28922857
    28932858  return v;
Note: See TracChangeset for help on using the changeset viewer.