Ignore:
Timestamp:
Jan 21, 2018, 12:10:09 AM (6 years ago)
Author:
coas-nagasima
Message:

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

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

Legend:

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

    r321 r331  
    88#include <stdarg.h>
    99#include <math.h>
    10 #include "mruby.h"
    11 #include "mruby/array.h"
    12 #include "mruby/class.h"
    13 #include "mruby/hash.h"
    14 #include "mruby/irep.h"
    15 #include "mruby/numeric.h"
    16 #include "mruby/proc.h"
    17 #include "mruby/range.h"
    18 #include "mruby/string.h"
    19 #include "mruby/variable.h"
    20 #include "mruby/error.h"
    21 #include "mruby/opcode.h"
     10#include <mruby.h>
     11#include <mruby/array.h>
     12#include <mruby/class.h>
     13#include <mruby/hash.h>
     14#include <mruby/irep.h>
     15#include <mruby/numeric.h>
     16#include <mruby/proc.h>
     17#include <mruby/range.h>
     18#include <mruby/string.h>
     19#include <mruby/variable.h>
     20#include <mruby/error.h>
     21#include <mruby/opcode.h>
    2222#include "value_array.h"
    23 #include "mruby/throw.h"
    24 
    25 #ifdef MRB_DISABLE_STDIO
     23#include <mruby/throw.h>
     24
     25#ifndef MRB_DISABLE_STDIO
    2626#if defined(__cplusplus)
    2727extern "C" {
     
    3636#define CALLINFO_INIT_SIZE 32
    3737
     38#ifndef ENSURE_STACK_INIT_SIZE
     39#define ENSURE_STACK_INIT_SIZE 16
     40#endif
     41
     42#ifndef RESCUE_STACK_INIT_SIZE
     43#define RESCUE_STACK_INIT_SIZE 16
     44#endif
     45
    3846/* Define amount of linear stack growth. */
    3947#ifndef MRB_STACK_GROWTH
    4048#define MRB_STACK_GROWTH 128
     49#endif
     50
     51/* Maximum mrb_funcall() depth. Should be set lower on memory constrained systems. */
     52#ifndef MRB_FUNCALL_DEPTH_MAX
     53#define MRB_FUNCALL_DEPTH_MAX 512
    4154#endif
    4255
     
    5467
    5568#define ARENA_RESTORE(mrb,ai) (mrb)->gc.arena_idx = (ai)
     69
     70#define CALL_MAXARGS 127
     71
     72void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args);
    5673
    5774static inline void
     
    99116
    100117static inline void
    101 envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase)
     118envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t size)
    102119{
    103120  mrb_callinfo *ci = mrb->c->cibase;
     
    106123  while (ci <= mrb->c->ci) {
    107124    struct REnv *e = ci->env;
    108     if (e && MRB_ENV_STACK_SHARED_P(e)) {
     125    mrb_value *st;
     126
     127    if (e && MRB_ENV_STACK_SHARED_P(e) &&
     128        (st = e->stack) && oldbase <= st && st < oldbase+size) {
    109129      ptrdiff_t off = e->stack - oldbase;
    110130
     
    116136}
    117137
    118 static inline void
    119 init_new_stack_space(mrb_state *mrb, int room, int keep)
    120 {
    121   if (room > keep) {
    122     /* do not leave uninitialized malloc region */
    123     stack_clear(&(mrb->c->stack[keep]), room - keep);
    124   }
    125 }
    126 
    127138/** def rec ; $deep =+ 1 ; if $deep > 1000 ; return 0 ; end ; rec ; end  */
    128139
    129140static void
    130 stack_extend_alloc(mrb_state *mrb, int room, int keep)
     141stack_extend_alloc(mrb_state *mrb, int room)
    131142{
    132143  mrb_value *oldbase = mrb->c->stbase;
    133   int size = mrb->c->stend - mrb->c->stbase;
    134   int off = mrb->c->stack - mrb->c->stbase;
    135 
     144  mrb_value *newstack;
     145  size_t oldsize = mrb->c->stend - mrb->c->stbase;
     146  size_t size = oldsize;
     147  size_t off = mrb->c->stack - mrb->c->stbase;
     148
     149  if (off > size) size = off;
    136150#ifdef MRB_STACK_EXTEND_DOUBLING
    137151  if (room <= size)
     
    149163#endif
    150164
    151   mrb->c->stbase = (mrb_value *)mrb_realloc(mrb, mrb->c->stbase, sizeof(mrb_value) * size);
     165  newstack = (mrb_value *)mrb_realloc(mrb, mrb->c->stbase, sizeof(mrb_value) * size);
     166  if (newstack == NULL) {
     167    mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
     168  }
     169  stack_clear(&(newstack[oldsize]), size - oldsize);
     170  envadjust(mrb, oldbase, newstack, size);
     171  mrb->c->stbase = newstack;
    152172  mrb->c->stack = mrb->c->stbase + off;
    153173  mrb->c->stend = mrb->c->stbase + size;
    154   envadjust(mrb, oldbase, mrb->c->stbase);
    155174
    156175  /* Raise an exception if the new stack size will be too large,
    157176     to prevent infinite recursion. However, do this only after resizing the stack, so mrb_raise has stack space to work with. */
    158177  if (size > MRB_STACK_MAX) {
    159     init_new_stack_space(mrb, room, keep);
    160     mrb_raise(mrb, E_SYSSTACK_ERROR, "stack level too deep. (limit=" MRB_STRINGIZE(MRB_STACK_MAX) ")");
     178    mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
    161179  }
    162180}
    163181
    164182static inline void
    165 stack_extend(mrb_state *mrb, int room, int keep)
     183stack_extend(mrb_state *mrb, int room)
    166184{
    167185  if (mrb->c->stack + room >= mrb->c->stend) {
    168     stack_extend_alloc(mrb, room, keep);
    169   }
    170   init_new_stack_space(mrb, room, keep);
     186    stack_extend_alloc(mrb, room);
     187  }
    171188}
    172189
     
    188205  int cioff = e->cioff;
    189206
    190   if (MRB_ENV_STACK_SHARED_P(e) && mrb->c->cibase[cioff].proc &&
    191       MRB_PROC_STRICT_P(mrb->c->cibase[cioff].proc)) {
     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)) {
    192209    return TRUE;
    193210  }
     
    210227#define CI_ACC_SKIP    -1
    211228#define CI_ACC_DIRECT  -2
     229#define CI_ACC_RESUMED -3
    212230
    213231static mrb_callinfo*
     
    217235  mrb_callinfo *ci = c->ci;
    218236
    219   int eidx = ci->eidx;
    220237  int ridx = ci->ridx;
    221238
     
    228245  }
    229246  ci = ++c->ci;
    230   ci->eidx = eidx;
     247  ci->epos = mrb->c->eidx;
    231248  ci->ridx = ridx;
    232249  ci->env = 0;
     
    234251  ci->err = 0;
    235252  ci->proc = 0;
     253  ci->acc = 0;
    236254
    237255  return ci;
     256}
     257
     258MRB_API void
     259mrb_env_unshare(mrb_state *mrb, struct REnv *e)
     260{
     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);
    238280}
    239281
     
    242284{
    243285  struct mrb_context *c = mrb->c;
    244 
    245   if (c->ci->env) {
    246     struct REnv *e = c->ci->env;
    247     size_t len = (size_t)MRB_ENV_STACK_LEN(e);
    248     mrb_value *p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len);
    249 
    250     MRB_ENV_UNSHARE_STACK(e);
    251     if (len > 0) {
    252       stack_copy(p, e->stack, len);
    253     }
    254     e->stack = p;
    255     mrb_write_barrier(mrb, (struct RBasic *)e);
    256   }
     286  struct REnv *env = c->ci->env;
    257287
    258288  c->ci--;
    259 }
     289
     290  if (env) {
     291    mrb_env_unshare(mrb, env);
     292  }
     293}
     294
     295void mrb_exc_set(mrb_state *mrb, mrb_value exc);
    260296
    261297static void
     
    263299{
    264300  struct RProc *p;
    265   mrb_callinfo *ci;
     301  mrb_callinfo *ci = mrb->c->ci;
    266302  mrb_value *self = mrb->c->stack;
    267303  struct RObject *exc;
     304  ptrdiff_t cioff;
     305  int ai = mrb_gc_arena_save(mrb);
    268306
    269307  if (i<0) return;
     308  if (ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
     309    mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
     310  }
    270311  p = mrb->c->ensure[i];
    271312  if (!p) return;
    272   if (mrb->c->ci->eidx > i)
    273     mrb->c->ci->eidx = i;
     313  mrb->c->ensure[i] = NULL;
     314  cioff = ci - mrb->c->cibase;
    274315  ci = cipush(mrb);
    275316  ci->stackent = mrb->c->stack;
     
    282323  mrb->c->stack = mrb->c->stack + ci[-1].nregs;
    283324  exc = mrb->exc; mrb->exc = 0;
     325  if (exc) {
     326    mrb_gc_protect(mrb, mrb_obj_value(exc));
     327  }
    284328  mrb_run(mrb, p, *self);
    285   mrb->c->ensure[i] = NULL;
     329  mrb->c->ci = mrb->c->cibase + cioff;
    286330  if (!mrb->exc) mrb->exc = exc;
     331  mrb_gc_arena_restore(mrb, ai);
    287332}
    288333
     
    335380    }
    336381    MRB_END_EXC(&c_jmp);
     382    mrb->jmp = 0;
    337383  }
    338384  else {
    339385    struct RProc *p;
    340386    struct RClass *c;
    341     mrb_sym undef = 0;
    342387    mrb_callinfo *ci;
    343388    int n;
     
    354399    p = mrb_method_search_vm(mrb, &c, mid);
    355400    if (!p) {
    356       undef = mid;
    357       mid = mrb_intern_lit(mrb, "method_missing");
    358       p = mrb_method_search_vm(mrb, &c, mid);
    359       n++; argc++;
     401      mrb_sym missing = mrb_intern_lit(mrb, "method_missing");
     402      mrb_value args = mrb_ary_new_from_values(mrb, argc, argv);
     403      p = mrb_method_search_vm(mrb, &c, missing);
     404      if (!p) {
     405        mrb_method_missing(mrb, mid, self, args);
     406      }
     407      mrb_ary_unshift(mrb, args, mrb_symbol_value(mid));
     408      stack_extend(mrb, n+2);
     409      mrb->c->stack[n+1] = args;
     410      argc = -1;
     411    }
     412    if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
     413      mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
    360414    }
    361415    ci = cipush(mrb);
     
    371425    if (MRB_PROC_CFUNC_P(p)) {
    372426      ci->nregs = argc + 2;
    373       stack_extend(mrb, ci->nregs, 0);
     427      stack_extend(mrb, ci->nregs);
     428    }
     429    else if (argc >= CALL_MAXARGS) {
     430      mrb_value args = mrb_ary_new_from_values(mrb, argc, argv);
     431      stack_extend(mrb, ci->nregs);
     432      mrb->c->stack[1] = args;
     433      ci->argc = -1;
     434      argc = 1;
    374435    }
    375436    else {
    376       ci->nregs = p->body.irep->nregs + n;
    377       stack_extend(mrb, ci->nregs, argc+2);
     437      if (argc < 0) argc = 1;
     438      ci->nregs = p->body.irep->nregs + argc;
     439      stack_extend(mrb, ci->nregs);
    378440    }
    379441    if (voff >= 0) {
     
    381443    }
    382444    mrb->c->stack[0] = self;
    383     if (undef) {
    384       mrb->c->stack[1] = mrb_symbol_value(undef);
    385       if (argc > 1) {
    386         stack_copy(mrb->c->stack+2, argv, argc-1);
    387       }
    388     }
    389     else if (argc > 0) {
     445    if (ci->argc > 0) {
    390446      stack_copy(mrb->c->stack+1, argv, argc);
    391447    }
     
    414470{
    415471  return mrb_funcall_with_block(mrb, self, mid, argc, argv, mrb_nil_value());
     472}
     473
     474mrb_value
     475mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p)
     476{
     477  mrb_callinfo *ci = mrb->c->ci;
     478
     479  mrb->c->stack[0] = self;
     480  ci->proc = p;
     481  ci->target_class = p->target_class;
     482  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);
     487  }
     488  else {
     489    stack_extend(mrb, p->body.irep->nregs);
     490  }
     491
     492  ci->nregs = p->body.irep->nregs;
     493  ci = cipush(mrb);
     494  ci->nregs = 0;
     495  ci->target_class = 0;
     496  ci->pc = p->body.irep->iseq;
     497  ci->stackent = mrb->c->stack;
     498  ci->acc = 0;
     499
     500  return self;
    416501}
    417502
     
    446531
    447532  mrb_get_args(mrb, "n*&", &name, &argv, &argc, &block);
     533  ci = mrb->c->ci;
     534  if (ci->acc < 0) {
     535  funcall:
     536    return mrb_funcall_with_block(mrb, self, name, argc, argv, block);
     537  }
    448538
    449539  c = mrb_class(mrb, self);
     
    451541
    452542  if (!p) {                     /* call method_mising */
    453     return mrb_funcall_with_block(mrb, self, name, argc, argv, block);
    454   }
    455 
    456   ci = mrb->c->ci;
     543    goto funcall;
     544  }
     545
    457546  ci->mid = name;
    458547  ci->target_class = c;
    459   ci->proc = p;
    460548  regs = mrb->c->stack+1;
    461549  /* remove first symbol from arguments */
     
    470558  }
    471559
    472   if (MRB_PROC_CFUNC_P(p)) {
    473     return p->body.func(mrb, self);
    474   }
    475 
    476   if (ci->argc < 0) {
    477     stack_extend(mrb, (p->body.irep->nregs < 3) ? 3 : p->body.irep->nregs, 3);
    478   }
    479   else {
    480     stack_extend(mrb, p->body.irep->nregs, ci->argc+2);
    481   }
    482 
    483   ci->nregs = p->body.irep->nregs;
    484   ci = cipush(mrb);
    485   ci->nregs = 0;
    486   ci->target_class = 0;
    487   ci->pc = p->body.irep->iseq;
    488   ci->stackent = mrb->c->stack;
    489   ci->acc = 0;
    490 
    491   return self;
     560  return mrb_exec_irep(mrb, self, p);
    492561}
    493562
     
    497566  struct RProc *p;
    498567  mrb_callinfo *ci;
     568  mrb_int max = 3;
    499569
    500570  if (mrb_nil_p(blk)) {
     
    503573  ci = mrb->c->ci;
    504574  if (ci->acc == CI_ACC_DIRECT) {
    505     return mrb_yield_with_class(mrb, blk, 0, 0, self, c);
     575    ci->target_class = c;
     576    return mrb_yield_cont(mrb, blk, self, 1, &self);
    506577  }
    507578  ci->target_class = c;
    508579  p = mrb_proc_ptr(blk);
    509580  ci->proc = p;
     581  ci->argc = 1;
     582  ci->mid = ci[-1].mid;
    510583  if (MRB_PROC_CFUNC_P(p)) {
     584    stack_extend(mrb, 3);
     585    mrb->c->stack[0] = self;
     586    mrb->c->stack[1] = self;
     587    mrb->c->stack[2] = mrb_nil_value();
    511588    return p->body.func(mrb, self);
    512589  }
    513590  ci->nregs = p->body.irep->nregs;
     591  if (max < ci->nregs) max = ci->nregs;
     592  stack_extend(mrb, max);
     593  mrb->c->stack[0] = self;
     594  mrb->c->stack[1] = self;
     595  mrb->c->stack[2] = mrb_nil_value();
    514596  ci = cipush(mrb);
    515597  ci->nregs = 0;
     
    600682    mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
    601683  }
     684  if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
     685    mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
     686  }
    602687  p = mrb_proc_ptr(b);
    603688  ci = cipush(mrb);
     
    611696  if (MRB_PROC_CFUNC_P(p)) {
    612697    ci->nregs = argc + 2;
    613     stack_extend(mrb, ci->nregs, 0);
     698    stack_extend(mrb, ci->nregs);
    614699  }
    615700  else {
    616701    ci->nregs = p->body.irep->nregs;
    617     stack_extend(mrb, ci->nregs, argc+2);
     702    stack_extend(mrb, ci->nregs);
    618703  }
    619704
     
    627712    val = p->body.func(mrb, self);
    628713    mrb->c->stack = mrb->c->ci->stackent;
    629     cipop(mrb);
    630714  }
    631715  else {
     716    int cioff = mrb->c->ci - mrb->c->cibase;
    632717    val = mrb_run(mrb, p, self);
    633   }
     718    mrb->c->ci = mrb->c->cibase + cioff;
     719  }
     720  cipop(mrb);
    634721  return val;
    635722}
     
    649736
    650737  return mrb_yield_with_class(mrb, b, 1, &arg, p->env->stack[0], p->target_class);
     738}
     739
     740mrb_value
     741mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const mrb_value *argv)
     742{
     743  struct RProc *p;
     744  mrb_callinfo *ci;
     745
     746  if (mrb_nil_p(b)) {
     747    mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
     748  }
     749  if (mrb_type(b) != MRB_TT_PROC) {
     750    mrb_raise(mrb, E_TYPE_ERROR, "not a block");
     751  }
     752
     753  p = mrb_proc_ptr(b);
     754  ci = mrb->c->ci;
     755
     756  stack_extend(mrb, 3);
     757  mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv);
     758  mrb->c->stack[2] = mrb_nil_value();
     759  ci->argc = -1;
     760  return mrb_exec_irep(mrb, self, p);
     761}
     762
     763static struct RBreak*
     764break_new(mrb_state *mrb, struct RProc *p, mrb_value val)
     765{
     766  struct RBreak *brk;
     767
     768  brk = (struct RBreak*)mrb_obj_alloc(mrb, MRB_TT_BREAK, NULL);
     769  brk->iv = NULL;
     770  brk->proc = p;
     771  brk->val = val;
     772
     773  return brk;
    651774}
    652775
     
    670793  mrb_str_cat(mrb, msg, kind_str[kind], kind_str_len[kind]);
    671794  exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg);
    672   mrb->exc = mrb_obj_ptr(exc);
     795  mrb_exc_set(mrb, exc);
    673796}
    674797
     
    678801  mrb_value exc;
    679802  mrb_value str;
    680 
     803  mrb_int argc = mrb->c->ci->argc;
     804
     805  if (argc < 0) {
     806    mrb_value args = mrb->c->stack[1];
     807    if (mrb_array_p(args)) {
     808      argc = RARRAY_LEN(args);
     809    }
     810  }
    681811  if (mrb->c->ci->mid) {
    682812    str = mrb_format(mrb, "'%S': wrong number of arguments (%S for %S)",
    683813                  mrb_sym2str(mrb, mrb->c->ci->mid),
    684                   mrb_fixnum_value(mrb->c->ci->argc), mrb_fixnum_value(num));
     814                  mrb_fixnum_value(argc), mrb_fixnum_value(num));
    685815  }
    686816  else {
    687817    str = mrb_format(mrb, "wrong number of arguments (%S for %S)",
    688                   mrb_fixnum_value(mrb->c->ci->argc), mrb_fixnum_value(num));
     818                     mrb_fixnum_value(argc), mrb_fixnum_value(num));
    689819  }
    690820  exc = mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str);
    691   mrb->exc = mrb_obj_ptr(exc);
     821  mrb_exc_set(mrb, exc);
    692822}
    693823
     
    700830#endif
    701831
     832#ifdef MRB_BYTECODE_DECODE_OPTION
     833#define BYTECODE_DECODER(x) ((mrb)->bytecode_decoder)?(mrb)->bytecode_decoder((mrb), (x)):(x)
     834#else
     835#define BYTECODE_DECODER(x) (x)
     836#endif
     837
     838
    702839#if defined __GNUC__ || defined __clang__ || defined __INTEL_COMPILER
    703840#define DIRECT_THREADED
     
    706843#ifndef DIRECT_THREADED
    707844
    708 #define INIT_DISPATCH for (;;) { i = *pc; CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (GET_OPCODE(i)) {
     845#define INIT_DISPATCH for (;;) { i = BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (GET_OPCODE(i)) {
    709846#define CASE(op) case op:
    710847#define NEXT pc++; break
     
    716853#define INIT_DISPATCH JUMP; return mrb_nil_value();
    717854#define CASE(op) L_ ## op:
    718 #define NEXT i=*++pc; CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)]
    719 #define JUMP i=*pc; CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)]
     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)]
    720857
    721858#define END_DISPATCH
     
    723860#endif
    724861
    725 #define CALL_MAXARGS 127
    726 
    727 void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args);
    728 
    729862MRB_API mrb_value
    730 mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep)
     863mrb_vm_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep)
     864{
     865  mrb_irep *irep = proc->body.irep;
     866  mrb_value result;
     867  struct mrb_context *c = mrb->c;
     868  int cioff = c->ci - c->cibase;
     869  unsigned int nregs = irep->nregs;
     870
     871  if (!c->stack) {
     872    stack_init(mrb);
     873  }
     874  if (stack_keep > nregs)
     875    nregs = stack_keep;
     876  stack_extend(mrb, nregs);
     877  stack_clear(c->stack + stack_keep, nregs - stack_keep);
     878  c->stack[0] = self;
     879  result = mrb_vm_exec(mrb, proc, irep->iseq);
     880  if (c->ci - c->cibase > cioff) {
     881    c->ci = c->cibase + cioff;
     882  }
     883  if (mrb->c != c) {
     884    if (mrb->c->fib) {
     885      mrb_write_barrier(mrb, (struct RBasic*)mrb->c->fib);
     886    }
     887    mrb->c = c;
     888  }
     889  return result;
     890}
     891
     892MRB_API mrb_value
     893mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc)
    731894{
    732895  /* mrb_assert(mrb_proc_cfunc_p(proc)) */
    733896  mrb_irep *irep = proc->body.irep;
    734   mrb_code *pc = irep->iseq;
    735897  mrb_value *pool = irep->pool;
    736898  mrb_sym *syms = irep->syms;
    737   mrb_value *regs = NULL;
    738899  mrb_code i;
    739900  int ai = mrb_gc_arena_save(mrb);
     
    773934  if (exc_catched) {
    774935    exc_catched = FALSE;
     936    if (mrb->exc && mrb->exc->tt == MRB_TT_BREAK)
     937      goto L_BREAK;
    775938    goto L_RAISE;
    776939  }
    777940  mrb->jmp = &c_jmp;
    778   if (!mrb->c->stack) {
    779     stack_init(mrb);
    780   }
    781   stack_extend(mrb, irep->nregs, stack_keep);
    782941  mrb->c->ci->proc = proc;
    783942  mrb->c->ci->nregs = irep->nregs;
    784   regs = mrb->c->stack;
    785   regs[0] = self;
    786 
     943
     944#define regs (mrb->c->stack)
    787945  INIT_DISPATCH {
    788946    CASE(OP_NOP) {
     
    793951    CASE(OP_MOVE) {
    794952      /* A B    R(A) := R(B) */
    795       regs[GETARG_A(i)] = regs[GETARG_B(i)];
     953      int a = GETARG_A(i);
     954      int b = GETARG_B(i);
     955      regs[a] = regs[b];
    796956      NEXT;
    797957    }
     
    799959    CASE(OP_LOADL) {
    800960      /* A Bx   R(A) := Pool(Bx) */
    801       regs[GETARG_A(i)] = pool[GETARG_Bx(i)];
     961      int a = GETARG_A(i);
     962      int bx = GETARG_Bx(i);
     963#ifdef MRB_WORD_BOXING
     964      mrb_value val = pool[bx];
     965      if (mrb_float_p(val)) {
     966        val = mrb_float_value(mrb, mrb_float(val));
     967      }
     968      regs[a] = val;
     969#else
     970      regs[a] = pool[bx];
     971#endif
    802972      NEXT;
    803973    }
     
    811981    CASE(OP_LOADSYM) {
    812982      /* A Bx   R(A) := Syms(Bx) */
    813       SET_SYM_VALUE(regs[GETARG_A(i)], syms[GETARG_Bx(i)]);
     983      int a = GETARG_A(i);
     984      int bx = GETARG_Bx(i);
     985      SET_SYM_VALUE(regs[a], syms[bx]);
    814986      NEXT;
    815987    }
     
    817989    CASE(OP_LOADSELF) {
    818990      /* A      R(A) := self */
    819       regs[GETARG_A(i)] = regs[0];
     991      int a = GETARG_A(i);
     992      regs[a] = regs[0];
    820993      NEXT;
    821994    }
     
    823996    CASE(OP_LOADT) {
    824997      /* A      R(A) := true */
    825       SET_TRUE_VALUE(regs[GETARG_A(i)]);
     998      int a = GETARG_A(i);
     999      SET_TRUE_VALUE(regs[a]);
    8261000      NEXT;
    8271001    }
     
    8291003    CASE(OP_LOADF) {
    8301004      /* A      R(A) := false */
    831       SET_FALSE_VALUE(regs[GETARG_A(i)]);
     1005      int a = GETARG_A(i);
     1006      SET_FALSE_VALUE(regs[a]);
    8321007      NEXT;
    8331008    }
     
    8351010    CASE(OP_GETGLOBAL) {
    8361011      /* A Bx   R(A) := getglobal(Syms(Bx)) */
    837       regs[GETARG_A(i)] = mrb_gv_get(mrb, syms[GETARG_Bx(i)]);
     1012      int a = GETARG_A(i);
     1013      int bx = GETARG_Bx(i);
     1014      mrb_value val = mrb_gv_get(mrb, syms[bx]);
     1015      regs[a] = val;
    8381016      NEXT;
    8391017    }
    8401018
    8411019    CASE(OP_SETGLOBAL) {
    842       /* setglobal(Syms(Bx), R(A)) */
    843       mrb_gv_set(mrb, syms[GETARG_Bx(i)], regs[GETARG_A(i)]);
     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]);
    8441024      NEXT;
    8451025    }
     
    8471027    CASE(OP_GETSPECIAL) {
    8481028      /* A Bx   R(A) := Special[Bx] */
    849       regs[GETARG_A(i)] = mrb_vm_special_get(mrb, GETARG_Bx(i));
     1029      int a = GETARG_A(i);
     1030      int bx = GETARG_Bx(i);
     1031      mrb_value val = mrb_vm_special_get(mrb, bx);
     1032      regs[a] = val;
    8501033      NEXT;
    8511034    }
     
    8531036    CASE(OP_SETSPECIAL) {
    8541037      /* A Bx   Special[Bx] := R(A) */
    855       mrb_vm_special_set(mrb, GETARG_Bx(i), regs[GETARG_A(i)]);
     1038      int a = GETARG_A(i);
     1039      int bx = GETARG_Bx(i);
     1040      mrb_vm_special_set(mrb, bx, regs[a]);
    8561041      NEXT;
    8571042    }
     
    8591044    CASE(OP_GETIV) {
    8601045      /* A Bx   R(A) := ivget(Bx) */
    861       regs[GETARG_A(i)] = mrb_vm_iv_get(mrb, syms[GETARG_Bx(i)]);
     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;
    8621050      NEXT;
    8631051    }
    8641052
    8651053    CASE(OP_SETIV) {
    866       /* ivset(Syms(Bx),R(A)) */
    867       mrb_vm_iv_set(mrb, syms[GETARG_Bx(i)], regs[GETARG_A(i)]);
     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]);
    8681058      NEXT;
    8691059    }
     
    8711061    CASE(OP_GETCV) {
    8721062      /* A Bx   R(A) := cvget(Syms(Bx)) */
     1063      int a = GETARG_A(i);
     1064      int bx = GETARG_Bx(i);
     1065      mrb_value val;
    8731066      ERR_PC_SET(mrb, pc);
    874       regs[GETARG_A(i)] = mrb_vm_cv_get(mrb, syms[GETARG_Bx(i)]);
     1067      val = mrb_vm_cv_get(mrb, syms[bx]);
    8751068      ERR_PC_CLR(mrb);
     1069      regs[a] = val;
    8761070      NEXT;
    8771071    }
    8781072
    8791073    CASE(OP_SETCV) {
    880       /* cvset(Syms(Bx),R(A)) */
    881       mrb_vm_cv_set(mrb, syms[GETARG_Bx(i)], regs[GETARG_A(i)]);
     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]);
    8821078      NEXT;
    8831079    }
     
    8861082      /* A Bx    R(A) := constget(Syms(Bx)) */
    8871083      mrb_value val;
     1084      int a = GETARG_A(i);
     1085      int bx = GETARG_Bx(i);
     1086      mrb_sym sym = syms[bx];
    8881087
    8891088      ERR_PC_SET(mrb, pc);
    890       val = mrb_vm_const_get(mrb, syms[GETARG_Bx(i)]);
     1089      val = mrb_vm_const_get(mrb, sym);
    8911090      ERR_PC_CLR(mrb);
    892       regs = mrb->c->stack;
    893       regs[GETARG_A(i)] = val;
     1091      regs[a] = val;
    8941092      NEXT;
    8951093    }
     
    8971095    CASE(OP_SETCONST) {
    8981096      /* A Bx   constset(Syms(Bx),R(A)) */
    899       mrb_vm_const_set(mrb, syms[GETARG_Bx(i)], regs[GETARG_A(i)]);
     1097      int a = GETARG_A(i);
     1098      int bx = GETARG_Bx(i);
     1099      mrb_vm_const_set(mrb, syms[bx], regs[a]);
    9001100      NEXT;
    9011101    }
     
    9051105      mrb_value val;
    9061106      int a = GETARG_A(i);
     1107      int bx = GETARG_Bx(i);
    9071108
    9081109      ERR_PC_SET(mrb, pc);
    909       val = mrb_const_get(mrb, regs[a], syms[GETARG_Bx(i)]);
     1110      val = mrb_const_get(mrb, regs[a], syms[bx]);
    9101111      ERR_PC_CLR(mrb);
    911       regs = mrb->c->stack;
    9121112      regs[a] = val;
    9131113      NEXT;
     
    9171117      /* A Bx    R(A+1)::Syms(Bx) := R(A) */
    9181118      int a = GETARG_A(i);
    919 
    920       mrb_const_set(mrb, regs[a+1], syms[GETARG_Bx(i)], regs[a]);
     1119      int bx = GETARG_Bx(i);
     1120      mrb_const_set(mrb, regs[a+1], syms[bx], regs[a]);
    9211121      NEXT;
    9221122    }
     
    9241124    CASE(OP_GETUPVAR) {
    9251125      /* A B C  R(A) := uvget(B,C) */
    926       mrb_value *regs_a = regs + GETARG_A(i);
    927       int up = GETARG_C(i);
    928 
    929       struct REnv *e = uvenv(mrb, up);
     1126      int a = GETARG_A(i);
     1127      int b = GETARG_B(i);
     1128      int c = GETARG_C(i);
     1129      mrb_value *regs_a = regs + a;
     1130      struct REnv *e = uvenv(mrb, c);
    9301131
    9311132      if (!e) {
     
    9331134      }
    9341135      else {
    935         int idx = GETARG_B(i);
    936         *regs_a = e->stack[idx];
     1136        *regs_a = e->stack[b];
    9371137      }
    9381138      NEXT;
     
    9411141    CASE(OP_SETUPVAR) {
    9421142      /* A B C  uvset(B,C,R(A)) */
    943       int up = GETARG_C(i);
    944 
    945       struct REnv *e = uvenv(mrb, up);
     1143      int a = GETARG_A(i);
     1144      int b = GETARG_B(i);
     1145      int c = GETARG_C(i);
     1146
     1147      struct REnv *e = uvenv(mrb, c);
    9461148
    9471149      if (e) {
    948         mrb_value *regs_a = regs + GETARG_A(i);
    949         int idx = GETARG_B(i);
    950         e->stack[idx] = *regs_a;
    951         mrb_write_barrier(mrb, (struct RBasic*)e);
     1150        mrb_value *regs_a = regs + a;
     1151
     1152        if (b < MRB_ENV_STACK_LEN(e)) {
     1153          e->stack[b] = *regs_a;
     1154          mrb_write_barrier(mrb, (struct RBasic*)e);
     1155        }
    9521156      }
    9531157      NEXT;
     
    9561160    CASE(OP_JMP) {
    9571161      /* sBx    pc+=sBx */
    958       pc += GETARG_sBx(i);
     1162      int sbx = GETARG_sBx(i);
     1163      pc += sbx;
    9591164      JUMP;
    9601165    }
     
    9621167    CASE(OP_JMPIF) {
    9631168      /* A sBx  if R(A) pc+=sBx */
    964       if (mrb_test(regs[GETARG_A(i)])) {
    965         pc += GETARG_sBx(i);
     1169      int a = GETARG_A(i);
     1170      int sbx = GETARG_sBx(i);
     1171      if (mrb_test(regs[a])) {
     1172        pc += sbx;
    9661173        JUMP;
    9671174      }
     
    9711178    CASE(OP_JMPNOT) {
    9721179      /* A sBx  if !R(A) pc+=sBx */
    973       if (!mrb_test(regs[GETARG_A(i)])) {
    974         pc += GETARG_sBx(i);
     1180      int a = GETARG_A(i);
     1181      int sbx = GETARG_sBx(i);
     1182      if (!mrb_test(regs[a])) {
     1183        pc += sbx;
    9751184        JUMP;
    9761185      }
     
    9801189    CASE(OP_ONERR) {
    9811190      /* sBx    pc+=sBx on exception */
     1191      int sbx = GETARG_sBx(i);
    9821192      if (mrb->c->rsize <= mrb->c->ci->ridx) {
    983         if (mrb->c->rsize == 0) mrb->c->rsize = 16;
     1193        if (mrb->c->rsize == 0) mrb->c->rsize = RESCUE_STACK_INIT_SIZE;
    9841194        else mrb->c->rsize *= 2;
    9851195        mrb->c->rescue = (mrb_code **)mrb_realloc(mrb, mrb->c->rescue, sizeof(mrb_code*) * mrb->c->rsize);
    9861196      }
    987       mrb->c->rescue[mrb->c->ci->ridx++] = pc + GETARG_sBx(i);
     1197      mrb->c->rescue[mrb->c->ci->ridx++] = pc + sbx;
    9881198      NEXT;
    9891199    }
    9901200
    9911201    CASE(OP_RESCUE) {
    992       /* A      R(A) := exc; clear(exc) */
    993       SET_OBJ_VALUE(regs[GETARG_A(i)], mrb->exc);
    994       mrb->exc = 0;
     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      }
    9951239      NEXT;
    9961240    }
     
    10081252    CASE(OP_RAISE) {
    10091253      /* A      raise(R(A)) */
    1010       mrb->exc = mrb_obj_ptr(regs[GETARG_A(i)]);
     1254      int a = GETARG_A(i);
     1255
     1256      mrb_exc_set(mrb, regs[a]);
    10111257      goto L_RAISE;
    10121258    }
     
    10141260    CASE(OP_EPUSH) {
    10151261      /* Bx     ensure_push(SEQ[Bx]) */
     1262      int bx = GETARG_Bx(i);
    10161263      struct RProc *p;
    10171264
    1018       p = mrb_closure_new(mrb, irep->reps[GETARG_Bx(i)]);
     1265      p = mrb_closure_new(mrb, irep->reps[bx]);
    10191266      /* push ensure_stack */
    1020       if (mrb->c->esize <= mrb->c->ci->eidx) {
    1021         if (mrb->c->esize == 0) mrb->c->esize = 16;
     1267      if (mrb->c->esize <= mrb->c->eidx+1) {
     1268        if (mrb->c->esize == 0) mrb->c->esize = ENSURE_STACK_INIT_SIZE;
    10221269        else mrb->c->esize *= 2;
    10231270        mrb->c->ensure = (struct RProc **)mrb_realloc(mrb, mrb->c->ensure, sizeof(struct RProc*) * mrb->c->esize);
    10241271      }
    1025       mrb->c->ensure[mrb->c->ci->eidx++] = p;
     1272      mrb->c->ensure[mrb->c->eidx++] = p;
     1273      mrb->c->ensure[mrb->c->eidx] = NULL;
    10261274      ARENA_RESTORE(mrb, ai);
    10271275      NEXT;
     
    10321280      int a = GETARG_A(i);
    10331281      mrb_callinfo *ci = mrb->c->ci;
    1034       int n, eidx = ci->eidx;
    1035 
    1036       for (n=0; n<a && (ci == mrb->c->cibase || eidx > ci[-1].eidx); n++) {
    1037         ecall(mrb, --eidx);
     1282      int n, epos = ci->epos;
     1283
     1284      for (n=0; n<a && mrb->c->eidx > epos; n++) {
     1285        ecall(mrb, --mrb->c->eidx);
    10381286        ARENA_RESTORE(mrb, ai);
    10391287      }
     
    10611309      struct RProc *m;
    10621310      struct RClass *c;
    1063       mrb_callinfo *ci;
     1311      mrb_callinfo *ci = mrb->c->ci;
    10641312      mrb_value recv, result;
    10651313      mrb_sym mid = syms[GETARG_B(i)];
     1314      int bidx;
     1315      mrb_value blk;
    10661316
    10671317      recv = regs[a];
     1318      if (n == CALL_MAXARGS) {
     1319        bidx = a+2;
     1320      }
     1321      else {
     1322        bidx = a+n+1;
     1323      }
    10681324      if (GET_OPCODE(i) != OP_SENDB) {
    1069         if (n == CALL_MAXARGS) {
    1070           SET_NIL_VALUE(regs[a+2]);
    1071         }
    1072         else {
    1073           SET_NIL_VALUE(regs[a+n+1]);
     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;
    10741341        }
    10751342      }
     
    10901357            args = mrb_ary_new_from_values(mrb, n, regs+a+1);
    10911358          }
     1359          ERR_PC_SET(mrb, pc);
    10921360          mrb_method_missing(mrb, mid, recv, args);
    10931361        }
    10941362        mid = missing;
    1095         if (n == CALL_MAXARGS) {
    1096           mrb_ary_unshift(mrb, regs[a+1], sym);
    1097         }
    1098         else {
    1099           value_move(regs+a+2, regs+a+1, ++n);
    1100           regs[a+1] = sym;
    1101         }
     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);
    11021372      }
    11031373
     
    11251395        }
    11261396        result = m->body.func(mrb, recv);
    1127         mrb->c->stack[0] = result;
    11281397        mrb_gc_arena_restore(mrb, ai);
    11291398        if (mrb->exc) goto L_RAISE;
    1130         /* pop stackpos */
    11311399        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            }
     1407          }
     1408        }
    11321409        if (!ci->target_class) { /* return from context modifying method (resume/yield) */
    1133           if (!MRB_PROC_CFUNC_P(ci[-1].proc)) {
     1410          if (ci->acc == CI_ACC_RESUMED) {
     1411            mrb->jmp = prev_jmp;
     1412            return result;
     1413          }
     1414          else {
     1415            mrb_assert(!MRB_PROC_CFUNC_P(ci[-1].proc));
    11341416            proc = ci[-1].proc;
    11351417            irep = proc->body.irep;
     
    11381420          }
    11391421        }
    1140         regs = mrb->c->stack = ci->stackent;
     1422        mrb->c->stack[0] = result;
     1423        /* pop stackpos */
     1424        mrb->c->stack = ci->stackent;
    11411425        pc = ci->pc;
    11421426        cipop(mrb);
     
    11521436        if (n == CALL_MAXARGS) {
    11531437          ci->argc = -1;
    1154           stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs, 3);
     1438          stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs);
    11551439        }
    11561440        else {
    11571441          ci->argc = n;
    1158           stack_extend(mrb, irep->nregs,  n+2);
    1159         }
    1160         regs = mrb->c->stack;
     1442          stack_extend(mrb, irep->nregs);
     1443        }
    11611444        pc = irep->iseq;
    11621445        JUMP;
     
    11661449    CASE(OP_FSEND) {
    11671450      /* A B C  R(A) := fcall(R(A),Syms(B),R(A+1),... ,R(A+C-1)) */
     1451      /* not implemented yet */
    11681452      NEXT;
    11691453    }
     
    11801464      ci->proc = m;
    11811465      if (m->env) {
    1182         if (m->env->mid) {
    1183           ci->mid = m->env->mid;
    1184         }
     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;
    11851475        if (!m->env->stack) {
    11861476          m->env->stack = mrb->c->stack;
     
    11951485        /* pop stackpos */
    11961486        ci = mrb->c->ci;
    1197         regs = mrb->c->stack = ci->stackent;
     1487        mrb->c->stack = ci->stackent;
    11981488        regs[ci->acc] = recv;
    11991489        pc = ci->pc;
     
    12151505        syms = irep->syms;
    12161506        ci->nregs = irep->nregs;
     1507        stack_extend(mrb, irep->nregs);
    12171508        if (ci->argc < 0) {
    1218           stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs, 3);
    1219         }
    1220         else {
    1221           stack_extend(mrb, irep->nregs, ci->argc+2);
    1222         }
    1223         regs = mrb->c->stack;
    1224         regs[0] = m->env->stack[0];
     1509          if (irep->nregs > 3) {
     1510            stack_clear(regs+3, irep->nregs-3);
     1511          }
     1512        }
     1513        else if (ci->argc+2 < irep->nregs) {
     1514          stack_clear(regs+ci->argc+2, irep->nregs-ci->argc-2);
     1515        }
     1516        if (m->env) {
     1517          regs[0] = m->env->stack[0];
     1518        }
    12251519        pc = irep->iseq;
    12261520        JUMP;
     
    12371531      int a = GETARG_A(i);
    12381532      int n = GETARG_C(i);
    1239 
    1240       if (mid == 0) {
     1533      mrb_value blk;
     1534      int bidx;
     1535
     1536      if (mid == 0 || !ci->target_class) {
    12411537        mrb_value exc;
    12421538
    12431539        exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method");
    1244         mrb->exc = mrb_obj_ptr(exc);
     1540        mrb_exc_set(mrb, exc);
    12451541        goto L_RAISE;
    12461542      }
     
    12491545      m = mrb_method_search_vm(mrb, &c, mid);
    12501546      if (!m) {
    1251         mid = mrb_intern_lit(mrb, "method_missing");
    1252         m = mrb_method_search_vm(mrb, &c, mid);
     1547        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);
     1559          mrb_method_missing(mrb, mid, recv, args);
     1560        }
     1561        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        }
    12531566        if (n == CALL_MAXARGS) {
    12541567          mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid));
     
    12581571          SET_SYM_VALUE(regs[a+1], ci->mid);
    12591572        }
     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;
    12601591      }
    12611592
     
    12651596      ci->proc = m;
    12661597      ci->stackent = mrb->c->stack;
     1598      ci->target_class = c;
     1599      ci->pc = pc + 1;
    12671600      if (n == CALL_MAXARGS) {
    12681601        ci->argc = -1;
     
    12711604        ci->argc = n;
    12721605      }
    1273       ci->target_class = c;
    1274       ci->pc = pc + 1;
    12751606
    12761607      /* prepare stack */
     
    12791610
    12801611      if (MRB_PROC_CFUNC_P(m)) {
     1612        mrb_value v;
     1613
    12811614        if (n == CALL_MAXARGS) {
    12821615          ci->nregs = 3;
     
    12851618          ci->nregs = n + 2;
    12861619        }
    1287         mrb->c->stack[0] = m->body.func(mrb, recv);
     1620        v = m->body.func(mrb, recv);
    12881621        mrb_gc_arena_restore(mrb, ai);
    12891622        if (mrb->exc) goto L_RAISE;
     1623        ci = mrb->c->ci;
     1624        if (!ci->target_class) { /* return from context modifying method (resume/yield) */
     1625          if (ci->acc == CI_ACC_RESUMED) {
     1626            mrb->jmp = prev_jmp;
     1627            return v;
     1628          }
     1629          else {
     1630            mrb_assert(!MRB_PROC_CFUNC_P(ci[-1].proc));
     1631            proc = ci[-1].proc;
     1632            irep = proc->body.irep;
     1633            pool = irep->pool;
     1634            syms = irep->syms;
     1635          }
     1636        }
     1637        mrb->c->stack[0] = v;
    12901638        /* pop stackpos */
    1291         regs = mrb->c->stack = mrb->c->ci->stackent;
     1639        mrb->c->stack = ci->stackent;
     1640        pc = ci->pc;
    12921641        cipop(mrb);
    1293         NEXT;
     1642        JUMP;
    12941643      }
    12951644      else {
     
    13041653        ci->nregs = irep->nregs;
    13051654        if (n == CALL_MAXARGS) {
    1306           stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs, 3);
     1655          stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs);
    13071656        }
    13081657        else {
    1309           stack_extend(mrb, irep->nregs, ci->argc+2);
    1310         }
    1311         regs = mrb->c->stack;
     1658          stack_extend(mrb, irep->nregs);
     1659        }
    13121660        pc = irep->iseq;
    13131661        JUMP;
     
    13251673      mrb_value *stack;
    13261674
     1675      if (mrb->c->ci->mid == 0 || mrb->c->ci->target_class == NULL) {
     1676        mrb_value exc;
     1677
     1678      L_NOSUPER:
     1679        exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method");
     1680        mrb_exc_set(mrb, exc);
     1681        goto L_RAISE;
     1682      }
    13271683      if (lv == 0) stack = regs + 1;
    13281684      else {
    13291685        struct REnv *e = uvenv(mrb, lv-1);
    1330         if (!e) {
    1331           mrb_value exc;
    1332 
    1333           exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method");
    1334           mrb->exc = mrb_obj_ptr(exc);
    1335           goto L_RAISE;
    1336         }
     1686        if (!e) goto L_NOSUPER;
    13371687        stack = e->stack + 1;
    13381688      }
     
    13881738      mrb_value *blk = &argv[argc < 0 ? 1 : argc];
    13891739
    1390       if (!mrb_nil_p(*blk) && mrb_type(*blk) != MRB_TT_PROC) {
    1391         *blk = mrb_convert_type(mrb, *blk, MRB_TT_PROC, "Proc", "to_proc");
    1392       }
    13931740      if (argc < 0) {
    13941741        struct RArray *ary = mrb_ary_ptr(regs[1]);
     
    14101757        argv = mrb_ary_ptr(argv[0])->ptr;
    14111758      }
    1412       mrb->c->ci->argc = len;
    14131759      if (argc < len) {
    14141760        int mlen = m2;
     
    14241770          value_move(&regs[1], argv, argc-mlen); /* m1 + o */
    14251771        }
     1772        if (argc < m1) {
     1773          stack_clear(&regs[argc+1], m1-argc);
     1774        }
    14261775        if (mlen) {
    14271776          value_move(&regs[len-m2+1], &argv[argc-mlen], mlen);
     1777        }
     1778        if (mlen < m2) {
     1779          stack_clear(&regs[len-m2+mlen+1], m2-mlen);
    14281780        }
    14291781        if (r) {
     
    14541806        pc += o + 1;
    14551807      }
     1808      mrb->c->ci->argc = len;
     1809      /* clear local (but non-argument) variables */
     1810      if (irep->nlocals-len-2 > 0) {
     1811        stack_clear(&regs[len+2], irep->nlocals-len-2);
     1812      }
    14561813      JUMP;
    14571814    }
     
    14741831    CASE(OP_RETURN) {
    14751832      /* A B     return R(A) (B=normal,in-block return/break) */
     1833      mrb_callinfo *ci;
     1834
     1835      ci = mrb->c->ci;
     1836      if (ci->mid) {
     1837        mrb_value blk;
     1838
     1839        if (ci->argc < 0) {
     1840          blk = regs[2];
     1841        }
     1842        else {
     1843          blk = regs[ci->argc+1];
     1844        }
     1845        if (mrb_type(blk) == MRB_TT_PROC) {
     1846          struct RProc *p = mrb_proc_ptr(blk);
     1847
     1848          if (!MRB_PROC_STRICT_P(proc) &&
     1849              ci > mrb->c->cibase && p->env == ci[-1].env) {
     1850            p->flags |= MRB_PROC_ORPHAN;
     1851          }
     1852        }
     1853      }
     1854
    14761855      if (mrb->exc) {
    1477         mrb_callinfo *ci;
    1478         int eidx;
     1856        mrb_callinfo *ci0;
     1857        mrb_value *stk;
    14791858
    14801859      L_RAISE:
    1481         ci = mrb->c->ci;
    1482         mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern_lit(mrb, "lastpc"), mrb_cptr_value(mrb, pc));
    1483         mrb_obj_iv_ifnone(mrb, mrb->exc, mrb_intern_lit(mrb, "ciidx"), mrb_fixnum_value(ci - mrb->c->cibase));
    1484         eidx = ci->eidx;
     1860        ci0 = ci = mrb->c->ci;
    14851861        if (ci == mrb->c->cibase) {
    1486           if (ci->ridx == 0) goto L_STOP;
     1862          if (ci->ridx == 0) goto L_FTOP;
    14871863          goto L_RESCUE;
    14881864        }
     1865        stk = mrb->c->stack;
    14891866        while (ci[0].ridx == ci[-1].ridx) {
    14901867          cipop(mrb);
    1491           ci = mrb->c->ci;
    1492           mrb->c->stack = ci[1].stackent;
    1493           if (ci[1].acc == CI_ACC_SKIP && prev_jmp) {
     1868          mrb->c->stack = ci->stackent;
     1869          if (ci->acc == CI_ACC_SKIP && prev_jmp) {
    14941870            mrb->jmp = prev_jmp;
    14951871            MRB_THROW(prev_jmp);
    14961872          }
     1873          ci = mrb->c->ci;
    14971874          if (ci == mrb->c->cibase) {
    1498             while (eidx > 0) {
    1499               ecall(mrb, --eidx);
    1500             }
     1875            mrb->c->stack = stk;
    15011876            if (ci->ridx == 0) {
     1877            L_FTOP:             /* fiber top */
    15021878              if (mrb->c == mrb->root_c) {
    1503                 regs = mrb->c->stack = mrb->c->stbase;
     1879                mrb->c->stack = mrb->c->stbase;
    15041880                goto L_STOP;
    15051881              }
     
    15071883                struct mrb_context *c = mrb->c;
    15081884
     1885                if (c->fib) {
     1886                  mrb_write_barrier(mrb, (struct RBasic*)c->fib);
     1887                }
    15091888                mrb->c = c->prev;
    15101889                c->prev = NULL;
     
    15161895          /* call ensure only when we skip this callinfo */
    15171896          if (ci[0].ridx == ci[-1].ridx) {
    1518             while (eidx > ci[-1].eidx) {
    1519               ecall(mrb, --eidx);
     1897            while (mrb->c->eidx > ci->epos) {
     1898              ecall(mrb, --mrb->c->eidx);
     1899              ci = mrb->c->ci;
    15201900            }
    15211901          }
     
    15271907        pool = irep->pool;
    15281908        syms = irep->syms;
    1529         regs = mrb->c->stack = ci[1].stackent;
     1909        if (ci != ci0) {
     1910          mrb->c->stack = ci[1].stackent;
     1911        }
     1912        stack_extend(mrb, irep->nregs);
    15301913        pc = mrb->c->rescue[--ci->ridx];
    15311914      }
    15321915      else {
    1533         mrb_callinfo *ci = mrb->c->ci;
    1534         int acc, eidx = mrb->c->ci->eidx;
    1535         mrb_value v = regs[GETARG_A(i)];
    1536 
     1916        int acc;
     1917        mrb_value v;
     1918
     1919        v = regs[GETARG_A(i)];
     1920        mrb_gc_protect(mrb, v);
    15371921        switch (GETARG_B(i)) {
    15381922        case OP_R_RETURN:
    15391923          /* Fall through to OP_R_NORMAL otherwise */
    1540           if (proc->env && !MRB_PROC_STRICT_P(proc)) {
     1924          if (ci->acc >=0 && proc->env && !MRB_PROC_STRICT_P(proc)) {
    15411925            struct REnv *e = top_env(mrb, proc);
    1542 
    1543             if (!MRB_ENV_STACK_SHARED_P(e)) {
     1926            mrb_callinfo *ce;
     1927
     1928            if (!MRB_ENV_STACK_SHARED_P(e) || e->cxt.c != mrb->c) {
    15441929              localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
    15451930              goto L_RAISE;
    15461931            }
    1547             ci = mrb->c->cibase + e->cioff;
    1548             if (ci == mrb->c->cibase) {
     1932           
     1933            ce = mrb->c->cibase + e->cioff;
     1934            while (ci >= ce) {
     1935              if (ci->env) {
     1936                mrb_env_unshare(mrb, ci->env);
     1937              }
     1938              if (ci->acc < 0) {
     1939                localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
     1940                goto L_RAISE;
     1941              }
     1942              ci--;
     1943            }
     1944            if (ce == mrb->c->cibase) {
    15491945              localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
    15501946              goto L_RAISE;
    15511947            }
    15521948            mrb->c->stack = mrb->c->ci->stackent;
    1553             mrb->c->ci = ci;
     1949            mrb->c->ci = ce;
    15541950            break;
    15551951          }
    15561952        case OP_R_NORMAL:
     1953        NORMAL_RETURN:
    15571954          if (ci == mrb->c->cibase) {
    15581955            if (!mrb->c->prev) { /* toplevel return */
     
    15621959            if (mrb->c->prev->ci == mrb->c->prev->cibase) {
    15631960              mrb_value exc = mrb_exc_new_str_lit(mrb, E_FIBER_ERROR, "double resume");
    1564               mrb->exc = mrb_obj_ptr(exc);
     1961              mrb_exc_set(mrb, exc);
    15651962              goto L_RAISE;
     1963            }
     1964            while (mrb->c->eidx > 0) {
     1965              ecall(mrb, --mrb->c->eidx);
    15661966            }
    15671967            /* automatic yield at the end */
     
    15731973          break;
    15741974        case OP_R_BREAK:
     1975          if (MRB_PROC_STRICT_P(proc)) goto NORMAL_RETURN;
     1976          if (MRB_PROC_ORPHAN_P(proc)) {
     1977            mrb_value exc;
     1978
     1979          L_BREAK_ERROR:
     1980            exc = mrb_exc_new_str_lit(mrb, E_LOCALJUMP_ERROR,
     1981                                      "break from proc-closure");
     1982            mrb_exc_set(mrb, exc);
     1983            goto L_RAISE;
     1984          }
    15751985          if (!proc->env || !MRB_ENV_STACK_SHARED_P(proc->env)) {
    1576             localjump_error(mrb, LOCALJUMP_ERROR_BREAK);
    1577             goto L_RAISE;
     1986            goto L_BREAK_ERROR;
    15781987          }
    15791988          /* break from fiber block */
     
    15811990            struct mrb_context *c = mrb->c;
    15821991
     1992            while (mrb->c->eidx > 0) {
     1993              ecall(mrb, --mrb->c->eidx);
     1994            }
    15831995            mrb->c = c->prev;
    15841996            c->prev = NULL;
    1585           }
    1586           ci = mrb->c->ci;
     1997            ci = mrb->c->ci;
     1998          }
     1999          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);
     2004            mrb->c->vmexec = FALSE;
     2005            mrb->exc = (struct RObject*)break_new(mrb, proc, v);
     2006            mrb->jmp = prev_jmp;
     2007            MRB_THROW(prev_jmp);
     2008          }
     2009          if (FALSE) {
     2010          L_BREAK:
     2011            v = ((struct RBreak*)mrb->exc)->val;
     2012            proc = ((struct RBreak*)mrb->exc)->proc;
     2013            mrb->exc = NULL;
     2014            ci = mrb->c->ci;
     2015          }
    15872016          mrb->c->stack = ci->stackent;
    15882017          mrb->c->ci = mrb->c->cibase + proc->env->cioff + 1;
    15892018          while (ci > mrb->c->ci) {
     2019            if (ci->env) {
     2020              mrb_env_unshare(mrb, ci->env);
     2021            }
    15902022            if (ci[-1].acc == CI_ACC_SKIP) {
    15912023              mrb->c->ci = ci;
    1592               break;
     2024              goto L_BREAK_ERROR;
    15932025            }
    15942026            ci--;
     
    15992031          break;
    16002032        }
    1601         while (eidx > mrb->c->ci[-1].eidx) {
    1602           ecall(mrb, --eidx);
    1603         }
    1604         cipop(mrb);
    1605         acc = ci->acc;
    1606         pc = ci->pc;
    1607         regs = mrb->c->stack = ci->stackent;
    1608         if (acc == CI_ACC_SKIP) {
     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);
     2038          mrb->c->vmexec = FALSE;
    16092039          mrb->jmp = prev_jmp;
    16102040          return v;
    16112041        }
    1612         DEBUG(printf("from :%s\n", mrb_sym2name(mrb, ci->mid)));
     2042        ci = mrb->c->ci;
     2043        acc = ci->acc;
     2044        mrb->c->stack = ci->stackent;
     2045        cipop(mrb);
     2046        if (acc == CI_ACC_SKIP || acc == CI_ACC_DIRECT) {
     2047          ARENA_RESTORE(mrb, ai);
     2048          mrb->jmp = prev_jmp;
     2049          return v;
     2050        }
     2051        pc = ci->pc;
     2052        DEBUG(fprintf(stderr, "from :%s\n", mrb_sym2name(mrb, ci->mid)));
    16132053        proc = mrb->c->ci->proc;
    16142054        irep = proc->body.irep;
     
    16172057
    16182058        regs[acc] = v;
     2059        ARENA_RESTORE(mrb, ai);
    16192060      }
    16202061      JUMP;
     
    16362077      if (!m) {
    16372078        mrb_value sym = mrb_symbol_value(mid);
    1638 
    1639         mid = mrb_intern_lit(mrb, "method_missing");
    1640         m = mrb_method_search_vm(mrb, &c, 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;
    16412094        if (n == CALL_MAXARGS) {
    16422095          mrb_ary_unshift(mrb, regs[a+1], sym);
     
    16632116
    16642117      if (MRB_PROC_CFUNC_P(m)) {
    1665         mrb->c->stack[0] = m->body.func(mrb, recv);
     2118        mrb_value v = m->body.func(mrb, recv);
     2119        mrb->c->stack[0] = v;
    16662120        mrb_gc_arena_restore(mrb, ai);
    16672121        goto L_RETURN;
     
    16732127        syms = irep->syms;
    16742128        if (ci->argc < 0) {
    1675           stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs, 3);
     2129          stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs);
    16762130        }
    16772131        else {
    1678           stack_extend(mrb, irep->nregs, ci->argc+2);
    1679         }
    1680         regs = mrb->c->stack;
     2132          stack_extend(mrb, irep->nregs);
     2133        }
    16812134        pc = irep->iseq;
    16822135      }
     
    16972150      else {
    16982151        struct REnv *e = uvenv(mrb, lv-1);
    1699         if (!e) {
     2152        if (!e || e->cioff == 0 ||
     2153            (!MRB_ENV_STACK_SHARED_P(e) && e->cxt.mid == 0)) {
    17002154          localjump_error(mrb, LOCALJUMP_ERROR_YIELD);
    17012155          goto L_RAISE;
    17022156        }
    17032157        stack = e->stack + 1;
     2158      }
     2159      if (mrb_nil_p(stack[m1+r+m2])) {
     2160        localjump_error(mrb, LOCALJUMP_ERROR_YIELD);
     2161        goto L_RAISE;
    17042162      }
    17052163      regs[a] = stack[m1+r+m2];
     
    18332291      case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):
    18342292        {
    1835           mrb_value z;
    1836 
    1837           z = mrb_fixnum_mul(mrb, regs[a], regs[a+1]);
    1838 
    1839           switch (mrb_type(z)) {
    1840           case MRB_TT_FIXNUM:
    1841             {
    1842               SET_INT_VALUE(regs[a], mrb_fixnum(z));
    1843             }
     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);
    18442299            break;
    1845           case MRB_TT_FLOAT:
    1846             {
    1847               SET_FLOAT_VALUE(mrb, regs[a], mrb_float(z));
    1848             }
    1849             break;
    1850           default:
    1851             /* cannot happen */
    1852             break;
    1853           }
     2300          }
     2301          SET_INT_VALUE(regs[a], z);
    18542302        }
    18552303        break;
     
    19362384#ifdef MRB_NAN_BOXING
    19372385      if (isnan(mrb_float(regs[a]))) {
    1938         regs[a] = mrb_float_value(mrb, mrb_float(regs[a]));
     2386        mrb_value v = mrb_float_value(mrb, mrb_float(regs[a]));
     2387        regs[a] = v;
    19392388      }
    19402389#endif
     
    20892538    CASE(OP_ARRAY) {
    20902539      /* A B C          R(A) := ary_new(R(B),R(B+1)..R(B+C)) */
    2091       regs[GETARG_A(i)] = mrb_ary_new_from_values(mrb, GETARG_C(i), &regs[GETARG_B(i)]);
     2540      int a = GETARG_A(i);
     2541      int b = GETARG_B(i);
     2542      int c = GETARG_C(i);
     2543      mrb_value v = mrb_ary_new_from_values(mrb, c, &regs[b]);
     2544      regs[a] = v;
    20922545      ARENA_RESTORE(mrb, ai);
    20932546      NEXT;
     
    20962549    CASE(OP_ARYCAT) {
    20972550      /* A B            mrb_ary_concat(R(A),R(B)) */
    2098       mrb_ary_concat(mrb, regs[GETARG_A(i)],
    2099                      mrb_ary_splat(mrb, regs[GETARG_B(i)]));
     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);
    21002555      ARENA_RESTORE(mrb, ai);
    21012556      NEXT;
     
    21042559    CASE(OP_ARYPUSH) {
    21052560      /* A B            R(A).push(R(B)) */
    2106       mrb_ary_push(mrb, regs[GETARG_A(i)], regs[GETARG_B(i)]);
     2561      int a = GETARG_A(i);
     2562      int b = GETARG_B(i);
     2563      mrb_ary_push(mrb, regs[a], regs[b]);
    21072564      NEXT;
    21082565    }
     
    21112568      /* A B C          R(A) := R(B)[C] */
    21122569      int a = GETARG_A(i);
     2570      int b = GETARG_B(i);
    21132571      int c = GETARG_C(i);
    2114       mrb_value v = regs[GETARG_B(i)];
     2572      mrb_value v = regs[b];
    21152573
    21162574      if (!mrb_array_p(v)) {
    21172575        if (c == 0) {
    2118           regs[GETARG_A(i)] = v;
     2576          regs[a] = v;
    21192577        }
    21202578        else {
     
    21232581      }
    21242582      else {
    2125         regs[GETARG_A(i)] = mrb_ary_ref(mrb, v, c);
     2583        v = mrb_ary_ref(mrb, v, c);
     2584        regs[a] = v;
    21262585      }
    21272586      NEXT;
     
    21302589    CASE(OP_ASET) {
    21312590      /* A B C          R(B)[C] := R(A) */
    2132       mrb_ary_set(mrb, regs[GETARG_B(i)], GETARG_C(i), regs[GETARG_A(i)]);
     2591      int a = GETARG_A(i);
     2592      int b = GETARG_B(i);
     2593      int c = GETARG_C(i);
     2594      mrb_ary_set(mrb, regs[b], c, regs[a]);
    21332595      NEXT;
    21342596    }
     
    21402602      int pre  = GETARG_B(i);
    21412603      int post = GETARG_C(i);
    2142 
    21432604      struct RArray *ary;
    21442605      int len, idx;
     
    21502611      len = ary->len;
    21512612      if (len > pre + post) {
    2152         regs[a++] = mrb_ary_new_from_values(mrb, len - pre - post, ary->ptr+pre);
     2613        v = mrb_ary_new_from_values(mrb, len - pre - post, ary->ptr+pre);
     2614        regs[a++] = v;
    21532615        while (post--) {
    21542616          regs[a++] = ary->ptr[len-post-1];
     
    21562618      }
    21572619      else {
    2158         regs[a++] = mrb_ary_new_capa(mrb, 0);
     2620        v = mrb_ary_new_capa(mrb, 0);
     2621        regs[a++] = v;
    21592622        for (idx=0; idx+pre<len; idx++) {
    21602623          regs[a+idx] = ary->ptr[pre+idx];
     
    21712634    CASE(OP_STRING) {
    21722635      /* A Bx           R(A) := str_new(Lit(Bx)) */
    2173       regs[GETARG_A(i)] = mrb_str_dup(mrb, pool[GETARG_Bx(i)]);
     2636      mrb_value str = mrb_str_dup(mrb, pool[GETARG_Bx(i)]);
     2637      regs[GETARG_A(i)] = str;
    21742638      ARENA_RESTORE(mrb, ai);
    21752639      NEXT;
     
    21792643      /* A B    R(A).concat(R(B)) */
    21802644      mrb_str_concat(mrb, regs[GETARG_A(i)], regs[GETARG_B(i)]);
    2181       regs = mrb->c->stack;
    21822645      NEXT;
    21832646    }
     
    22242687    CASE(OP_CLASS) {
    22252688      /* A B    R(A) := newclass(R(A),Syms(B),R(A+1)) */
    2226       struct RClass *c = 0;
     2689      struct RClass *c = 0, *baseclass;
    22272690      int a = GETARG_A(i);
    22282691      mrb_value base, super;
     
    22322695      super = regs[a+1];
    22332696      if (mrb_nil_p(base)) {
    2234         base = mrb_obj_value(mrb->c->ci->target_class);
     2697        baseclass = mrb->c->ci->proc->target_class;
     2698        if (!baseclass) baseclass = mrb->c->ci->target_class;
     2699
     2700        base = mrb_obj_value(baseclass);
    22352701      }
    22362702      c = mrb_vm_define_class(mrb, base, super, id);
     
    22422708    CASE(OP_MODULE) {
    22432709      /* A B            R(A) := newmodule(R(A),Syms(B)) */
    2244       struct RClass *c = 0;
     2710      struct RClass *c = 0, *baseclass;
    22452711      int a = GETARG_A(i);
    22462712      mrb_value base;
     
    22492715      base = regs[a];
    22502716      if (mrb_nil_p(base)) {
    2251         base = mrb_obj_value(mrb->c->ci->target_class);
     2717        baseclass = mrb->c->ci->proc->target_class;
     2718        if (!baseclass) baseclass = mrb->c->ci->target_class;
     2719
     2720        base = mrb_obj_value(baseclass);
    22522721      }
    22532722      c = mrb_vm_define_module(mrb, base, id);
     
    22632732      mrb_value recv = regs[a];
    22642733      struct RProc *p;
     2734
     2735      /* prepare closure */
     2736      p = mrb_closure_new(mrb, irep->reps[GETARG_Bx(i)]);
     2737      p->c = NULL;
    22652738
    22662739      /* prepare stack */
     
    22762749      mrb->c->stack += a;
    22772750
    2278       p = mrb_proc_new(mrb, irep->reps[GETARG_Bx(i)]);
     2751      /* setup closure */
    22792752      p->target_class = ci->target_class;
    22802753      ci->proc = p;
    22812754
    2282       if (MRB_PROC_CFUNC_P(p)) {
    2283         ci->nregs = 0;
    2284         mrb->c->stack[0] = p->body.func(mrb, recv);
    2285         mrb_gc_arena_restore(mrb, ai);
    2286         if (mrb->exc) goto L_RAISE;
    2287         /* pop stackpos */
    2288         regs = mrb->c->stack = mrb->c->ci->stackent;
    2289         cipop(mrb);
    2290         NEXT;
    2291       }
    2292       else {
    2293         irep = p->body.irep;
    2294         pool = irep->pool;
    2295         syms = irep->syms;
    2296         stack_extend(mrb, irep->nregs, 1);
    2297         ci->nregs = irep->nregs;
    2298         regs = mrb->c->stack;
    2299         pc = irep->iseq;
    2300         JUMP;
    2301       }
     2755      irep = p->body.irep;
     2756      pool = irep->pool;
     2757      syms = irep->syms;
     2758      stack_extend(mrb, irep->nregs);
     2759      stack_clear(regs+1, irep->nregs-1);
     2760      ci->nregs = irep->nregs;
     2761      pc = irep->iseq;
     2762      JUMP;
    23022763    }
    23032764
     
    23242785      if (!mrb->c->ci->target_class) {
    23252786        mrb_value exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, "no target class or module");
    2326         mrb->exc = mrb_obj_ptr(exc);
     2787        mrb_exc_set(mrb, exc);
    23272788        goto L_RAISE;
    23282789      }
     
    23342795      /* A B C  R(A) := range_new(R(B),R(B+1),C) */
    23352796      int b = GETARG_B(i);
    2336       regs[GETARG_A(i)] = mrb_range_new(mrb, regs[b], regs[b+1], GETARG_C(i));
     2797      mrb_value val = mrb_range_new(mrb, regs[b], regs[b+1], GETARG_C(i));
     2798      regs[GETARG_A(i)] = val;
    23372799      ARENA_RESTORE(mrb, ai);
    23382800      NEXT;
     
    23572819    L_STOP:
    23582820      {
    2359         int eidx_stop = mrb->c->ci == mrb->c->cibase ? 0 : mrb->c->ci[-1].eidx;
    2360         int eidx = mrb->c->ci->eidx;
    2361         while (eidx > eidx_stop) {
    2362           ecall(mrb, --eidx);
     2821        int epos = mrb->c->ci->epos;
     2822
     2823        while (mrb->c->eidx > epos) {
     2824          ecall(mrb, --mrb->c->eidx);
    23632825        }
    23642826      }
     
    23822844        exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg);
    23832845      }
    2384       mrb->exc = mrb_obj_ptr(exc);
     2846      mrb_exc_set(mrb, exc);
    23852847      goto L_RAISE;
    23862848    }
    23872849  }
    23882850  END_DISPATCH;
     2851#undef regs
    23892852
    23902853  }
     
    23992862mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
    24002863{
    2401   return mrb_context_run(mrb, proc, self, mrb->c->ci->argc + 2); /* argc + 2 (receiver and block) */
     2864  if (mrb->c->ci->argc < 0) {
     2865    return mrb_vm_run(mrb, proc, self, 3); /* receiver, args and block) */
     2866  }
     2867  else {
     2868    return mrb_vm_run(mrb, proc, self, mrb->c->ci->argc + 2); /* argc + 2 (receiver and block) */
     2869  }
    24022870}
    24032871
    24042872MRB_API mrb_value
    2405 mrb_toplevel_run_keep(mrb_state *mrb, struct RProc *proc, unsigned int stack_keep)
     2873mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep)
    24062874{
    24072875  mrb_callinfo *ci;
    24082876  mrb_value v;
    24092877
    2410   if (!mrb->c->cibase || mrb->c->ci == mrb->c->cibase) {
    2411     return mrb_context_run(mrb, proc, mrb_top_self(mrb), stack_keep);
     2878  if (!mrb->c->cibase) {
     2879    return mrb_vm_run(mrb, proc, self, stack_keep);
     2880  }
     2881  if (mrb->c->ci == mrb->c->cibase) {
     2882    mrb->c->ci->env = NULL;
     2883    return mrb_vm_run(mrb, proc, self, stack_keep);
    24122884  }
    24132885  ci = cipush(mrb);
     2886  ci->mid = 0;
    24142887  ci->nregs = 1;   /* protect the receiver */
    24152888  ci->acc = CI_ACC_SKIP;
    24162889  ci->target_class = mrb->object_class;
    2417   v = mrb_context_run(mrb, proc, mrb_top_self(mrb), stack_keep);
     2890  v = mrb_vm_run(mrb, proc, self, stack_keep);
    24182891  cipop(mrb);
    24192892
     
    24212894}
    24222895
    2423 MRB_API mrb_value
    2424 mrb_toplevel_run(mrb_state *mrb, struct RProc *proc)
    2425 {
    2426   return mrb_toplevel_run_keep(mrb, proc, 0);
    2427 }
     2896#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus)
     2897# if !defined(MRB_ENABLE_CXX_ABI)
     2898} /* end of extern "C" */
     2899# endif
     2900mrb_int mrb_jmpbuf::jmpbuf_id = 0;
     2901# if !defined(MRB_ENABLE_CXX_ABI)
     2902extern "C" {
     2903# endif
     2904#endif
Note: See TracChangeset for help on using the changeset viewer.