misc/liblua/lcode.c
changeset 2812 0a24853de796
child 10017 de822cd3df3a
equal deleted inserted replaced
2811:4cad87e11bf6 2812:0a24853de796
       
     1 /*
       
     2 ** $Id: lcode.c,v 2.25.1.3 2007/12/28 15:32:23 roberto Exp $
       
     3 ** Code generator for Lua
       
     4 ** See Copyright Notice in lua.h
       
     5 */
       
     6 
       
     7 
       
     8 #include <stdlib.h>
       
     9 
       
    10 #define lcode_c
       
    11 #define LUA_CORE
       
    12 
       
    13 #include "lua.h"
       
    14 
       
    15 #include "lcode.h"
       
    16 #include "ldebug.h"
       
    17 #include "ldo.h"
       
    18 #include "lgc.h"
       
    19 #include "llex.h"
       
    20 #include "lmem.h"
       
    21 #include "lobject.h"
       
    22 #include "lopcodes.h"
       
    23 #include "lparser.h"
       
    24 #include "ltable.h"
       
    25 
       
    26 
       
    27 #define hasjumps(e)	((e)->t != (e)->f)
       
    28 
       
    29 
       
    30 static int isnumeral(expdesc *e) {
       
    31   return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
       
    32 }
       
    33 
       
    34 
       
    35 void luaK_nil (FuncState *fs, int from, int n) {
       
    36   Instruction *previous;
       
    37   if (fs->pc > fs->lasttarget) {  /* no jumps to current position? */
       
    38     if (fs->pc == 0) {  /* function start? */
       
    39       if (from >= fs->nactvar)
       
    40         return;  /* positions are already clean */
       
    41     }
       
    42     else {
       
    43       previous = &fs->f->code[fs->pc-1];
       
    44       if (GET_OPCODE(*previous) == OP_LOADNIL) {
       
    45         int pfrom = GETARG_A(*previous);
       
    46         int pto = GETARG_B(*previous);
       
    47         if (pfrom <= from && from <= pto+1) {  /* can connect both? */
       
    48           if (from+n-1 > pto)
       
    49             SETARG_B(*previous, from+n-1);
       
    50           return;
       
    51         }
       
    52       }
       
    53     }
       
    54   }
       
    55   luaK_codeABC(fs, OP_LOADNIL, from, from+n-1, 0);  /* else no optimization */
       
    56 }
       
    57 
       
    58 
       
    59 int luaK_jump (FuncState *fs) {
       
    60   int jpc = fs->jpc;  /* save list of jumps to here */
       
    61   int j;
       
    62   fs->jpc = NO_JUMP;
       
    63   j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
       
    64   luaK_concat(fs, &j, jpc);  /* keep them on hold */
       
    65   return j;
       
    66 }
       
    67 
       
    68 
       
    69 void luaK_ret (FuncState *fs, int first, int nret) {
       
    70   luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
       
    71 }
       
    72 
       
    73 
       
    74 static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
       
    75   luaK_codeABC(fs, op, A, B, C);
       
    76   return luaK_jump(fs);
       
    77 }
       
    78 
       
    79 
       
    80 static void fixjump (FuncState *fs, int pc, int dest) {
       
    81   Instruction *jmp = &fs->f->code[pc];
       
    82   int offset = dest-(pc+1);
       
    83   lua_assert(dest != NO_JUMP);
       
    84   if (abs(offset) > MAXARG_sBx)
       
    85     luaX_syntaxerror(fs->ls, "control structure too long");
       
    86   SETARG_sBx(*jmp, offset);
       
    87 }
       
    88 
       
    89 
       
    90 /*
       
    91 ** returns current `pc' and marks it as a jump target (to avoid wrong
       
    92 ** optimizations with consecutive instructions not in the same basic block).
       
    93 */
       
    94 int luaK_getlabel (FuncState *fs) {
       
    95   fs->lasttarget = fs->pc;
       
    96   return fs->pc;
       
    97 }
       
    98 
       
    99 
       
   100 static int getjump (FuncState *fs, int pc) {
       
   101   int offset = GETARG_sBx(fs->f->code[pc]);
       
   102   if (offset == NO_JUMP)  /* point to itself represents end of list */
       
   103     return NO_JUMP;  /* end of list */
       
   104   else
       
   105     return (pc+1)+offset;  /* turn offset into absolute position */
       
   106 }
       
   107 
       
   108 
       
   109 static Instruction *getjumpcontrol (FuncState *fs, int pc) {
       
   110   Instruction *pi = &fs->f->code[pc];
       
   111   if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
       
   112     return pi-1;
       
   113   else
       
   114     return pi;
       
   115 }
       
   116 
       
   117 
       
   118 /*
       
   119 ** check whether list has any jump that do not produce a value
       
   120 ** (or produce an inverted value)
       
   121 */
       
   122 static int need_value (FuncState *fs, int list) {
       
   123   for (; list != NO_JUMP; list = getjump(fs, list)) {
       
   124     Instruction i = *getjumpcontrol(fs, list);
       
   125     if (GET_OPCODE(i) != OP_TESTSET) return 1;
       
   126   }
       
   127   return 0;  /* not found */
       
   128 }
       
   129 
       
   130 
       
   131 static int patchtestreg (FuncState *fs, int node, int reg) {
       
   132   Instruction *i = getjumpcontrol(fs, node);
       
   133   if (GET_OPCODE(*i) != OP_TESTSET)
       
   134     return 0;  /* cannot patch other instructions */
       
   135   if (reg != NO_REG && reg != GETARG_B(*i))
       
   136     SETARG_A(*i, reg);
       
   137   else  /* no register to put value or register already has the value */
       
   138     *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
       
   139 
       
   140   return 1;
       
   141 }
       
   142 
       
   143 
       
   144 static void removevalues (FuncState *fs, int list) {
       
   145   for (; list != NO_JUMP; list = getjump(fs, list))
       
   146       patchtestreg(fs, list, NO_REG);
       
   147 }
       
   148 
       
   149 
       
   150 static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
       
   151                           int dtarget) {
       
   152   while (list != NO_JUMP) {
       
   153     int next = getjump(fs, list);
       
   154     if (patchtestreg(fs, list, reg))
       
   155       fixjump(fs, list, vtarget);
       
   156     else
       
   157       fixjump(fs, list, dtarget);  /* jump to default target */
       
   158     list = next;
       
   159   }
       
   160 }
       
   161 
       
   162 
       
   163 static void dischargejpc (FuncState *fs) {
       
   164   patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
       
   165   fs->jpc = NO_JUMP;
       
   166 }
       
   167 
       
   168 
       
   169 void luaK_patchlist (FuncState *fs, int list, int target) {
       
   170   if (target == fs->pc)
       
   171     luaK_patchtohere(fs, list);
       
   172   else {
       
   173     lua_assert(target < fs->pc);
       
   174     patchlistaux(fs, list, target, NO_REG, target);
       
   175   }
       
   176 }
       
   177 
       
   178 
       
   179 void luaK_patchtohere (FuncState *fs, int list) {
       
   180   luaK_getlabel(fs);
       
   181   luaK_concat(fs, &fs->jpc, list);
       
   182 }
       
   183 
       
   184 
       
   185 void luaK_concat (FuncState *fs, int *l1, int l2) {
       
   186   if (l2 == NO_JUMP) return;
       
   187   else if (*l1 == NO_JUMP)
       
   188     *l1 = l2;
       
   189   else {
       
   190     int list = *l1;
       
   191     int next;
       
   192     while ((next = getjump(fs, list)) != NO_JUMP)  /* find last element */
       
   193       list = next;
       
   194     fixjump(fs, list, l2);
       
   195   }
       
   196 }
       
   197 
       
   198 
       
   199 void luaK_checkstack (FuncState *fs, int n) {
       
   200   int newstack = fs->freereg + n;
       
   201   if (newstack > fs->f->maxstacksize) {
       
   202     if (newstack >= MAXSTACK)
       
   203       luaX_syntaxerror(fs->ls, "function or expression too complex");
       
   204     fs->f->maxstacksize = cast_byte(newstack);
       
   205   }
       
   206 }
       
   207 
       
   208 
       
   209 void luaK_reserveregs (FuncState *fs, int n) {
       
   210   luaK_checkstack(fs, n);
       
   211   fs->freereg += n;
       
   212 }
       
   213 
       
   214 
       
   215 static void freereg (FuncState *fs, int reg) {
       
   216   if (!ISK(reg) && reg >= fs->nactvar) {
       
   217     fs->freereg--;
       
   218     lua_assert(reg == fs->freereg);
       
   219   }
       
   220 }
       
   221 
       
   222 
       
   223 static void freeexp (FuncState *fs, expdesc *e) {
       
   224   if (e->k == VNONRELOC)
       
   225     freereg(fs, e->u.s.info);
       
   226 }
       
   227 
       
   228 
       
   229 static int addk (FuncState *fs, TValue *k, TValue *v) {
       
   230   lua_State *L = fs->L;
       
   231   TValue *idx = luaH_set(L, fs->h, k);
       
   232   Proto *f = fs->f;
       
   233   int oldsize = f->sizek;
       
   234   if (ttisnumber(idx)) {
       
   235     lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v));
       
   236     return cast_int(nvalue(idx));
       
   237   }
       
   238   else {  /* constant not found; create a new entry */
       
   239     setnvalue(idx, cast_num(fs->nk));
       
   240     luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,
       
   241                     MAXARG_Bx, "constant table overflow");
       
   242     while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
       
   243     setobj(L, &f->k[fs->nk], v);
       
   244     luaC_barrier(L, f, v);
       
   245     return fs->nk++;
       
   246   }
       
   247 }
       
   248 
       
   249 
       
   250 int luaK_stringK (FuncState *fs, TString *s) {
       
   251   TValue o;
       
   252   setsvalue(fs->L, &o, s);
       
   253   return addk(fs, &o, &o);
       
   254 }
       
   255 
       
   256 
       
   257 int luaK_numberK (FuncState *fs, lua_Number r) {
       
   258   TValue o;
       
   259   setnvalue(&o, r);
       
   260   return addk(fs, &o, &o);
       
   261 }
       
   262 
       
   263 
       
   264 static int boolK (FuncState *fs, int b) {
       
   265   TValue o;
       
   266   setbvalue(&o, b);
       
   267   return addk(fs, &o, &o);
       
   268 }
       
   269 
       
   270 
       
   271 static int nilK (FuncState *fs) {
       
   272   TValue k, v;
       
   273   setnilvalue(&v);
       
   274   /* cannot use nil as key; instead use table itself to represent nil */
       
   275   sethvalue(fs->L, &k, fs->h);
       
   276   return addk(fs, &k, &v);
       
   277 }
       
   278 
       
   279 
       
   280 void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
       
   281   if (e->k == VCALL) {  /* expression is an open function call? */
       
   282     SETARG_C(getcode(fs, e), nresults+1);
       
   283   }
       
   284   else if (e->k == VVARARG) {
       
   285     SETARG_B(getcode(fs, e), nresults+1);
       
   286     SETARG_A(getcode(fs, e), fs->freereg);
       
   287     luaK_reserveregs(fs, 1);
       
   288   }
       
   289 }
       
   290 
       
   291 
       
   292 void luaK_setoneret (FuncState *fs, expdesc *e) {
       
   293   if (e->k == VCALL) {  /* expression is an open function call? */
       
   294     e->k = VNONRELOC;
       
   295     e->u.s.info = GETARG_A(getcode(fs, e));
       
   296   }
       
   297   else if (e->k == VVARARG) {
       
   298     SETARG_B(getcode(fs, e), 2);
       
   299     e->k = VRELOCABLE;  /* can relocate its simple result */
       
   300   }
       
   301 }
       
   302 
       
   303 
       
   304 void luaK_dischargevars (FuncState *fs, expdesc *e) {
       
   305   switch (e->k) {
       
   306     case VLOCAL: {
       
   307       e->k = VNONRELOC;
       
   308       break;
       
   309     }
       
   310     case VUPVAL: {
       
   311       e->u.s.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.s.info, 0);
       
   312       e->k = VRELOCABLE;
       
   313       break;
       
   314     }
       
   315     case VGLOBAL: {
       
   316       e->u.s.info = luaK_codeABx(fs, OP_GETGLOBAL, 0, e->u.s.info);
       
   317       e->k = VRELOCABLE;
       
   318       break;
       
   319     }
       
   320     case VINDEXED: {
       
   321       freereg(fs, e->u.s.aux);
       
   322       freereg(fs, e->u.s.info);
       
   323       e->u.s.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.s.info, e->u.s.aux);
       
   324       e->k = VRELOCABLE;
       
   325       break;
       
   326     }
       
   327     case VVARARG:
       
   328     case VCALL: {
       
   329       luaK_setoneret(fs, e);
       
   330       break;
       
   331     }
       
   332     default: break;  /* there is one value available (somewhere) */
       
   333   }
       
   334 }
       
   335 
       
   336 
       
   337 static int code_label (FuncState *fs, int A, int b, int jump) {
       
   338   luaK_getlabel(fs);  /* those instructions may be jump targets */
       
   339   return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
       
   340 }
       
   341 
       
   342 
       
   343 static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
       
   344   luaK_dischargevars(fs, e);
       
   345   switch (e->k) {
       
   346     case VNIL: {
       
   347       luaK_nil(fs, reg, 1);
       
   348       break;
       
   349     }
       
   350     case VFALSE:  case VTRUE: {
       
   351       luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
       
   352       break;
       
   353     }
       
   354     case VK: {
       
   355       luaK_codeABx(fs, OP_LOADK, reg, e->u.s.info);
       
   356       break;
       
   357     }
       
   358     case VKNUM: {
       
   359       luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval));
       
   360       break;
       
   361     }
       
   362     case VRELOCABLE: {
       
   363       Instruction *pc = &getcode(fs, e);
       
   364       SETARG_A(*pc, reg);
       
   365       break;
       
   366     }
       
   367     case VNONRELOC: {
       
   368       if (reg != e->u.s.info)
       
   369         luaK_codeABC(fs, OP_MOVE, reg, e->u.s.info, 0);
       
   370       break;
       
   371     }
       
   372     default: {
       
   373       lua_assert(e->k == VVOID || e->k == VJMP);
       
   374       return;  /* nothing to do... */
       
   375     }
       
   376   }
       
   377   e->u.s.info = reg;
       
   378   e->k = VNONRELOC;
       
   379 }
       
   380 
       
   381 
       
   382 static void discharge2anyreg (FuncState *fs, expdesc *e) {
       
   383   if (e->k != VNONRELOC) {
       
   384     luaK_reserveregs(fs, 1);
       
   385     discharge2reg(fs, e, fs->freereg-1);
       
   386   }
       
   387 }
       
   388 
       
   389 
       
   390 static void exp2reg (FuncState *fs, expdesc *e, int reg) {
       
   391   discharge2reg(fs, e, reg);
       
   392   if (e->k == VJMP)
       
   393     luaK_concat(fs, &e->t, e->u.s.info);  /* put this jump in `t' list */
       
   394   if (hasjumps(e)) {
       
   395     int final;  /* position after whole expression */
       
   396     int p_f = NO_JUMP;  /* position of an eventual LOAD false */
       
   397     int p_t = NO_JUMP;  /* position of an eventual LOAD true */
       
   398     if (need_value(fs, e->t) || need_value(fs, e->f)) {
       
   399       int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
       
   400       p_f = code_label(fs, reg, 0, 1);
       
   401       p_t = code_label(fs, reg, 1, 0);
       
   402       luaK_patchtohere(fs, fj);
       
   403     }
       
   404     final = luaK_getlabel(fs);
       
   405     patchlistaux(fs, e->f, final, reg, p_f);
       
   406     patchlistaux(fs, e->t, final, reg, p_t);
       
   407   }
       
   408   e->f = e->t = NO_JUMP;
       
   409   e->u.s.info = reg;
       
   410   e->k = VNONRELOC;
       
   411 }
       
   412 
       
   413 
       
   414 void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
       
   415   luaK_dischargevars(fs, e);
       
   416   freeexp(fs, e);
       
   417   luaK_reserveregs(fs, 1);
       
   418   exp2reg(fs, e, fs->freereg - 1);
       
   419 }
       
   420 
       
   421 
       
   422 int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
       
   423   luaK_dischargevars(fs, e);
       
   424   if (e->k == VNONRELOC) {
       
   425     if (!hasjumps(e)) return e->u.s.info;  /* exp is already in a register */
       
   426     if (e->u.s.info >= fs->nactvar) {  /* reg. is not a local? */
       
   427       exp2reg(fs, e, e->u.s.info);  /* put value on it */
       
   428       return e->u.s.info;
       
   429     }
       
   430   }
       
   431   luaK_exp2nextreg(fs, e);  /* default */
       
   432   return e->u.s.info;
       
   433 }
       
   434 
       
   435 
       
   436 void luaK_exp2val (FuncState *fs, expdesc *e) {
       
   437   if (hasjumps(e))
       
   438     luaK_exp2anyreg(fs, e);
       
   439   else
       
   440     luaK_dischargevars(fs, e);
       
   441 }
       
   442 
       
   443 
       
   444 int luaK_exp2RK (FuncState *fs, expdesc *e) {
       
   445   luaK_exp2val(fs, e);
       
   446   switch (e->k) {
       
   447     case VKNUM:
       
   448     case VTRUE:
       
   449     case VFALSE:
       
   450     case VNIL: {
       
   451       if (fs->nk <= MAXINDEXRK) {  /* constant fit in RK operand? */
       
   452         e->u.s.info = (e->k == VNIL)  ? nilK(fs) :
       
   453                       (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) :
       
   454                                         boolK(fs, (e->k == VTRUE));
       
   455         e->k = VK;
       
   456         return RKASK(e->u.s.info);
       
   457       }
       
   458       else break;
       
   459     }
       
   460     case VK: {
       
   461       if (e->u.s.info <= MAXINDEXRK)  /* constant fit in argC? */
       
   462         return RKASK(e->u.s.info);
       
   463       else break;
       
   464     }
       
   465     default: break;
       
   466   }
       
   467   /* not a constant in the right range: put it in a register */
       
   468   return luaK_exp2anyreg(fs, e);
       
   469 }
       
   470 
       
   471 
       
   472 void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
       
   473   switch (var->k) {
       
   474     case VLOCAL: {
       
   475       freeexp(fs, ex);
       
   476       exp2reg(fs, ex, var->u.s.info);
       
   477       return;
       
   478     }
       
   479     case VUPVAL: {
       
   480       int e = luaK_exp2anyreg(fs, ex);
       
   481       luaK_codeABC(fs, OP_SETUPVAL, e, var->u.s.info, 0);
       
   482       break;
       
   483     }
       
   484     case VGLOBAL: {
       
   485       int e = luaK_exp2anyreg(fs, ex);
       
   486       luaK_codeABx(fs, OP_SETGLOBAL, e, var->u.s.info);
       
   487       break;
       
   488     }
       
   489     case VINDEXED: {
       
   490       int e = luaK_exp2RK(fs, ex);
       
   491       luaK_codeABC(fs, OP_SETTABLE, var->u.s.info, var->u.s.aux, e);
       
   492       break;
       
   493     }
       
   494     default: {
       
   495       lua_assert(0);  /* invalid var kind to store */
       
   496       break;
       
   497     }
       
   498   }
       
   499   freeexp(fs, ex);
       
   500 }
       
   501 
       
   502 
       
   503 void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
       
   504   int func;
       
   505   luaK_exp2anyreg(fs, e);
       
   506   freeexp(fs, e);
       
   507   func = fs->freereg;
       
   508   luaK_reserveregs(fs, 2);
       
   509   luaK_codeABC(fs, OP_SELF, func, e->u.s.info, luaK_exp2RK(fs, key));
       
   510   freeexp(fs, key);
       
   511   e->u.s.info = func;
       
   512   e->k = VNONRELOC;
       
   513 }
       
   514 
       
   515 
       
   516 static void invertjump (FuncState *fs, expdesc *e) {
       
   517   Instruction *pc = getjumpcontrol(fs, e->u.s.info);
       
   518   lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
       
   519                                            GET_OPCODE(*pc) != OP_TEST);
       
   520   SETARG_A(*pc, !(GETARG_A(*pc)));
       
   521 }
       
   522 
       
   523 
       
   524 static int jumponcond (FuncState *fs, expdesc *e, int cond) {
       
   525   if (e->k == VRELOCABLE) {
       
   526     Instruction ie = getcode(fs, e);
       
   527     if (GET_OPCODE(ie) == OP_NOT) {
       
   528       fs->pc--;  /* remove previous OP_NOT */
       
   529       return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
       
   530     }
       
   531     /* else go through */
       
   532   }
       
   533   discharge2anyreg(fs, e);
       
   534   freeexp(fs, e);
       
   535   return condjump(fs, OP_TESTSET, NO_REG, e->u.s.info, cond);
       
   536 }
       
   537 
       
   538 
       
   539 void luaK_goiftrue (FuncState *fs, expdesc *e) {
       
   540   int pc;  /* pc of last jump */
       
   541   luaK_dischargevars(fs, e);
       
   542   switch (e->k) {
       
   543     case VK: case VKNUM: case VTRUE: {
       
   544       pc = NO_JUMP;  /* always true; do nothing */
       
   545       break;
       
   546     }
       
   547     case VFALSE: {
       
   548       pc = luaK_jump(fs);  /* always jump */
       
   549       break;
       
   550     }
       
   551     case VJMP: {
       
   552       invertjump(fs, e);
       
   553       pc = e->u.s.info;
       
   554       break;
       
   555     }
       
   556     default: {
       
   557       pc = jumponcond(fs, e, 0);
       
   558       break;
       
   559     }
       
   560   }
       
   561   luaK_concat(fs, &e->f, pc);  /* insert last jump in `f' list */
       
   562   luaK_patchtohere(fs, e->t);
       
   563   e->t = NO_JUMP;
       
   564 }
       
   565 
       
   566 
       
   567 static void luaK_goiffalse (FuncState *fs, expdesc *e) {
       
   568   int pc;  /* pc of last jump */
       
   569   luaK_dischargevars(fs, e);
       
   570   switch (e->k) {
       
   571     case VNIL: case VFALSE: {
       
   572       pc = NO_JUMP;  /* always false; do nothing */
       
   573       break;
       
   574     }
       
   575     case VTRUE: {
       
   576       pc = luaK_jump(fs);  /* always jump */
       
   577       break;
       
   578     }
       
   579     case VJMP: {
       
   580       pc = e->u.s.info;
       
   581       break;
       
   582     }
       
   583     default: {
       
   584       pc = jumponcond(fs, e, 1);
       
   585       break;
       
   586     }
       
   587   }
       
   588   luaK_concat(fs, &e->t, pc);  /* insert last jump in `t' list */
       
   589   luaK_patchtohere(fs, e->f);
       
   590   e->f = NO_JUMP;
       
   591 }
       
   592 
       
   593 
       
   594 static void codenot (FuncState *fs, expdesc *e) {
       
   595   luaK_dischargevars(fs, e);
       
   596   switch (e->k) {
       
   597     case VNIL: case VFALSE: {
       
   598       e->k = VTRUE;
       
   599       break;
       
   600     }
       
   601     case VK: case VKNUM: case VTRUE: {
       
   602       e->k = VFALSE;
       
   603       break;
       
   604     }
       
   605     case VJMP: {
       
   606       invertjump(fs, e);
       
   607       break;
       
   608     }
       
   609     case VRELOCABLE:
       
   610     case VNONRELOC: {
       
   611       discharge2anyreg(fs, e);
       
   612       freeexp(fs, e);
       
   613       e->u.s.info = luaK_codeABC(fs, OP_NOT, 0, e->u.s.info, 0);
       
   614       e->k = VRELOCABLE;
       
   615       break;
       
   616     }
       
   617     default: {
       
   618       lua_assert(0);  /* cannot happen */
       
   619       break;
       
   620     }
       
   621   }
       
   622   /* interchange true and false lists */
       
   623   { int temp = e->f; e->f = e->t; e->t = temp; }
       
   624   removevalues(fs, e->f);
       
   625   removevalues(fs, e->t);
       
   626 }
       
   627 
       
   628 
       
   629 void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
       
   630   t->u.s.aux = luaK_exp2RK(fs, k);
       
   631   t->k = VINDEXED;
       
   632 }
       
   633 
       
   634 
       
   635 static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
       
   636   lua_Number v1, v2, r;
       
   637   if (!isnumeral(e1) || !isnumeral(e2)) return 0;
       
   638   v1 = e1->u.nval;
       
   639   v2 = e2->u.nval;
       
   640   switch (op) {
       
   641     case OP_ADD: r = luai_numadd(v1, v2); break;
       
   642     case OP_SUB: r = luai_numsub(v1, v2); break;
       
   643     case OP_MUL: r = luai_nummul(v1, v2); break;
       
   644     case OP_DIV:
       
   645       if (v2 == 0) return 0;  /* do not attempt to divide by 0 */
       
   646       r = luai_numdiv(v1, v2); break;
       
   647     case OP_MOD:
       
   648       if (v2 == 0) return 0;  /* do not attempt to divide by 0 */
       
   649       r = luai_nummod(v1, v2); break;
       
   650     case OP_POW: r = luai_numpow(v1, v2); break;
       
   651     case OP_UNM: r = luai_numunm(v1); break;
       
   652     case OP_LEN: return 0;  /* no constant folding for 'len' */
       
   653     default: lua_assert(0); r = 0; break;
       
   654   }
       
   655   if (luai_numisnan(r)) return 0;  /* do not attempt to produce NaN */
       
   656   e1->u.nval = r;
       
   657   return 1;
       
   658 }
       
   659 
       
   660 
       
   661 static void codearith (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
       
   662   if (constfolding(op, e1, e2))
       
   663     return;
       
   664   else {
       
   665     int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
       
   666     int o1 = luaK_exp2RK(fs, e1);
       
   667     if (o1 > o2) {
       
   668       freeexp(fs, e1);
       
   669       freeexp(fs, e2);
       
   670     }
       
   671     else {
       
   672       freeexp(fs, e2);
       
   673       freeexp(fs, e1);
       
   674     }
       
   675     e1->u.s.info = luaK_codeABC(fs, op, 0, o1, o2);
       
   676     e1->k = VRELOCABLE;
       
   677   }
       
   678 }
       
   679 
       
   680 
       
   681 static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
       
   682                                                           expdesc *e2) {
       
   683   int o1 = luaK_exp2RK(fs, e1);
       
   684   int o2 = luaK_exp2RK(fs, e2);
       
   685   freeexp(fs, e2);
       
   686   freeexp(fs, e1);
       
   687   if (cond == 0 && op != OP_EQ) {
       
   688     int temp;  /* exchange args to replace by `<' or `<=' */
       
   689     temp = o1; o1 = o2; o2 = temp;  /* o1 <==> o2 */
       
   690     cond = 1;
       
   691   }
       
   692   e1->u.s.info = condjump(fs, op, cond, o1, o2);
       
   693   e1->k = VJMP;
       
   694 }
       
   695 
       
   696 
       
   697 void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
       
   698   expdesc e2;
       
   699   e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
       
   700   switch (op) {
       
   701     case OPR_MINUS: {
       
   702       if (!isnumeral(e))
       
   703         luaK_exp2anyreg(fs, e);  /* cannot operate on non-numeric constants */
       
   704       codearith(fs, OP_UNM, e, &e2);
       
   705       break;
       
   706     }
       
   707     case OPR_NOT: codenot(fs, e); break;
       
   708     case OPR_LEN: {
       
   709       luaK_exp2anyreg(fs, e);  /* cannot operate on constants */
       
   710       codearith(fs, OP_LEN, e, &e2);
       
   711       break;
       
   712     }
       
   713     default: lua_assert(0);
       
   714   }
       
   715 }
       
   716 
       
   717 
       
   718 void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
       
   719   switch (op) {
       
   720     case OPR_AND: {
       
   721       luaK_goiftrue(fs, v);
       
   722       break;
       
   723     }
       
   724     case OPR_OR: {
       
   725       luaK_goiffalse(fs, v);
       
   726       break;
       
   727     }
       
   728     case OPR_CONCAT: {
       
   729       luaK_exp2nextreg(fs, v);  /* operand must be on the `stack' */
       
   730       break;
       
   731     }
       
   732     case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
       
   733     case OPR_MOD: case OPR_POW: {
       
   734       if (!isnumeral(v)) luaK_exp2RK(fs, v);
       
   735       break;
       
   736     }
       
   737     default: {
       
   738       luaK_exp2RK(fs, v);
       
   739       break;
       
   740     }
       
   741   }
       
   742 }
       
   743 
       
   744 
       
   745 void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
       
   746   switch (op) {
       
   747     case OPR_AND: {
       
   748       lua_assert(e1->t == NO_JUMP);  /* list must be closed */
       
   749       luaK_dischargevars(fs, e2);
       
   750       luaK_concat(fs, &e2->f, e1->f);
       
   751       *e1 = *e2;
       
   752       break;
       
   753     }
       
   754     case OPR_OR: {
       
   755       lua_assert(e1->f == NO_JUMP);  /* list must be closed */
       
   756       luaK_dischargevars(fs, e2);
       
   757       luaK_concat(fs, &e2->t, e1->t);
       
   758       *e1 = *e2;
       
   759       break;
       
   760     }
       
   761     case OPR_CONCAT: {
       
   762       luaK_exp2val(fs, e2);
       
   763       if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
       
   764         lua_assert(e1->u.s.info == GETARG_B(getcode(fs, e2))-1);
       
   765         freeexp(fs, e1);
       
   766         SETARG_B(getcode(fs, e2), e1->u.s.info);
       
   767         e1->k = VRELOCABLE; e1->u.s.info = e2->u.s.info;
       
   768       }
       
   769       else {
       
   770         luaK_exp2nextreg(fs, e2);  /* operand must be on the 'stack' */
       
   771         codearith(fs, OP_CONCAT, e1, e2);
       
   772       }
       
   773       break;
       
   774     }
       
   775     case OPR_ADD: codearith(fs, OP_ADD, e1, e2); break;
       
   776     case OPR_SUB: codearith(fs, OP_SUB, e1, e2); break;
       
   777     case OPR_MUL: codearith(fs, OP_MUL, e1, e2); break;
       
   778     case OPR_DIV: codearith(fs, OP_DIV, e1, e2); break;
       
   779     case OPR_MOD: codearith(fs, OP_MOD, e1, e2); break;
       
   780     case OPR_POW: codearith(fs, OP_POW, e1, e2); break;
       
   781     case OPR_EQ: codecomp(fs, OP_EQ, 1, e1, e2); break;
       
   782     case OPR_NE: codecomp(fs, OP_EQ, 0, e1, e2); break;
       
   783     case OPR_LT: codecomp(fs, OP_LT, 1, e1, e2); break;
       
   784     case OPR_LE: codecomp(fs, OP_LE, 1, e1, e2); break;
       
   785     case OPR_GT: codecomp(fs, OP_LT, 0, e1, e2); break;
       
   786     case OPR_GE: codecomp(fs, OP_LE, 0, e1, e2); break;
       
   787     default: lua_assert(0);
       
   788   }
       
   789 }
       
   790 
       
   791 
       
   792 void luaK_fixline (FuncState *fs, int line) {
       
   793   fs->f->lineinfo[fs->pc - 1] = line;
       
   794 }
       
   795 
       
   796 
       
   797 static int luaK_code (FuncState *fs, Instruction i, int line) {
       
   798   Proto *f = fs->f;
       
   799   dischargejpc(fs);  /* `pc' will change */
       
   800   /* put new instruction in code array */
       
   801   luaM_growvector(fs->L, f->code, fs->pc, f->sizecode, Instruction,
       
   802                   MAX_INT, "code size overflow");
       
   803   f->code[fs->pc] = i;
       
   804   /* save corresponding line information */
       
   805   luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
       
   806                   MAX_INT, "code size overflow");
       
   807   f->lineinfo[fs->pc] = line;
       
   808   return fs->pc++;
       
   809 }
       
   810 
       
   811 
       
   812 int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
       
   813   lua_assert(getOpMode(o) == iABC);
       
   814   lua_assert(getBMode(o) != OpArgN || b == 0);
       
   815   lua_assert(getCMode(o) != OpArgN || c == 0);
       
   816   return luaK_code(fs, CREATE_ABC(o, a, b, c), fs->ls->lastline);
       
   817 }
       
   818 
       
   819 
       
   820 int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
       
   821   lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
       
   822   lua_assert(getCMode(o) == OpArgN);
       
   823   return luaK_code(fs, CREATE_ABx(o, a, bc), fs->ls->lastline);
       
   824 }
       
   825 
       
   826 
       
   827 void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
       
   828   int c =  (nelems - 1)/LFIELDS_PER_FLUSH + 1;
       
   829   int b = (tostore == LUA_MULTRET) ? 0 : tostore;
       
   830   lua_assert(tostore != 0);
       
   831   if (c <= MAXARG_C)
       
   832     luaK_codeABC(fs, OP_SETLIST, base, b, c);
       
   833   else {
       
   834     luaK_codeABC(fs, OP_SETLIST, base, b, 0);
       
   835     luaK_code(fs, cast(Instruction, c), fs->ls->lastline);
       
   836   }
       
   837   fs->freereg = base + 1;  /* free registers with list values */
       
   838 }
       
   839