LCOV - code coverage report
Current view: top level - src - lcode.c Coverage Total Hit
Test: Lua 5.2.4 Lines: 96.2 % 528 508
Test Date: 2024-04-28 10:23:12
Legend: Lines: hit not hit

            Line data    Source code
       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         3564 : static int isnumeral(expdesc *e) {
      33         3564 :   return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
      34              : }
      35              : 
      36              : 
      37          281 : void luaK_nil (FuncState *fs, int from, int n) {
      38              :   Instruction *previous;
      39          281 :   int l = from + n - 1;  /* last register to set nil */
      40          281 :   if (fs->pc > fs->lasttarget) {  /* no jumps to current position? */
      41          264 :     previous = &fs->f->code[fs->pc-1];
      42          264 :     if (GET_OPCODE(*previous) == OP_LOADNIL) {
      43            5 :       int pfrom = GETARG_A(*previous);
      44            5 :       int pl = pfrom + GETARG_B(*previous);
      45            5 :       if ((pfrom <= from && from <= pl + 1) ||
      46            0 :           (from <= pfrom && pfrom <= l + 1)) {  /* can connect both? */
      47            5 :         if (pfrom < from) from = pfrom;  /* from = min(from, pfrom) */
      48            5 :         if (pl > l) l = pl;  /* l = max(l, pl) */
      49            5 :         SETARG_A(*previous, from);
      50            5 :         SETARG_B(*previous, l - from);
      51            5 :         return;
      52              :       }
      53              :     }  /* else go through */
      54              :   }
      55          276 :   luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0);  /* else no optimization */
      56              : }
      57              : 
      58              : 
      59         2962 : int luaK_jump (FuncState *fs) {
      60         2962 :   int jpc = fs->jpc;  /* save list of jumps to here */
      61              :   int j;
      62         2962 :   fs->jpc = NO_JUMP;
      63         2962 :   j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
      64         2962 :   luaK_concat(fs, &j, jpc);  /* keep them on hold */
      65         2962 :   return j;
      66              : }
      67              : 
      68              : 
      69         3170 : void luaK_ret (FuncState *fs, int first, int nret) {
      70         3170 :   luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
      71         3170 : }
      72              : 
      73              : 
      74         2165 : static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
      75         2165 :   luaK_codeABC(fs, op, A, B, C);
      76         2165 :   return luaK_jump(fs);
      77              : }
      78              : 
      79              : 
      80         3757 : static void fixjump (FuncState *fs, int pc, int dest) {
      81         3757 :   Instruction *jmp = &fs->f->code[pc];
      82         3757 :   int offset = dest-(pc+1);
      83              :   lua_assert(dest != NO_JUMP);
      84         3757 :   if (abs(offset) > MAXARG_sBx)
      85            0 :     luaX_syntaxerror(fs->ls, "control structure too long");
      86         3757 :   SETARG_sBx(*jmp, offset);
      87         3757 : }
      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         6892 : int luaK_getlabel (FuncState *fs) {
      95         6892 :   fs->lasttarget = fs->pc;
      96         6892 :   return fs->pc;
      97              : }
      98              : 
      99              : 
     100         4037 : static int getjump (FuncState *fs, int pc) {
     101         4037 :   int offset = GETARG_sBx(fs->f->code[pc]);
     102         4037 :   if (offset == NO_JUMP)  /* point to itself represents end of list */
     103         3789 :     return NO_JUMP;  /* end of list */
     104              :   else
     105          248 :     return (pc+1)+offset;  /* turn offset into absolute position */
     106              : }
     107              : 
     108              : 
     109         4720 : static Instruction *getjumpcontrol (FuncState *fs, int pc) {
     110         4720 :   Instruction *pi = &fs->f->code[pc];
     111         4720 :   if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
     112         3334 :     return pi-1;
     113              :   else
     114         1386 :     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          763 : static int need_value (FuncState *fs, int list) {
     123          929 :   for (; list != NO_JUMP; list = getjump(fs, list)) {
     124          592 :     Instruction i = *getjumpcontrol(fs, list);
     125          592 :     if (GET_OPCODE(i) != OP_TESTSET) return 1;
     126              :   }
     127          337 :   return 0;  /* not found */
     128              : }
     129              : 
     130              : 
     131         3551 : static int patchtestreg (FuncState *fs, int node, int reg) {
     132         3551 :   Instruction *i = getjumpcontrol(fs, node);
     133         3551 :   if (GET_OPCODE(*i) != OP_TESTSET)
     134         2776 :     return 0;  /* cannot patch other instructions */
     135          775 :   if (reg != NO_REG && reg != GETARG_B(*i))
     136            4 :     SETARG_A(*i, reg);
     137              :   else  /* no register to put value or register already has the value */
     138          771 :     *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
     139              : 
     140          775 :   return 1;
     141              : }
     142              : 
     143              : 
     144          894 : static void removevalues (FuncState *fs, int list) {
     145          894 :   for (; list != NO_JUMP; list = getjump(fs, list))
     146            0 :       patchtestreg(fs, list, NO_REG);
     147          894 : }
     148              : 
     149              : 
     150        58184 : static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
     151              :                           int dtarget) {
     152        61735 :   while (list != NO_JUMP) {
     153         3551 :     int next = getjump(fs, list);
     154         3551 :     if (patchtestreg(fs, list, reg))
     155          775 :       fixjump(fs, list, vtarget);
     156              :     else
     157         2776 :       fixjump(fs, list, dtarget);  /* jump to default target */
     158         3551 :     list = next;
     159              :   }
     160        58184 : }
     161              : 
     162              : 
     163        56618 : static void dischargejpc (FuncState *fs) {
     164        56618 :   patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
     165        56618 :   fs->jpc = NO_JUMP;
     166        56618 : }
     167              : 
     168              : 
     169          397 : void luaK_patchlist (FuncState *fs, int list, int target) {
     170          397 :   if (target == fs->pc)
     171           15 :     luaK_patchtohere(fs, list);
     172              :   else {
     173              :     lua_assert(target < fs->pc);
     174          382 :     patchlistaux(fs, list, target, NO_REG, target);
     175              :   }
     176          397 : }
     177              : 
     178              : 
     179           72 : LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level) {
     180           72 :   level++;  /* argument is +1 to reserve 0 as non-op */
     181          149 :   while (list != NO_JUMP) {
     182           77 :     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           77 :     SETARG_A(fs->f->code[list], level);
     187           77 :     list = next;
     188              :   }
     189           72 : }
     190              : 
     191              : 
     192         5381 : void luaK_patchtohere (FuncState *fs, int list) {
     193         5381 :   luaK_getlabel(fs);
     194         5381 :   luaK_concat(fs, &fs->jpc, list);
     195         5381 : }
     196              : 
     197              : 
     198        11460 : void luaK_concat (FuncState *fs, int *l1, int l2) {
     199        11460 :   if (l2 == NO_JUMP) return;
     200         5540 :   else if (*l1 == NO_JUMP)
     201         5334 :     *l1 = l2;
     202              :   else {
     203          206 :     int list = *l1;
     204              :     int next;
     205          243 :     while ((next = getjump(fs, list)) != NO_JUMP)  /* find last element */
     206           37 :       list = next;
     207          206 :     fixjump(fs, list, l2);
     208              :   }
     209              : }
     210              : 
     211              : 
     212        56618 : static int luaK_code (FuncState *fs, Instruction i) {
     213        56618 :   Proto *f = fs->f;
     214        56618 :   dischargejpc(fs);  /* `pc' will change */
     215              :   /* put new instruction in code array */
     216        56618 :   luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
     217              :                   MAX_INT, "opcodes");
     218        56618 :   f->code[fs->pc] = i;
     219              :   /* save corresponding line information */
     220        56618 :   luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
     221              :                   MAX_INT, "opcodes");
     222        56618 :   f->lineinfo[fs->pc] = fs->ls->lastline;
     223        56618 :   return fs->pc++;
     224              : }
     225              : 
     226              : 
     227        41811 : 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        41811 :   return luaK_code(fs, CREATE_ABC(o, a, b, c));
     233              : }
     234              : 
     235              : 
     236        14807 : 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        14807 :   return luaK_code(fs, CREATE_ABx(o, a, bc));
     241              : }
     242              : 
     243              : 
     244            0 : static int codeextraarg (FuncState *fs, int a) {
     245              :   lua_assert(a <= MAXARG_Ax);
     246            0 :   return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a));
     247              : }
     248              : 
     249              : 
     250         9554 : int luaK_codek (FuncState *fs, int reg, int k) {
     251         9554 :   if (k <= MAXARG_Bx)
     252         9554 :     return luaK_codeABx(fs, OP_LOADK, reg, k);
     253              :   else {
     254            0 :     int p = luaK_codeABx(fs, OP_LOADKX, reg, 0);
     255            0 :     codeextraarg(fs, k);
     256            0 :     return p;
     257              :   }
     258              : }
     259              : 
     260              : 
     261        39130 : void luaK_checkstack (FuncState *fs, int n) {
     262        39130 :   int newstack = fs->freereg + n;
     263        39130 :   if (newstack > fs->f->maxstacksize) {
     264         7115 :     if (newstack >= MAXSTACK)
     265            0 :       luaX_syntaxerror(fs->ls, "function or expression too complex");
     266         7115 :     fs->f->maxstacksize = cast_byte(newstack);
     267              :   }
     268        39130 : }
     269              : 
     270              : 
     271        39090 : void luaK_reserveregs (FuncState *fs, int n) {
     272        39090 :   luaK_checkstack(fs, n);
     273        39090 :   fs->freereg += n;
     274        39090 : }
     275              : 
     276              : 
     277        31301 : static void freereg (FuncState *fs, int reg) {
     278        31301 :   if (!ISK(reg) && reg >= fs->nactvar) {
     279        12162 :     fs->freereg--;
     280              :     lua_assert(reg == fs->freereg);
     281              :   }
     282        31301 : }
     283              : 
     284              : 
     285        48875 : static void freeexp (FuncState *fs, expdesc *e) {
     286        48875 :   if (e->k == VNONRELOC)
     287        18429 :     freereg(fs, e->u.info);
     288        48875 : }
     289              : 
     290              : 
     291        23531 : static int addk (FuncState *fs, TValue *key, TValue *v) {
     292        23531 :   lua_State *L = fs->ls->L;
     293        23531 :   TValue *idx = luaH_set(L, fs->h, key);
     294        23531 :   Proto *f = fs->f;
     295              :   int k, oldsize;
     296        23531 :   if (ttisnumber(idx)) {
     297        10191 :     lua_Number n = nvalue(idx);
     298        10191 :     lua_number2int(k, n);
     299        10191 :     if (luaV_rawequalobj(&f->k[k], v))
     300        10190 :       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        13341 :   oldsize = f->sizek;
     306        13341 :   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        13341 :   setnvalue(idx, cast_num(k));
     310        13341 :   luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
     311        33405 :   while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
     312        13341 :   setobj(L, &f->k[k], v);
     313        13341 :   fs->nk++;
     314        13341 :   luaC_barrier(L, f, v);
     315        13341 :   return k;
     316              : }
     317              : 
     318              : 
     319        19732 : int luaK_stringK (FuncState *fs, TString *s) {
     320              :   TValue o;
     321        19732 :   setsvalue(fs->ls->L, &o, s);
     322        19732 :   return addk(fs, &o, &o);
     323              : }
     324              : 
     325              : 
     326         3609 : int luaK_numberK (FuncState *fs, lua_Number r) {
     327              :   int n;
     328         3609 :   lua_State *L = fs->ls->L;
     329              :   TValue o;
     330         3609 :   setnvalue(&o, r);
     331         3609 :   if (r == 0 || luai_numisnan(NULL, r)) {  /* handle -0 and NaN */
     332              :     /* use raw representation as key to avoid numeric problems */
     333          738 :     setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r)));
     334          738 :     n = addk(fs, L->top - 1, &o);
     335          738 :     L->top--;
     336              :   }
     337              :   else
     338         2871 :     n = addk(fs, &o, &o);  /* regular case */
     339         3609 :   return n;
     340              : }
     341              : 
     342              : 
     343          147 : static int boolK (FuncState *fs, int b) {
     344              :   TValue o;
     345          147 :   setbvalue(&o, b);
     346          147 :   return addk(fs, &o, &o);
     347              : }
     348              : 
     349              : 
     350           43 : static int nilK (FuncState *fs) {
     351              :   TValue k, v;
     352           43 :   setnilvalue(&v);
     353              :   /* cannot use nil as key; instead use table itself to represent nil */
     354           43 :   sethvalue(fs->ls->L, &k, fs->h);
     355           43 :   return addk(fs, &k, &v);
     356              : }
     357              : 
     358              : 
     359         9389 : void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
     360         9389 :   if (e->k == VCALL) {  /* expression is an open function call? */
     361         1134 :     SETARG_C(getcode(fs, e), nresults+1);
     362              :   }
     363         8255 :   else if (e->k == VVARARG) {
     364           19 :     SETARG_B(getcode(fs, e), nresults+1);
     365           19 :     SETARG_A(getcode(fs, e), fs->freereg);
     366           19 :     luaK_reserveregs(fs, 1);
     367              :   }
     368         9389 : }
     369              : 
     370              : 
     371         3917 : void luaK_setoneret (FuncState *fs, expdesc *e) {
     372         3917 :   if (e->k == VCALL) {  /* expression is an open function call? */
     373         2833 :     e->k = VNONRELOC;
     374         2833 :     e->u.info = GETARG_A(getcode(fs, e));
     375              :   }
     376         1084 :   else if (e->k == VVARARG) {
     377            1 :     SETARG_B(getcode(fs, e), 2);
     378            1 :     e->k = VRELOCABLE;  /* can relocate its simple result */
     379              :   }
     380         3917 : }
     381              : 
     382              : 
     383       116185 : void luaK_dischargevars (FuncState *fs, expdesc *e) {
     384       116185 :   switch (e->k) {
     385         9811 :     case VLOCAL: {
     386         9811 :       e->k = VNONRELOC;
     387         9811 :       break;
     388              :     }
     389         2268 :     case VUPVAL: {
     390         2268 :       e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
     391         2268 :       e->k = VRELOCABLE;
     392         2268 :       break;
     393              :     }
     394        10402 :     case VINDEXED: {
     395        10402 :       OpCode op = OP_GETTABUP;  /* assume 't' is in an upvalue */
     396        10402 :       freereg(fs, e->u.ind.idx);
     397        10402 :       if (e->u.ind.vt == VLOCAL) {  /* 't' is in a register? */
     398         2470 :         freereg(fs, e->u.ind.t);
     399         2470 :         op = OP_GETTABLE;
     400              :       }
     401        10402 :       e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);
     402        10402 :       e->k = VRELOCABLE;
     403        10402 :       break;
     404              :     }
     405         2003 :     case VVARARG:
     406              :     case VCALL: {
     407         2003 :       luaK_setoneret(fs, e);
     408         2003 :       break;
     409              :     }
     410        91701 :     default: break;  /* there is one value available (somewhere) */
     411              :   }
     412       116185 : }
     413              : 
     414              : 
     415          852 : static int code_label (FuncState *fs, int A, int b, int jump) {
     416          852 :   luaK_getlabel(fs);  /* those instructions may be jump targets */
     417          852 :   return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
     418              : }
     419              : 
     420              : 
     421        36724 : static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
     422        36724 :   luaK_dischargevars(fs, e);
     423        36724 :   switch (e->k) {
     424          217 :     case VNIL: {
     425          217 :       luaK_nil(fs, reg, 1);
     426          217 :       break;
     427              :     }
     428          752 :     case VFALSE: case VTRUE: {
     429          752 :       luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
     430          752 :       break;
     431              :     }
     432         6859 :     case VK: {
     433         6859 :       luaK_codek(fs, reg, e->u.info);
     434         6859 :       break;
     435              :     }
     436         2432 :     case VKNUM: {
     437         2432 :       luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval));
     438         2432 :       break;
     439              :     }
     440        17752 :     case VRELOCABLE: {
     441        17752 :       Instruction *pc = &getcode(fs, e);
     442        17752 :       SETARG_A(*pc, reg);
     443        17752 :       break;
     444              :     }
     445         8338 :     case VNONRELOC: {
     446         8338 :       if (reg != e->u.info)
     447         5492 :         luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0);
     448         8338 :       break;
     449              :     }
     450          374 :     default: {
     451              :       lua_assert(e->k == VVOID || e->k == VJMP);
     452          374 :       return;  /* nothing to do... */
     453              :     }
     454              :   }
     455        36350 :   e->u.info = reg;
     456        36350 :   e->k = VNONRELOC;
     457              : }
     458              : 
     459              : 
     460         1209 : static void discharge2anyreg (FuncState *fs, expdesc *e) {
     461         1209 :   if (e->k != VNONRELOC) {
     462          270 :     luaK_reserveregs(fs, 1);
     463          270 :     discharge2reg(fs, e, fs->freereg-1);
     464              :   }
     465         1209 : }
     466              : 
     467              : 
     468        36454 : static void exp2reg (FuncState *fs, expdesc *e, int reg) {
     469        36454 :   discharge2reg(fs, e, reg);
     470        36454 :   if (e->k == VJMP)
     471          374 :     luaK_concat(fs, &e->t, e->u.info);  /* put this jump in `t' list */
     472        36454 :   if (hasjumps(e)) {
     473              :     int final;  /* position after whole expression */
     474          592 :     int p_f = NO_JUMP;  /* position of an eventual LOAD false */
     475          592 :     int p_t = NO_JUMP;  /* position of an eventual LOAD true */
     476          592 :     if (need_value(fs, e->t) || need_value(fs, e->f)) {
     477          426 :       int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
     478          426 :       p_f = code_label(fs, reg, 0, 1);
     479          426 :       p_t = code_label(fs, reg, 1, 0);
     480          426 :       luaK_patchtohere(fs, fj);
     481              :     }
     482          592 :     final = luaK_getlabel(fs);
     483          592 :     patchlistaux(fs, e->f, final, reg, p_f);
     484          592 :     patchlistaux(fs, e->t, final, reg, p_t);
     485              :   }
     486        36454 :   e->f = e->t = NO_JUMP;
     487        36454 :   e->u.info = reg;
     488        36454 :   e->k = VNONRELOC;
     489        36454 : }
     490              : 
     491              : 
     492        35595 : void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
     493        35595 :   luaK_dischargevars(fs, e);
     494        35595 :   freeexp(fs, e);
     495        35595 :   luaK_reserveregs(fs, 1);
     496        35595 :   exp2reg(fs, e, fs->freereg - 1);
     497        35595 : }
     498              : 
     499              : 
     500        14537 : int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
     501        14537 :   luaK_dischargevars(fs, e);
     502        14537 :   if (e->k == VNONRELOC) {
     503        10623 :     if (!hasjumps(e)) return e->u.info;  /* exp is already in a register */
     504            1 :     if (e->u.info >= fs->nactvar) {  /* reg. is not a local? */
     505            0 :       exp2reg(fs, e, e->u.info);  /* put value on it */
     506            0 :       return e->u.info;
     507              :     }
     508              :   }
     509         3915 :   luaK_exp2nextreg(fs, e);  /* default */
     510         3915 :   return e->u.info;
     511              : }
     512              : 
     513              : 
     514         2945 : void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
     515         2945 :   if (e->k != VUPVAL || hasjumps(e))
     516         2845 :     luaK_exp2anyreg(fs, e);
     517         2945 : }
     518              : 
     519              : 
     520        26602 : void luaK_exp2val (FuncState *fs, expdesc *e) {
     521        26602 :   if (hasjumps(e))
     522           43 :     luaK_exp2anyreg(fs, e);
     523              :   else
     524        26559 :     luaK_dischargevars(fs, e);
     525        26602 : }
     526              : 
     527              : 
     528        23759 : int luaK_exp2RK (FuncState *fs, expdesc *e) {
     529        23759 :   luaK_exp2val(fs, e);
     530        23759 :   switch (e->k) {
     531          190 :     case VTRUE:
     532              :     case VFALSE:
     533              :     case VNIL: {
     534          190 :       if (fs->nk <= MAXINDEXRK) {  /* constant fits in RK operand? */
     535          190 :         e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE));
     536          190 :         e->k = VK;
     537          190 :         return RKASK(e->u.info);
     538              :       }
     539            0 :       else break;
     540              :     }
     541          914 :     case VKNUM: {
     542          914 :       e->u.info = luaK_numberK(fs, e->u.nval);
     543          914 :       e->k = VK;
     544              :       /* go through */
     545              :     }
     546        13966 :     case VK: {
     547        13966 :       if (e->u.info <= MAXINDEXRK)  /* constant fits in argC? */
     548        13913 :         return RKASK(e->u.info);
     549           53 :       else break;
     550              :     }
     551         9603 :     default: break;
     552              :   }
     553              :   /* not a constant in the right range: put it in a register */
     554         9656 :   return luaK_exp2anyreg(fs, e);
     555              : }
     556              : 
     557              : 
     558         3057 : void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
     559         3057 :   switch (var->k) {
     560          859 :     case VLOCAL: {
     561          859 :       freeexp(fs, ex);
     562          859 :       exp2reg(fs, ex, var->u.info);
     563          859 :       return;
     564              :     }
     565          224 :     case VUPVAL: {
     566          224 :       int e = luaK_exp2anyreg(fs, ex);
     567          224 :       luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
     568          224 :       break;
     569              :     }
     570         1974 :     case VINDEXED: {
     571         1974 :       OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP;
     572         1974 :       int e = luaK_exp2RK(fs, ex);
     573         1974 :       luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e);
     574         1974 :       break;
     575              :     }
     576            0 :     default: {
     577              :       lua_assert(0);  /* invalid var kind to store */
     578            0 :       break;
     579              :     }
     580              :   }
     581         2198 :   freeexp(fs, ex);
     582              : }
     583              : 
     584              : 
     585          520 : void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
     586              :   int ereg;
     587          520 :   luaK_exp2anyreg(fs, e);
     588          520 :   ereg = e->u.info;  /* register where 'e' was placed */
     589          520 :   freeexp(fs, e);
     590          520 :   e->u.info = fs->freereg;  /* base register for op_self */
     591          520 :   e->k = VNONRELOC;
     592          520 :   luaK_reserveregs(fs, 2);  /* function and 'self' produced by op_self */
     593          520 :   luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key));
     594          520 :   freeexp(fs, key);
     595          520 : }
     596              : 
     597              : 
     598          577 : static void invertjump (FuncState *fs, expdesc *e) {
     599          577 :   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          577 :   SETARG_A(*pc, !(GETARG_A(*pc)));
     603          577 : }
     604              : 
     605              : 
     606         1153 : static int jumponcond (FuncState *fs, expdesc *e, int cond) {
     607         1153 :   if (e->k == VRELOCABLE) {
     608          613 :     Instruction ie = getcode(fs, e);
     609          613 :     if (GET_OPCODE(ie) == OP_NOT) {
     610          378 :       fs->pc--;  /* remove previous OP_NOT */
     611          378 :       return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
     612              :     }
     613              :     /* else go through */
     614              :   }
     615          775 :   discharge2anyreg(fs, e);
     616          775 :   freeexp(fs, e);
     617          775 :   return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond);
     618              : }
     619              : 
     620              : 
     621         1567 : void luaK_goiftrue (FuncState *fs, expdesc *e) {
     622              :   int pc;  /* pc of last jump */
     623         1567 :   luaK_dischargevars(fs, e);
     624         1567 :   switch (e->k) {
     625          575 :     case VJMP: {
     626          575 :       invertjump(fs, e);
     627          575 :       pc = e->u.info;
     628          575 :       break;
     629              :     }
     630           12 :     case VK: case VKNUM: case VTRUE: {
     631           12 :       pc = NO_JUMP;  /* always true; do nothing */
     632           12 :       break;
     633              :     }
     634          980 :     default: {
     635          980 :       pc = jumponcond(fs, e, 0);
     636          980 :       break;
     637              :     }
     638              :   }
     639         1567 :   luaK_concat(fs, &e->f, pc);  /* insert last jump in `f' list */
     640         1567 :   luaK_patchtohere(fs, e->t);
     641         1567 :   e->t = NO_JUMP;
     642         1567 : }
     643              : 
     644              : 
     645          240 : void luaK_goiffalse (FuncState *fs, expdesc *e) {
     646              :   int pc;  /* pc of last jump */
     647          240 :   luaK_dischargevars(fs, e);
     648          240 :   switch (e->k) {
     649           63 :     case VJMP: {
     650           63 :       pc = e->u.info;
     651           63 :       break;
     652              :     }
     653            4 :     case VNIL: case VFALSE: {
     654            4 :       pc = NO_JUMP;  /* always false; do nothing */
     655            4 :       break;
     656              :     }
     657          173 :     default: {
     658          173 :       pc = jumponcond(fs, e, 1);
     659          173 :       break;
     660              :     }
     661              :   }
     662          240 :   luaK_concat(fs, &e->t, pc);  /* insert last jump in `t' list */
     663          240 :   luaK_patchtohere(fs, e->f);
     664          240 :   e->f = NO_JUMP;
     665          240 : }
     666              : 
     667              : 
     668          447 : static void codenot (FuncState *fs, expdesc *e) {
     669          447 :   luaK_dischargevars(fs, e);
     670          447 :   switch (e->k) {
     671            5 :     case VNIL: case VFALSE: {
     672            5 :       e->k = VTRUE;
     673            5 :       break;
     674              :     }
     675            6 :     case VK: case VKNUM: case VTRUE: {
     676            6 :       e->k = VFALSE;
     677            6 :       break;
     678              :     }
     679            2 :     case VJMP: {
     680            2 :       invertjump(fs, e);
     681            2 :       break;
     682              :     }
     683          434 :     case VRELOCABLE:
     684              :     case VNONRELOC: {
     685          434 :       discharge2anyreg(fs, e);
     686          434 :       freeexp(fs, e);
     687          434 :       e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0);
     688          434 :       e->k = VRELOCABLE;
     689          434 :       break;
     690              :     }
     691            0 :     default: {
     692              :       lua_assert(0);  /* cannot happen */
     693            0 :       break;
     694              :     }
     695              :   }
     696              :   /* interchange true and false lists */
     697          447 :   { int temp = e->f; e->f = e->t; e->t = temp; }
     698          447 :   removevalues(fs, e->f);
     699          447 :   removevalues(fs, e->t);
     700          447 : }
     701              : 
     702              : 
     703        12395 : void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
     704              :   lua_assert(!hasjumps(t));
     705        12395 :   t->u.ind.t = t->u.info;
     706        12395 :   t->u.ind.idx = luaK_exp2RK(fs, k);
     707        12395 :   t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL
     708              :                                  : check_exp(vkisinreg(t->k), VLOCAL);
     709        12395 :   t->k = VINDEXED;
     710        12395 : }
     711              : 
     712              : 
     713         2633 : static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
     714              :   lua_Number r;
     715         2633 :   if (!isnumeral(e1) || !isnumeral(e2)) return 0;
     716           29 :   if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0)
     717            7 :     return 0;  /* do not attempt to divide by 0 */
     718           22 :   r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval);
     719           22 :   e1->u.nval = r;
     720           22 :   return 1;
     721              : }
     722              : 
     723              : 
     724         2633 : static void codearith (FuncState *fs, OpCode op,
     725              :                        expdesc *e1, expdesc *e2, int line) {
     726         2633 :   if (constfolding(op, e1, e2))
     727           22 :     return;
     728              :   else {
     729         2611 :     int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
     730         2611 :     int o1 = luaK_exp2RK(fs, e1);
     731         2611 :     if (o1 > o2) {
     732          274 :       freeexp(fs, e1);
     733          274 :       freeexp(fs, e2);
     734              :     }
     735              :     else {
     736         2337 :       freeexp(fs, e2);
     737         2337 :       freeexp(fs, e1);
     738              :     }
     739         2611 :     e1->u.info = luaK_codeABC(fs, op, 0, o1, o2);
     740         2611 :     e1->k = VRELOCABLE;
     741         2611 :     luaK_fixline(fs, line);
     742              :   }
     743              : }
     744              : 
     745              : 
     746         1012 : static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
     747              :                                                           expdesc *e2) {
     748         1012 :   int o1 = luaK_exp2RK(fs, e1);
     749         1012 :   int o2 = luaK_exp2RK(fs, e2);
     750         1012 :   freeexp(fs, e2);
     751         1012 :   freeexp(fs, e1);
     752         1012 :   if (cond == 0 && op != OP_EQ) {
     753              :     int temp;  /* exchange args to replace by `<' or `<=' */
     754          227 :     temp = o1; o1 = o2; o2 = temp;  /* o1 <==> o2 */
     755          227 :     cond = 1;
     756              :   }
     757         1012 :   e1->u.info = condjump(fs, op, cond, o1, o2);
     758         1012 :   e1->k = VJMP;
     759         1012 : }
     760              : 
     761              : 
     762         1094 : void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
     763              :   expdesc e2;
     764         1094 :   e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
     765         1094 :   switch (op) {
     766          127 :     case OPR_MINUS: {
     767          127 :       if (isnumeral(e))  /* minus constant? */
     768          111 :         e->u.nval = luai_numunm(NULL, e->u.nval);  /* fold it */
     769              :       else {
     770           16 :         luaK_exp2anyreg(fs, e);
     771           16 :         codearith(fs, OP_UNM, e, &e2, line);
     772              :       }
     773          127 :       break;
     774              :     }
     775          447 :     case OPR_NOT: codenot(fs, e); break;
     776          520 :     case OPR_LEN: {
     777          520 :       luaK_exp2anyreg(fs, e);  /* cannot operate on constants */
     778          520 :       codearith(fs, OP_LEN, e, &e2, line);
     779          520 :       break;
     780              :     }
     781         1094 :     default: lua_assert(0);
     782              :   }
     783         1094 : }
     784              : 
     785              : 
     786         4214 : void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
     787         4214 :   switch (op) {
     788          145 :     case OPR_AND: {
     789          145 :       luaK_goiftrue(fs, v);
     790          145 :       break;
     791              :     }
     792          232 :     case OPR_OR: {
     793          232 :       luaK_goiffalse(fs, v);
     794          232 :       break;
     795              :     }
     796         2099 :     case OPR_CONCAT: {
     797         2099 :       luaK_exp2nextreg(fs, v);  /* operand must be on the `stack' */
     798         2099 :       break;
     799              :     }
     800          726 :     case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
     801              :     case OPR_MOD: case OPR_POW: {
     802          726 :       if (!isnumeral(v)) luaK_exp2RK(fs, v);
     803          726 :       break;
     804              :     }
     805         1012 :     default: {
     806         1012 :       luaK_exp2RK(fs, v);
     807         1012 :       break;
     808              :     }
     809              :   }
     810         4214 : }
     811              : 
     812              : 
     813         4214 : void luaK_posfix (FuncState *fs, BinOpr op,
     814              :                   expdesc *e1, expdesc *e2, int line) {
     815         4214 :   switch (op) {
     816          145 :     case OPR_AND: {
     817              :       lua_assert(e1->t == NO_JUMP);  /* list must be closed */
     818          145 :       luaK_dischargevars(fs, e2);
     819          145 :       luaK_concat(fs, &e2->f, e1->f);
     820          145 :       *e1 = *e2;
     821          145 :       break;
     822              :     }
     823          232 :     case OPR_OR: {
     824              :       lua_assert(e1->f == NO_JUMP);  /* list must be closed */
     825          232 :       luaK_dischargevars(fs, e2);
     826          232 :       luaK_concat(fs, &e2->t, e1->t);
     827          232 :       *e1 = *e2;
     828          232 :       break;
     829              :     }
     830         2099 :     case OPR_CONCAT: {
     831         2099 :       luaK_exp2val(fs, e2);
     832         2099 :       if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) {
     833              :         lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1);
     834          728 :         freeexp(fs, e1);
     835          728 :         SETARG_B(getcode(fs, e2), e1->u.info);
     836          728 :         e1->k = VRELOCABLE; e1->u.info = e2->u.info;
     837              :       }
     838              :       else {
     839         1371 :         luaK_exp2nextreg(fs, e2);  /* operand must be on the 'stack' */
     840         1371 :         codearith(fs, OP_CONCAT, e1, e2, line);
     841              :       }
     842         2099 :       break;
     843              :     }
     844          726 :     case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
     845              :     case OPR_MOD: case OPR_POW: {
     846          726 :       codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line);
     847          726 :       break;
     848              :     }
     849          552 :     case OPR_EQ: case OPR_LT: case OPR_LE: {
     850          552 :       codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2);
     851          552 :       break;
     852              :     }
     853          460 :     case OPR_NE: case OPR_GT: case OPR_GE: {
     854          460 :       codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2);
     855          460 :       break;
     856              :     }
     857         4214 :     default: lua_assert(0);
     858              :   }
     859         4214 : }
     860              : 
     861              : 
     862        13166 : void luaK_fixline (FuncState *fs, int line) {
     863        13166 :   fs->f->lineinfo[fs->pc - 1] = line;
     864        13166 : }
     865              : 
     866              : 
     867          416 : void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
     868          416 :   int c =  (nelems - 1)/LFIELDS_PER_FLUSH + 1;
     869          416 :   int b = (tostore == LUA_MULTRET) ? 0 : tostore;
     870              :   lua_assert(tostore != 0);
     871          416 :   if (c <= MAXARG_C)
     872          416 :     luaK_codeABC(fs, OP_SETLIST, base, b, c);
     873            0 :   else if (c <= MAXARG_Ax) {
     874            0 :     luaK_codeABC(fs, OP_SETLIST, base, b, 0);
     875            0 :     codeextraarg(fs, c);
     876              :   }
     877              :   else
     878            0 :     luaX_syntaxerror(fs->ls, "constructor too long");
     879          416 :   fs->freereg = base + 1;  /* free registers with list values */
     880          416 : }
     881              : 
        

Generated by: LCOV version 2.0-1