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/mrbgems/mruby-compiler/core/codegen.c

    r331 r439  
    99#include <stdlib.h>
    1010#include <string.h>
     11#include <math.h>
    1112#include <mruby.h>
    1213#include <mruby/compile.h>
     
    2425#endif
    2526
     27#define MAXARG_S (1<<16)
     28
    2629typedef mrb_ast_node node;
    2730typedef struct mrb_parser_state parser_state;
     
    3740struct loopinfo {
    3841  enum looptype type;
    39   int pc1, pc2, pc3, acc;
     42  int pc0, pc1, pc2, pc3, acc;
    4043  int ensure_level;
    4144  struct loopinfo *prev;
     
    5154  node *lv;
    5255
    53   int sp;
    54   int pc;
    55   int lastlabel;
     56  uint16_t sp;
     57  uint16_t pc;
     58  uint16_t lastpc;
     59  uint16_t lastlabel;
    5660  int ainfo:15;
    5761  mrb_bool mscope:1;
     
    5963  struct loopinfo *loop;
    6064  int ensure_level;
    61   char const *filename;
     65  mrb_sym filename_sym;
    6266  uint16_t lineno;
    6367
    6468  mrb_code *iseq;
    6569  uint16_t *lines;
    66   int icapa;
     70  uint32_t icapa;
    6771
    6872  mrb_irep *irep;
    69   size_t pcapa;
    70   size_t scapa;
    71   size_t rcapa;
     73  uint32_t pcapa, scapa, rcapa;
    7274
    7375  uint16_t nlocals;
     
    101103    codegen_scope *tmp = s->prev;
    102104    mrb_free(s->mrb, s->iseq);
     105    mrb_free(s->mrb, s->lines);
    103106    mrb_pool_close(s->mpool);
    104107    s = tmp;
    105108  }
    106109#ifndef MRB_DISABLE_STDIO
    107   if (s->filename && s->lineno) {
    108     fprintf(stderr, "codegen error:%s:%d: %s\n", s->filename, s->lineno, message);
     110  if (s->filename_sym && s->lineno) {
     111    const char *filename = mrb_sym_name_len(s->mrb, s->filename_sym, NULL);
     112    fprintf(stderr, "codegen error:%s:%d: %s\n", filename, s->lineno, message);
    109113  }
    110114  else {
     
    125129
    126130static void*
    127 codegen_malloc(codegen_scope *s, size_t len)
    128 {
    129   void *p = mrb_malloc_simple(s->mrb, len);
    130 
    131   if (!p) codegen_error(s, "mrb_malloc");
    132   return p;
    133 }
    134 
    135 static void*
    136131codegen_realloc(codegen_scope *s, void *p, size_t len)
    137132{
     
    145140new_label(codegen_scope *s)
    146141{
    147   s->lastlabel = s->pc;
    148   return s->pc;
    149 }
    150 
    151 static inline int
    152 genop(codegen_scope *s, mrb_code i)
    153 {
    154   if (s->pc == s->icapa) {
     142  return s->lastlabel = s->pc;
     143}
     144
     145static void
     146emit_B(codegen_scope *s, uint32_t pc, uint8_t i)
     147{
     148  if (pc >= MAXARG_S || s->icapa >= MAXARG_S) {
     149    codegen_error(s, "too big code block");
     150  }
     151  if (pc >= s->icapa) {
    155152    s->icapa *= 2;
     153    if (s->icapa > MAXARG_S) {
     154      s->icapa = MAXARG_S;
     155    }
    156156    s->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->icapa);
    157157    if (s->lines) {
    158       s->lines = (uint16_t*)codegen_realloc(s, s->lines, sizeof(short)*s->icapa);
    159       s->irep->lines = s->lines;
    160     }
    161   }
    162   s->iseq[s->pc] = i;
     158      s->lines = (uint16_t*)codegen_realloc(s, s->lines, sizeof(uint16_t)*s->icapa);
     159    }
     160  }
    163161  if (s->lines) {
    164     s->lines[s->pc] = s->lineno;
    165   }
    166   return s->pc++;
     162    if (s->lineno > 0 || pc == 0)
     163      s->lines[pc] = s->lineno;
     164    else
     165      s->lines[pc] = s->lines[pc-1];
     166  }
     167  s->iseq[pc] = i;
     168}
     169
     170static void
     171emit_S(codegen_scope *s, int pc, uint16_t i)
     172{
     173  uint8_t hi = i>>8;
     174  uint8_t lo = i&0xff;
     175
     176  emit_B(s, pc,   hi);
     177  emit_B(s, pc+1, lo);
     178}
     179
     180static void
     181gen_B(codegen_scope *s, uint8_t i)
     182{
     183  emit_B(s, s->pc, i);
     184  s->pc++;
     185}
     186
     187static void
     188gen_S(codegen_scope *s, uint16_t i)
     189{
     190  emit_S(s, s->pc, i);
     191  s->pc += 2;
     192}
     193
     194static void
     195genop_0(codegen_scope *s, mrb_code i)
     196{
     197  s->lastpc = s->pc;
     198  gen_B(s, i);
     199}
     200
     201static void
     202genop_1(codegen_scope *s, mrb_code i, uint16_t a)
     203{
     204  s->lastpc = s->pc;
     205  if (a > 0xff) {
     206    gen_B(s, OP_EXT1);
     207    gen_B(s, i);
     208    gen_S(s, a);
     209  }
     210  else {
     211    gen_B(s, i);
     212    gen_B(s, (uint8_t)a);
     213  }
     214}
     215
     216static void
     217genop_2(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b)
     218{
     219  s->lastpc = s->pc;
     220  if (a > 0xff && b > 0xff) {
     221    gen_B(s, OP_EXT3);
     222    gen_B(s, i);
     223    gen_S(s, a);
     224    gen_S(s, b);
     225  }
     226  else if (b > 0xff) {
     227    gen_B(s, OP_EXT2);
     228    gen_B(s, i);
     229    gen_B(s, (uint8_t)a);
     230    gen_S(s, b);
     231  }
     232  else if (a > 0xff) {
     233    gen_B(s, OP_EXT1);
     234    gen_B(s, i);
     235    gen_S(s, a);
     236    gen_B(s, (uint8_t)b);
     237  }
     238  else {
     239    gen_B(s, i);
     240    gen_B(s, (uint8_t)a);
     241    gen_B(s, (uint8_t)b);
     242  }
     243}
     244
     245static void
     246genop_3(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b, uint8_t c)
     247{
     248  genop_2(s, i, a, b);
     249  gen_B(s, c);
     250}
     251
     252static void
     253genop_2S(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b)
     254{
     255  genop_1(s, i, a);
     256  gen_S(s, b);
     257}
     258
     259static void
     260genop_W(codegen_scope *s, mrb_code i, uint32_t a)
     261{
     262  uint8_t a1 = (a>>16) & 0xff;
     263  uint8_t a2 = (a>>8) & 0xff;
     264  uint8_t a3 = a & 0xff;
     265
     266  s->lastpc = s->pc;
     267  gen_B(s, i);
     268  gen_B(s, a1);
     269  gen_B(s, a2);
     270  gen_B(s, a3);
    167271}
    168272
     
    178282}
    179283
    180 static int
    181 genop_peep(codegen_scope *s, mrb_code i, int val)
    182 {
    183   /* peephole optimization */
    184   if (!no_optimize(s) && s->lastlabel != s->pc && s->pc > 0) {
    185     mrb_code i0 = s->iseq[s->pc-1];
    186     int c1 = GET_OPCODE(i);
    187     int c0 = GET_OPCODE(i0);
    188 
    189     switch (c1) {
     284static
     285mrb_bool
     286on_eval(codegen_scope *s)
     287{
     288  if (s && s->parser && s->parser->on_eval)
     289    return TRUE;
     290  return FALSE;
     291}
     292
     293struct mrb_insn_data
     294mrb_decode_insn(const mrb_code *pc)
     295{
     296  struct mrb_insn_data data = { 0 };
     297  mrb_code insn = READ_B();
     298  uint16_t a = 0;
     299  uint16_t b = 0;
     300  uint8_t  c = 0;
     301
     302  switch (insn) {
     303#define FETCH_Z() /* empty */
     304#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x (); break;
     305#include "mruby/ops.h"
     306#undef OPCODE
     307  }
     308  switch (insn) {
     309  case OP_EXT1:
     310    insn = READ_B();
     311    switch (insn) {
     312#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _1 (); break;
     313#include "mruby/ops.h"
     314#undef OPCODE
     315    }
     316    break;
     317  case OP_EXT2:
     318    insn = READ_B();
     319    switch (insn) {
     320#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _2 (); break;
     321#include "mruby/ops.h"
     322#undef OPCODE
     323    }
     324    break;
     325  case OP_EXT3:
     326    insn = READ_B();
     327    switch (insn) {
     328#define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _3 (); break;
     329#include "mruby/ops.h"
     330#undef OPCODE
     331    }
     332    break;
     333  default:
     334    break;
     335  }
     336  data.insn = insn;
     337  data.a = a;
     338  data.b = b;
     339  data.c = c;
     340  return data;
     341}
     342
     343static struct mrb_insn_data
     344mrb_last_insn(codegen_scope *s)
     345{
     346  if (s->pc == s->lastpc) {
     347    struct mrb_insn_data data;
     348
     349    data.insn = OP_NOP;
     350    return data;
     351  }
     352  return mrb_decode_insn(&s->iseq[s->lastpc]);
     353}
     354
     355static mrb_bool
     356no_peephole(codegen_scope *s)
     357{
     358  return no_optimize(s) || s->lastlabel == s->pc || s->pc == 0 || s->pc == s->lastpc;
     359}
     360
     361static uint16_t
     362genjmp(codegen_scope *s, mrb_code i, uint16_t pc)
     363{
     364  uint16_t pos;
     365
     366  s->lastpc = s->pc;
     367  gen_B(s, i);
     368  pos = s->pc;
     369  gen_S(s, pc);
     370  return pos;
     371}
     372
     373static uint16_t
     374genjmp2(codegen_scope *s, mrb_code i, uint16_t a, int pc, int val)
     375{
     376  uint16_t pos;
     377
     378  if (!no_peephole(s) && !val) {
     379    struct mrb_insn_data data = mrb_last_insn(s);
     380
     381    if (data.insn == OP_MOVE && data.a == a) {
     382      s->pc = s->lastpc;
     383      a = data.b;
     384    }
     385  }
     386
     387  s->lastpc = s->pc;
     388  if (a > 0xff) {
     389    gen_B(s, OP_EXT1);
     390    gen_B(s, i);
     391    gen_S(s, a);
     392    pos = s->pc;
     393    gen_S(s, pc);
     394  }
     395  else {
     396    gen_B(s, i);
     397    gen_B(s, (uint8_t)a);
     398    pos = s->pc;
     399    gen_S(s, pc);
     400  }
     401  return pos;
     402}
     403
     404static void
     405gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep)
     406{
     407  if (no_peephole(s)) {
     408  normal:
     409    genop_2(s, OP_MOVE, dst, src);
     410    if (on_eval(s)) {
     411      genop_0(s, OP_NOP);
     412    }
     413    return;
     414  }
     415  else {
     416    struct mrb_insn_data data = mrb_last_insn(s);
     417
     418    switch (data.insn) {
    190419    case OP_MOVE:
    191       if (GETARG_A(i) == GETARG_B(i)) {
    192         /* skip useless OP_MOVE */
    193         return 0;
    194       }
    195       if (val) break;
    196       switch (c0) {
    197       case OP_MOVE:
    198         if (GETARG_A(i) == GETARG_A(i0)) {
    199           /* skip overriden OP_MOVE */
    200           s->pc--;
    201           s->iseq[s->pc] = i;
    202         }
    203         if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i) == GETARG_B(i0)) {
    204           /* skip swapping OP_MOVE */
    205           return 0;
    206         }
    207         if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
    208           s->pc--;
    209           return genop_peep(s, MKOP_AB(OP_MOVE, GETARG_A(i), GETARG_B(i0)), val);
    210         }
    211         break;
    212       case OP_LOADI:
    213         if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
    214           s->iseq[s->pc-1] = MKOP_AsBx(OP_LOADI, GETARG_A(i), GETARG_sBx(i0));
    215           return 0;
    216         }
    217         break;
    218       case OP_ARRAY:
    219       case OP_HASH:
    220       case OP_RANGE:
    221       case OP_AREF:
    222       case OP_GETUPVAR:
    223         if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
    224           s->iseq[s->pc-1] = MKOP_ABC(c0, GETARG_A(i), GETARG_B(i0), GETARG_C(i0));
    225           return 0;
    226         }
    227         break;
    228       case OP_LOADSYM:
    229       case OP_GETGLOBAL:
    230       case OP_GETIV:
    231       case OP_GETCV:
    232       case OP_GETCONST:
    233       case OP_GETSPECIAL:
    234       case OP_LOADL:
    235       case OP_STRING:
    236         if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
    237           s->iseq[s->pc-1] = MKOP_ABx(c0, GETARG_A(i), GETARG_Bx(i0));
    238           return 0;
    239         }
    240         break;
    241       case OP_SCLASS:
    242         if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
    243           s->iseq[s->pc-1] = MKOP_AB(c0, GETARG_A(i), GETARG_B(i0));
    244           return 0;
    245         }
    246         break;
    247       case OP_LOADNIL:
    248       case OP_LOADSELF:
    249       case OP_LOADT:
    250       case OP_LOADF:
    251       case OP_OCLASS:
    252         if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
    253           s->iseq[s->pc-1] = MKOP_A(c0, GETARG_A(i));
    254           return 0;
    255         }
    256         break;
    257       default:
    258         break;
    259       }
     420      if (dst == src) return;             /* remove useless MOVE */
     421      if (data.b == dst && data.a == src) /* skip swapping MOVE */
     422        return;
     423      goto normal;
     424    case OP_LOADNIL: case OP_LOADSELF: case OP_LOADT: case OP_LOADF:
     425    case OP_LOADI__1:
     426    case OP_LOADI_0: case OP_LOADI_1: case OP_LOADI_2: case OP_LOADI_3:
     427    case OP_LOADI_4: case OP_LOADI_5: case OP_LOADI_6: case OP_LOADI_7:
     428      if (nopeep || data.a != src || data.a < s->nlocals) goto normal;
     429      s->pc = s->lastpc;
     430      genop_1(s, data.insn, dst);
    260431      break;
    261     case OP_SETIV:
    262     case OP_SETCV:
    263     case OP_SETCONST:
    264     case OP_SETMCNST:
    265     case OP_SETGLOBAL:
    266       if (val) break;
    267       if (c0 == OP_MOVE) {
    268         if (GETARG_A(i) == GETARG_A(i0)) {
    269           s->iseq[s->pc-1] = MKOP_ABx(c1, GETARG_B(i0), GETARG_Bx(i));
    270           return 0;
    271         }
    272       }
    273       break;
    274     case OP_SETUPVAR:
    275       if (val) break;
    276       if (c0 == OP_MOVE) {
    277         if (GETARG_A(i) == GETARG_A(i0)) {
    278           s->iseq[s->pc-1] = MKOP_ABC(c1, GETARG_B(i0), GETARG_B(i), GETARG_C(i));
    279           return 0;
    280         }
    281       }
    282       break;
    283     case OP_EPOP:
    284       if (c0 == OP_EPOP) {
    285         s->iseq[s->pc-1] = MKOP_A(OP_EPOP, GETARG_A(i0)+GETARG_A(i));
    286         return 0;
    287       }
    288       break;
    289     case OP_POPERR:
    290       if (c0 == OP_POPERR) {
    291         s->iseq[s->pc-1] = MKOP_A(OP_POPERR, GETARG_A(i0)+GETARG_A(i));
    292         return 0;
    293       }
    294       break;
    295     case OP_RETURN:
    296       switch (c0) {
    297       case OP_RETURN:
    298         return 0;
    299       case OP_MOVE:
    300         if (GETARG_A(i0) >= s->nlocals) {
    301           s->iseq[s->pc-1] = MKOP_AB(OP_RETURN, GETARG_B(i0), OP_R_NORMAL);
    302           return 0;
    303         }
    304         break;
    305       case OP_SETIV:
    306       case OP_SETCV:
    307       case OP_SETCONST:
    308       case OP_SETMCNST:
    309       case OP_SETUPVAR:
    310       case OP_SETGLOBAL:
    311         s->pc--;
    312         genop_peep(s, i0, NOVAL);
    313         i0 = s->iseq[s->pc-1];
    314         return genop(s, MKOP_AB(OP_RETURN, GETARG_A(i0), OP_R_NORMAL));
    315 #if 0
    316       case OP_SEND:
    317         if (GETARG_B(i) == OP_R_NORMAL && GETARG_A(i) == GETARG_A(i0)) {
    318           s->iseq[s->pc-1] = MKOP_ABC(OP_TAILCALL, GETARG_A(i0), GETARG_B(i0), GETARG_C(i0));
    319           return;
    320         }
    321         break;
    322 #endif
    323       default:
    324         break;
    325       }
    326       break;
    327     case OP_ADD:
    328     case OP_SUB:
    329       if (c0 == OP_LOADI) {
    330         int c = GETARG_sBx(i0);
    331 
    332         if (c1 == OP_SUB) c = -c;
    333         if (c > 127 || c < -127) break;
    334         if (0 <= c)
    335           s->iseq[s->pc-1] = MKOP_ABC(OP_ADDI, GETARG_A(i), GETARG_B(i), c);
    336         else
    337           s->iseq[s->pc-1] = MKOP_ABC(OP_SUBI, GETARG_A(i), GETARG_B(i), -c);
    338         return 0;
    339       }
    340     case OP_STRCAT:
    341       if (c0 == OP_STRING) {
    342         mrb_value v = s->irep->pool[GETARG_Bx(i0)];
    343 
    344         if (mrb_string_p(v) && RSTRING_LEN(v) == 0) {
    345           s->pc--;
    346           return 0;
    347         }
    348       }
    349       if (c0 == OP_LOADNIL) {
    350         if (GETARG_B(i) == GETARG_A(i0)) {
    351           s->pc--;
    352           return 0;
    353         }
    354       }
    355       break;
    356     case OP_JMPIF:
    357     case OP_JMPNOT:
    358       if (c0 == OP_MOVE && GETARG_A(i) == GETARG_A(i0)) {
    359         s->iseq[s->pc-1] = MKOP_AsBx(c1, GETARG_B(i0), GETARG_sBx(i));
    360         return s->pc-1;
    361       }
     432    case OP_LOADI: case OP_LOADINEG: case OP_LOADL: case OP_LOADSYM:
     433    case OP_GETGV: case OP_GETSV: case OP_GETIV: case OP_GETCV:
     434    case OP_GETCONST: case OP_STRING:
     435    case OP_LAMBDA: case OP_BLOCK: case OP_METHOD: case OP_BLKPUSH:
     436      if (nopeep || data.a != src || data.a < s->nlocals) goto normal;
     437      s->pc = s->lastpc;
     438      genop_2(s, data.insn, dst, data.b);
    362439      break;
    363440    default:
     441      goto normal;
     442    }
     443  }
     444}
     445
     446static void
     447gen_return(codegen_scope *s, uint8_t op, uint16_t src)
     448{
     449  if (no_peephole(s)) {
     450    genop_1(s, op, src);
     451  }
     452  else {
     453    struct mrb_insn_data data = mrb_last_insn(s);
     454
     455    if (data.insn == OP_MOVE && src == data.a) {
     456      s->pc = s->lastpc;
     457      genop_1(s, op, data.b);
     458    }
     459    else if (data.insn != OP_RETURN) {
     460      genop_1(s, op, src);
     461    }
     462  }
     463}
     464
     465static void
     466gen_addsub(codegen_scope *s, uint8_t op, uint16_t dst)
     467{
     468  if (no_peephole(s)) {
     469  normal:
     470    genop_1(s, op, dst);
     471    return;
     472  }
     473  else {
     474    struct mrb_insn_data data = mrb_last_insn(s);
     475
     476    switch (data.insn) {
     477    case OP_LOADI__1:
     478      if (op == OP_ADD) op = OP_SUB;
     479      else op = OP_ADD;
     480      data.b = 1;
     481      goto replace;
     482    case OP_LOADI_0: case OP_LOADI_1: case OP_LOADI_2: case OP_LOADI_3:
     483    case OP_LOADI_4: case OP_LOADI_5: case OP_LOADI_6: case OP_LOADI_7:
     484      data.b = data.insn - OP_LOADI_0;
     485      /* fall through */
     486    case OP_LOADI:
     487    replace:
     488      if (data.b >= 128) goto normal;
     489      s->pc = s->lastpc;
     490      if (op == OP_ADD) {
     491        genop_2(s, OP_ADDI, dst, (uint8_t)data.b);
     492      }
     493      else {
     494        genop_2(s, OP_SUBI, dst, (uint8_t)data.b);
     495      }
    364496      break;
    365     }
    366   }
    367   return genop(s, i);
     497    default:
     498      goto normal;
     499    }
     500  }
     501}
     502
     503static int
     504dispatch(codegen_scope *s, uint16_t pos0)
     505{
     506  uint16_t newpos;
     507
     508  s->lastlabel = s->pc;
     509  newpos = PEEK_S(s->iseq+pos0);
     510  emit_S(s, pos0, s->pc);
     511  return newpos;
    368512}
    369513
    370514static void
    371 scope_error(codegen_scope *s)
    372 {
    373   exit(EXIT_FAILURE);
    374 }
    375 
    376 static inline void
    377 dispatch(codegen_scope *s, int pc)
    378 {
    379   int diff = s->pc - pc;
    380   mrb_code i = s->iseq[pc];
    381   int c = GET_OPCODE(i);
    382 
    383   s->lastlabel = s->pc;
    384   switch (c) {
    385   case OP_JMP:
    386   case OP_JMPIF:
    387   case OP_JMPNOT:
    388   case OP_ONERR:
    389     break;
    390   default:
    391 #ifndef MRB_DISABLE_STDIO
    392     fprintf(stderr, "bug: dispatch on non JMP op\n");
    393 #endif
    394     scope_error(s);
    395     break;
    396   }
    397   if (diff > MAXARG_sBx) {
    398     codegen_error(s, "too distant jump address");
    399   }
    400   s->iseq[pc] = MKOP_AsBx(c, GETARG_A(i), diff);
    401 }
    402 
    403 static void
    404 dispatch_linked(codegen_scope *s, int pc)
    405 {
    406   mrb_code i;
    407   int pos;
    408 
    409   if (!pc) return;
     515dispatch_linked(codegen_scope *s, uint16_t pos)
     516{
     517  if (pos==0) return;
    410518  for (;;) {
    411     i = s->iseq[pc];
    412     pos = GETARG_sBx(i);
    413     dispatch(s, pc);
    414     if (!pos) break;
    415     pc = pos;
     519    pos = dispatch(s, pos);
     520    if (pos==0) break;
    416521  }
    417522}
     
    419524#define nregs_update do {if (s->sp > s->nregs) s->nregs = s->sp;} while (0)
    420525static void
    421 push_(codegen_scope *s)
    422 {
    423   if (s->sp > 511) {
    424     codegen_error(s, "too complex expression");
    425   }
    426   s->sp++;
    427   nregs_update;
    428 }
    429 
    430 static void
    431 push_n_(codegen_scope *s, size_t n)
    432 {
    433   if (s->sp+n > 511) {
     526push_n_(codegen_scope *s, int n)
     527{
     528  if (s->sp+n >= 0xffff) {
    434529    codegen_error(s, "too complex expression");
    435530  }
     
    438533}
    439534
    440 #define push() push_(s)
     535static void
     536pop_n_(codegen_scope *s, int n)
     537{
     538  if ((int)s->sp-n < 0) {
     539    codegen_error(s, "stack pointer underflow");
     540  }
     541  s->sp-=n;
     542}
     543
     544#define push() push_n_(s,1)
    441545#define push_n(n) push_n_(s,n)
    442 #define pop_(s) ((s)->sp--)
    443 #define pop() pop_(s)
    444 #define pop_n(n) (s->sp-=(n))
     546#define pop() pop_n_(s,1)
     547#define pop_n(n) pop_n_(s,n)
    445548#define cursp() (s->sp)
    446549
     
    448551new_lit(codegen_scope *s, mrb_value val)
    449552{
    450   size_t i;
     553  int i;
    451554  mrb_value *pv;
    452555
     
    457560      pv = &s->irep->pool[i];
    458561
    459       if (mrb_type(*pv) != MRB_TT_STRING) continue;
     562      if (!mrb_string_p(*pv)) continue;
    460563      if ((len = RSTRING_LEN(*pv)) != RSTRING_LEN(val)) continue;
    461564      if (memcmp(RSTRING_PTR(*pv), RSTRING_PTR(val), len) == 0)
     
    463566    }
    464567    break;
     568#ifndef MRB_WITHOUT_FLOAT
    465569  case MRB_TT_FLOAT:
    466570    for (i=0; i<s->irep->plen; i++) {
     571      mrb_float f1, f2;
    467572      pv = &s->irep->pool[i];
    468       if (mrb_type(*pv) != MRB_TT_FLOAT) continue;
    469       if (mrb_float(*pv) == mrb_float(val)) return i;
    470     }
    471     break;
     573      if (!mrb_float_p(*pv)) continue;
     574      f1 = mrb_float(*pv);
     575      f2 = mrb_float(val);
     576      if (f1 == f2 && !signbit(f1) == !signbit(f2)) return i;
     577    }
     578    break;
     579#endif
    472580  case MRB_TT_FIXNUM:
    473581    for (i=0; i<s->irep->plen; i++) {
     
    492600  switch (mrb_type(val)) {
    493601  case MRB_TT_STRING:
    494     *pv = mrb_str_pool(s->mrb, val);
    495     break;
    496 
     602    *pv = mrb_str_pool(s->mrb, RSTRING_PTR(val), RSTRING_LEN(val), RSTR_NOFREE_P(RSTRING(val)));
     603    break;
     604
     605#ifndef MRB_WITHOUT_FLOAT
    497606  case MRB_TT_FLOAT:
    498607#ifdef MRB_WORD_BOXING
     
    500609    break;
    501610#endif
     611#endif
    502612  case MRB_TT_FIXNUM:
    503613    *pv = val;
     
    511621}
    512622
    513 /* method symbols should be fit in 9 bits */
    514 #define MAXMSYMLEN 512
    515623/* maximum symbol numbers */
    516 #define MAXSYMLEN 65536
     624#define MAXSYMLEN 0x10000
    517625
    518626static int
    519 new_msym(codegen_scope *s, mrb_sym sym)
    520 {
    521   size_t i, len;
     627new_sym(codegen_scope *s, mrb_sym sym)
     628{
     629  int i, len;
    522630
    523631  mrb_assert(s->irep);
    524632
    525633  len = s->irep->slen;
    526   if (len > MAXMSYMLEN) len = MAXMSYMLEN;
    527634  for (i=0; i<len; i++) {
    528635    if (s->irep->syms[i] == sym) return i;
    529     if (s->irep->syms[i] == 0) break;
    530   }
    531   if (i == MAXMSYMLEN) {
    532     codegen_error(s, "too many symbols (max " MRB_STRINGIZE(MAXMSYMLEN) ")");
    533   }
    534   s->irep->syms[i] = sym;
    535   if (i == s->irep->slen) s->irep->slen++;
    536   return i;
    537 }
    538 
    539 static int
    540 new_sym(codegen_scope *s, mrb_sym sym)
    541 {
    542   size_t i;
    543 
    544   for (i=0; i<s->irep->slen; i++) {
    545     if (s->irep->syms[i] == sym) return i;
    546   }
    547   if (s->irep->slen == MAXSYMLEN) {
    548     codegen_error(s, "too many symbols (max " MRB_STRINGIZE(MAXSYMLEN) ")");
    549   }
    550 
    551   if (s->irep->slen > MAXMSYMLEN/2 && s->scapa == MAXMSYMLEN) {
    552     s->scapa = MAXSYMLEN;
    553     s->irep->syms = (mrb_sym *)codegen_realloc(s, s->irep->syms, sizeof(mrb_sym)*MAXSYMLEN);
    554     for (i = s->irep->slen; i < MAXMSYMLEN; i++) {
    555       static const mrb_sym mrb_sym_zero = { 0 };
    556       s->irep->syms[i] = mrb_sym_zero;
    557     }
    558     s->irep->slen = MAXMSYMLEN;
     636  }
     637  if (s->irep->slen >= s->scapa) {
     638    s->scapa *= 2;
     639    s->irep->syms = (mrb_sym*)codegen_realloc(s, s->irep->syms, sizeof(mrb_sym)*s->scapa);
    559640  }
    560641  s->irep->syms[s->irep->slen] = sym;
     
    574655}
    575656
    576 #define sym(x) ((mrb_sym)(intptr_t)(x))
    577 #define lv_name(lv) sym((lv)->car)
     657#define nint(x) ((int)(intptr_t)(x))
     658#define nchar(x) ((char)(intptr_t)(x))
     659#define nsym(x) ((mrb_sym)(intptr_t)(x))
     660
     661#define lv_name(lv) nsym((lv)->car)
     662
    578663static int
    579664lv_idx(codegen_scope *s, mrb_sym id)
     
    597682  struct loopinfo *lp;
    598683  node *n2;
    599   mrb_code c;
    600684
    601685  /* generate receiver */
     
    603687  /* generate loop-block */
    604688  s = scope_new(s->mrb, s, NULL);
    605   if (s == NULL) {
    606     raise_error(prev, "unexpected scope");
    607   }
    608689
    609690  push();                       /* push for a block parameter */
     
    611692  /* generate loop variable */
    612693  n2 = tree->car;
    613   genop(s, MKOP_Ax(OP_ENTER, 0x40000));
     694  genop_W(s, OP_ENTER, 0x40000);
    614695  if (n2->car && !n2->car->cdr && !n2->cdr) {
    615696    gen_assignment(s, n2->car->car, 1, NOVAL);
     
    625706  codegen(s, tree->cdr->cdr->car, VAL);
    626707  pop();
    627   if (s->pc > 0) {
    628     c = s->iseq[s->pc-1];
    629     if (GET_OPCODE(c) != OP_RETURN || GETARG_B(c) != OP_R_NORMAL || s->pc == s->lastlabel)
    630       genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
    631   }
     708  gen_return(s, OP_RETURN, cursp());
    632709  loop_pop(s, NOVAL);
    633710  scope_finish(s);
    634711  s = prev;
    635   genop(s, MKOP_Abc(OP_LAMBDA, cursp(), s->irep->rlen-1, OP_L_BLOCK));
     712  genop_2(s, OP_BLOCK, cursp(), s->irep->rlen-1);
     713  push();pop(); /* space for a block */
    636714  pop();
    637   idx = new_msym(s, mrb_intern_lit(s->mrb, "each"));
    638   genop(s, MKOP_ABC(OP_SENDB, cursp(), idx, 0));
     715  idx = new_sym(s, mrb_intern_lit(s->mrb, "each"));
     716  genop_3(s, OP_SENDB, cursp(), idx, 0);
    639717}
    640718
     
    642720lambda_body(codegen_scope *s, node *tree, int blk)
    643721{
    644   mrb_code c;
    645722  codegen_scope *parent = s;
    646723  s = scope_new(s->mrb, s, tree->car);
    647   if (s == NULL) {
    648     raise_error(parent, "unexpected scope");
    649   }
    650724
    651725  s->mscope = !blk;
     
    653727  if (blk) {
    654728    struct loopinfo *lp = loop_push(s, LOOP_BLOCK);
    655     lp->pc1 = new_label(s);
     729    lp->pc0 = new_label(s);
    656730  }
    657731  tree = tree->cdr;
    658   if (tree->car) {
     732  if (tree->car == NULL) {
     733    genop_W(s, OP_ENTER, 0);
     734  }
     735  else {
    659736    mrb_aspec a;
    660737    int ma, oa, ra, pa, ka, kd, ba;
    661738    int pos, i;
    662     node *n, *opt;
    663 
     739    node *opt;
     740    node *margs, *pargs;
     741    node *tail;
     742
     743    /* mandatory arguments */
    664744    ma = node_len(tree->car->car);
    665     n = tree->car->car;
    666     while (n) {
    667       n = n->cdr;
    668     }
     745    margs = tree->car->car;
     746    tail = tree->car->cdr->cdr->cdr->cdr;
     747
     748    /* optional arguments */
    669749    oa = node_len(tree->car->cdr->car);
     750    /* rest argument? */
    670751    ra = tree->car->cdr->cdr->car ? 1 : 0;
     752    /* mandatory arugments after rest argument */
    671753    pa = node_len(tree->car->cdr->cdr->cdr->car);
    672     ka = kd = 0;
    673     ba = tree->car->cdr->cdr->cdr->cdr ? 1 : 0;
     754    pargs = tree->car->cdr->cdr->cdr->car;
     755    /* keyword arguments */
     756    ka = tail? node_len(tail->cdr->car) : 0;
     757    /* keyword dictionary? */
     758    kd = tail && tail->cdr->cdr->car? 1 : 0;
     759    /* block argument? */
     760    ba = tail && tail->cdr->cdr->cdr->car ? 1 : 0;
    674761
    675762    if (ma > 0x1f || oa > 0x1f || pa > 0x1f || ka > 0x1f) {
    676763      codegen_error(s, "too many formal arguments");
    677764    }
    678     a = ((mrb_aspec)(ma & 0x1f) << 18)
    679       | ((mrb_aspec)(oa & 0x1f) << 13)
    680       | ((ra & 1) << 12)
    681       | ((pa & 0x1f) << 7)
    682       | ((ka & 0x1f) << 2)
    683       | ((kd & 1)<< 1)
    684       | (ba & 1);
    685     s->ainfo = (((ma+oa) & 0x3f) << 6) /* (12bits = 6:1:5) */
    686       | ((ra & 1) << 5)
    687       | (pa & 0x1f);
    688     genop(s, MKOP_Ax(OP_ENTER, a));
     765    a = MRB_ARGS_REQ(ma)
     766      | MRB_ARGS_OPT(oa)
     767      | (ra? MRB_ARGS_REST() : 0)
     768      | MRB_ARGS_POST(pa)
     769      | MRB_ARGS_KEY(ka, kd)
     770      | (ba? MRB_ARGS_BLOCK() : 0);
     771    s->ainfo = (((ma+oa) & 0x3f) << 7) /* (12bits = 5:1:5:1) */
     772      | ((ra & 0x1) << 6)
     773      | ((pa & 0x1f) << 1)
     774      | ((ka | kd) != 0 ? 0x01 : 0x00);
     775    genop_W(s, OP_ENTER, a);
     776    /* generate jump table for optional arguments initializer */
    689777    pos = new_label(s);
    690778    for (i=0; i<oa; i++) {
    691779      new_label(s);
    692       genop(s, MKOP_sBx(OP_JMP, 0));
     780      genjmp(s, OP_JMP, 0);
    693781    }
    694782    if (oa > 0) {
    695       genop(s, MKOP_sBx(OP_JMP, 0));
     783      genjmp(s, OP_JMP, 0);
    696784    }
    697785    opt = tree->car->cdr->car;
     
    700788      int idx;
    701789
    702       dispatch(s, pos+i);
     790      dispatch(s, pos+i*3+1);
    703791      codegen(s, opt->car->cdr, VAL);
    704       idx = lv_idx(s, (mrb_sym)(intptr_t)opt->car->car);
    705792      pop();
    706       genop_peep(s, MKOP_AB(OP_MOVE, idx, cursp()), NOVAL);
     793      idx = lv_idx(s, nsym(opt->car->car));
     794      gen_move(s, idx, cursp(), 0);
    707795      i++;
    708796      opt = opt->cdr;
    709797    }
    710798    if (oa > 0) {
    711       dispatch(s, pos+i);
    712     }
    713   }
     799      dispatch(s, pos+i*3+1);
     800    }
     801
     802    /* keyword arguments */
     803    if (tail) {
     804      node *kwds = tail->cdr->car;
     805      int kwrest = 0;
     806
     807      if (tail->cdr->cdr->car) {
     808        kwrest = 1;
     809      }
     810      mrb_assert(nint(tail->car) == NODE_ARGS_TAIL);
     811      mrb_assert(node_len(tail) == 4);
     812
     813      while (kwds) {
     814        int jmpif_key_p, jmp_def_set = -1;
     815        node *kwd = kwds->car, *def_arg = kwd->cdr->cdr->car;
     816        mrb_sym kwd_sym = nsym(kwd->cdr->car);
     817
     818        mrb_assert(nint(kwd->car) == NODE_KW_ARG);
     819
     820        if (def_arg) {
     821          genop_2(s, OP_KEY_P, lv_idx(s, kwd_sym), new_sym(s, kwd_sym));
     822          jmpif_key_p = genjmp2(s, OP_JMPIF, lv_idx(s, kwd_sym), 0, 0);
     823          codegen(s, def_arg, VAL);
     824          pop();
     825          gen_move(s, lv_idx(s, kwd_sym), cursp(), 0);
     826          jmp_def_set = genjmp(s, OP_JMP, 0);
     827          dispatch(s, jmpif_key_p);
     828        }
     829        genop_2(s, OP_KARG, lv_idx(s, kwd_sym), new_sym(s, kwd_sym));
     830        if (jmp_def_set != -1) {
     831          dispatch(s, jmp_def_set);
     832        }
     833        i++;
     834
     835        kwds = kwds->cdr;
     836      }
     837      if (tail->cdr->car && !kwrest) {
     838        genop_0(s, OP_KEYEND);
     839      }
     840    }
     841
     842    /* argument destructuring */
     843    if (margs) {
     844      node *n = margs;
     845
     846      pos = 1;
     847      while (n) {
     848        if (nint(n->car->car) == NODE_MASGN) {
     849          gen_vmassignment(s, n->car->cdr->car, pos, NOVAL);
     850        }
     851        pos++;
     852        n = n->cdr;
     853      }
     854    }
     855    if (pargs) {
     856      node *n = margs;
     857
     858      pos = ma+oa+ra+1;
     859      while (n) {
     860        if (nint(n->car->car) == NODE_MASGN) {
     861          gen_vmassignment(s, n->car->cdr->car, pos, NOVAL);
     862        }
     863        pos++;
     864        n = n->cdr;
     865      }
     866    }
     867  }
     868
    714869  codegen(s, tree->cdr->car, VAL);
    715870  pop();
    716871  if (s->pc > 0) {
    717     c = s->iseq[s->pc-1];
    718     if (GET_OPCODE(c) != OP_RETURN || GETARG_B(c) != OP_R_NORMAL || s->pc == s->lastlabel) {
    719       if (s->nregs == 0) {
    720         genop(s, MKOP_A(OP_LOADNIL, 0));
    721         genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
    722       }
    723       else {
    724         genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
    725       }
    726     }
     872    gen_return(s, OP_RETURN, cursp());
    727873  }
    728874  if (blk) {
     
    737883{
    738884  codegen_scope *scope = scope_new(s->mrb, s, tree->car);
    739   if (scope == NULL) {
    740     raise_error(s, "unexpected scope");
    741   }
    742885
    743886  codegen(scope, tree->cdr, VAL);
     887  gen_return(scope, OP_RETURN, scope->sp-1);
    744888  if (!s->iseq) {
    745     genop(scope, MKOP_A(OP_STOP, 0));
    746   }
    747   else if (!val) {
    748     genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
    749   }
    750   else {
    751     if (scope->nregs == 0) {
    752       genop(scope, MKOP_A(OP_LOADNIL, 0));
    753       genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
    754     }
    755     else {
    756       genop_peep(scope, MKOP_AB(OP_RETURN, scope->sp-1, OP_R_NORMAL), NOVAL);
    757     }
     889    genop_0(scope, OP_STOP);
    758890  }
    759891  scope_finish(scope);
     
    769901{
    770902  while (t) {
    771     if ((intptr_t)t->car->car == NODE_SPLAT) return FALSE;
     903    if (nint(t->car->car) == NODE_SPLAT) return FALSE;
    772904    t = t->cdr;
    773905  }
     
    782914  char *name2;
    783915
    784   name = mrb_sym2name_len(s->mrb, a, &len);
     916  name = mrb_sym_name_len(s->mrb, a, &len);
    785917  name2 = (char *)codegen_palloc(s,
    786918                                 (size_t)len
     
    805937
    806938  while (t) {
    807     is_splat = (intptr_t)t->car->car == NODE_SPLAT; /* splat mode */
     939    is_splat = nint(t->car->car) == NODE_SPLAT; /* splat mode */
    808940    if (
    809941      n+extra >= CALL_MAXARGS - 1 /* need to subtract one because vm.c expects an array if n == CALL_MAXARGS */
    810942      || is_splat) {
    811943      if (val) {
    812         if (is_splat && n == 0 && (intptr_t)t->car->cdr->car == NODE_ARRAY) {
     944        if (is_splat && n == 0 && nint(t->car->cdr->car) == NODE_ARRAY) {
    813945          codegen(s, t->car->cdr, VAL);
    814946          pop();
     
    816948        else {
    817949          pop_n(n);
    818           genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n));
     950          if (n == 0 && is_splat) {
     951            genop_1(s, OP_LOADNIL, cursp());
     952          }
     953          else {
     954            genop_2(s, OP_ARRAY, cursp(), n);
     955          }
    819956          push();
    820957          codegen(s, t->car, VAL);
    821958          pop(); pop();
    822959          if (is_splat) {
    823             genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));
     960            genop_1(s, OP_ARYCAT, cursp());
    824961          }
    825962          else {
    826             genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));
     963            genop_1(s, OP_ARYPUSH, cursp());
    827964          }
    828965        }
     
    832969          codegen(s, t->car, VAL);
    833970          pop(); pop();
    834           if ((intptr_t)t->car->car == NODE_SPLAT) {
    835             genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));
     971          if (nint(t->car->car) == NODE_SPLAT) {
     972            genop_1(s, OP_ARYCAT, cursp());
    836973          }
    837974          else {
    838             genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));
     975            genop_1(s, OP_ARYPUSH, cursp());
    839976          }
    840977          t = t->cdr;
     
    860997gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe)
    861998{
    862   mrb_sym sym = name ? name : sym(tree->cdr->car);
    863   int idx, skip = 0;
     999  mrb_sym sym = name ? name : nsym(tree->cdr->car);
     1000  int skip = 0;
    8641001  int n = 0, noop = 0, sendv = 0, blk = 0;
    8651002
     
    8671004  if (safe) {
    8681005    int recv = cursp()-1;
    869     genop(s, MKOP_A(OP_LOADNIL, cursp()));
    870     push();
    871     genop(s, MKOP_AB(OP_MOVE, cursp(), recv));
    872     push(); pop();              /* space for a block */
    873     pop();
    874     idx = new_msym(s, mrb_intern_lit(s->mrb, "=="));
    875     genop(s, MKOP_ABC(OP_EQ, cursp(), idx, 1));
    876     skip = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), 0));
    877   }
    878   idx = new_msym(s, sym);
     1006    gen_move(s, cursp(), recv, 1);
     1007    skip = genjmp2(s, OP_JMPNIL, cursp(), 0, val);
     1008  }
    8791009  tree = tree->cdr->cdr->car;
    8801010  if (tree) {
     
    8851015    }
    8861016  }
    887   if (sp) {
     1017  if (sp) {                     /* last argument pushed (attr=) */
    8881018    if (sendv) {
     1019      gen_move(s, cursp(), sp, 0);
    8891020      pop();
    890       genop(s, MKOP_AB(OP_ARYPUSH, cursp(), sp));
     1021      genop_1(s, OP_ARYPUSH, cursp());
    8911022      push();
    8921023    }
    8931024    else {
    894       genop(s, MKOP_AB(OP_MOVE, cursp(), sp));
     1025      gen_move(s, cursp(), sp, 0);
    8951026      push();
    8961027      n++;
     
    9011032    codegen(s, tree->cdr, VAL);
    9021033    pop();
    903   }
    904   else {
    905     blk = cursp();
     1034    blk = 1;
    9061035  }
    9071036  push();pop();
     
    9091038  {
    9101039    mrb_int symlen;
    911     const char *symname = mrb_sym2name_len(s->mrb, sym, &symlen);
     1040    const char *symname = mrb_sym_name_len(s->mrb, sym, &symlen);
    9121041
    9131042    if (!noop && symlen == 1 && symname[0] == '+' && n == 1)  {
    914       genop_peep(s, MKOP_ABC(OP_ADD, cursp(), idx, n), val);
     1043      gen_addsub(s, OP_ADD, cursp());
    9151044    }
    9161045    else if (!noop && symlen == 1 && symname[0] == '-' && n == 1)  {
    917       genop_peep(s, MKOP_ABC(OP_SUB, cursp(), idx, n), val);
     1046      gen_addsub(s, OP_SUB, cursp());
    9181047    }
    9191048    else if (!noop && symlen == 1 && symname[0] == '*' && n == 1)  {
    920       genop(s, MKOP_ABC(OP_MUL, cursp(), idx, n));
     1049      genop_1(s, OP_MUL, cursp());
    9211050    }
    9221051    else if (!noop && symlen == 1 && symname[0] == '/' && n == 1)  {
    923       genop(s, MKOP_ABC(OP_DIV, cursp(), idx, n));
     1052      genop_1(s, OP_DIV, cursp());
    9241053    }
    9251054    else if (!noop && symlen == 1 && symname[0] == '<' && n == 1)  {
    926       genop(s, MKOP_ABC(OP_LT, cursp(), idx, n));
     1055      genop_1(s, OP_LT, cursp());
    9271056    }
    9281057    else if (!noop && symlen == 2 && symname[0] == '<' && symname[1] == '=' && n == 1)  {
    929       genop(s, MKOP_ABC(OP_LE, cursp(), idx, n));
     1058      genop_1(s, OP_LE, cursp());
    9301059    }
    9311060    else if (!noop && symlen == 1 && symname[0] == '>' && n == 1)  {
    932       genop(s, MKOP_ABC(OP_GT, cursp(), idx, n));
     1061      genop_1(s, OP_GT, cursp());
    9331062    }
    9341063    else if (!noop && symlen == 2 && symname[0] == '>' && symname[1] == '=' && n == 1)  {
    935       genop(s, MKOP_ABC(OP_GE, cursp(), idx, n));
     1064      genop_1(s, OP_GE, cursp());
    9361065    }
    9371066    else if (!noop && symlen == 2 && symname[0] == '=' && symname[1] == '=' && n == 1)  {
    938       genop(s, MKOP_ABC(OP_EQ, cursp(), idx, n));
     1067      genop_1(s, OP_EQ, cursp());
    9391068    }
    9401069    else {
    941       if (sendv) n = CALL_MAXARGS;
    942       if (blk > 0) {                   /* no block */
    943         genop(s, MKOP_ABC(OP_SEND, cursp(), idx, n));
     1070      int idx = new_sym(s, sym);
     1071
     1072      if (sendv) {
     1073        genop_2(s, blk ? OP_SENDVB : OP_SENDV, cursp(), idx);
    9441074      }
    9451075      else {
    946         genop(s, MKOP_ABC(OP_SENDB, cursp(), idx, n));
     1076        genop_3(s, blk ? OP_SENDB : OP_SEND, cursp(), idx, n);
    9471077      }
    9481078    }
     
    9601090{
    9611091  int idx;
    962   int type = (intptr_t)tree->car;
     1092  int type = nint(tree->car);
    9631093
    9641094  tree = tree->cdr;
    9651095  switch (type) {
    9661096  case NODE_GVAR:
    967     idx = new_sym(s, sym(tree));
    968     genop_peep(s, MKOP_ABx(OP_SETGLOBAL, sp, idx), val);
    969     break;
     1097    idx = new_sym(s, nsym(tree));
     1098    genop_2(s, OP_SETGV, sp, idx);
     1099    break;
     1100  case NODE_ARG:
    9701101  case NODE_LVAR:
    971     idx = lv_idx(s, sym(tree));
     1102    idx = lv_idx(s, nsym(tree));
    9721103    if (idx > 0) {
    9731104      if (idx != sp) {
    974         genop_peep(s, MKOP_AB(OP_MOVE, idx, sp), val);
     1105        gen_move(s, idx, sp, val);
     1106        if (val && on_eval(s)) genop_0(s, OP_NOP);
    9751107      }
    9761108      break;
     
    9811113
    9821114      while (up) {
    983         idx = lv_idx(up, sym(tree));
     1115        idx = lv_idx(up, nsym(tree));
    9841116        if (idx > 0) {
    985           genop_peep(s, MKOP_ABC(OP_SETUPVAR, sp, idx, lv), val);
     1117          genop_3(s, OP_SETUPVAR, sp, idx, lv);
    9861118          break;
    9871119        }
     
    9911123    }
    9921124    break;
     1125  case NODE_NVAR:
     1126    idx = nint(tree);
     1127    codegen_error(s, "Can't assign to numbered parameter");
     1128    break;
    9931129  case NODE_IVAR:
    994     idx = new_sym(s, sym(tree));
    995     genop_peep(s, MKOP_ABx(OP_SETIV, sp, idx), val);
     1130    idx = new_sym(s, nsym(tree));
     1131    genop_2(s, OP_SETIV, sp, idx);
    9961132    break;
    9971133  case NODE_CVAR:
    998     idx = new_sym(s, sym(tree));
    999     genop_peep(s, MKOP_ABx(OP_SETCV, sp, idx), val);
     1134    idx = new_sym(s, nsym(tree));
     1135    genop_2(s, OP_SETCV, sp, idx);
    10001136    break;
    10011137  case NODE_CONST:
    1002     idx = new_sym(s, sym(tree));
    1003     genop_peep(s, MKOP_ABx(OP_SETCONST, sp, idx), val);
     1138    idx = new_sym(s, nsym(tree));
     1139    genop_2(s, OP_SETCONST, sp, idx);
    10041140    break;
    10051141  case NODE_COLON2:
    1006     idx = new_sym(s, sym(tree->cdr));
    1007     genop_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), NOVAL);
     1142    gen_move(s, cursp(), sp, 0);
    10081143    push();
    10091144    codegen(s, tree->car, VAL);
    10101145    pop_n(2);
    1011     genop_peep(s, MKOP_ABx(OP_SETMCNST, cursp(), idx), val);
     1146    idx = new_sym(s, nsym(tree->cdr));
     1147    genop_2(s, OP_SETMCNST, sp, idx);
    10121148    break;
    10131149
     
    10151151  case NODE_SCALL:
    10161152    push();
    1017     gen_call(s, tree, attrsym(s, sym(tree->cdr->car)), sp, NOVAL,
     1153    gen_call(s, tree, attrsym(s, nsym(tree->cdr->car)), sp, NOVAL,
    10181154             type == NODE_SCALL);
    10191155    pop();
    10201156    if (val) {
    1021       genop_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), val);
     1157      gen_move(s, cursp(), sp, 0);
    10221158    }
    10231159    break;
     
    10501186    n = 0;
    10511187    while (t) {
    1052       genop(s, MKOP_ABC(OP_AREF, cursp(), rhs, n));
    1053       gen_assignment(s, t->car, cursp(), NOVAL);
     1188      int sp = cursp();
     1189
     1190      genop_3(s, OP_AREF, sp, rhs, n);
     1191      push();
     1192      gen_assignment(s, t->car, sp, NOVAL);
     1193      pop();
    10541194      n++;
    10551195      t = t->cdr;
     
    10651205      }
    10661206    }
    1067     if (val) {
    1068       genop(s, MKOP_AB(OP_MOVE, cursp(), rhs));
    1069     }
    1070     else {
    1071       pop();
    1072     }
    1073     push_n(post);
    1074     pop_n(post);
    1075     genop(s, MKOP_ABC(OP_APOST, cursp(), n, post));
     1207    gen_move(s, cursp(), rhs, val);
     1208    push_n(post+1);
     1209    pop_n(post+1);
     1210    genop_3(s, OP_APOST, cursp(), n, post);
    10761211    n = 1;
    1077     if (t->car) {              /* rest */
     1212    if (t->car && t->car != (node*)-1) { /* rest */
    10781213      gen_assignment(s, t->car, cursp(), NOVAL);
    10791214    }
     
    10861221      }
    10871222    }
    1088     if (!val) {
    1089       push();
     1223    if (val) {
     1224      gen_move(s, cursp(), rhs, 0);
    10901225    }
    10911226  }
     
    10931228
    10941229static void
    1095 gen_send_intern(codegen_scope *s)
     1230gen_intern(codegen_scope *s)
    10961231{
    10971232  pop();
    1098   genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "intern")), 0));
     1233  genop_1(s, OP_INTERN, cursp());
    10991234  push();
    11001235}
     1236
    11011237static void
    11021238gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val)
     
    11061242
    11071243    while (tree) {
    1108       switch ((intptr_t)tree->car->car) {
     1244      switch (nint(tree->car->car)) {
    11091245      case NODE_STR:
    1110         if ((tree->cdr == NULL) && ((intptr_t)tree->car->cdr->cdr == 0))
     1246        if ((tree->cdr == NULL) && (nint(tree->car->cdr->cdr) == 0))
    11111247          break;
    11121248        /* fall through */
     
    11211257          ++i;
    11221258          if (sym)
    1123             gen_send_intern(s);
     1259            gen_intern(s);
    11241260        }
    11251261        break;
    11261262      }
    1127       if (j >= 2) {
     1263      while (j >= 2) {
    11281264        pop(); pop();
    1129         genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
     1265        genop_1(s, OP_STRCAT, cursp());
    11301266        push();
    1131         j = 1;
     1267        j--;
    11321268      }
    11331269      tree = tree->cdr;
     
    11361272      ++i;
    11371273      if (sym)
    1138         gen_send_intern(s);
     1274        gen_intern(s);
    11391275    }
    11401276    pop_n(i);
    1141     genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), i));
     1277    genop_2(s, OP_ARRAY, cursp(), i);
    11421278    push();
    11431279  }
    11441280  else {
    11451281    while (tree) {
    1146       switch ((intptr_t)tree->car->car) {
     1282      switch (nint(tree->car->car)) {
    11471283      case NODE_BEGIN: case NODE_BLOCK:
    11481284        codegen(s, tree->car, NOVAL);
     
    11581294  int idx = new_lit(s, mrb_str_new_cstr(s->mrb, msg));
    11591295
    1160   genop(s, MKOP_ABx(OP_ERR, 1, idx));
    1161 }
    1162 
     1296  genop_1(s, OP_ERR, idx);
     1297}
     1298
     1299#ifndef MRB_WITHOUT_FLOAT
    11631300static double
    11641301readint_float(codegen_scope *s, const char *p, int base)
     
    11861323  return f;
    11871324}
     1325#endif
    11881326
    11891327static mrb_int
     
    12331371gen_retval(codegen_scope *s, node *tree)
    12341372{
    1235   if ((intptr_t)tree->car == NODE_SPLAT) {
    1236     genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), 0));
    1237     push();
     1373  if (nint(tree->car) == NODE_SPLAT) {
    12381374    codegen(s, tree, VAL);
    1239     pop(); pop();
    1240     genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));
     1375    pop();
     1376    genop_1(s, OP_ARYDUP, cursp());
    12411377  }
    12421378  else {
     
    12541390  if (!tree) {
    12551391    if (val) {
    1256       genop(s, MKOP_A(OP_LOADNIL, cursp()));
     1392      genop_1(s, OP_LOADNIL, cursp());
    12571393      push();
    12581394    }
     
    12651401  }
    12661402  if (s->irep && s->filename_index != tree->filename_index) {
    1267     s->irep->filename = mrb_parser_get_filename(s->parser, s->filename_index);
    1268     mrb_debug_info_append_file(s->mrb, s->irep, s->debug_start_pos, s->pc);
     1403    mrb_sym fname = mrb_parser_get_filename(s->parser, s->filename_index);
     1404    const char *filename = mrb_sym_name_len(s->mrb, fname, NULL);
     1405
     1406    mrb_debug_info_append_file(s->mrb, s->irep->debug_info,
     1407                               filename, s->lines, s->debug_start_pos, s->pc);
    12691408    s->debug_start_pos = s->pc;
    12701409    s->filename_index = tree->filename_index;
    1271     s->filename = mrb_parser_get_filename(s->parser, tree->filename_index);
    1272   }
    1273 
    1274   nt = (intptr_t)tree->car;
     1410    s->filename_sym = mrb_parser_get_filename(s->parser, tree->filename_index);
     1411  }
     1412
     1413  nt = nint(tree->car);
    12751414  s->lineno = tree->lineno;
    12761415  tree = tree->cdr;
     
    12781417  case NODE_BEGIN:
    12791418    if (val && !tree) {
    1280       genop(s, MKOP_A(OP_LOADNIL, cursp()));
     1419      genop_1(s, OP_LOADNIL, cursp());
    12811420      push();
    12821421    }
     
    12891428  case NODE_RESCUE:
    12901429    {
    1291       int onerr, noexc, exend, pos1, pos2, tmp;
     1430      int noexc, exend, pos1, pos2, tmp;
    12921431      struct loopinfo *lp;
    12931432
    12941433      if (tree->car == NULL) goto exit;
    1295       onerr = genop(s, MKOP_Bx(OP_ONERR, 0));
    12961434      lp = loop_push(s, LOOP_BEGIN);
    1297       lp->pc1 = onerr;
     1435      lp->pc0 = new_label(s);
     1436      lp->pc1 = genjmp(s, OP_ONERR, 0);
    12981437      codegen(s, tree->car, VAL);
    12991438      pop();
    13001439      lp->type = LOOP_RESCUE;
    1301       noexc = genop(s, MKOP_Bx(OP_JMP, 0));
    1302       dispatch(s, onerr);
     1440      noexc = genjmp(s, OP_JMP, 0);
     1441      dispatch(s, lp->pc1);
    13031442      tree = tree->cdr;
    13041443      exend = 0;
     
    13081447        int exc = cursp();
    13091448
    1310         genop(s, MKOP_ABC(OP_RESCUE, exc, 0, 0));
     1449        genop_1(s, OP_EXCEPT, exc);
    13111450        push();
    13121451        while (n2) {
     
    13171456          pos2 = 0;
    13181457          do {
    1319             if (n4 && n4->car && (intptr_t)n4->car->car == NODE_SPLAT) {
     1458            if (n4 && n4->car && nint(n4->car->car) == NODE_SPLAT) {
    13201459              codegen(s, n4->car, VAL);
    1321               genop(s, MKOP_AB(OP_MOVE, cursp(), exc));
     1460              gen_move(s, cursp(), exc, 0);
     1461              push_n(2); pop_n(2); /* space for one arg and a block */
    13221462              pop();
    1323               genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1));
     1463              genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1);
    13241464            }
    13251465            else {
     
    13281468              }
    13291469              else {
    1330                 genop(s, MKOP_ABx(OP_GETCONST, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "StandardError"))));
     1470                genop_2(s, OP_GETCONST, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "StandardError")));
    13311471                push();
    13321472              }
    13331473              pop();
    1334               genop(s, MKOP_ABC(OP_RESCUE, exc, cursp(), 1));
     1474              genop_2(s, OP_RESCUE, exc, cursp());
    13351475            }
    1336             tmp = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
     1476            tmp = genjmp2(s, OP_JMPIF, cursp(), pos2, val);
    13371477            pos2 = tmp;
    13381478            if (n4) {
     
    13401480            }
    13411481          } while (n4);
    1342           pos1 = genop(s, MKOP_sBx(OP_JMP, 0));
     1482          pos1 = genjmp(s, OP_JMP, 0);
    13431483          dispatch_linked(s, pos2);
    13441484
     
    13511491            if (val) pop();
    13521492          }
    1353           tmp = genop(s, MKOP_sBx(OP_JMP, exend));
     1493          tmp = genjmp(s, OP_JMP, exend);
    13541494          exend = tmp;
    13551495          n2 = n2->cdr;
     
    13581498        if (pos1) {
    13591499          dispatch(s, pos1);
    1360           genop(s, MKOP_A(OP_RAISE, exc));
     1500          genop_1(s, OP_RAISE, exc);
    13611501        }
    13621502      }
     
    13641504      tree = tree->cdr;
    13651505      dispatch(s, noexc);
    1366       genop(s, MKOP_A(OP_POPERR, 1));
     1506      genop_1(s, OP_POPERR, 1);
    13671507      if (tree->car) {
    13681508        codegen(s, tree->car, val);
     
    13781518  case NODE_ENSURE:
    13791519    if (!tree->cdr || !tree->cdr->cdr ||
    1380         ((intptr_t)tree->cdr->cdr->car == NODE_BEGIN &&
     1520        (nint(tree->cdr->cdr->car) == NODE_BEGIN &&
    13811521         tree->cdr->cdr->cdr)) {
    13821522      int idx;
    1383       int epush = s->pc;
    1384 
    1385       genop(s, MKOP_Bx(OP_EPUSH, 0));
     1523
    13861524      s->ensure_level++;
     1525      idx = scope_body(s, tree->cdr, NOVAL);
     1526      genop_1(s, OP_EPUSH, idx);
    13871527      codegen(s, tree->car, val);
    1388       idx = scope_body(s, tree->cdr, NOVAL);
    1389       s->iseq[epush] = MKOP_Bx(OP_EPUSH, idx);
    13901528      s->ensure_level--;
    1391       genop_peep(s, MKOP_A(OP_EPOP, 1), NOVAL);
     1529      genop_1(s, OP_EPOP, 1);
    13921530    }
    13931531    else {                      /* empty ensure ignored */
     
    14001538      int idx = lambda_body(s, tree, 1);
    14011539
    1402       genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_LAMBDA));
     1540      genop_2(s, OP_LAMBDA, cursp(), idx);
    14031541      push();
    14041542    }
     
    14091547      int idx = lambda_body(s, tree, 1);
    14101548
    1411       genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_BLOCK));
     1549      genop_2(s, OP_BLOCK, cursp(), idx);
    14121550      push();
    14131551    }
     
    14161554  case NODE_IF:
    14171555    {
    1418       int pos1, pos2;
    1419       node *e = tree->cdr->cdr->car;
     1556      int pos1, pos2, nil_p = FALSE;
     1557      node *elsepart = tree->cdr->cdr->car;
    14201558
    14211559      if (!tree->car) {
    1422         codegen(s, e, val);
     1560        codegen(s, elsepart, val);
    14231561        goto exit;
    14241562      }
    1425       switch ((intptr_t)tree->car->car) {
     1563      switch (nint(tree->car->car)) {
    14261564      case NODE_TRUE:
    14271565      case NODE_INT:
     
    14311569      case NODE_FALSE:
    14321570      case NODE_NIL:
    1433         codegen(s, e, val);
     1571        codegen(s, elsepart, val);
    14341572        goto exit;
    1435       }
    1436       codegen(s, tree->car, VAL);
     1573      case NODE_CALL:
     1574        {
     1575          node *n = tree->car->cdr;
     1576          mrb_sym mid = nsym(n->cdr->car);
     1577          mrb_sym mnil = mrb_intern_lit(s->mrb, "nil?");
     1578          if (mid == mnil && n->cdr->cdr->car == NULL) {
     1579            nil_p = TRUE;
     1580            codegen(s, n->car, VAL);
     1581          }
     1582        }
     1583        break;
     1584      }
     1585      if (!nil_p) {
     1586        codegen(s, tree->car, VAL);
     1587      }
    14371588      pop();
    1438       pos1 = genop_peep(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0), NOVAL);
    1439 
    1440       codegen(s, tree->cdr->car, val);
    1441       if (e) {
     1589      if (val || tree->cdr->car) {
     1590        if (nil_p) {
     1591          pos2 = genjmp2(s, OP_JMPNIL, cursp(), 0, val);
     1592          pos1 = genjmp(s, OP_JMP, 0);
     1593          dispatch(s, pos2);
     1594        }
     1595        else {
     1596          pos1 = genjmp2(s, OP_JMPNOT, cursp(), 0, val);
     1597        }
     1598        codegen(s, tree->cdr->car, val);
    14421599        if (val) pop();
    1443         pos2 = genop(s, MKOP_sBx(OP_JMP, 0));
    1444         dispatch(s, pos1);
    1445         codegen(s, e, val);
    1446         dispatch(s, pos2);
    1447       }
    1448       else {
    1449         if (val) {
    1450           pop();
    1451           pos2 = genop(s, MKOP_sBx(OP_JMP, 0));
     1600        if (elsepart || val) {
     1601          pos2 = genjmp(s, OP_JMP, 0);
    14521602          dispatch(s, pos1);
    1453           genop(s, MKOP_A(OP_LOADNIL, cursp()));
     1603          codegen(s, elsepart, val);
    14541604          dispatch(s, pos2);
    1455           push();
    14561605        }
    14571606        else {
    14581607          dispatch(s, pos1);
     1608        }
     1609      }
     1610      else {                    /* empty then-part */
     1611        if (elsepart) {
     1612          if (nil_p) {
     1613            pos1 = genjmp2(s, OP_JMPNIL, cursp(), 0, val);
     1614          }
     1615          else {
     1616            pos1 = genjmp2(s, OP_JMPIF, cursp(), 0, val);
     1617          }
     1618          codegen(s, elsepart, val);
     1619          dispatch(s, pos1);
     1620        }
     1621        else if (val && !nil_p) {
     1622          genop_1(s, OP_LOADNIL, cursp());
     1623          push();
    14591624        }
    14601625      }
     
    14681633      codegen(s, tree->car, VAL);
    14691634      pop();
    1470       pos = genop(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0));
     1635      pos = genjmp2(s, OP_JMPNOT, cursp(), 0, val);
    14711636      codegen(s, tree->cdr, val);
    14721637      dispatch(s, pos);
     
    14801645      codegen(s, tree->car, VAL);
    14811646      pop();
    1482       pos = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), 0));
     1647      pos = genjmp2(s, OP_JMPIF, cursp(), 0, val);
    14831648      codegen(s, tree->cdr, val);
    14841649      dispatch(s, pos);
     
    14901655      struct loopinfo *lp = loop_push(s, LOOP_NORMAL);
    14911656
    1492       lp->pc1 = genop(s, MKOP_sBx(OP_JMP, 0));
     1657      lp->pc0 = new_label(s);
     1658      lp->pc1 = genjmp(s, OP_JMP, 0);
    14931659      lp->pc2 = new_label(s);
    14941660      codegen(s, tree->cdr, NOVAL);
     
    14961662      codegen(s, tree->car, VAL);
    14971663      pop();
    1498       genop(s, MKOP_AsBx(OP_JMPIF, cursp(), lp->pc2 - s->pc));
     1664      genjmp2(s, OP_JMPIF, cursp(), lp->pc2, NOVAL);
    14991665
    15001666      loop_pop(s, val);
     
    15061672      struct loopinfo *lp = loop_push(s, LOOP_NORMAL);
    15071673
    1508       lp->pc1 = genop(s, MKOP_sBx(OP_JMP, 0));
     1674      lp->pc0 = new_label(s);
     1675      lp->pc1 = genjmp(s, OP_JMP, 0);
    15091676      lp->pc2 = new_label(s);
    15101677      codegen(s, tree->cdr, NOVAL);
     
    15121679      codegen(s, tree->car, VAL);
    15131680      pop();
    1514       genop(s, MKOP_AsBx(OP_JMPNOT, cursp(), lp->pc2 - s->pc));
     1681      genjmp2(s, OP_JMPNOT, cursp(), lp->pc2, NOVAL);
    15151682
    15161683      loop_pop(s, val);
     
    15411708          codegen(s, n->car, VAL);
    15421709          if (head) {
    1543             genop(s, MKOP_AB(OP_MOVE, cursp(), head));
    1544             pop();
    1545             if ((intptr_t)n->car->car == NODE_SPLAT) {
    1546               genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1));
     1710            gen_move(s, cursp(), head, 0);
     1711            push(); push(); pop(); pop(); pop();
     1712            if (nint(n->car->car) == NODE_SPLAT) {
     1713              genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1);
    15471714            }
    15481715            else {
    1549               genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "===")), 1));
     1716              genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "===")), 1);
    15501717            }
    15511718          }
     
    15531720            pop();
    15541721          }
    1555           tmp = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
     1722          tmp = genjmp2(s, OP_JMPIF, cursp(), pos2, NOVAL);
    15561723          pos2 = tmp;
    15571724          n = n->cdr;
    15581725        }
    15591726        if (tree->car->car) {
    1560           pos1 = genop(s, MKOP_sBx(OP_JMP, 0));
     1727          pos1 = genjmp(s, OP_JMP, 0);
    15611728          dispatch_linked(s, pos2);
    15621729        }
    15631730        codegen(s, tree->car->cdr, val);
    15641731        if (val) pop();
    1565         tmp = genop(s, MKOP_sBx(OP_JMP, pos3));
     1732        tmp = genjmp(s, OP_JMP, pos3);
    15661733        pos3 = tmp;
    15671734        if (pos1) dispatch(s, pos1);
     
    15701737      if (val) {
    15711738        int pos = cursp();
    1572         genop(s, MKOP_A(OP_LOADNIL, cursp()));
     1739        genop_1(s, OP_LOADNIL, cursp());
    15731740        if (pos3) dispatch_linked(s, pos3);
    15741741        if (head) pop();
    15751742        if (cursp() != pos) {
    1576           genop(s, MKOP_AB(OP_MOVE, cursp(), pos));
     1743          gen_move(s, cursp(), pos, 0);
    15771744        }
    15781745        push();
     
    16061773    if (val) {
    16071774      pop(); pop();
    1608       genop(s, MKOP_ABC(OP_RANGE, cursp(), cursp(), FALSE));
     1775      genop_1(s, OP_RANGE_INC, cursp());
    16091776      push();
    16101777    }
     
    16161783    if (val) {
    16171784      pop(); pop();
    1618       genop(s, MKOP_ABC(OP_RANGE, cursp(), cursp(), TRUE));
     1785      genop_1(s, OP_RANGE_EXC, cursp());
    16191786      push();
    16201787    }
     
    16231790  case NODE_COLON2:
    16241791    {
    1625       int sym = new_sym(s, sym(tree->cdr));
     1792      int sym = new_sym(s, nsym(tree->cdr));
    16261793
    16271794      codegen(s, tree->car, VAL);
    16281795      pop();
    1629       genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
     1796      genop_2(s, OP_GETMCNST, cursp(), sym);
    16301797      if (val) push();
    16311798    }
     
    16341801  case NODE_COLON3:
    16351802    {
    1636       int sym = new_sym(s, sym(tree));
    1637 
    1638       genop(s, MKOP_A(OP_OCLASS, cursp()));
    1639       genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
     1803      int sym = new_sym(s, nsym(tree));
     1804
     1805      genop_1(s, OP_OCLASS, cursp());
     1806      genop_2(s, OP_GETMCNST, cursp(), sym);
    16401807      if (val) push();
    16411808    }
     
    16501817        if (val) {
    16511818          pop_n(n);
    1652           genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n));
     1819          genop_2(s, OP_ARRAY, cursp(), n);
    16531820          push();
    16541821        }
     
    16611828
    16621829  case NODE_HASH:
     1830  case NODE_KW_HASH:
    16631831    {
    16641832      int len = 0;
     
    16661834
    16671835      while (tree) {
    1668         codegen(s, tree->car->car, val);
    1669         codegen(s, tree->car->cdr, val);
    1670         len++;
     1836        if (nint(tree->car->car->car) == NODE_KW_REST_ARGS) {
     1837          if (len > 0) {
     1838            pop_n(len*2);
     1839            if (!update) {
     1840              genop_2(s, OP_HASH, cursp(), len);
     1841            }
     1842            else {
     1843              pop();
     1844              genop_2(s, OP_HASHADD, cursp(), len);
     1845            }
     1846            push();
     1847          }
     1848          codegen(s, tree->car->cdr, VAL);
     1849          if (len > 0 || update) {
     1850            pop(); pop();
     1851            genop_1(s, OP_HASHCAT, cursp());
     1852            push();
     1853          }
     1854          update = TRUE;
     1855          len = 0;
     1856        }
     1857        else {
     1858          codegen(s, tree->car->car, val);
     1859          codegen(s, tree->car->cdr, val);
     1860          len++;
     1861        }
    16711862        tree = tree->cdr;
    1672         if (val && len == 126) {
     1863        if (val && len == 255) {
    16731864          pop_n(len*2);
    1674           genop(s, MKOP_ABC(OP_HASH, cursp(), cursp(), len));
    1675           if (update) {
     1865          if (!update) {
     1866            genop_2(s, OP_HASH, cursp(), len);
     1867          }
     1868          else {
    16761869            pop();
    1677             genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__update")), 1));
     1870            genop_2(s, OP_HASHADD, cursp(), len);
    16781871          }
    16791872          push();
     
    16841877      if (val) {
    16851878        pop_n(len*2);
    1686         genop(s, MKOP_ABC(OP_HASH, cursp(), cursp(), len));
    1687         if (update) {
     1879        if (!update) {
     1880          genop_2(s, OP_HASH, cursp(), len);
     1881        }
     1882        else {
    16881883          pop();
    1689           genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__update")), 1));
     1884          if (len > 0) {
     1885            genop_2(s, OP_HASHADD, cursp(), len);
     1886          }
    16901887        }
    16911888        push();
     
    17101907      int rhs = cursp();
    17111908
    1712       if ((intptr_t)t->car == NODE_ARRAY && t->cdr && nosplat(t->cdr)) {
     1909      if (nint(t->car) == NODE_ARRAY && t->cdr && nosplat(t->cdr)) {
    17131910        /* fixed rhs */
    17141911        t = t->cdr;
     
    17281925            }
    17291926            else {
    1730               genop(s, MKOP_A(OP_LOADNIL, rhs+n));
     1927              genop_1(s, OP_LOADNIL, rhs+n);
    17311928              gen_assignment(s, t->car, rhs+n, NOVAL);
    17321929            }
     
    17521949              rn = len - post - n;
    17531950            }
    1754             genop(s, MKOP_ABC(OP_ARRAY, cursp(), rhs+n, rn));
     1951            genop_3(s, OP_ARRAY2, cursp(), rhs+n, rn);
    17551952            gen_assignment(s, t->car, cursp(), NOVAL);
    17561953            n += rn;
     
    17671964        pop_n(len);
    17681965        if (val) {
    1769           genop(s, MKOP_ABC(OP_ARRAY, rhs, rhs, len));
     1966          genop_2(s, OP_ARRAY, rhs, len);
    17701967          push();
    17711968        }
     
    17841981  case NODE_OP_ASGN:
    17851982    {
    1786       mrb_sym sym = sym(tree->cdr->car);
     1983      mrb_sym sym = nsym(tree->cdr->car);
    17871984      mrb_int len;
    1788       const char *name = mrb_sym2name_len(s->mrb, sym, &len);
     1985      const char *name = mrb_sym_name_len(s->mrb, sym, &len);
    17891986      int idx, callargs = -1, vsp = -1;
    17901987
    17911988      if ((len == 2 && name[0] == '|' && name[1] == '|') &&
    1792           ((intptr_t)tree->car->car == NODE_CONST ||
    1793            (intptr_t)tree->car->car == NODE_CVAR)) {
     1989          (nint(tree->car->car) == NODE_CONST ||
     1990           nint(tree->car->car) == NODE_CVAR)) {
    17941991        int onerr, noexc, exc;
    17951992        struct loopinfo *lp;
    17961993
    1797         onerr = genop(s, MKOP_Bx(OP_ONERR, 0));
     1994        onerr = genjmp(s, OP_ONERR, 0);
    17981995        lp = loop_push(s, LOOP_BEGIN);
    17991996        lp->pc1 = onerr;
     
    18011998        codegen(s, tree->car, VAL);
    18021999        lp->type = LOOP_RESCUE;
    1803         genop(s, MKOP_A(OP_POPERR, 1));
    1804         noexc = genop(s, MKOP_Bx(OP_JMP, 0));
     2000        genop_1(s, OP_POPERR, 1);
     2001        noexc = genjmp(s, OP_JMP, 0);
    18052002        dispatch(s, onerr);
    1806         genop(s, MKOP_ABC(OP_RESCUE, exc, 0, 0));
    1807         genop(s, MKOP_A(OP_LOADF, exc));
     2003        genop_1(s, OP_EXCEPT, exc);
     2004        genop_1(s, OP_LOADF, exc);
    18082005        dispatch(s, noexc);
    18092006        loop_pop(s, NOVAL);
    18102007      }
    1811       else if ((intptr_t)tree->car->car == NODE_CALL) {
     2008      else if (nint(tree->car->car) == NODE_CALL) {
    18122009        node *n = tree->car->cdr;
     2010        int base, i, nargs = 0;
     2011        callargs = 0;
    18132012
    18142013        if (val) {
     
    18172016        }
    18182017        codegen(s, n->car, VAL);   /* receiver */
    1819         idx = new_msym(s, sym(n->cdr->car));
     2018        idx = new_sym(s, nsym(n->cdr->car));
     2019        base = cursp()-1;
    18202020        if (n->cdr->cdr->car) {
    1821           int base = cursp()-1;
    1822           int nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 1);
    1823 
    1824           /* copy receiver and arguments */
     2021          nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 1);
    18252022          if (nargs >= 0) {
    1826             int i;
    1827 
    1828             genop(s, MKOP_AB(OP_MOVE, cursp(), base));
    1829             for (i=0; i<nargs; i++) {
    1830               genop(s, MKOP_AB(OP_MOVE, cursp()+i+1, base+i+1));
    1831             }
    1832             push_n(nargs+1);
    1833             pop_n(nargs+1);
    18342023            callargs = nargs;
    18352024          }
    1836           else {
    1837             /* varargs */
     2025          else { /* varargs */
    18382026            push();
    1839             genop(s, MKOP_AB(OP_MOVE, cursp(), base));
    1840             genop(s, MKOP_AB(OP_MOVE, cursp()+1, base+1));
     2027            nargs = 1;
    18412028            callargs = CALL_MAXARGS;
    18422029          }
    1843           genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs));
    1844         }
    1845         else {
    1846           genop(s, MKOP_AB(OP_MOVE, cursp(), cursp()-1));
    1847           genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 0));
    1848           callargs = 0;
    1849         }
     2030        }
     2031        /* copy receiver and arguments */
     2032        gen_move(s, cursp(), base, 1);
     2033        for (i=0; i<nargs; i++) {
     2034          gen_move(s, cursp()+i+1, base+i+1, 1);
     2035        }
     2036        push_n(nargs+2);pop_n(nargs+2); /* space for receiver, arguments and a block */
     2037        genop_3(s, OP_SEND, cursp(), idx, callargs);
    18502038        push();
    18512039      }
     
    18612049        if (val) {
    18622050          if (vsp >= 0) {
    1863             genop(s, MKOP_AB(OP_MOVE, vsp, cursp()));
    1864           }
    1865           pos = genop(s, MKOP_AsBx(name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0));
     2051            gen_move(s, vsp, cursp(), 1);
     2052          }
     2053          pos = genjmp2(s, name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0, val);
    18662054        }
    18672055        else {
    1868           pos = genop_peep(s, MKOP_AsBx(name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0), NOVAL);
     2056          pos = genjmp2(s, name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0, val);
    18692057        }
    18702058        codegen(s, tree->cdr->cdr->car, VAL);
    18712059        pop();
    18722060        if (val && vsp >= 0) {
    1873           genop(s, MKOP_AB(OP_MOVE, vsp, cursp()));
    1874         }
    1875         if ((intptr_t)tree->car->car == NODE_CALL) {
    1876           mrb_sym m = sym(tree->car->cdr->cdr->car);
    1877           mrb_sym m2 = attrsym(s, m);
    1878 
    1879           idx = new_msym(s, m2);
    1880           pop();
     2061          gen_move(s, vsp, cursp(), 1);
     2062        }
     2063        if (nint(tree->car->car) == NODE_CALL) {
    18812064          if (callargs == CALL_MAXARGS) {
    1882             genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));
    18832065            pop();
    1884             genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs));
     2066            genop_1(s, OP_ARYPUSH, cursp());
    18852067          }
    18862068          else {
    18872069            pop_n(callargs);
    1888             genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs+1));
    1889           }
     2070            callargs++;
     2071          }
     2072          pop();
     2073          idx = new_sym(s, attrsym(s, nsym(tree->car->cdr->cdr->car)));
     2074          genop_3(s, OP_SEND, cursp(), idx, callargs);
    18902075        }
    18912076        else {
     
    18992084      pop(); pop();
    19002085
    1901       idx = new_msym(s, sym);
    19022086      if (len == 1 && name[0] == '+')  {
    1903         genop_peep(s, MKOP_ABC(OP_ADD, cursp(), idx, 1), val);
     2087        gen_addsub(s, OP_ADD, cursp());
    19042088      }
    19052089      else if (len == 1 && name[0] == '-')  {
    1906         genop_peep(s, MKOP_ABC(OP_SUB, cursp(), idx, 1), val);
     2090        gen_addsub(s, OP_SUB, cursp());
    19072091      }
    19082092      else if (len == 1 && name[0] == '*')  {
    1909         genop(s, MKOP_ABC(OP_MUL, cursp(), idx, 1));
     2093        genop_1(s, OP_MUL, cursp());
    19102094      }
    19112095      else if (len == 1 && name[0] == '/')  {
    1912         genop(s, MKOP_ABC(OP_DIV, cursp(), idx, 1));
     2096        genop_1(s, OP_DIV, cursp());
    19132097      }
    19142098      else if (len == 1 && name[0] == '<')  {
    1915         genop(s, MKOP_ABC(OP_LT, cursp(), idx, 1));
     2099        genop_1(s, OP_LT, cursp());
    19162100      }
    19172101      else if (len == 2 && name[0] == '<' && name[1] == '=')  {
    1918         genop(s, MKOP_ABC(OP_LE, cursp(), idx, 1));
     2102        genop_1(s, OP_LE, cursp());
    19192103      }
    19202104      else if (len == 1 && name[0] == '>')  {
    1921         genop(s, MKOP_ABC(OP_GT, cursp(), idx, 1));
     2105        genop_1(s, OP_GT, cursp());
    19222106      }
    19232107      else if (len == 2 && name[0] == '>' && name[1] == '=')  {
    1924         genop(s, MKOP_ABC(OP_GE, cursp(), idx, 1));
     2108        genop_1(s, OP_GE, cursp());
    19252109      }
    19262110      else {
    1927         genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 1));
     2111        idx = new_sym(s, sym);
     2112        genop_3(s, OP_SEND, cursp(), idx, 1);
    19282113      }
    19292114      if (callargs < 0) {
     
    19322117      else {
    19332118        if (val && vsp >= 0) {
    1934           genop(s, MKOP_AB(OP_MOVE, vsp, cursp()));
     2119          gen_move(s, vsp, cursp(), 0);
    19352120        }
    19362121        if (callargs == CALL_MAXARGS) {
    19372122          pop();
    1938           genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));
     2123          genop_1(s, OP_ARYPUSH, cursp());
    19392124        }
    19402125        else {
     
    19432128        }
    19442129        pop();
    1945         idx = new_msym(s, attrsym(s,sym(tree->car->cdr->cdr->car)));
    1946         genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs));
     2130        idx = new_sym(s, attrsym(s,nsym(tree->car->cdr->cdr->car)));
     2131        genop_3(s, OP_SEND, cursp(), idx, callargs);
    19472132      }
    19482133    }
     
    19612146        if (!s2) break;
    19622147      }
    1963       genop(s, MKOP_ABx(OP_ARGARY, cursp(), (lv & 0xf)));
     2148      genop_2S(s, OP_ARGARY, cursp(), (lv & 0xf));
    19642149      push(); push();         /* ARGARY pushes two values */
    19652150      pop(); pop();
     
    19792164      }
    19802165      else {
    1981         genop(s, MKOP_A(OP_LOADNIL, cursp()));
     2166        genop_1(s, OP_LOADNIL, cursp());
    19822167        push(); pop();
    19832168      }
    19842169      pop_n(n+1);
    19852170      if (sendv) n = CALL_MAXARGS;
    1986       genop(s, MKOP_ABC(OP_SUPER, cursp(), 0, n));
     2171      genop_2(s, OP_SUPER, cursp(), n);
    19872172      if (val) push();
    19882173    }
     
    20012186      }
    20022187      if (s2) ainfo = s2->ainfo;
    2003       genop(s, MKOP_ABx(OP_ARGARY, cursp(), (ainfo<<4)|(lv & 0xf)));
     2188      genop_2S(s, OP_ARGARY, cursp(), (ainfo<<4)|(lv & 0xf));
    20042189      push(); push(); pop();    /* ARGARY pushes two values */
    20052190      if (tree && tree->cdr) {
     
    20082193      }
    20092194      pop(); pop();
    2010       genop(s, MKOP_ABC(OP_SUPER, cursp(), 0, CALL_MAXARGS));
     2195      genop_2(s, OP_SUPER, cursp(), CALL_MAXARGS);
    20112196      if (val) push();
    20122197    }
     
    20182203    }
    20192204    else {
    2020       genop(s, MKOP_A(OP_LOADNIL, cursp()));
     2205      genop_1(s, OP_LOADNIL, cursp());
    20212206    }
    20222207    if (s->loop) {
    2023       genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_RETURN));
     2208      gen_return(s, OP_RETURN_BLK, cursp());
    20242209    }
    20252210    else {
    2026       genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
     2211      gen_return(s, OP_RETURN, cursp());
    20272212    }
    20282213    if (val) push();
     
    20492234        }
    20502235      }
     2236      push();pop(); /* space for a block */
    20512237      pop_n(n+1);
    2052       genop(s, MKOP_ABx(OP_BLKPUSH, cursp(), (ainfo<<4)|(lv & 0xf)));
     2238      genop_2S(s, OP_BLKPUSH, cursp(), (ainfo<<4)|(lv & 0xf));
    20532239      if (sendv) n = CALL_MAXARGS;
    2054       genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "call")), n));
     2240      genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "call")), n);
    20552241      if (val) push();
    20562242    }
     
    20682254    else if (s->loop->type == LOOP_NORMAL) {
    20692255      if (s->ensure_level > s->loop->ensure_level) {
    2070         genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);
     2256        genop_1(s, OP_EPOP, s->ensure_level - s->loop->ensure_level);
    20712257      }
    20722258      codegen(s, tree, NOVAL);
    2073       genop(s, MKOP_sBx(OP_JMP, s->loop->pc1 - s->pc));
     2259      genjmp(s, OP_JMP, s->loop->pc0);
    20742260    }
    20752261    else {
     
    20792265      }
    20802266      else {
    2081         genop(s, MKOP_A(OP_LOADNIL, cursp()));
    2082       }
    2083       genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
     2267        genop_1(s, OP_LOADNIL, cursp());
     2268      }
     2269      gen_return(s, OP_RETURN, cursp());
    20842270    }
    20852271    if (val) push();
     
    20922278    else {
    20932279      if (s->ensure_level > s->loop->ensure_level) {
    2094         genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);
    2095       }
    2096       genop(s, MKOP_sBx(OP_JMP, s->loop->pc2 - s->pc));
     2280        genop_1(s, OP_EPOP, s->ensure_level - s->loop->ensure_level);
     2281      }
     2282      genjmp(s, OP_JMP, s->loop->pc2);
    20972283    }
    20982284    if (val) push();
     
    21212307        else {
    21222308          if (n > 0) {
    2123             while (n--) {
    2124               genop_peep(s, MKOP_A(OP_POPERR, 1), NOVAL);
    2125             }
     2309            genop_1(s, OP_POPERR, n);
    21262310          }
    21272311          if (s->ensure_level > lp->ensure_level) {
    2128             genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - lp->ensure_level), NOVAL);
    2129           }
    2130           genop(s, MKOP_sBx(OP_JMP, lp->pc1 - s->pc));
     2312            genop_1(s, OP_EPOP, s->ensure_level - lp->ensure_level);
     2313          }
     2314          genjmp(s, OP_JMP, lp->pc0);
    21312315        }
    21322316      }
     
    21372321  case NODE_LVAR:
    21382322    if (val) {
    2139       int idx = lv_idx(s, sym(tree));
     2323      int idx = lv_idx(s, nsym(tree));
    21402324
    21412325      if (idx > 0) {
    2142         genop_peep(s, MKOP_AB(OP_MOVE, cursp(), idx), NOVAL);
     2326        gen_move(s, cursp(), idx, val);
     2327        if (val && on_eval(s)) genop_0(s, OP_NOP);
    21432328      }
    21442329      else {
     
    21472332
    21482333        while (up) {
    2149           idx = lv_idx(up, sym(tree));
     2334          idx = lv_idx(up, nsym(tree));
    21502335          if (idx > 0) {
    2151             genop(s, MKOP_ABC(OP_GETUPVAR, cursp(), idx, lv));
     2336            genop_3(s, OP_GETUPVAR, cursp(), idx, lv);
    21522337            break;
    21532338          }
     
    21602345    break;
    21612346
     2347  case NODE_NVAR:
     2348    if (val) {
     2349      int idx = nint(tree);
     2350
     2351      gen_move(s, cursp(), idx, val);
     2352      if (val && on_eval(s)) genop_0(s, OP_NOP);
     2353
     2354      push();
     2355    }
     2356    break;
     2357
    21622358  case NODE_GVAR:
    2163     if (val) {
    2164       int sym = new_sym(s, sym(tree));
    2165 
    2166       genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));
    2167       push();
     2359    {
     2360      int sym = new_sym(s, nsym(tree));
     2361
     2362      genop_2(s, OP_GETGV, cursp(), sym);
     2363      if (val) push();
    21682364    }
    21692365    break;
    21702366
    21712367  case NODE_IVAR:
    2172     if (val) {
    2173       int sym = new_sym(s, sym(tree));
    2174 
    2175       genop(s, MKOP_ABx(OP_GETIV, cursp(), sym));
    2176       push();
     2368    {
     2369      int sym = new_sym(s, nsym(tree));
     2370
     2371      genop_2(s, OP_GETIV, cursp(), sym);
     2372      if (val) push();
    21772373    }
    21782374    break;
    21792375
    21802376  case NODE_CVAR:
    2181     if (val) {
    2182       int sym = new_sym(s, sym(tree));
    2183 
    2184       genop(s, MKOP_ABx(OP_GETCV, cursp(), sym));
    2185       push();
     2377    {
     2378      int sym = new_sym(s, nsym(tree));
     2379
     2380      genop_2(s, OP_GETCV, cursp(), sym);
     2381      if (val) push();
    21862382    }
    21872383    break;
     
    21892385  case NODE_CONST:
    21902386    {
    2191       int sym = new_sym(s, sym(tree));
    2192 
    2193       genop(s, MKOP_ABx(OP_GETCONST, cursp(), sym));
    2194       if (val) {
    2195         push();
    2196       }
    2197     }
    2198     break;
    2199 
    2200   case NODE_DEFINED:
    2201     codegen(s, tree, VAL);
     2387      int sym = new_sym(s, nsym(tree));
     2388
     2389      genop_2(s, OP_GETCONST, cursp(), sym);
     2390      if (val) push();
     2391    }
    22022392    break;
    22032393
    22042394  case NODE_BACK_REF:
    22052395    if (val) {
    2206       char buf[3];
    2207       int sym;
    2208 
    2209       buf[0] = '$';
    2210       buf[1] = (char)(intptr_t)tree;
    2211       buf[2] = 0;
    2212       sym = new_sym(s, mrb_intern_cstr(s->mrb, buf));
    2213       genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));
     2396      char buf[] = {'$', nchar(tree)};
     2397      int sym = new_sym(s, mrb_intern(s->mrb, buf, sizeof(buf)));
     2398
     2399      genop_2(s, OP_GETGV, cursp(), sym);
    22142400      push();
    22152401    }
     
    22222408      int sym;
    22232409
    2224       str = mrb_format(mrb, "$%S", mrb_fixnum_value((mrb_int)(intptr_t)tree));
     2410      str = mrb_format(mrb, "$%d", nint(tree));
    22252411      sym = new_sym(s, mrb_intern_str(mrb, str));
    2226       genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));
     2412      genop_2(s, OP_GETGV, cursp(), sym);
    22272413      push();
    22282414    }
     
    22342420
    22352421  case NODE_BLOCK_ARG:
    2236     codegen(s, tree, VAL);
     2422    codegen(s, tree, val);
    22372423    break;
    22382424
     
    22402426    if (val) {
    22412427      char *p = (char*)tree->car;
    2242       int base = (intptr_t)tree->cdr->car;
     2428      int base = nint(tree->cdr->car);
    22432429      mrb_int i;
    2244       mrb_code co;
    22452430      mrb_bool overflow;
    22462431
    22472432      i = readint_mrb_int(s, p, base, FALSE, &overflow);
     2433#ifndef MRB_WITHOUT_FLOAT
    22482434      if (overflow) {
    22492435        double f = readint_float(s, p, base);
    22502436        int off = new_lit(s, mrb_float_value(s->mrb, f));
    22512437
    2252         genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
    2253       }
    2254       else {
    2255         if (i < MAXARG_sBx && i > -MAXARG_sBx) {
    2256           co = MKOP_AsBx(OP_LOADI, cursp(), i);
    2257         }
     2438        genop_2(s, OP_LOADL, cursp(), off);
     2439      }
     2440      else
     2441#endif
     2442      {
     2443        if (i == -1) genop_1(s, OP_LOADI__1, cursp());
     2444        else if (i < 0) genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i);
     2445        else if (i < 8) genop_1(s, OP_LOADI_0 + (uint8_t)i, cursp());
     2446        else if (i <= 0xffff) genop_2(s, OP_LOADI, cursp(), (uint16_t)i);
    22582447        else {
    22592448          int off = new_lit(s, mrb_fixnum_value(i));
    2260           co = MKOP_ABx(OP_LOADL, cursp(), off);
    2261         }
    2262         genop(s, co);
     2449          genop_2(s, OP_LOADL, cursp(), off);
     2450        }
    22632451      }
    22642452      push();
     
    22662454    break;
    22672455
     2456#ifndef MRB_WITHOUT_FLOAT
    22682457  case NODE_FLOAT:
    22692458    if (val) {
     
    22722461      int off = new_lit(s, mrb_float_value(s->mrb, f));
    22732462
    2274       genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
     2463      genop_2(s, OP_LOADL, cursp(), off);
    22752464      push();
    22762465    }
    22772466    break;
     2467#endif
    22782468
    22792469  case NODE_NEGATE:
    22802470    {
    2281       nt = (intptr_t)tree->car;
    2282       tree = tree->cdr;
     2471      nt = nint(tree->car);
    22832472      switch (nt) {
     2473#ifndef MRB_WITHOUT_FLOAT
    22842474      case NODE_FLOAT:
    22852475        if (val) {
    2286           char *p = (char*)tree;
     2476          char *p = (char*)tree->cdr;
    22872477          mrb_float f = mrb_float_read(p, NULL);
    22882478          int off = new_lit(s, mrb_float_value(s->mrb, -f));
    22892479
    2290           genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
     2480          genop_2(s, OP_LOADL, cursp(), off);
    22912481          push();
    22922482        }
    22932483        break;
     2484#endif
    22942485
    22952486      case NODE_INT:
    22962487        if (val) {
    2297           char *p = (char*)tree->car;
    2298           int base = (intptr_t)tree->cdr->car;
     2488          char *p = (char*)tree->cdr->car;
     2489          int base = nint(tree->cdr->cdr->car);
    22992490          mrb_int i;
    2300           mrb_code co;
    23012491          mrb_bool overflow;
    23022492
    23032493          i = readint_mrb_int(s, p, base, TRUE, &overflow);
     2494#ifndef MRB_WITHOUT_FLOAT
    23042495          if (overflow) {
    23052496            double f = readint_float(s, p, base);
    23062497            int off = new_lit(s, mrb_float_value(s->mrb, -f));
    23072498
    2308             genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
     2499            genop_2(s, OP_LOADL, cursp(), off);
    23092500          }
    23102501          else {
    2311             if (i < MAXARG_sBx && i > -MAXARG_sBx) {
    2312               co = MKOP_AsBx(OP_LOADI, cursp(), i);
     2502#endif
     2503            if (i == -1) genop_1(s, OP_LOADI__1, cursp());
     2504            else if (i >= -0xffff) {
     2505              genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i);
    23132506            }
    23142507            else {
    23152508              int off = new_lit(s, mrb_fixnum_value(i));
    2316               co = MKOP_ABx(OP_LOADL, cursp(), off);
     2509              genop_2(s, OP_LOADL, cursp(), off);
    23172510            }
    2318             genop(s, co);
    2319           }
     2511#ifndef MRB_WITHOUT_FLOAT
     2512          }
     2513#endif
    23202514          push();
    23212515        }
     
    23242518      default:
    23252519        if (val) {
    2326           int sym = new_msym(s, mrb_intern_lit(s->mrb, "-"));
    2327 
    2328           genop(s, MKOP_ABx(OP_LOADI, cursp(), 0));
     2520          int sym = new_sym(s, mrb_intern_lit(s->mrb, "-@"));
     2521          codegen(s, tree, VAL);
     2522          pop();
     2523          genop_3(s, OP_SEND, cursp(), sym, 0);
    23292524          push();
    2330           codegen(s, tree, VAL);
    2331           pop(); pop();
    2332           genop(s, MKOP_ABC(OP_SUB, cursp(), sym, 2));
    23332525        }
    23342526        else {
     
    23482540
    23492541      mrb_gc_arena_restore(s->mrb, ai);
    2350       genop(s, MKOP_ABx(OP_STRING, cursp(), off));
     2542      genop_2(s, OP_STRING, cursp(), off);
    23512543      push();
    23522544    }
     
    23612553
    23622554      if (!n) {
    2363         genop(s, MKOP_A(OP_LOADNIL, cursp()));
     2555        genop_1(s, OP_LOADNIL, cursp());
    23642556        push();
    23652557        break;
     
    23702562        codegen(s, n->car, VAL);
    23712563        pop(); pop();
    2372         genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
     2564        genop_1(s, OP_STRCAT, cursp());
    23732565        push();
    23742566        n = n->cdr;
     
    23792571
    23802572      while (n) {
    2381         if ((intptr_t)n->car->car != NODE_STR) {
     2573        if (nint(n->car->car) != NODE_STR) {
    23822574          codegen(s, n->car, NOVAL);
    23832575        }
     
    24012593      int sym = new_sym(s, mrb_intern_lit(s->mrb, "Kernel"));
    24022594
    2403       genop(s, MKOP_A(OP_LOADSELF, cursp()));
     2595      genop_1(s, OP_LOADSELF, cursp());
    24042596      push();
    24052597      codegen(s, tree->car, VAL);
    24062598      n = tree->cdr;
    24072599      while (n) {
    2408         if ((intptr_t)n->car->car == NODE_XSTR) {
     2600        if (nint(n->car->car) == NODE_XSTR) {
    24092601          n->car->car = (struct mrb_ast_node*)(intptr_t)NODE_STR;
    24102602          mrb_assert(!n->cdr); /* must be the end */
     
    24122604        codegen(s, n->car, VAL);
    24132605        pop(); pop();
    2414         genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
     2606        genop_1(s, OP_STRCAT, cursp());
    24152607        push();
    24162608        n = n->cdr;
     
    24192611      pop_n(3);
    24202612      sym = new_sym(s, mrb_intern_lit(s->mrb, "`"));
    2421       genop(s, MKOP_ABC(OP_SEND, cursp(), sym, 1));
     2613      genop_3(s, OP_SEND, cursp(), sym, 1);
    24222614      if (val) push();
    24232615      mrb_gc_arena_restore(s->mrb, ai);
     
    24332625      int sym;
    24342626
    2435       genop(s, MKOP_A(OP_LOADSELF, cursp()));
     2627      genop_1(s, OP_LOADSELF, cursp());
    24362628      push();
    2437       genop(s, MKOP_ABx(OP_STRING, cursp(), off));
     2629      genop_2(s, OP_STRING, cursp(), off);
    24382630      push(); push();
    24392631      pop_n(3);
    24402632      sym = new_sym(s, mrb_intern_lit(s->mrb, "`"));
    2441       genop(s, MKOP_ABC(OP_SEND, cursp(), sym, 1));
     2633      genop_3(s, OP_SEND, cursp(), sym, 1);
    24422634      if (val) push();
    24432635      mrb_gc_arena_restore(s->mrb, ai);
     
    24552647      int argc = 1;
    24562648
    2457       genop(s, MKOP_A(OP_OCLASS, cursp()));
    2458       genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
     2649      genop_1(s, OP_OCLASS, cursp());
     2650      genop_2(s, OP_GETMCNST, cursp(), sym);
    24592651      push();
    2460       genop(s, MKOP_ABx(OP_STRING, cursp(), off));
     2652      genop_2(s, OP_STRING, cursp(), off);
     2653      push();
    24612654      if (p2 || p3) {
     2655        if (p2) { /* opt */
     2656          off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
     2657          genop_2(s, OP_STRING, cursp(), off);
     2658        }
     2659        else {
     2660          genop_1(s, OP_LOADNIL, cursp());
     2661        }
    24622662        push();
    2463         if (p2) {
    2464           off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
    2465           genop(s, MKOP_ABx(OP_STRING, cursp(), off));
    2466         }
    2467         else {
    2468           genop(s, MKOP_A(OP_LOADNIL, cursp()));
    2469         }
    24702663        argc++;
    2471         if (p3) {
     2664        if (p3) { /* enc */
     2665          off = new_lit(s, mrb_str_new(s->mrb, p3, 1));
     2666          genop_2(s, OP_STRING, cursp(), off);
    24722667          push();
    2473           off = new_lit(s, mrb_str_new(s->mrb, p3, 1));
    2474           genop(s, MKOP_ABx(OP_STRING, cursp(), off));
    24752668          argc++;
    2476           pop();
    2477         }
    2478         pop();
    2479       }
    2480       pop();
     2669        }
     2670      }
     2671      push(); /* space for a block */
     2672      pop_n(argc+2);
    24812673      sym = new_sym(s, mrb_intern_lit(s->mrb, "compile"));
    2482       genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc));
     2674      genop_3(s, OP_SEND, cursp(), sym, argc);
    24832675      mrb_gc_arena_restore(s->mrb, ai);
    24842676      push();
     
    24952687      char *p;
    24962688
    2497       genop(s, MKOP_A(OP_OCLASS, cursp()));
    2498       genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
     2689      genop_1(s, OP_OCLASS, cursp());
     2690      genop_2(s, OP_GETMCNST, cursp(), sym);
    24992691      push();
    25002692      codegen(s, n->car, VAL);
     
    25032695        codegen(s, n->car, VAL);
    25042696        pop(); pop();
    2505         genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
     2697        genop_1(s, OP_STRCAT, cursp());
    25062698        push();
    25072699        n = n->cdr;
    25082700      }
    25092701      n = tree->cdr->cdr;
    2510       if (n->car) {
     2702      if (n->car) { /* tail */
    25112703        p = (char*)n->car;
    25122704        off = new_lit(s, mrb_str_new_cstr(s->mrb, p));
    25132705        codegen(s, tree->car, VAL);
    2514         genop(s, MKOP_ABx(OP_STRING, cursp(), off));
     2706        genop_2(s, OP_STRING, cursp(), off);
    25152707        pop();
    2516         genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
    2517       }
    2518       if (n->cdr->car) {
     2708        genop_1(s, OP_STRCAT, cursp());
     2709        push();
     2710      }
     2711      if (n->cdr->car) { /* opt */
    25192712        char *p2 = (char*)n->cdr->car;
    2520 
     2713        off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
     2714        genop_2(s, OP_STRING, cursp(), off);
    25212715        push();
     2716        argc++;
     2717      }
     2718      if (n->cdr->cdr) { /* enc */
     2719        char *p2 = (char*)n->cdr->cdr;
    25222720        off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
    2523         genop(s, MKOP_ABx(OP_STRING, cursp(), off));
     2721        genop_2(s, OP_STRING, cursp(), off);
     2722        push();
    25242723        argc++;
    25252724      }
    2526       if (n->cdr->cdr) {
    2527         char *p2 = (char*)n->cdr->cdr;
    2528 
    2529         push();
    2530         off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));
    2531         genop(s, MKOP_ABx(OP_STRING, cursp(), off));
    2532         argc++;
    2533       }
    2534       pop_n(argc);
     2725      push(); /* space for a block */
     2726      pop_n(argc+2);
    25352727      sym = new_sym(s, mrb_intern_lit(s->mrb, "compile"));
    2536       genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc));
     2728      genop_3(s, OP_SEND, cursp(), sym, argc);
    25372729      mrb_gc_arena_restore(s->mrb, ai);
    25382730      push();
     
    25422734
    25432735      while (n) {
    2544         if ((intptr_t)n->car->car != NODE_STR) {
     2736        if (nint(n->car->car) != NODE_STR) {
    25452737          codegen(s, n->car, NOVAL);
    25462738        }
     
    25522744  case NODE_SYM:
    25532745    if (val) {
    2554       int sym = new_sym(s, sym(tree));
    2555 
    2556       genop(s, MKOP_ABx(OP_LOADSYM, cursp(), sym));
     2746      int sym = new_sym(s, nsym(tree));
     2747
     2748      genop_2(s, OP_LOADSYM, cursp(), sym);
    25572749      push();
    25582750    }
     
    25622754    codegen(s, tree, val);
    25632755    if (val) {
    2564       gen_send_intern(s);
     2756      gen_intern(s);
    25652757    }
    25662758    break;
     
    25682760  case NODE_SELF:
    25692761    if (val) {
    2570       genop(s, MKOP_A(OP_LOADSELF, cursp()));
     2762      genop_1(s, OP_LOADSELF, cursp());
    25712763      push();
    25722764    }
     
    25752767  case NODE_NIL:
    25762768    if (val) {
    2577       genop(s, MKOP_A(OP_LOADNIL, cursp()));
     2769      genop_1(s, OP_LOADNIL, cursp());
    25782770      push();
    25792771    }
     
    25822774  case NODE_TRUE:
    25832775    if (val) {
    2584       genop(s, MKOP_A(OP_LOADT, cursp()));
     2776      genop_1(s, OP_LOADT, cursp());
    25852777      push();
    25862778    }
     
    25892781  case NODE_FALSE:
    25902782    if (val) {
    2591       genop(s, MKOP_A(OP_LOADF, cursp()));
     2783      genop_1(s, OP_LOADF, cursp());
    25922784      push();
    25932785    }
     
    25962788  case NODE_ALIAS:
    25972789    {
    2598       int a = new_msym(s, sym(tree->car));
    2599       int b = new_msym(s, sym(tree->cdr));
    2600       int c = new_msym(s, mrb_intern_lit(s->mrb, "alias_method"));
    2601 
    2602       genop(s, MKOP_A(OP_TCLASS, cursp()));
    2603       push();
    2604       genop(s, MKOP_ABx(OP_LOADSYM, cursp(), a));
    2605       push();
    2606       genop(s, MKOP_ABx(OP_LOADSYM, cursp(), b));
    2607       push();
    2608       genop(s, MKOP_A(OP_LOADNIL, cursp()));
    2609       push();
    2610       pop_n(4);
    2611       genop(s, MKOP_ABC(OP_SEND, cursp(), c, 2));
     2790      int a = new_sym(s, nsym(tree->car));
     2791      int b = new_sym(s, nsym(tree->cdr));
     2792
     2793      genop_2(s, OP_ALIAS, a, b);
    26122794      if (val) {
     2795        genop_1(s, OP_LOADNIL, cursp());
    26132796        push();
    26142797      }
     
    26182801  case NODE_UNDEF:
    26192802    {
    2620       int undef = new_msym(s, mrb_intern_lit(s->mrb, "undef_method"));
    2621       int num = 0;
    26222803      node *t = tree;
    26232804
    2624       genop(s, MKOP_A(OP_TCLASS, cursp()));
    2625       push();
    26262805      while (t) {
    2627         int symbol;
    2628         if (num >= CALL_MAXARGS - 1) {
    2629           pop_n(num);
    2630           genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), num));
    2631           while (t) {
    2632             symbol = new_msym(s, sym(t->car));
    2633             push();
    2634             genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol));
    2635             pop();
    2636             genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));
    2637             t = t->cdr;
    2638           }
    2639           num = CALL_MAXARGS;
    2640           break;
    2641         }
    2642         symbol = new_msym(s, sym(t->car));
    2643         genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol));
    2644         push();
     2806        int symbol = new_sym(s, nsym(t->car));
     2807        genop_1(s, OP_UNDEF, symbol);
    26452808        t = t->cdr;
    2646         num++;
    2647       }
    2648       pop();
    2649       if (num < CALL_MAXARGS) {
    2650         pop_n(num);
    2651       }
    2652       genop(s, MKOP_ABC(OP_SEND, cursp(), undef, num));
     2809      }
    26532810      if (val) {
     2811        genop_1(s, OP_LOADNIL, cursp());
    26542812        push();
    26552813      }
     
    26602818    {
    26612819      int idx;
     2820      node *body;
    26622821
    26632822      if (tree->car->car == (node*)0) {
    2664         genop(s, MKOP_A(OP_LOADNIL, cursp()));
     2823        genop_1(s, OP_LOADNIL, cursp());
    26652824        push();
    26662825      }
    26672826      else if (tree->car->car == (node*)1) {
    2668         genop(s, MKOP_A(OP_OCLASS, cursp()));
     2827        genop_1(s, OP_OCLASS, cursp());
    26692828        push();
    26702829      }
     
    26762835      }
    26772836      else {
    2678         genop(s, MKOP_A(OP_LOADNIL, cursp()));
     2837        genop_1(s, OP_LOADNIL, cursp());
    26792838        push();
    26802839      }
    26812840      pop(); pop();
    2682       idx = new_msym(s, sym(tree->car->cdr));
    2683       genop(s, MKOP_AB(OP_CLASS, cursp(), idx));
    2684       idx = scope_body(s, tree->cdr->cdr->car, val);
    2685       genop(s, MKOP_ABx(OP_EXEC, cursp(), idx));
     2841      idx = new_sym(s, nsym(tree->car->cdr));
     2842      genop_2(s, OP_CLASS, cursp(), idx);
     2843      body = tree->cdr->cdr->car;
     2844      if (nint(body->cdr->car) == NODE_BEGIN && body->cdr->cdr == NULL) {
     2845        genop_1(s, OP_LOADNIL, cursp());
     2846      }
     2847      else {
     2848        idx = scope_body(s, body, val);
     2849        genop_2(s, OP_EXEC, cursp(), idx);
     2850      }
    26862851      if (val) {
    26872852        push();
     
    26952860
    26962861      if (tree->car->car == (node*)0) {
    2697         genop(s, MKOP_A(OP_LOADNIL, cursp()));
     2862        genop_1(s, OP_LOADNIL, cursp());
    26982863        push();
    26992864      }
    27002865      else if (tree->car->car == (node*)1) {
    2701         genop(s, MKOP_A(OP_OCLASS, cursp()));
     2866        genop_1(s, OP_OCLASS, cursp());
    27022867        push();
    27032868      }
     
    27062871      }
    27072872      pop();
    2708       idx = new_msym(s, sym(tree->car->cdr));
    2709       genop(s, MKOP_AB(OP_MODULE, cursp(), idx));
    2710       idx = scope_body(s, tree->cdr->car, val);
    2711       genop(s, MKOP_ABx(OP_EXEC, cursp(), idx));
     2873      idx = new_sym(s, nsym(tree->car->cdr));
     2874      genop_2(s, OP_MODULE, cursp(), idx);
     2875      if (nint(tree->cdr->car->cdr->car) == NODE_BEGIN &&
     2876          tree->cdr->car->cdr->cdr == NULL) {
     2877        genop_1(s, OP_LOADNIL, cursp());
     2878      }
     2879      else {
     2880        idx = scope_body(s, tree->cdr->car, val);
     2881        genop_2(s, OP_EXEC, cursp(), idx);
     2882      }
    27122883      if (val) {
    27132884        push();
     
    27222893      codegen(s, tree->car, VAL);
    27232894      pop();
    2724       genop(s, MKOP_AB(OP_SCLASS, cursp(), cursp()));
    2725       idx = scope_body(s, tree->cdr->car, val);
    2726       genop(s, MKOP_ABx(OP_EXEC, cursp(), idx));
     2895      genop_1(s, OP_SCLASS, cursp());
     2896      if (nint(tree->cdr->car->cdr->car) == NODE_BEGIN &&
     2897          tree->cdr->car->cdr->cdr == NULL) {
     2898        genop_1(s, OP_LOADNIL, cursp());
     2899      }
     2900      else {
     2901        idx = scope_body(s, tree->cdr->car, val);
     2902        genop_2(s, OP_EXEC, cursp(), idx);
     2903      }
    27272904      if (val) {
    27282905        push();
     
    27332910  case NODE_DEF:
    27342911    {
    2735       int sym = new_msym(s, sym(tree->car));
     2912      int sym = new_sym(s, nsym(tree->car));
    27362913      int idx = lambda_body(s, tree->cdr, 0);
    27372914
    2738       genop(s, MKOP_A(OP_TCLASS, cursp()));
     2915      genop_1(s, OP_TCLASS, cursp());
    27392916      push();
    2740       genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_METHOD));
     2917      genop_2(s, OP_METHOD, cursp(), idx);
    27412918      push(); pop();
    27422919      pop();
    2743       genop(s, MKOP_AB(OP_METHOD, cursp(), sym));
     2920      genop_2(s, OP_DEF, cursp(), sym);
    27442921      if (val) {
    2745         genop(s, MKOP_ABx(OP_LOADSYM, cursp(), sym));
     2922        genop_2(s, OP_LOADSYM, cursp(), sym);
    27462923        push();
    27472924      }
     
    27522929    {
    27532930      node *recv = tree->car;
    2754       int sym = new_msym(s, sym(tree->cdr->car));
     2931      int sym = new_sym(s, nsym(tree->cdr->car));
    27552932      int idx = lambda_body(s, tree->cdr->cdr, 0);
    27562933
    27572934      codegen(s, recv, VAL);
    27582935      pop();
    2759       genop(s, MKOP_AB(OP_SCLASS, cursp(), cursp()));
     2936      genop_1(s, OP_SCLASS, cursp());
    27602937      push();
    2761       genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_METHOD));
     2938      genop_2(s, OP_METHOD, cursp(), idx);
    27622939      pop();
    2763       genop(s, MKOP_AB(OP_METHOD, cursp(), sym));
     2940      genop_2(s, OP_DEF, cursp(), sym);
    27642941      if (val) {
    2765         genop(s, MKOP_ABx(OP_LOADSYM, cursp(), sym));
     2942        genop_2(s, OP_LOADSYM, cursp(), sym);
    27662943        push();
    27672944      }
     
    28022979  codegen_scope *p = (codegen_scope *)mrb_pool_alloc(pool, sizeof(codegen_scope));
    28032980
    2804   if (!p) return NULL;
     2981  if (!p) {
     2982    if (prev)
     2983      codegen_error(prev, "unexpected scope");
     2984    return NULL;
     2985  }
    28052986  *p = codegen_scope_zero;
    28062987  p->mrb = mrb;
     
    28253006  p->irep->plen = 0;
    28263007
    2827   p->scapa = MAXMSYMLEN;
     3008  p->scapa = 256;
    28283009  p->irep->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*p->scapa);
    28293010  p->irep->slen = 0;
     
    28503031  p->ai = mrb_gc_arena_save(mrb);
    28513032
    2852   p->filename = prev->filename;
    2853   if (p->filename) {
     3033  p->filename_sym = prev->filename_sym;
     3034  if (p->filename_sym) {
    28543035    p->lines = (uint16_t*)mrb_malloc(mrb, sizeof(short)*p->icapa);
    28553036  }
     
    28583039  /* debug setting */
    28593040  p->debug_start_pos = 0;
    2860   if (p->filename) {
     3041  if (p->filename_sym) {
    28613042    mrb_debug_info_alloc(mrb, p->irep);
    2862     p->irep->filename = p->filename;
    2863     p->irep->lines = p->lines;
    28643043  }
    28653044  else {
     
    28793058  mrb_state *mrb = s->mrb;
    28803059  mrb_irep *irep = s->irep;
    2881   size_t fname_len;
    2882   char *fname;
    2883 
     3060
     3061  if (s->nlocals >= 0x3ff) {
     3062    codegen_error(s, "too many local variables");
     3063  }
    28843064  irep->flags = 0;
    28853065  if (s->iseq) {
    28863066    irep->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->pc);
    28873067    irep->ilen = s->pc;
    2888     if (s->lines) {
    2889       irep->lines = (uint16_t *)codegen_realloc(s, s->lines, sizeof(uint16_t)*s->pc);
    2890     }
    2891     else {
    2892       irep->lines = 0;
    2893     }
    28943068  }
    28953069  irep->pool = (mrb_value*)codegen_realloc(s, irep->pool, sizeof(mrb_value)*irep->plen);
    28963070  irep->syms = (mrb_sym*)codegen_realloc(s, irep->syms, sizeof(mrb_sym)*irep->slen);
    28973071  irep->reps = (mrb_irep**)codegen_realloc(s, irep->reps, sizeof(mrb_irep*)*irep->rlen);
    2898   if (s->filename) {
    2899     irep->filename = mrb_parser_get_filename(s->parser, s->filename_index);
    2900     mrb_debug_info_append_file(mrb, irep, s->debug_start_pos, s->pc);
    2901 
    2902     fname_len = strlen(s->filename);
    2903     fname = (char*)codegen_malloc(s, fname_len + 1);
    2904     memcpy(fname, s->filename, fname_len);
    2905     fname[fname_len] = '\0';
    2906     irep->filename = fname;
    2907     irep->own_filename = TRUE;
    2908   }
     3072  if (s->filename_sym) {
     3073    mrb_sym fname = mrb_parser_get_filename(s->parser, s->filename_index);
     3074    const char *filename = mrb_sym_name_len(s->mrb, fname, NULL);
     3075
     3076    mrb_debug_info_append_file(s->mrb, s->irep->debug_info,
     3077                               filename, s->lines, s->debug_start_pos, s->pc);
     3078  }
     3079  mrb_free(s->mrb, s->lines);
    29093080
    29103081  irep->nlocals = s->nlocals;
     
    29213092
    29223093  p->type = t;
    2923   p->pc1 = p->pc2 = p->pc3 = 0;
     3094  p->pc0 = p->pc1 = p->pc2 = p->pc3 = 0;
    29243095  p->prev = s->loop;
    29253096  p->ensure_level = s->ensure_level;
     
    29393110  else {
    29403111    struct loopinfo *loop;
     3112    int n = 0;
    29413113
    29423114    if (tree) {
     
    29453117
    29463118    loop = s->loop;
    2947     while (loop && loop->type == LOOP_BEGIN) {
    2948       genop_peep(s, MKOP_A(OP_POPERR, 1), NOVAL);
    2949       loop = loop->prev;
    2950     }
    2951     while (loop && loop->type == LOOP_RESCUE) {
    2952       loop = loop->prev;
     3119    while (loop) {
     3120      if (loop->type == LOOP_BEGIN) {
     3121        n++;
     3122        loop = loop->prev;
     3123      }
     3124      else if (loop->type == LOOP_RESCUE) {
     3125        loop = loop->prev;
     3126      }
     3127      else{
     3128        break;
     3129      }
    29533130    }
    29543131    if (!loop) {
     
    29563133      return;
    29573134    }
     3135    if (n > 0) {
     3136      genop_1(s, OP_POPERR, n);
     3137    }
    29583138
    29593139    if (loop->type == LOOP_NORMAL) {
     
    29613141
    29623142      if (s->ensure_level > s->loop->ensure_level) {
    2963         genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);
     3143        genop_1(s, OP_EPOP, s->ensure_level - s->loop->ensure_level);
    29643144      }
    29653145      if (tree) {
    2966         genop_peep(s, MKOP_AB(OP_MOVE, loop->acc, cursp()), NOVAL);
    2967       }
    2968       tmp = genop(s, MKOP_sBx(OP_JMP, loop->pc3));
     3146        gen_move(s, loop->acc, cursp(), 0);
     3147      }
     3148      tmp = genjmp(s, OP_JMP, loop->pc3);
    29693149      loop->pc3 = tmp;
    29703150    }
    29713151    else {
    29723152      if (!tree) {
    2973         genop(s, MKOP_A(OP_LOADNIL, cursp()));
    2974       }
    2975       genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_BREAK));
     3153        genop_1(s, OP_LOADNIL, cursp());
     3154      }
     3155      gen_return(s, OP_BREAK, cursp());
    29763156    }
    29773157  }
     
    29813161loop_pop(codegen_scope *s, int val)
    29823162{
     3163  if (val) {
     3164    genop_1(s, OP_LOADNIL, cursp());
     3165  }
    29833166  dispatch_linked(s, s->loop->pc3);
    2984   if (val) {
    2985     genop(s, MKOP_A(OP_LOADNIL, cursp()));
    2986   }
    29873167  s->loop = s->loop->prev;
    29883168  if (val) push();
    29893169}
    29903170
    2991 MRB_API struct RProc*
    2992 mrb_generate_code(mrb_state *mrb, parser_state *p)
     3171static struct RProc*
     3172generate_code(mrb_state *mrb, parser_state *p, int val)
    29933173{
    29943174  codegen_scope *scope = scope_new(mrb, 0, 0);
     
    29963176  struct mrb_jmpbuf *prev_jmp = mrb->jmp;
    29973177
    2998   if (!scope) {
    2999     return NULL;
    3000   }
    30013178  scope->mrb = mrb;
    30023179  scope->parser = p;
    3003   scope->filename = p->filename;
     3180  scope->filename_sym = p->filename_sym;
    30043181  scope->filename_index = p->current_filename_index;
    30053182
    30063183  MRB_TRY(&scope->jmp) {
    3007     mrb->jmp = &scope->jmp; 
     3184    mrb->jmp = &scope->jmp;
    30083185    /* prepare irep */
    3009     codegen(scope, p->tree, NOVAL);
     3186    codegen(scope, p->tree, val);
    30103187    proc = mrb_proc_new(mrb, scope->irep);
    30113188    mrb_irep_decref(mrb, scope->irep);
    30123189    mrb_pool_close(scope->mpool);
    30133190    proc->c = NULL;
     3191    if (mrb->c->cibase && mrb->c->cibase->proc == proc->upper) {
     3192      proc->upper = NULL;
     3193    }
    30143194    mrb->jmp = prev_jmp;
    30153195    return proc;
     
    30233203  MRB_END_EXC(&scope->jmp);
    30243204}
     3205
     3206MRB_API struct RProc*
     3207mrb_generate_code(mrb_state *mrb, parser_state *p)
     3208{
     3209  return generate_code(mrb, p, VAL);
     3210}
     3211
     3212void
     3213mrb_irep_remove_lv(mrb_state *mrb, mrb_irep *irep)
     3214{
     3215  int i;
     3216
     3217  if (irep->lv) {
     3218    mrb_free(mrb, irep->lv);
     3219    irep->lv = NULL;
     3220  }
     3221
     3222  for (i = 0; i < irep->rlen; ++i) {
     3223    mrb_irep_remove_lv(mrb, irep->reps[i]);
     3224  }
     3225}
     3226
     3227#undef OPCODE
     3228#define Z 1
     3229#define S 3
     3230#define W 4
     3231/* instruction sizes */
     3232uint8_t mrb_insn_size[] = {
     3233#define B 2
     3234#define BB 3
     3235#define BBB 4
     3236#define BS 4
     3237#define SB 4
     3238#define OPCODE(_,x) x,
     3239#include "mruby/ops.h"
     3240#undef OPCODE
     3241#undef B
     3242#undef BB
     3243#undef BS
     3244#undef SB
     3245#undef BBB
     3246};
     3247/* EXT1 instruction sizes */
     3248uint8_t mrb_insn_size1[] = {
     3249#define B 3
     3250#define BB 4
     3251#define BBB 5
     3252#define BS 5
     3253#define SB 5
     3254#define OPCODE(_,x) x,
     3255#include "mruby/ops.h"
     3256#undef OPCODE
     3257#undef B
     3258};
     3259/* EXT2 instruction sizes */
     3260uint8_t mrb_insn_size2[] = {
     3261#define B 2
     3262#define OPCODE(_,x) x,
     3263#include "mruby/ops.h"
     3264#undef OPCODE
     3265#undef BB
     3266#undef BBB
     3267#undef BS
     3268#undef SB
     3269};
     3270/* EXT3 instruction sizes */
     3271#define BB 5
     3272#define BBB 6
     3273#define BS 4
     3274#define SB 5
     3275uint8_t mrb_insn_size3[] = {
     3276#define OPCODE(_,x) x,
     3277#include "mruby/ops.h"
     3278};
Note: See TracChangeset for help on using the changeset viewer.