LCOV - code coverage report
Current view: top level - src - lcode.c Coverage Total Hit
Test: Lua 5.3.6 Lines: 97.0 % 559 542
Test Date: 2024-04-28 10:23:15
Legend: Lines: hit not hit

            Line data    Source code
       1              : /*
       2              : ** $Id: lcode.c,v 2.112.1.1 2017/04/19 17:20:42 roberto Exp $
       3              : ** Code generator for Lua
       4              : ** See Copyright Notice in lua.h
       5              : */
       6              : 
       7              : #define lcode_c
       8              : #define LUA_CORE
       9              : 
      10              : #include "lprefix.h"
      11              : 
      12              : 
      13              : #include <math.h>
      14              : #include <stdlib.h>
      15              : 
      16              : #include "lua.h"
      17              : 
      18              : #include "lcode.h"
      19              : #include "ldebug.h"
      20              : #include "ldo.h"
      21              : #include "lgc.h"
      22              : #include "llex.h"
      23              : #include "lmem.h"
      24              : #include "lobject.h"
      25              : #include "lopcodes.h"
      26              : #include "lparser.h"
      27              : #include "lstring.h"
      28              : #include "ltable.h"
      29              : #include "lvm.h"
      30              : 
      31              : 
      32              : /* Maximum number of registers in a Lua function (must fit in 8 bits) */
      33              : #define MAXREGS         255
      34              : 
      35              : 
      36              : #define hasjumps(e)     ((e)->t != (e)->f)
      37              : 
      38              : 
      39              : /*
      40              : ** If expression is a numeric constant, fills 'v' with its value
      41              : ** and returns 1. Otherwise, returns 0.
      42              : */
      43         2149 : static int tonumeral(const expdesc *e, TValue *v) {
      44         2149 :   if (hasjumps(e))
      45            0 :     return 0;  /* not a numeral */
      46         2149 :   switch (e->k) {
      47          517 :     case VKINT:
      48          517 :       if (v) setivalue(v, e->u.ival);
      49          517 :       return 1;
      50           67 :     case VKFLT:
      51           67 :       if (v) setfltvalue(v, e->u.nval);
      52           67 :       return 1;
      53         1565 :     default: return 0;
      54              :   }
      55              : }
      56              : 
      57              : 
      58              : /*
      59              : ** Create a OP_LOADNIL instruction, but try to optimize: if the previous
      60              : ** instruction is also OP_LOADNIL and ranges are compatible, adjust
      61              : ** range of previous instruction instead of emitting a new one. (For
      62              : ** instance, 'local a; local b' will generate a single opcode.)
      63              : */
      64          292 : void luaK_nil (FuncState *fs, int from, int n) {
      65              :   Instruction *previous;
      66          292 :   int l = from + n - 1;  /* last register to set nil */
      67          292 :   if (fs->pc > fs->lasttarget) {  /* no jumps to current position? */
      68          274 :     previous = &fs->f->code[fs->pc-1];
      69          274 :     if (GET_OPCODE(*previous) == OP_LOADNIL) {  /* previous is LOADNIL? */
      70            5 :       int pfrom = GETARG_A(*previous);  /* get previous range */
      71            5 :       int pl = pfrom + GETARG_B(*previous);
      72            5 :       if ((pfrom <= from && from <= pl + 1) ||
      73            0 :           (from <= pfrom && pfrom <= l + 1)) {  /* can connect both? */
      74            5 :         if (pfrom < from) from = pfrom;  /* from = min(from, pfrom) */
      75            5 :         if (pl > l) l = pl;  /* l = max(l, pl) */
      76            5 :         SETARG_A(*previous, from);
      77            5 :         SETARG_B(*previous, l - from);
      78            5 :         return;
      79              :       }
      80              :     }  /* else go through */
      81              :   }
      82          287 :   luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0);  /* else no optimization */
      83              : }
      84              : 
      85              : 
      86              : /*
      87              : ** Gets the destination address of a jump instruction. Used to traverse
      88              : ** a list of jumps.
      89              : */
      90         4069 : static int getjump (FuncState *fs, int pc) {
      91         4069 :   int offset = GETARG_sBx(fs->f->code[pc]);
      92         4069 :   if (offset == NO_JUMP)  /* point to itself represents end of list */
      93         3821 :     return NO_JUMP;  /* end of list */
      94              :   else
      95          248 :     return (pc+1)+offset;  /* turn offset into absolute position */
      96              : }
      97              : 
      98              : 
      99              : /*
     100              : ** Fix jump instruction at position 'pc' to jump to 'dest'.
     101              : ** (Jump addresses are relative in Lua)
     102              : */
     103         3789 : static void fixjump (FuncState *fs, int pc, int dest) {
     104         3789 :   Instruction *jmp = &fs->f->code[pc];
     105         3789 :   int offset = dest - (pc + 1);
     106              :   lua_assert(dest != NO_JUMP);
     107         3789 :   if (abs(offset) > MAXARG_sBx)
     108            0 :     luaX_syntaxerror(fs->ls, "control structure too long");
     109         3789 :   SETARG_sBx(*jmp, offset);
     110         3789 : }
     111              : 
     112              : 
     113              : /*
     114              : ** Concatenate jump-list 'l2' into jump-list 'l1'
     115              : */
     116        11557 : void luaK_concat (FuncState *fs, int *l1, int l2) {
     117        11557 :   if (l2 == NO_JUMP) return;  /* nothing to concatenate? */
     118         5597 :   else if (*l1 == NO_JUMP)  /* no original list? */
     119         5391 :     *l1 = l2;  /* 'l1' points to 'l2' */
     120              :   else {
     121          206 :     int list = *l1;
     122              :     int next;
     123          243 :     while ((next = getjump(fs, list)) != NO_JUMP)  /* find last element */
     124           37 :       list = next;
     125          206 :     fixjump(fs, list, l2);  /* last element links to 'l2' */
     126              :   }
     127              : }
     128              : 
     129              : 
     130              : /*
     131              : ** Create a jump instruction and return its position, so its destination
     132              : ** can be fixed later (with 'fixjump'). If there are jumps to
     133              : ** this position (kept in 'jpc'), link them all together so that
     134              : ** 'patchlistaux' will fix all them directly to the final destination.
     135              : */
     136         2991 : int luaK_jump (FuncState *fs) {
     137         2991 :   int jpc = fs->jpc;  /* save list of jumps to here */
     138              :   int j;
     139         2991 :   fs->jpc = NO_JUMP;  /* no more jumps to here */
     140         2991 :   j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP);
     141         2991 :   luaK_concat(fs, &j, jpc);  /* keep them on hold */
     142         2991 :   return j;
     143              : }
     144              : 
     145              : 
     146              : /*
     147              : ** Code a 'return' instruction
     148              : */
     149         3412 : void luaK_ret (FuncState *fs, int first, int nret) {
     150         3412 :   luaK_codeABC(fs, OP_RETURN, first, nret+1, 0);
     151         3412 : }
     152              : 
     153              : 
     154              : /*
     155              : ** Code a "conditional jump", that is, a test or comparison opcode
     156              : ** followed by a jump. Return jump position.
     157              : */
     158         2180 : static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
     159         2180 :   luaK_codeABC(fs, op, A, B, C);
     160         2180 :   return luaK_jump(fs);
     161              : }
     162              : 
     163              : 
     164              : /*
     165              : ** returns current 'pc' and marks it as a jump target (to avoid wrong
     166              : ** optimizations with consecutive instructions not in the same basic block).
     167              : */
     168         6943 : int luaK_getlabel (FuncState *fs) {
     169         6943 :   fs->lasttarget = fs->pc;
     170         6943 :   return fs->pc;
     171              : }
     172              : 
     173              : 
     174              : /*
     175              : ** Returns the position of the instruction "controlling" a given
     176              : ** jump (that is, its condition), or the jump itself if it is
     177              : ** unconditional.
     178              : */
     179         4758 : static Instruction *getjumpcontrol (FuncState *fs, int pc) {
     180         4758 :   Instruction *pi = &fs->f->code[pc];
     181         4758 :   if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
     182         3355 :     return pi-1;
     183              :   else
     184         1403 :     return pi;
     185              : }
     186              : 
     187              : 
     188              : /*
     189              : ** Patch destination register for a TESTSET instruction.
     190              : ** If instruction in position 'node' is not a TESTSET, return 0 ("fails").
     191              : ** Otherwise, if 'reg' is not 'NO_REG', set it as the destination
     192              : ** register. Otherwise, change instruction to a simple 'TEST' (produces
     193              : ** no register value)
     194              : */
     195         3583 : static int patchtestreg (FuncState *fs, int node, int reg) {
     196         3583 :   Instruction *i = getjumpcontrol(fs, node);
     197         3583 :   if (GET_OPCODE(*i) != OP_TESTSET)
     198         2799 :     return 0;  /* cannot patch other instructions */
     199          784 :   if (reg != NO_REG && reg != GETARG_B(*i))
     200            4 :     SETARG_A(*i, reg);
     201              :   else {
     202              :      /* no register to put value or register already has the value;
     203              :         change instruction to simple test */
     204          780 :     *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i));
     205              :   }
     206          784 :   return 1;
     207              : }
     208              : 
     209              : 
     210              : /*
     211              : ** Traverse a list of tests ensuring no one produces a value
     212              : */
     213          894 : static void removevalues (FuncState *fs, int list) {
     214          894 :   for (; list != NO_JUMP; list = getjump(fs, list))
     215            0 :       patchtestreg(fs, list, NO_REG);
     216          894 : }
     217              : 
     218              : 
     219              : /*
     220              : ** Traverse a list of tests, patching their destination address and
     221              : ** registers: tests producing values jump to 'vtarget' (and put their
     222              : ** values in 'reg'), other tests jump to 'dtarget'.
     223              : */
     224        60403 : static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
     225              :                           int dtarget) {
     226        63986 :   while (list != NO_JUMP) {
     227         3583 :     int next = getjump(fs, list);
     228         3583 :     if (patchtestreg(fs, list, reg))
     229          784 :       fixjump(fs, list, vtarget);
     230              :     else
     231         2799 :       fixjump(fs, list, dtarget);  /* jump to default target */
     232         3583 :     list = next;
     233              :   }
     234        60403 : }
     235              : 
     236              : 
     237              : /*
     238              : ** Ensure all pending jumps to current position are fixed (jumping
     239              : ** to current position with no values) and reset list of pending
     240              : ** jumps
     241              : */
     242        58830 : static void dischargejpc (FuncState *fs) {
     243        58830 :   patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc);
     244        58830 :   fs->jpc = NO_JUMP;
     245        58830 : }
     246              : 
     247              : 
     248              : /*
     249              : ** Add elements in 'list' to list of pending jumps to "here"
     250              : ** (current position)
     251              : */
     252         5419 : void luaK_patchtohere (FuncState *fs, int list) {
     253         5419 :   luaK_getlabel(fs);  /* mark "here" as a jump target */
     254         5419 :   luaK_concat(fs, &fs->jpc, list);
     255         5419 : }
     256              : 
     257              : 
     258              : /*
     259              : ** Path all jumps in 'list' to jump to 'target'.
     260              : ** (The assert means that we cannot fix a jump to a forward address
     261              : ** because we only know addresses once code is generated.)
     262              : */
     263          400 : void luaK_patchlist (FuncState *fs, int list, int target) {
     264          400 :   if (target == fs->pc)  /* 'target' is current position? */
     265           15 :     luaK_patchtohere(fs, list);  /* add list to pending jumps */
     266              :   else {
     267              :     lua_assert(target < fs->pc);
     268          385 :     patchlistaux(fs, list, target, NO_REG, target);
     269              :   }
     270          400 : }
     271              : 
     272              : 
     273              : /*
     274              : ** Path all jumps in 'list' to close upvalues up to given 'level'
     275              : ** (The assertion checks that jumps either were closing nothing
     276              : ** or were closing higher levels, from inner blocks.)
     277              : */
     278           72 : void luaK_patchclose (FuncState *fs, int list, int level) {
     279           72 :   level++;  /* argument is +1 to reserve 0 as non-op */
     280          149 :   for (; list != NO_JUMP; list = getjump(fs, list)) {
     281              :     lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP &&
     282              :                 (GETARG_A(fs->f->code[list]) == 0 ||
     283              :                  GETARG_A(fs->f->code[list]) >= level));
     284           77 :     SETARG_A(fs->f->code[list], level);
     285              :   }
     286           72 : }
     287              : 
     288              : 
     289              : /*
     290              : ** Emit instruction 'i', checking for array sizes and saving also its
     291              : ** line information. Return 'i' position.
     292              : */
     293        58830 : static int luaK_code (FuncState *fs, Instruction i) {
     294        58830 :   Proto *f = fs->f;
     295        58830 :   dischargejpc(fs);  /* 'pc' will change */
     296              :   /* put new instruction in code array */
     297        58830 :   luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
     298              :                   MAX_INT, "opcodes");
     299        58830 :   f->code[fs->pc] = i;
     300              :   /* save corresponding line information */
     301        58830 :   luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
     302              :                   MAX_INT, "opcodes");
     303        58830 :   f->lineinfo[fs->pc] = fs->ls->lastline;
     304        58830 :   return fs->pc++;
     305              : }
     306              : 
     307              : 
     308              : /*
     309              : ** Format and emit an 'iABC' instruction. (Assertions check consistency
     310              : ** of parameters versus opcode.)
     311              : */
     312        43126 : int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) {
     313              :   lua_assert(getOpMode(o) == iABC);
     314              :   lua_assert(getBMode(o) != OpArgN || b == 0);
     315              :   lua_assert(getCMode(o) != OpArgN || c == 0);
     316              :   lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C);
     317        43126 :   return luaK_code(fs, CREATE_ABC(o, a, b, c));
     318              : }
     319              : 
     320              : 
     321              : /*
     322              : ** Format and emit an 'iABx' instruction.
     323              : */
     324        15704 : int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
     325              :   lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx);
     326              :   lua_assert(getCMode(o) == OpArgN);
     327              :   lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx);
     328        15704 :   return luaK_code(fs, CREATE_ABx(o, a, bc));
     329              : }
     330              : 
     331              : 
     332              : /*
     333              : ** Emit an "extra argument" instruction (format 'iAx')
     334              : */
     335            0 : static int codeextraarg (FuncState *fs, int a) {
     336              :   lua_assert(a <= MAXARG_Ax);
     337            0 :   return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a));
     338              : }
     339              : 
     340              : 
     341              : /*
     342              : ** Emit a "load constant" instruction, using either 'OP_LOADK'
     343              : ** (if constant index 'k' fits in 18 bits) or an 'OP_LOADKX'
     344              : ** instruction with "extra argument".
     345              : */
     346        10297 : int luaK_codek (FuncState *fs, int reg, int k) {
     347        10297 :   if (k <= MAXARG_Bx)
     348        10297 :     return luaK_codeABx(fs, OP_LOADK, reg, k);
     349              :   else {
     350            0 :     int p = luaK_codeABx(fs, OP_LOADKX, reg, 0);
     351            0 :     codeextraarg(fs, k);
     352            0 :     return p;
     353              :   }
     354              : }
     355              : 
     356              : 
     357              : /*
     358              : ** Check register-stack level, keeping track of its maximum size
     359              : ** in field 'maxstacksize'
     360              : */
     361        40972 : void luaK_checkstack (FuncState *fs, int n) {
     362        40972 :   int newstack = fs->freereg + n;
     363        40972 :   if (newstack > fs->f->maxstacksize) {
     364         7157 :     if (newstack >= MAXREGS)
     365            0 :       luaX_syntaxerror(fs->ls,
     366              :         "function or expression needs too many registers");
     367         7157 :     fs->f->maxstacksize = cast_byte(newstack);
     368              :   }
     369        40972 : }
     370              : 
     371              : 
     372              : /*
     373              : ** Reserve 'n' registers in register stack
     374              : */
     375        40929 : void luaK_reserveregs (FuncState *fs, int n) {
     376        40929 :   luaK_checkstack(fs, n);
     377        40929 :   fs->freereg += n;
     378        40929 : }
     379              : 
     380              : 
     381              : /*
     382              : ** Free register 'reg', if it is neither a constant index nor
     383              : ** a local variable.
     384              : )
     385              : */
     386        33467 : static void freereg (FuncState *fs, int reg) {
     387        33467 :   if (!ISK(reg) && reg >= fs->nactvar) {
     388        12693 :     fs->freereg--;
     389              :     lua_assert(reg == fs->freereg);
     390              :   }
     391        33467 : }
     392              : 
     393              : 
     394              : /*
     395              : ** Free register used by expression 'e' (if any)
     396              : */
     397        43914 : static void freeexp (FuncState *fs, expdesc *e) {
     398        43914 :   if (e->k == VNONRELOC)
     399        13640 :     freereg(fs, e->u.info);
     400        43914 : }
     401              : 
     402              : 
     403              : /*
     404              : ** Free registers used by expressions 'e1' and 'e2' (if any) in proper
     405              : ** order.
     406              : */
     407         3215 : static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) {
     408         3215 :   int r1 = (e1->k == VNONRELOC) ? e1->u.info : -1;
     409         3215 :   int r2 = (e2->k == VNONRELOC) ? e2->u.info : -1;
     410         3215 :   if (r1 > r2) {
     411          951 :     freereg(fs, r1);
     412          951 :     freereg(fs, r2);
     413              :   }
     414              :   else {
     415         2264 :     freereg(fs, r2);
     416         2264 :     freereg(fs, r1);
     417              :   }
     418         3215 : }
     419              : 
     420              : 
     421              : /*
     422              : ** Add constant 'v' to prototype's list of constants (field 'k').
     423              : ** Use scanner's table to cache position of constants in constant list
     424              : ** and try to reuse constants. Because some values should not be used
     425              : ** as keys (nil cannot be a key, integer keys can collapse with float
     426              : ** keys), the caller must provide a useful 'key' for indexing the cache.
     427              : */
     428        24870 : static int addk (FuncState *fs, TValue *key, TValue *v) {
     429        24870 :   lua_State *L = fs->ls->L;
     430        24870 :   Proto *f = fs->f;
     431        24870 :   TValue *idx = luaH_set(L, fs->ls->h, key);  /* index scanner table */
     432              :   int k, oldsize;
     433        24870 :   if (ttisinteger(idx)) {  /* is there an index there? */
     434        14356 :     k = cast_int(ivalue(idx));
     435              :     /* correct value? (warning: must distinguish floats from integers!) */
     436        25612 :     if (k < fs->nk && ttype(&f->k[k]) == ttype(v) &&
     437        11256 :                       luaV_rawequalobj(&f->k[k], v))
     438        10615 :       return k;  /* reuse index */
     439              :   }
     440              :   /* constant not found; create a new entry */
     441        14255 :   oldsize = f->sizek;
     442        14255 :   k = fs->nk;
     443              :   /* numerical value does not need GC barrier;
     444              :      table has no metatable, so it does not need to invalidate cache */
     445        14255 :   setivalue(idx, k);
     446        14255 :   luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
     447        35583 :   while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
     448        14255 :   setobj(L, &f->k[k], v);
     449        14255 :   fs->nk++;
     450        14255 :   luaC_barrier(L, f, v);
     451        14255 :   return k;
     452              : }
     453              : 
     454              : 
     455              : /*
     456              : ** Add a string to list of constants and return its index.
     457              : */
     458        20675 : int luaK_stringK (FuncState *fs, TString *s) {
     459              :   TValue o;
     460        20675 :   setsvalue(fs->ls->L, &o, s);
     461        20675 :   return addk(fs, &o, &o);  /* use string itself as key */
     462              : }
     463              : 
     464              : 
     465              : /*
     466              : ** Add an integer to list of constants and return its index.
     467              : ** Integers use userdata as keys to avoid collision with floats with
     468              : ** same value; conversion to 'void*' is used only for hashing, so there
     469              : ** are no "precision" problems.
     470              : */
     471         3713 : int luaK_intK (FuncState *fs, lua_Integer n) {
     472              :   TValue k, o;
     473         3713 :   setpvalue(&k, cast(void*, cast(size_t, n)));
     474         3713 :   setivalue(&o, n);
     475         3713 :   return addk(fs, &k, &o);
     476              : }
     477              : 
     478              : /*
     479              : ** Add a float to list of constants and return its index.
     480              : */
     481          220 : static int luaK_numberK (FuncState *fs, lua_Number r) {
     482              :   TValue o;
     483          220 :   setfltvalue(&o, r);
     484          220 :   return addk(fs, &o, &o);  /* use number itself as key */
     485              : }
     486              : 
     487              : 
     488              : /*
     489              : ** Add a boolean to list of constants and return its index.
     490              : */
     491          213 : static int boolK (FuncState *fs, int b) {
     492              :   TValue o;
     493          213 :   setbvalue(&o, b);
     494          213 :   return addk(fs, &o, &o);  /* use boolean itself as key */
     495              : }
     496              : 
     497              : 
     498              : /*
     499              : ** Add nil to list of constants and return its index.
     500              : */
     501           49 : static int nilK (FuncState *fs) {
     502              :   TValue k, v;
     503           49 :   setnilvalue(&v);
     504              :   /* cannot use nil as key; instead use table itself to represent nil */
     505           49 :   sethvalue(fs->ls->L, &k, fs->ls->h);
     506           49 :   return addk(fs, &k, &v);
     507              : }
     508              : 
     509              : 
     510              : /*
     511              : ** Fix an expression to return the number of results 'nresults'.
     512              : ** Either 'e' is a multi-ret expression (function call or vararg)
     513              : ** or 'nresults' is LUA_MULTRET (as any expression can satisfy that).
     514              : */
     515         9715 : void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
     516         9715 :   if (e->k == VCALL) {  /* expression is an open function call? */
     517         1146 :     SETARG_C(getinstruction(fs, e), nresults + 1);
     518              :   }
     519         8569 :   else if (e->k == VVARARG) {
     520           19 :     Instruction *pc = &getinstruction(fs, e);
     521           19 :     SETARG_B(*pc, nresults + 1);
     522           19 :     SETARG_A(*pc, fs->freereg);
     523           19 :     luaK_reserveregs(fs, 1);
     524              :   }
     525              :   else lua_assert(nresults == LUA_MULTRET);
     526         9715 : }
     527              : 
     528              : 
     529              : /*
     530              : ** Fix an expression to return one result.
     531              : ** If expression is not a multi-ret expression (function call or
     532              : ** vararg), it already returns one result, so nothing needs to be done.
     533              : ** Function calls become VNONRELOC expressions (as its result comes
     534              : ** fixed in the base register of the call), while vararg expressions
     535              : ** become VRELOCABLE (as OP_VARARG puts its results where it wants).
     536              : ** (Calls are created returning one result, so that does not need
     537              : ** to be fixed.)
     538              : */
     539         4005 : void luaK_setoneret (FuncState *fs, expdesc *e) {
     540         4005 :   if (e->k == VCALL) {  /* expression is an open function call? */
     541              :     /* already returns 1 value */
     542              :     lua_assert(GETARG_C(getinstruction(fs, e)) == 2);
     543         2911 :     e->k = VNONRELOC;  /* result has fixed position */
     544         2911 :     e->u.info = GETARG_A(getinstruction(fs, e));
     545              :   }
     546         1094 :   else if (e->k == VVARARG) {
     547            1 :     SETARG_B(getinstruction(fs, e), 2);
     548            1 :     e->k = VRELOCABLE;  /* can relocate its simple result */
     549              :   }
     550         4005 : }
     551              : 
     552              : 
     553              : /*
     554              : ** Ensure that expression 'e' is not a variable.
     555              : */
     556       117940 : void luaK_dischargevars (FuncState *fs, expdesc *e) {
     557       117940 :   switch (e->k) {
     558         9834 :     case VLOCAL: {  /* already in a register */
     559         9834 :       e->k = VNONRELOC;  /* becomes a non-relocatable value */
     560         9834 :       break;
     561              :     }
     562         2296 :     case VUPVAL: {  /* move value to some (pending) register */
     563         2296 :       e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
     564         2296 :       e->k = VRELOCABLE;
     565         2296 :       break;
     566              :     }
     567        10834 :     case VINDEXED: {
     568              :       OpCode op;
     569        10834 :       freereg(fs, e->u.ind.idx);
     570        10834 :       if (e->u.ind.vt == VLOCAL) {  /* is 't' in a register? */
     571         2563 :         freereg(fs, e->u.ind.t);
     572         2563 :         op = OP_GETTABLE;
     573              :       }
     574              :       else {
     575              :         lua_assert(e->u.ind.vt == VUPVAL);
     576         8271 :         op = OP_GETTABUP;  /* 't' is in an upvalue */
     577              :       }
     578        10834 :       e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx);
     579        10834 :       e->k = VRELOCABLE;
     580        10834 :       break;
     581              :     }
     582         2081 :     case VVARARG: case VCALL: {
     583         2081 :       luaK_setoneret(fs, e);
     584         2081 :       break;
     585              :     }
     586        92895 :     default: break;  /* there is one value available (somewhere) */
     587              :   }
     588       117940 : }
     589              : 
     590              : 
     591              : /*
     592              : ** Ensures expression value is in register 'reg' (and therefore
     593              : ** 'e' will become a non-relocatable expression).
     594              : */
     595        38423 : static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
     596        38423 :   luaK_dischargevars(fs, e);
     597        38423 :   switch (e->k) {
     598          228 :     case VNIL: {
     599          228 :       luaK_nil(fs, reg, 1);
     600          228 :       break;
     601              :     }
     602          756 :     case VFALSE: case VTRUE: {
     603          756 :       luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0);
     604          756 :       break;
     605              :     }
     606         7386 :     case VK: {
     607         7386 :       luaK_codek(fs, reg, e->u.info);
     608         7386 :       break;
     609              :     }
     610          178 :     case VKFLT: {
     611          178 :       luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval));
     612          178 :       break;
     613              :     }
     614         2470 :     case VKINT: {
     615         2470 :       luaK_codek(fs, reg, luaK_intK(fs, e->u.ival));
     616         2470 :       break;
     617              :     }
     618        18486 :     case VRELOCABLE: {
     619        18486 :       Instruction *pc = &getinstruction(fs, e);
     620        18486 :       SETARG_A(*pc, reg);  /* instruction will put result in 'reg' */
     621        18486 :       break;
     622              :     }
     623         8545 :     case VNONRELOC: {
     624         8545 :       if (reg != e->u.info)
     625         5504 :         luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0);
     626         8545 :       break;
     627              :     }
     628          374 :     default: {
     629              :       lua_assert(e->k == VJMP);
     630          374 :       return;  /* nothing to do... */
     631              :     }
     632              :   }
     633        38049 :   e->u.info = reg;
     634        38049 :   e->k = VNONRELOC;
     635              : }
     636              : 
     637              : 
     638              : /*
     639              : ** Ensures expression value is in any register.
     640              : */
     641         1218 : static void discharge2anyreg (FuncState *fs, expdesc *e) {
     642         1218 :   if (e->k != VNONRELOC) {  /* no fixed register yet? */
     643          277 :     luaK_reserveregs(fs, 1);  /* get a register */
     644          277 :     discharge2reg(fs, e, fs->freereg-1);  /* put value there */
     645              :   }
     646         1218 : }
     647              : 
     648              : 
     649          856 : static int code_loadbool (FuncState *fs, int A, int b, int jump) {
     650          856 :   luaK_getlabel(fs);  /* those instructions may be jump targets */
     651          856 :   return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump);
     652              : }
     653              : 
     654              : 
     655              : /*
     656              : ** check whether list has any jump that do not produce a value
     657              : ** or produce an inverted value
     658              : */
     659          765 : static int need_value (FuncState *fs, int list) {
     660          931 :   for (; list != NO_JUMP; list = getjump(fs, list)) {
     661          594 :     Instruction i = *getjumpcontrol(fs, list);
     662          594 :     if (GET_OPCODE(i) != OP_TESTSET) return 1;
     663              :   }
     664          337 :   return 0;  /* not found */
     665              : }
     666              : 
     667              : 
     668              : /*
     669              : ** Ensures final expression result (including results from its jump
     670              : ** lists) is in register 'reg'.
     671              : ** If expression has jumps, need to patch these jumps either to
     672              : ** its final position or to "load" instructions (for those tests
     673              : ** that do not produce values).
     674              : */
     675        38146 : static void exp2reg (FuncState *fs, expdesc *e, int reg) {
     676        38146 :   discharge2reg(fs, e, reg);
     677        38146 :   if (e->k == VJMP)  /* expression itself is a test? */
     678          374 :     luaK_concat(fs, &e->t, e->u.info);  /* put this jump in 't' list */
     679        38146 :   if (hasjumps(e)) {
     680              :     int final;  /* position after whole expression */
     681          594 :     int p_f = NO_JUMP;  /* position of an eventual LOAD false */
     682          594 :     int p_t = NO_JUMP;  /* position of an eventual LOAD true */
     683          594 :     if (need_value(fs, e->t) || need_value(fs, e->f)) {
     684          428 :       int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
     685          428 :       p_f = code_loadbool(fs, reg, 0, 1);
     686          428 :       p_t = code_loadbool(fs, reg, 1, 0);
     687          428 :       luaK_patchtohere(fs, fj);
     688              :     }
     689          594 :     final = luaK_getlabel(fs);
     690          594 :     patchlistaux(fs, e->f, final, reg, p_f);
     691          594 :     patchlistaux(fs, e->t, final, reg, p_t);
     692              :   }
     693        38146 :   e->f = e->t = NO_JUMP;
     694        38146 :   e->u.info = reg;
     695        38146 :   e->k = VNONRELOC;
     696        38146 : }
     697              : 
     698              : 
     699              : /*
     700              : ** Ensures final expression result (including results from its jump
     701              : ** lists) is in next available register.
     702              : */
     703        37282 : void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
     704        37282 :   luaK_dischargevars(fs, e);
     705        37282 :   freeexp(fs, e);
     706        37282 :   luaK_reserveregs(fs, 1);
     707        37282 :   exp2reg(fs, e, fs->freereg - 1);
     708        37282 : }
     709              : 
     710              : 
     711              : /*
     712              : ** Ensures final expression result (including results from its jump
     713              : ** lists) is in some (any) register and return that register.
     714              : */
     715        13539 : int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
     716        13539 :   luaK_dischargevars(fs, e);
     717        13539 :   if (e->k == VNONRELOC) {  /* expression already has a register? */
     718         9210 :     if (!hasjumps(e))  /* no jumps? */
     719         9209 :       return e->u.info;  /* result is already in a register */
     720            1 :     if (e->u.info >= fs->nactvar) {  /* reg. is not a local? */
     721            0 :       exp2reg(fs, e, e->u.info);  /* put final result in it */
     722            0 :       return e->u.info;
     723              :     }
     724              :   }
     725         4330 :   luaK_exp2nextreg(fs, e);  /* otherwise, use next available register */
     726         4330 :   return e->u.info;
     727              : }
     728              : 
     729              : 
     730              : /*
     731              : ** Ensures final expression result is either in a register or in an
     732              : ** upvalue.
     733              : */
     734         3040 : void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
     735         3040 :   if (e->k != VUPVAL || hasjumps(e))
     736         2940 :     luaK_exp2anyreg(fs, e);
     737         3040 : }
     738              : 
     739              : 
     740              : /*
     741              : ** Ensures final expression result is either in a register or it is
     742              : ** a constant.
     743              : */
     744        25948 : void luaK_exp2val (FuncState *fs, expdesc *e) {
     745        25948 :   if (hasjumps(e))
     746           43 :     luaK_exp2anyreg(fs, e);
     747              :   else
     748        25905 :     luaK_dischargevars(fs, e);
     749        25948 : }
     750              : 
     751              : 
     752              : /*
     753              : ** Ensures final expression result is in a valid R/K index
     754              : ** (that is, it is either in a register or in 'k' with an index
     755              : ** in the range of R/K indices).
     756              : ** Returns R/K index.
     757              : */
     758        23103 : int luaK_exp2RK (FuncState *fs, expdesc *e) {
     759        23103 :   luaK_exp2val(fs, e);
     760        23103 :   switch (e->k) {  /* move constants to 'k' */
     761          100 :     case VTRUE: e->u.info = boolK(fs, 1); goto vk;
     762          113 :     case VFALSE: e->u.info = boolK(fs, 0); goto vk;
     763           49 :     case VNIL: e->u.info = nilK(fs); goto vk;
     764          980 :     case VKINT: e->u.info = luaK_intK(fs, e->u.ival); goto vk;
     765           42 :     case VKFLT: e->u.info = luaK_numberK(fs, e->u.nval); goto vk;
     766              :     case VK:
     767        14904 :      vk:
     768        14904 :       e->k = VK;
     769        14904 :       if (e->u.info <= MAXINDEXRK)  /* constant fits in 'argC'? */
     770        14683 :         return RKASK(e->u.info);
     771          221 :       else break;
     772         8199 :     default: break;
     773              :   }
     774              :   /* not a constant in the right range: put it in a register */
     775         8420 :   return luaK_exp2anyreg(fs, e);
     776              : }
     777              : 
     778              : 
     779              : /*
     780              : ** Generate code to store result of expression 'ex' into variable 'var'.
     781              : */
     782         3071 : void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
     783         3071 :   switch (var->k) {
     784          864 :     case VLOCAL: {
     785          864 :       freeexp(fs, ex);
     786          864 :       exp2reg(fs, ex, var->u.info);  /* compute 'ex' into proper place */
     787          864 :       return;
     788              :     }
     789          231 :     case VUPVAL: {
     790          231 :       int e = luaK_exp2anyreg(fs, ex);
     791          231 :       luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
     792          231 :       break;
     793              :     }
     794         1976 :     case VINDEXED: {
     795         1976 :       OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP;
     796         1976 :       int e = luaK_exp2RK(fs, ex);
     797         1976 :       luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e);
     798         1976 :       break;
     799              :     }
     800         2207 :     default: lua_assert(0);  /* invalid var kind to store */
     801              :   }
     802         2207 :   freeexp(fs, ex);
     803              : }
     804              : 
     805              : 
     806              : /*
     807              : ** Emit SELF instruction (convert expression 'e' into 'e:key(e,').
     808              : */
     809          533 : void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
     810              :   int ereg;
     811          533 :   luaK_exp2anyreg(fs, e);
     812          533 :   ereg = e->u.info;  /* register where 'e' was placed */
     813          533 :   freeexp(fs, e);
     814          533 :   e->u.info = fs->freereg;  /* base register for op_self */
     815          533 :   e->k = VNONRELOC;  /* self expression has a fixed register */
     816          533 :   luaK_reserveregs(fs, 2);  /* function and 'self' produced by op_self */
     817          533 :   luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key));
     818          533 :   freeexp(fs, key);
     819          533 : }
     820              : 
     821              : 
     822              : /*
     823              : ** Negate condition 'e' (where 'e' is a comparison).
     824              : */
     825          581 : static void negatecondition (FuncState *fs, expdesc *e) {
     826          581 :   Instruction *pc = getjumpcontrol(fs, e->u.info);
     827              :   lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
     828              :                                            GET_OPCODE(*pc) != OP_TEST);
     829          581 :   SETARG_A(*pc, !(GETARG_A(*pc)));
     830          581 : }
     831              : 
     832              : 
     833              : /*
     834              : ** Emit instruction to jump if 'e' is 'cond' (that is, if 'cond'
     835              : ** is true, code will jump if 'e' is true.) Return jump position.
     836              : ** Optimize when 'e' is 'not' something, inverting the condition
     837              : ** and removing the 'not'.
     838              : */
     839         1162 : static int jumponcond (FuncState *fs, expdesc *e, int cond) {
     840         1162 :   if (e->k == VRELOCABLE) {
     841          620 :     Instruction ie = getinstruction(fs, e);
     842          620 :     if (GET_OPCODE(ie) == OP_NOT) {
     843          378 :       fs->pc--;  /* remove previous OP_NOT */
     844          378 :       return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
     845              :     }
     846              :     /* else go through */
     847              :   }
     848          784 :   discharge2anyreg(fs, e);
     849          784 :   freeexp(fs, e);
     850          784 :   return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond);
     851              : }
     852              : 
     853              : 
     854              : /*
     855              : ** Emit code to go through if 'e' is true, jump otherwise.
     856              : */
     857         1576 : void luaK_goiftrue (FuncState *fs, expdesc *e) {
     858              :   int pc;  /* pc of new jump */
     859         1576 :   luaK_dischargevars(fs, e);
     860         1576 :   switch (e->k) {
     861          579 :     case VJMP: {  /* condition? */
     862          579 :       negatecondition(fs, e);  /* jump when it is false */
     863          579 :       pc = e->u.info;  /* save jump position */
     864          579 :       break;
     865              :     }
     866           12 :     case VK: case VKFLT: case VKINT: case VTRUE: {
     867           12 :       pc = NO_JUMP;  /* always true; do nothing */
     868           12 :       break;
     869              :     }
     870          985 :     default: {
     871          985 :       pc = jumponcond(fs, e, 0);  /* jump when false */
     872          985 :       break;
     873              :     }
     874              :   }
     875         1576 :   luaK_concat(fs, &e->f, pc);  /* insert new jump in false list */
     876         1576 :   luaK_patchtohere(fs, e->t);  /* true list jumps to here (to go through) */
     877         1576 :   e->t = NO_JUMP;
     878         1576 : }
     879              : 
     880              : 
     881              : /*
     882              : ** Emit code to go through if 'e' is false, jump otherwise.
     883              : */
     884          246 : void luaK_goiffalse (FuncState *fs, expdesc *e) {
     885              :   int pc;  /* pc of new jump */
     886          246 :   luaK_dischargevars(fs, e);
     887          246 :   switch (e->k) {
     888           65 :     case VJMP: {
     889           65 :       pc = e->u.info;  /* already jump if true */
     890           65 :       break;
     891              :     }
     892            4 :     case VNIL: case VFALSE: {
     893            4 :       pc = NO_JUMP;  /* always false; do nothing */
     894            4 :       break;
     895              :     }
     896          177 :     default: {
     897          177 :       pc = jumponcond(fs, e, 1);  /* jump if true */
     898          177 :       break;
     899              :     }
     900              :   }
     901          246 :   luaK_concat(fs, &e->t, pc);  /* insert new jump in 't' list */
     902          246 :   luaK_patchtohere(fs, e->f);  /* false list jumps to here (to go through) */
     903          246 :   e->f = NO_JUMP;
     904          246 : }
     905              : 
     906              : 
     907              : /*
     908              : ** Code 'not e', doing constant folding.
     909              : */
     910          447 : static void codenot (FuncState *fs, expdesc *e) {
     911          447 :   luaK_dischargevars(fs, e);
     912          447 :   switch (e->k) {
     913            5 :     case VNIL: case VFALSE: {
     914            5 :       e->k = VTRUE;  /* true == not nil == not false */
     915            5 :       break;
     916              :     }
     917            6 :     case VK: case VKFLT: case VKINT: case VTRUE: {
     918            6 :       e->k = VFALSE;  /* false == not "x" == not 0.5 == not 1 == not true */
     919            6 :       break;
     920              :     }
     921            2 :     case VJMP: {
     922            2 :       negatecondition(fs, e);
     923            2 :       break;
     924              :     }
     925          434 :     case VRELOCABLE:
     926              :     case VNONRELOC: {
     927          434 :       discharge2anyreg(fs, e);
     928          434 :       freeexp(fs, e);
     929          434 :       e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0);
     930          434 :       e->k = VRELOCABLE;
     931          434 :       break;
     932              :     }
     933          447 :     default: lua_assert(0);  /* cannot happen */
     934              :   }
     935              :   /* interchange true and false lists */
     936          447 :   { int temp = e->f; e->f = e->t; e->t = temp; }
     937          447 :   removevalues(fs, e->f);  /* values are useless when negated */
     938          447 :   removevalues(fs, e->t);
     939          447 : }
     940              : 
     941              : 
     942              : /*
     943              : ** Create expression 't[k]'. 't' must have its final result already in a
     944              : ** register or upvalue.
     945              : */
     946        12832 : void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
     947              :   lua_assert(!hasjumps(t) && (vkisinreg(t->k) || t->k == VUPVAL));
     948        12832 :   t->u.ind.t = t->u.info;  /* register or upvalue index */
     949        12832 :   t->u.ind.idx = luaK_exp2RK(fs, k);  /* R/K index for key */
     950        12832 :   t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL : VLOCAL;
     951        12832 :   t->k = VINDEXED;
     952        12832 : }
     953              : 
     954              : 
     955              : /*
     956              : ** Return false if folding can raise an error.
     957              : ** Bitwise operations need operands convertible to integers; division
     958              : ** operations cannot have 0 as divisor.
     959              : */
     960          192 : static int validop (int op, TValue *v1, TValue *v2) {
     961          192 :   switch (op) {
     962           17 :     case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
     963              :     case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: {  /* conversion errors */
     964              :       lua_Integer i;
     965           17 :       return (tointeger(v1, &i) && tointeger(v2, &i));
     966              :     }
     967           19 :     case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD:  /* division by 0 */
     968           19 :       return (nvalue(v2) != 0);
     969          156 :     default: return 1;  /* everything else is valid */
     970              :   }
     971              : }
     972              : 
     973              : 
     974              : /*
     975              : ** Try to "constant-fold" an operation; return 1 iff successful.
     976              : ** (In this case, 'e1' has the final result.)
     977              : */
     978         1025 : static int constfolding (FuncState *fs, int op, expdesc *e1,
     979              :                                                 const expdesc *e2) {
     980              :   TValue v1, v2, res;
     981         1025 :   if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2))
     982          853 :     return 0;  /* non-numeric operands or not safe to fold */
     983          172 :   luaO_arith(fs->ls->L, op, &v1, &v2, &res);  /* does operation */
     984          172 :   if (ttisinteger(&res)) {
     985          139 :     e1->k = VKINT;
     986          139 :     e1->u.ival = ivalue(&res);
     987              :   }
     988              :   else {  /* folds neither NaN nor 0.0 (to avoid problems with -0.0) */
     989           33 :     lua_Number n = fltvalue(&res);
     990           33 :     if (luai_numisnan(n) || n == 0)
     991            0 :       return 0;
     992           33 :     e1->k = VKFLT;
     993           33 :     e1->u.nval = n;
     994              :   }
     995          172 :   return 1;
     996              : }
     997              : 
     998              : 
     999              : /*
    1000              : ** Emit code for unary expressions that "produce values"
    1001              : ** (everything but 'not').
    1002              : ** Expression to produce final result will be encoded in 'e'.
    1003              : */
    1004          549 : static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) {
    1005          549 :   int r = luaK_exp2anyreg(fs, e);  /* opcodes operate only on registers */
    1006          549 :   freeexp(fs, e);
    1007          549 :   e->u.info = luaK_codeABC(fs, op, 0, r, 0);  /* generate opcode */
    1008          549 :   e->k = VRELOCABLE;  /* all those operations are relocatable */
    1009          549 :   luaK_fixline(fs, line);
    1010          549 : }
    1011              : 
    1012              : 
    1013              : /*
    1014              : ** Emit code for binary expressions that "produce values"
    1015              : ** (everything but logical operators 'and'/'or' and comparison
    1016              : ** operators).
    1017              : ** Expression to produce final result will be encoded in 'e1'.
    1018              : ** Because 'luaK_exp2RK' can free registers, its calls must be
    1019              : ** in "stack order" (that is, first on 'e2', which may have more
    1020              : ** recent registers to be released).
    1021              : */
    1022         2197 : static void codebinexpval (FuncState *fs, OpCode op,
    1023              :                            expdesc *e1, expdesc *e2, int line) {
    1024         2197 :   int rk2 = luaK_exp2RK(fs, e2);  /* both operands are "RK" */
    1025         2197 :   int rk1 = luaK_exp2RK(fs, e1);
    1026         2197 :   freeexps(fs, e1, e2);
    1027         2197 :   e1->u.info = luaK_codeABC(fs, op, 0, rk1, rk2);  /* generate opcode */
    1028         2197 :   e1->k = VRELOCABLE;  /* all those operations are relocatable */
    1029         2197 :   luaK_fixline(fs, line);
    1030         2197 : }
    1031              : 
    1032              : 
    1033              : /*
    1034              : ** Emit code for comparisons.
    1035              : ** 'e1' was already put in R/K form by 'luaK_infix'.
    1036              : */
    1037         1018 : static void codecomp (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
    1038         2104 :   int rk1 = (e1->k == VK) ? RKASK(e1->u.info)
    1039         1018 :                           : check_exp(e1->k == VNONRELOC, e1->u.info);
    1040         1018 :   int rk2 = luaK_exp2RK(fs, e2);
    1041         1018 :   freeexps(fs, e1, e2);
    1042         1018 :   switch (opr) {
    1043          233 :     case OPR_NE: {  /* '(a ~= b)' ==> 'not (a == b)' */
    1044          233 :       e1->u.info = condjump(fs, OP_EQ, 0, rk1, rk2);
    1045          233 :       break;
    1046              :     }
    1047          233 :     case OPR_GT: case OPR_GE: {
    1048              :       /* '(a > b)' ==> '(b < a)';  '(a >= b)' ==> '(b <= a)' */
    1049          233 :       OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ);
    1050          233 :       e1->u.info = condjump(fs, op, 1, rk2, rk1);  /* invert operands */
    1051          233 :       break;
    1052              :     }
    1053          552 :     default: {  /* '==', '<', '<=' use their own opcodes */
    1054          552 :       OpCode op = cast(OpCode, (opr - OPR_EQ) + OP_EQ);
    1055          552 :       e1->u.info = condjump(fs, op, 1, rk1, rk2);
    1056          552 :       break;
    1057              :     }
    1058              :   }
    1059         1018 :   e1->k = VJMP;
    1060         1018 : }
    1061              : 
    1062              : 
    1063              : /*
    1064              : ** Apply prefix operation 'op' to expression 'e'.
    1065              : */
    1066         1137 : void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
    1067              :   static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP};
    1068         1137 :   switch (op) {
    1069          168 :     case OPR_MINUS: case OPR_BNOT:  /* use 'ef' as fake 2nd operand */
    1070          168 :       if (constfolding(fs, op + LUA_OPUNM, e, &ef))
    1071          141 :         break;
    1072              :       /* FALLTHROUGH */
    1073              :     case OPR_LEN:
    1074          549 :       codeunexpval(fs, cast(OpCode, op + OP_UNM), e, line);
    1075          549 :       break;
    1076          447 :     case OPR_NOT: codenot(fs, e); break;
    1077         1137 :     default: lua_assert(0);
    1078              :   }
    1079         1137 : }
    1080              : 
    1081              : 
    1082              : /*
    1083              : ** Process 1st operand 'v' of binary operation 'op' before reading
    1084              : ** 2nd operand.
    1085              : */
    1086         4357 : void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
    1087         4357 :   switch (op) {
    1088          145 :     case OPR_AND: {
    1089          145 :       luaK_goiftrue(fs, v);  /* go ahead only if 'v' is true */
    1090          145 :       break;
    1091              :     }
    1092          238 :     case OPR_OR: {
    1093          238 :       luaK_goiffalse(fs, v);  /* go ahead only if 'v' is false */
    1094          238 :       break;
    1095              :     }
    1096         2099 :     case OPR_CONCAT: {
    1097         2099 :       luaK_exp2nextreg(fs, v);  /* operand must be on the 'stack' */
    1098         2099 :       break;
    1099              :     }
    1100          857 :     case OPR_ADD: case OPR_SUB:
    1101              :     case OPR_MUL: case OPR_DIV: case OPR_IDIV:
    1102              :     case OPR_MOD: case OPR_POW:
    1103              :     case OPR_BAND: case OPR_BOR: case OPR_BXOR:
    1104              :     case OPR_SHL: case OPR_SHR: {
    1105          857 :       if (!tonumeral(v, NULL))
    1106          732 :         luaK_exp2RK(fs, v);
    1107              :       /* else keep numeral, which may be folded with 2nd operand */
    1108          857 :       break;
    1109              :     }
    1110         1018 :     default: {
    1111         1018 :       luaK_exp2RK(fs, v);
    1112         1018 :       break;
    1113              :     }
    1114              :   }
    1115         4357 : }
    1116              : 
    1117              : 
    1118              : /*
    1119              : ** Finalize code for binary operation, after reading 2nd operand.
    1120              : ** For '(a .. b .. c)' (which is '(a .. (b .. c))', because
    1121              : ** concatenation is right associative), merge second CONCAT into first
    1122              : ** one.
    1123              : */
    1124         4357 : void luaK_posfix (FuncState *fs, BinOpr op,
    1125              :                   expdesc *e1, expdesc *e2, int line) {
    1126         4357 :   switch (op) {
    1127          145 :     case OPR_AND: {
    1128              :       lua_assert(e1->t == NO_JUMP);  /* list closed by 'luK_infix' */
    1129          145 :       luaK_dischargevars(fs, e2);
    1130          145 :       luaK_concat(fs, &e2->f, e1->f);
    1131          145 :       *e1 = *e2;
    1132          145 :       break;
    1133              :     }
    1134          238 :     case OPR_OR: {
    1135              :       lua_assert(e1->f == NO_JUMP);  /* list closed by 'luK_infix' */
    1136          238 :       luaK_dischargevars(fs, e2);
    1137          238 :       luaK_concat(fs, &e2->t, e1->t);
    1138          238 :       *e1 = *e2;
    1139          238 :       break;
    1140              :     }
    1141         2099 :     case OPR_CONCAT: {
    1142         2099 :       luaK_exp2val(fs, e2);
    1143         2099 :       if (e2->k == VRELOCABLE &&
    1144          773 :           GET_OPCODE(getinstruction(fs, e2)) == OP_CONCAT) {
    1145              :         lua_assert(e1->u.info == GETARG_B(getinstruction(fs, e2))-1);
    1146          728 :         freeexp(fs, e1);
    1147          728 :         SETARG_B(getinstruction(fs, e2), e1->u.info);
    1148          728 :         e1->k = VRELOCABLE; e1->u.info = e2->u.info;
    1149              :       }
    1150              :       else {
    1151         1371 :         luaK_exp2nextreg(fs, e2);  /* operand must be on the 'stack' */
    1152         1371 :         codebinexpval(fs, OP_CONCAT, e1, e2, line);
    1153              :       }
    1154         2099 :       break;
    1155              :     }
    1156          857 :     case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
    1157              :     case OPR_IDIV: case OPR_MOD: case OPR_POW:
    1158              :     case OPR_BAND: case OPR_BOR: case OPR_BXOR:
    1159              :     case OPR_SHL: case OPR_SHR: {
    1160          857 :       if (!constfolding(fs, op + LUA_OPADD, e1, e2))
    1161          826 :         codebinexpval(fs, cast(OpCode, op + OP_ADD), e1, e2, line);
    1162          857 :       break;
    1163              :     }
    1164         1018 :     case OPR_EQ: case OPR_LT: case OPR_LE:
    1165              :     case OPR_NE: case OPR_GT: case OPR_GE: {
    1166         1018 :       codecomp(fs, op, e1, e2);
    1167         1018 :       break;
    1168              :     }
    1169         4357 :     default: lua_assert(0);
    1170              :   }
    1171         4357 : }
    1172              : 
    1173              : 
    1174              : /*
    1175              : ** Change line information associated with current position.
    1176              : */
    1177        13641 : void luaK_fixline (FuncState *fs, int line) {
    1178        13641 :   fs->f->lineinfo[fs->pc - 1] = line;
    1179        13641 : }
    1180              : 
    1181              : 
    1182              : /*
    1183              : ** Emit a SETLIST instruction.
    1184              : ** 'base' is register that keeps table;
    1185              : ** 'nelems' is #table plus those to be stored now;
    1186              : ** 'tostore' is number of values (in registers 'base + 1',...) to add to
    1187              : ** table (or LUA_MULTRET to add up to stack top).
    1188              : */
    1189          422 : void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
    1190          422 :   int c =  (nelems - 1)/LFIELDS_PER_FLUSH + 1;
    1191          422 :   int b = (tostore == LUA_MULTRET) ? 0 : tostore;
    1192              :   lua_assert(tostore != 0 && tostore <= LFIELDS_PER_FLUSH);
    1193          422 :   if (c <= MAXARG_C)
    1194          422 :     luaK_codeABC(fs, OP_SETLIST, base, b, c);
    1195            0 :   else if (c <= MAXARG_Ax) {
    1196            0 :     luaK_codeABC(fs, OP_SETLIST, base, b, 0);
    1197            0 :     codeextraarg(fs, c);
    1198              :   }
    1199              :   else
    1200            0 :     luaX_syntaxerror(fs->ls, "constructor too long");
    1201          422 :   fs->freereg = base + 1;  /* free registers with list values */
    1202          422 : }
    1203              : 
        

Generated by: LCOV version 2.0-1