lua/lcode.c
changeset 0 d7ee4e2ed49d
equal deleted inserted replaced
-1:000000000000 0:d7ee4e2ed49d
       
     1 /*
       
     2 ** $Id: lcode.c,v 2.62.1.1 2013/04/12 18:48:47 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 "lstring.h"
       
    25 #include "ltable.h"
       
    26 #include "lvm.h"
       
    27 
       
    28 
       
    29 #define hasjumps(e)	((e)->t != (e)->f)
       
    30 
       
    31 
       
    32 static int isnumeral(expdesc *e) {
       
    33   return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
       
    34 }
       
    35 
       
    36 
       
    37 void luaK_nil (FuncState *fs, int from, int n) {
       
    38   Instruction *previous;
       
    39   int l = from + n - 1;  /* last register to set nil */
       
    40   if (fs->pc > fs->lasttarget) {  /* no jumps to current position? */
       
    41     previous = &fs->f->code[fs->pc-1];
       
    42     if (GET_OPCODE(*previous) == OP_LOADNIL) {
       
    43       int pfrom = GETARG_A(*previous);
       
    44       int pl = pfrom + GETARG_B(*previous);
       
    45       if ((pfrom <= from && from <= pl + 1) ||
       
    46           (from <= pfrom && pfrom <= l + 1)) {  /* can connect both? */
       
    47         if (pfrom < from) from = pfrom;  /* from = min(from, pfrom) */
       
    48         if (pl > l) l = pl;  /* l = max(l, pl) */
       
    49         SETARG_A(*previous, from);
       
    50         SETARG_B(*previous, l - from);
       
    51         return;
       
    52       }
       
    53     }  /* else go through */
       
    54   }
       
    55   luaK_codeABC(fs, OP_LOADNIL, 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 LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level) {
       
   180   level++;  /* argument is +1 to reserve 0 as non-op */
       
   181   while (list != NO_JUMP) {
       
   182     int next = getjump(fs, list);
       
   183     lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP &&
       
   184                 (GETARG_A(fs->f->code[list]) == 0 ||
       
   185                  GETARG_A(fs->f->code[list]) >= level));
       
   186     SETARG_A(fs->f->code[list], level);
       
   187     list = next;
       
   188   }
       
   189 }
       
   190 
       
   191 
       
   192 void luaK_patchtohere (FuncState *fs, int list) {
       
   193   luaK_getlabel(fs);
       
   194   luaK_concat(fs, &fs->jpc, list);
       
   195 }
       
   196 
       
   197 
       
   198 void luaK_concat (FuncState *fs, int *l1, int l2) {
       
   199   if (l2 == NO_JUMP) return;
       
   200   else if (*l1 == NO_JUMP)
       
   201     *l1 = l2;
       
   202   else {
       
   203     int list = *l1;
       
   204     int next;
       
   205     while ((next = getjump(fs, list)) != NO_JUMP)  /* find last element */
       
   206       list = next;
       
   207     fixjump(fs, list, l2);
       
   208   }
       
   209 }
       
   210 
       
   211 
       
   212 static int luaK_code (FuncState *fs, Instruction i) {
       
   213   Proto *f = fs->f;
       
   214   dischargejpc(fs);  /* `pc' will change */
       
   215   /* put new instruction in code array */
       
   216   luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
       
   217                   MAX_INT, "opcodes");
       
   218   f->code[fs->pc] = i;
       
   219   /* save corresponding line information */
       
   220   luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
       
   221                   MAX_INT, "opcodes");
       
   222   f->lineinfo[fs->pc] = fs->ls->lastline;
       
   223   return fs->pc++;
       
   224 }
       
   225 
       
   226 
       
   227 int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
       
   228   lua_assert(getOpMode(o) == iABC);
       
   229   lua_assert(getBMode(o) != OpArgN || b == 0);
       
   230   lua_assert(getCMode(o) != OpArgN || c == 0);
       
   231   lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C);
       
   232   return luaK_code(fs, CREATE_ABC(o, a, b, c));
       
   233 }
       
   234 
       
   235 
       
   236 int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
       
   237   lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
       
   238   lua_assert(getCMode(o) == OpArgN);
       
   239   lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx);
       
   240   return luaK_code(fs, CREATE_ABx(o, a, bc));
       
   241 }
       
   242 
       
   243 
       
   244 static int codeextraarg (FuncState *fs, int a) {
       
   245   lua_assert(a <= MAXARG_Ax);
       
   246   return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a));
       
   247 }
       
   248 
       
   249 
       
   250 int luaK_codek (FuncState *fs, int reg, int k) {
       
   251   if (k <= MAXARG_Bx)
       
   252     return luaK_codeABx(fs, OP_LOADK, reg, k);
       
   253   else {
       
   254     int p = luaK_codeABx(fs, OP_LOADKX, reg, 0);
       
   255     codeextraarg(fs, k);
       
   256     return p;
       
   257   }
       
   258 }
       
   259 
       
   260 
       
   261 void luaK_checkstack (FuncState *fs, int n) {
       
   262   int newstack = fs->freereg + n;
       
   263   if (newstack > fs->f->maxstacksize) {
       
   264     if (newstack >= MAXSTACK)
       
   265       luaX_syntaxerror(fs->ls, "function or expression too complex");
       
   266     fs->f->maxstacksize = cast_byte(newstack);
       
   267   }
       
   268 }
       
   269 
       
   270 
       
   271 void luaK_reserveregs (FuncState *fs, int n) {
       
   272   luaK_checkstack(fs, n);
       
   273   fs->freereg += n;
       
   274 }
       
   275 
       
   276 
       
   277 static void freereg (FuncState *fs, int reg) {
       
   278   if (!ISK(reg) && reg >= fs->nactvar) {
       
   279     fs->freereg--;
       
   280     lua_assert(reg == fs->freereg);
       
   281   }
       
   282 }
       
   283 
       
   284 
       
   285 static void freeexp (FuncState *fs, expdesc *e) {
       
   286   if (e->k == VNONRELOC)
       
   287     freereg(fs, e->u.info);
       
   288 }
       
   289 
       
   290 
       
   291 static int addk (FuncState *fs, TValue *key, TValue *v) {
       
   292   lua_State *L = fs->ls->L;
       
   293   TValue *idx = luaH_set(L, fs->h, key);
       
   294   Proto *f = fs->f;
       
   295   int k, oldsize;
       
   296   if (ttisnumber(idx)) {
       
   297     lua_Number n = nvalue(idx);
       
   298     lua_number2int(k, n);
       
   299     if (luaV_rawequalobj(&f->k[k], v))
       
   300       return k;
       
   301     /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0");
       
   302        go through and create a new entry for this value */
       
   303   }
       
   304   /* constant not found; create a new entry */
       
   305   oldsize = f->sizek;
       
   306   k = fs->nk;
       
   307   /* numerical value does not need GC barrier;
       
   308      table has no metatable, so it does not need to invalidate cache */
       
   309   setnvalue(idx, cast_num(k));
       
   310   luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
       
   311   while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
       
   312   setobj(L, &f->k[k], v);
       
   313   fs->nk++;
       
   314   luaC_barrier(L, f, v);
       
   315   return k;
       
   316 }
       
   317 
       
   318 
       
   319 int luaK_stringK (FuncState *fs, TString *s) {
       
   320   TValue o;
       
   321   setsvalue(fs->ls->L, &o, s);
       
   322   return addk(fs, &o, &o);
       
   323 }
       
   324 
       
   325 
       
   326 int luaK_numberK (FuncState *fs, lua_Number r) {
       
   327   int n;
       
   328   lua_State *L = fs->ls->L;
       
   329   TValue o;
       
   330   setnvalue(&o, r);
       
   331   if (r == 0 || luai_numisnan(NULL, r)) {  /* handle -0 and NaN */
       
   332     /* use raw representation as key to avoid numeric problems */
       
   333     setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r)));
       
   334     n = addk(fs, L->top - 1, &o);
       
   335     L->top--;
       
   336   }
       
   337   else
       
   338     n = addk(fs, &o, &o);  /* regular case */
       
   339   return n;
       
   340 }
       
   341 
       
   342 
       
   343 static int boolK (FuncState *fs, int b) {
       
   344   TValue o;
       
   345   setbvalue(&o, b);
       
   346   return addk(fs, &o, &o);
       
   347 }
       
   348 
       
   349 
       
   350 static int nilK (FuncState *fs) {
       
   351   TValue k, v;
       
   352   setnilvalue(&v);
       
   353   /* cannot use nil as key; instead use table itself to represent nil */
       
   354   sethvalue(fs->ls->L, &k, fs->h);
       
   355   return addk(fs, &k, &v);
       
   356 }
       
   357 
       
   358 
       
   359 void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
       
   360   if (e->k == VCALL) {  /* expression is an open function call? */
       
   361     SETARG_C(getcode(fs, e), nresults+1);
       
   362   }
       
   363   else if (e->k == VVARARG) {
       
   364     SETARG_B(getcode(fs, e), nresults+1);
       
   365     SETARG_A(getcode(fs, e), fs->freereg);
       
   366     luaK_reserveregs(fs, 1);
       
   367   }
       
   368 }
       
   369 
       
   370 
       
   371 void luaK_setoneret (FuncState *fs, expdesc *e) {
       
   372   if (e->k == VCALL) {  /* expression is an open function call? */
       
   373     e->k = VNONRELOC;
       
   374     e->u.info = GETARG_A(getcode(fs, e));
       
   375   }
       
   376   else if (e->k == VVARARG) {
       
   377     SETARG_B(getcode(fs, e), 2);
       
   378     e->k = VRELOCABLE;  /* can relocate its simple result */
       
   379   }
       
   380 }
       
   381 
       
   382 
       
   383 void luaK_dischargevars (FuncState *fs, expdesc *e) {
       
   384   switch (e->k) {
       
   385     case VLOCAL: {
       
   386       e->k = VNONRELOC;
       
   387       break;
       
   388     }
       
   389     case VUPVAL: {
       
   390       e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
       
   391       e->k = VRELOCABLE;
       
   392       break;
       
   393     }
       
   394     case VINDEXED: {
       
   395       OpCode op = OP_GETTABUP;  /* assume 't' is in an upvalue */
       
   396       freereg(fs, e->u.ind.idx);
       
   397       if (e->u.ind.vt == VLOCAL) {  /* 't' is in a register? */
       
   398         freereg(fs, e->u.ind.t);
       
   399         op = OP_GETTABLE;
       
   400       }
       
   401       e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);
       
   402       e->k = VRELOCABLE;
       
   403       break;
       
   404     }
       
   405     case VVARARG:
       
   406     case VCALL: {
       
   407       luaK_setoneret(fs, e);
       
   408       break;
       
   409     }
       
   410     default: break;  /* there is one value available (somewhere) */
       
   411   }
       
   412 }
       
   413 
       
   414 
       
   415 static int code_label (FuncState *fs, int A, int b, int jump) {
       
   416   luaK_getlabel(fs);  /* those instructions may be jump targets */
       
   417   return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
       
   418 }
       
   419 
       
   420 
       
   421 static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
       
   422   luaK_dischargevars(fs, e);
       
   423   switch (e->k) {
       
   424     case VNIL: {
       
   425       luaK_nil(fs, reg, 1);
       
   426       break;
       
   427     }
       
   428     case VFALSE: case VTRUE: {
       
   429       luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
       
   430       break;
       
   431     }
       
   432     case VK: {
       
   433       luaK_codek(fs, reg, e->u.info);
       
   434       break;
       
   435     }
       
   436     case VKNUM: {
       
   437       luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval));
       
   438       break;
       
   439     }
       
   440     case VRELOCABLE: {
       
   441       Instruction *pc = &getcode(fs, e);
       
   442       SETARG_A(*pc, reg);
       
   443       break;
       
   444     }
       
   445     case VNONRELOC: {
       
   446       if (reg != e->u.info)
       
   447         luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0);
       
   448       break;
       
   449     }
       
   450     default: {
       
   451       lua_assert(e->k == VVOID || e->k == VJMP);
       
   452       return;  /* nothing to do... */
       
   453     }
       
   454   }
       
   455   e->u.info = reg;
       
   456   e->k = VNONRELOC;
       
   457 }
       
   458 
       
   459 
       
   460 static void discharge2anyreg (FuncState *fs, expdesc *e) {
       
   461   if (e->k != VNONRELOC) {
       
   462     luaK_reserveregs(fs, 1);
       
   463     discharge2reg(fs, e, fs->freereg-1);
       
   464   }
       
   465 }
       
   466 
       
   467 
       
   468 static void exp2reg (FuncState *fs, expdesc *e, int reg) {
       
   469   discharge2reg(fs, e, reg);
       
   470   if (e->k == VJMP)
       
   471     luaK_concat(fs, &e->t, e->u.info);  /* put this jump in `t' list */
       
   472   if (hasjumps(e)) {
       
   473     int final;  /* position after whole expression */
       
   474     int p_f = NO_JUMP;  /* position of an eventual LOAD false */
       
   475     int p_t = NO_JUMP;  /* position of an eventual LOAD true */
       
   476     if (need_value(fs, e->t) || need_value(fs, e->f)) {
       
   477       int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
       
   478       p_f = code_label(fs, reg, 0, 1);
       
   479       p_t = code_label(fs, reg, 1, 0);
       
   480       luaK_patchtohere(fs, fj);
       
   481     }
       
   482     final = luaK_getlabel(fs);
       
   483     patchlistaux(fs, e->f, final, reg, p_f);
       
   484     patchlistaux(fs, e->t, final, reg, p_t);
       
   485   }
       
   486   e->f = e->t = NO_JUMP;
       
   487   e->u.info = reg;
       
   488   e->k = VNONRELOC;
       
   489 }
       
   490 
       
   491 
       
   492 void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
       
   493   luaK_dischargevars(fs, e);
       
   494   freeexp(fs, e);
       
   495   luaK_reserveregs(fs, 1);
       
   496   exp2reg(fs, e, fs->freereg - 1);
       
   497 }
       
   498 
       
   499 
       
   500 int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
       
   501   luaK_dischargevars(fs, e);
       
   502   if (e->k == VNONRELOC) {
       
   503     if (!hasjumps(e)) return e->u.info;  /* exp is already in a register */
       
   504     if (e->u.info >= fs->nactvar) {  /* reg. is not a local? */
       
   505       exp2reg(fs, e, e->u.info);  /* put value on it */
       
   506       return e->u.info;
       
   507     }
       
   508   }
       
   509   luaK_exp2nextreg(fs, e);  /* default */
       
   510   return e->u.info;
       
   511 }
       
   512 
       
   513 
       
   514 void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
       
   515   if (e->k != VUPVAL || hasjumps(e))
       
   516     luaK_exp2anyreg(fs, e);
       
   517 }
       
   518 
       
   519 
       
   520 void luaK_exp2val (FuncState *fs, expdesc *e) {
       
   521   if (hasjumps(e))
       
   522     luaK_exp2anyreg(fs, e);
       
   523   else
       
   524     luaK_dischargevars(fs, e);
       
   525 }
       
   526 
       
   527 
       
   528 int luaK_exp2RK (FuncState *fs, expdesc *e) {
       
   529   luaK_exp2val(fs, e);
       
   530   switch (e->k) {
       
   531     case VTRUE:
       
   532     case VFALSE:
       
   533     case VNIL: {
       
   534       if (fs->nk <= MAXINDEXRK) {  /* constant fits in RK operand? */
       
   535         e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));
       
   536         e->k = VK;
       
   537         return RKASK(e->u.info);
       
   538       }
       
   539       else break;
       
   540     }
       
   541     case VKNUM: {
       
   542       e->u.info = luaK_numberK(fs, e->u.nval);
       
   543       e->k = VK;
       
   544       /* go through */
       
   545     }
       
   546     case VK: {
       
   547       if (e->u.info <= MAXINDEXRK)  /* constant fits in argC? */
       
   548         return RKASK(e->u.info);
       
   549       else break;
       
   550     }
       
   551     default: break;
       
   552   }
       
   553   /* not a constant in the right range: put it in a register */
       
   554   return luaK_exp2anyreg(fs, e);
       
   555 }
       
   556 
       
   557 
       
   558 void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
       
   559   switch (var->k) {
       
   560     case VLOCAL: {
       
   561       freeexp(fs, ex);
       
   562       exp2reg(fs, ex, var->u.info);
       
   563       return;
       
   564     }
       
   565     case VUPVAL: {
       
   566       int e = luaK_exp2anyreg(fs, ex);
       
   567       luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
       
   568       break;
       
   569     }
       
   570     case VINDEXED: {
       
   571       OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP;
       
   572       int e = luaK_exp2RK(fs, ex);
       
   573       luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e);
       
   574       break;
       
   575     }
       
   576     default: {
       
   577       lua_assert(0);  /* invalid var kind to store */
       
   578       break;
       
   579     }
       
   580   }
       
   581   freeexp(fs, ex);
       
   582 }
       
   583 
       
   584 
       
   585 void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
       
   586   int ereg;
       
   587   luaK_exp2anyreg(fs, e);
       
   588   ereg = e->u.info;  /* register where 'e' was placed */
       
   589   freeexp(fs, e);
       
   590   e->u.info = fs->freereg;  /* base register for op_self */
       
   591   e->k = VNONRELOC;
       
   592   luaK_reserveregs(fs, 2);  /* function and 'self' produced by op_self */
       
   593   luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key));
       
   594   freeexp(fs, key);
       
   595 }
       
   596 
       
   597 
       
   598 static void invertjump (FuncState *fs, expdesc *e) {
       
   599   Instruction *pc = getjumpcontrol(fs, e->u.info);
       
   600   lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
       
   601                                            GET_OPCODE(*pc) != OP_TEST);
       
   602   SETARG_A(*pc, !(GETARG_A(*pc)));
       
   603 }
       
   604 
       
   605 
       
   606 static int jumponcond (FuncState *fs, expdesc *e, int cond) {
       
   607   if (e->k == VRELOCABLE) {
       
   608     Instruction ie = getcode(fs, e);
       
   609     if (GET_OPCODE(ie) == OP_NOT) {
       
   610       fs->pc--;  /* remove previous OP_NOT */
       
   611       return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
       
   612     }
       
   613     /* else go through */
       
   614   }
       
   615   discharge2anyreg(fs, e);
       
   616   freeexp(fs, e);
       
   617   return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond);
       
   618 }
       
   619 
       
   620 
       
   621 void luaK_goiftrue (FuncState *fs, expdesc *e) {
       
   622   int pc;  /* pc of last jump */
       
   623   luaK_dischargevars(fs, e);
       
   624   switch (e->k) {
       
   625     case VJMP: {
       
   626       invertjump(fs, e);
       
   627       pc = e->u.info;
       
   628       break;
       
   629     }
       
   630     case VK: case VKNUM: case VTRUE: {
       
   631       pc = NO_JUMP;  /* always true; do nothing */
       
   632       break;
       
   633     }
       
   634     default: {
       
   635       pc = jumponcond(fs, e, 0);
       
   636       break;
       
   637     }
       
   638   }
       
   639   luaK_concat(fs, &e->f, pc);  /* insert last jump in `f' list */
       
   640   luaK_patchtohere(fs, e->t);
       
   641   e->t = NO_JUMP;
       
   642 }
       
   643 
       
   644 
       
   645 void luaK_goiffalse (FuncState *fs, expdesc *e) {
       
   646   int pc;  /* pc of last jump */
       
   647   luaK_dischargevars(fs, e);
       
   648   switch (e->k) {
       
   649     case VJMP: {
       
   650       pc = e->u.info;
       
   651       break;
       
   652     }
       
   653     case VNIL: case VFALSE: {
       
   654       pc = NO_JUMP;  /* always false; do nothing */
       
   655       break;
       
   656     }
       
   657     default: {
       
   658       pc = jumponcond(fs, e, 1);
       
   659       break;
       
   660     }
       
   661   }
       
   662   luaK_concat(fs, &e->t, pc);  /* insert last jump in `t' list */
       
   663   luaK_patchtohere(fs, e->f);
       
   664   e->f = NO_JUMP;
       
   665 }
       
   666 
       
   667 
       
   668 static void codenot (FuncState *fs, expdesc *e) {
       
   669   luaK_dischargevars(fs, e);
       
   670   switch (e->k) {
       
   671     case VNIL: case VFALSE: {
       
   672       e->k = VTRUE;
       
   673       break;
       
   674     }
       
   675     case VK: case VKNUM: case VTRUE: {
       
   676       e->k = VFALSE;
       
   677       break;
       
   678     }
       
   679     case VJMP: {
       
   680       invertjump(fs, e);
       
   681       break;
       
   682     }
       
   683     case VRELOCABLE:
       
   684     case VNONRELOC: {
       
   685       discharge2anyreg(fs, e);
       
   686       freeexp(fs, e);
       
   687       e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0);
       
   688       e->k = VRELOCABLE;
       
   689       break;
       
   690     }
       
   691     default: {
       
   692       lua_assert(0);  /* cannot happen */
       
   693       break;
       
   694     }
       
   695   }
       
   696   /* interchange true and false lists */
       
   697   { int temp = e->f; e->f = e->t; e->t = temp; }
       
   698   removevalues(fs, e->f);
       
   699   removevalues(fs, e->t);
       
   700 }
       
   701 
       
   702 
       
   703 void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
       
   704   lua_assert(!hasjumps(t));
       
   705   t->u.ind.t = t->u.info;
       
   706   t->u.ind.idx = luaK_exp2RK(fs, k);
       
   707   t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL
       
   708                                  : check_exp(vkisinreg(t->k), VLOCAL);
       
   709   t->k = VINDEXED;
       
   710 }
       
   711 
       
   712 
       
   713 static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
       
   714   lua_Number r;
       
   715   if (!isnumeral(e1) || !isnumeral(e2)) return 0;
       
   716   if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0)
       
   717     return 0;  /* do not attempt to divide by 0 */
       
   718   r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval);
       
   719   e1->u.nval = r;
       
   720   return 1;
       
   721 }
       
   722 
       
   723 
       
   724 static void codearith (FuncState *fs, OpCode op,
       
   725                        expdesc *e1, expdesc *e2, int line) {
       
   726   if (constfolding(op, e1, e2))
       
   727     return;
       
   728   else {
       
   729     int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
       
   730     int o1 = luaK_exp2RK(fs, e1);
       
   731     if (o1 > o2) {
       
   732       freeexp(fs, e1);
       
   733       freeexp(fs, e2);
       
   734     }
       
   735     else {
       
   736       freeexp(fs, e2);
       
   737       freeexp(fs, e1);
       
   738     }
       
   739     e1->u.info = luaK_codeABC(fs, op, 0, o1, o2);
       
   740     e1->k = VRELOCABLE;
       
   741     luaK_fixline(fs, line);
       
   742   }
       
   743 }
       
   744 
       
   745 
       
   746 static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
       
   747                                                           expdesc *e2) {
       
   748   int o1 = luaK_exp2RK(fs, e1);
       
   749   int o2 = luaK_exp2RK(fs, e2);
       
   750   freeexp(fs, e2);
       
   751   freeexp(fs, e1);
       
   752   if (cond == 0 && op != OP_EQ) {
       
   753     int temp;  /* exchange args to replace by `<' or `<=' */
       
   754     temp = o1; o1 = o2; o2 = temp;  /* o1 <==> o2 */
       
   755     cond = 1;
       
   756   }
       
   757   e1->u.info = condjump(fs, op, cond, o1, o2);
       
   758   e1->k = VJMP;
       
   759 }
       
   760 
       
   761 
       
   762 void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
       
   763   expdesc e2;
       
   764   e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
       
   765   switch (op) {
       
   766     case OPR_MINUS: {
       
   767       if (isnumeral(e))  /* minus constant? */
       
   768         e->u.nval = luai_numunm(NULL, e->u.nval);  /* fold it */
       
   769       else {
       
   770         luaK_exp2anyreg(fs, e);
       
   771         codearith(fs, OP_UNM, e, &e2, line);
       
   772       }
       
   773       break;
       
   774     }
       
   775     case OPR_NOT: codenot(fs, e); break;
       
   776     case OPR_LEN: {
       
   777       luaK_exp2anyreg(fs, e);  /* cannot operate on constants */
       
   778       codearith(fs, OP_LEN, e, &e2, line);
       
   779       break;
       
   780     }
       
   781     default: lua_assert(0);
       
   782   }
       
   783 }
       
   784 
       
   785 
       
   786 void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
       
   787   switch (op) {
       
   788     case OPR_AND: {
       
   789       luaK_goiftrue(fs, v);
       
   790       break;
       
   791     }
       
   792     case OPR_OR: {
       
   793       luaK_goiffalse(fs, v);
       
   794       break;
       
   795     }
       
   796     case OPR_CONCAT: {
       
   797       luaK_exp2nextreg(fs, v);  /* operand must be on the `stack' */
       
   798       break;
       
   799     }
       
   800     case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
       
   801     case OPR_MOD: case OPR_POW: {
       
   802       if (!isnumeral(v)) luaK_exp2RK(fs, v);
       
   803       break;
       
   804     }
       
   805     default: {
       
   806       luaK_exp2RK(fs, v);
       
   807       break;
       
   808     }
       
   809   }
       
   810 }
       
   811 
       
   812 
       
   813 void luaK_posfix (FuncState *fs, BinOpr op,
       
   814                   expdesc *e1, expdesc *e2, int line) {
       
   815   switch (op) {
       
   816     case OPR_AND: {
       
   817       lua_assert(e1->t == NO_JUMP);  /* list must be closed */
       
   818       luaK_dischargevars(fs, e2);
       
   819       luaK_concat(fs, &e2->f, e1->f);
       
   820       *e1 = *e2;
       
   821       break;
       
   822     }
       
   823     case OPR_OR: {
       
   824       lua_assert(e1->f == NO_JUMP);  /* list must be closed */
       
   825       luaK_dischargevars(fs, e2);
       
   826       luaK_concat(fs, &e2->t, e1->t);
       
   827       *e1 = *e2;
       
   828       break;
       
   829     }
       
   830     case OPR_CONCAT: {
       
   831       luaK_exp2val(fs, e2);
       
   832       if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
       
   833         lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1);
       
   834         freeexp(fs, e1);
       
   835         SETARG_B(getcode(fs, e2), e1->u.info);
       
   836         e1->k = VRELOCABLE; e1->u.info = e2->u.info;
       
   837       }
       
   838       else {
       
   839         luaK_exp2nextreg(fs, e2);  /* operand must be on the 'stack' */
       
   840         codearith(fs, OP_CONCAT, e1, e2, line);
       
   841       }
       
   842       break;
       
   843     }
       
   844     case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
       
   845     case OPR_MOD: case OPR_POW: {
       
   846       codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line);
       
   847       break;
       
   848     }
       
   849     case OPR_EQ: case OPR_LT: case OPR_LE: {
       
   850       codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2);
       
   851       break;
       
   852     }
       
   853     case OPR_NE: case OPR_GT: case OPR_GE: {
       
   854       codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2);
       
   855       break;
       
   856     }
       
   857     default: lua_assert(0);
       
   858   }
       
   859 }
       
   860 
       
   861 
       
   862 void luaK_fixline (FuncState *fs, int line) {
       
   863   fs->f->lineinfo[fs->pc - 1] = line;
       
   864 }
       
   865 
       
   866 
       
   867 void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
       
   868   int c =  (nelems - 1)/LFIELDS_PER_FLUSH + 1;
       
   869   int b = (tostore == LUA_MULTRET) ? 0 : tostore;
       
   870   lua_assert(tostore != 0);
       
   871   if (c <= MAXARG_C)
       
   872     luaK_codeABC(fs, OP_SETLIST, base, b, c);
       
   873   else if (c <= MAXARG_Ax) {
       
   874     luaK_codeABC(fs, OP_SETLIST, base, b, 0);
       
   875     codeextraarg(fs, c);
       
   876   }
       
   877   else
       
   878     luaX_syntaxerror(fs->ls, "constructor too long");
       
   879   fs->freereg = base + 1;  /* free registers with list values */
       
   880 }
       
   881