LCOV - code coverage report
Current view: top level - external/lua/src - lcode.c (source / functions) Hit Total Coverage
Test: rapport Lines: 491 857 57.3 %
Date: 2021-12-10 16:22:55 Functions: 74 98 75.5 %
Branches: 141 369 38.2 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            : ** $Id: lcode.c $
       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 <limits.h>
      14                 :            : #include <math.h>
      15                 :            : #include <stdlib.h>
      16                 :            : 
      17                 :            : #include "lua.h"
      18                 :            : 
      19                 :            : #include "lcode.h"
      20                 :            : #include "ldebug.h"
      21                 :            : #include "ldo.h"
      22                 :            : #include "lgc.h"
      23                 :            : #include "llex.h"
      24                 :            : #include "lmem.h"
      25                 :            : #include "lobject.h"
      26                 :            : #include "lopcodes.h"
      27                 :            : #include "lparser.h"
      28                 :            : #include "lstring.h"
      29                 :            : #include "ltable.h"
      30                 :            : #include "lvm.h"
      31                 :            : 
      32                 :            : 
      33                 :            : /* Maximum number of registers in a Lua function (must fit in 8 bits) */
      34                 :            : #define MAXREGS         255
      35                 :            : 
      36                 :            : 
      37                 :            : #define hasjumps(e)     ((e)->t != (e)->f)
      38                 :            : 
      39                 :            : 
      40                 :            : static int codesJ (FuncState *fs, OpCode o, int sj, int k);
      41                 :            : 
      42                 :            : 
      43                 :            : 
      44                 :            : /* semantic error */
      45                 :          0 : l_noret luaK_semerror (LexState *ls, const char *msg) {
      46                 :          0 :   ls->t.token = 0;  /* remove "near <token>" from final message */
      47                 :          0 :   luaX_syntaxerror(ls, msg);
      48                 :            : }
      49                 :            : 
      50                 :            : 
      51                 :            : /*
      52                 :            : ** If expression is a numeric constant, fills 'v' with its value
      53                 :            : ** and returns 1. Otherwise, returns 0.
      54                 :            : */
      55                 :        187 : static int tonumeral (const expdesc *e, TValue *v) {
      56         [ -  + ]:        187 :   if (hasjumps(e))
      57                 :          0 :     return 0;  /* not a numeral */
      58      [ +  -  - ]:        187 :   switch (e->k) {
      59                 :            :     case VKINT:
      60         [ #  # ]:          0 :       if (v) setivalue(v, e->u.ival);
      61                 :          0 :       return 1;
      62                 :            :     case VKFLT:
      63         [ #  # ]:          0 :       if (v) setfltvalue(v, e->u.nval);
      64                 :          0 :       return 1;
      65                 :        187 :     default: return 0;
      66                 :            :   }
      67                 :        187 : }
      68                 :            : 
      69                 :            : 
      70                 :            : /*
      71                 :            : ** Get the constant value from a constant expression
      72                 :            : */
      73                 :          0 : static TValue *const2val (FuncState *fs, const expdesc *e) {
      74                 :            :   lua_assert(e->k == VCONST);
      75                 :          0 :   return &fs->ls->dyd->actvar.arr[e->u.info].k;
      76                 :            : }
      77                 :            : 
      78                 :            : 
      79                 :            : /*
      80                 :            : ** If expression is a constant, fills 'v' with its value
      81                 :            : ** and returns 1. Otherwise, returns 0.
      82                 :            : */
      83                 :          0 : int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v) {
      84         [ #  # ]:          0 :   if (hasjumps(e))
      85                 :          0 :     return 0;  /* not a constant */
      86   [ #  #  #  #  :          0 :   switch (e->k) {
                   #  # ]
      87                 :            :     case VFALSE:
      88                 :          0 :       setbfvalue(v);
      89                 :          0 :       return 1;
      90                 :            :     case VTRUE:
      91                 :          0 :       setbtvalue(v);
      92                 :          0 :       return 1;
      93                 :            :     case VNIL:
      94                 :          0 :       setnilvalue(v);
      95                 :          0 :       return 1;
      96                 :            :     case VKSTR: {
      97                 :          0 :       setsvalue(fs->ls->L, v, e->u.strval);
      98                 :          0 :       return 1;
      99                 :            :     }
     100                 :            :     case VCONST: {
     101                 :          0 :       setobj(fs->ls->L, v, const2val(fs, e));
     102                 :          0 :       return 1;
     103                 :            :     }
     104                 :          0 :     default: return tonumeral(e, v);
     105                 :            :   }
     106                 :          0 : }
     107                 :            : 
     108                 :            : 
     109                 :            : /*
     110                 :            : ** Return the previous instruction of the current code. If there
     111                 :            : ** may be a jump target between the current instruction and the
     112                 :            : ** previous one, return an invalid instruction (to avoid wrong
     113                 :            : ** optimizations).
     114                 :            : */
     115                 :         48 : static Instruction *previousinstruction (FuncState *fs) {
     116                 :            :   static const Instruction invalidinstruction = ~(Instruction)0;
     117         [ +  - ]:         48 :   if (fs->pc > fs->lasttarget)
     118                 :         48 :     return &fs->f->code[fs->pc - 1];  /* previous instruction */
     119                 :            :   else
     120                 :          0 :     return cast(Instruction*, &invalidinstruction);
     121                 :         48 : }
     122                 :            : 
     123                 :            : 
     124                 :            : /*
     125                 :            : ** Create a OP_LOADNIL instruction, but try to optimize: if the previous
     126                 :            : ** instruction is also OP_LOADNIL and ranges are compatible, adjust
     127                 :            : ** range of previous instruction instead of emitting a new one. (For
     128                 :            : ** instance, 'local a; local b' will generate a single opcode.)
     129                 :            : */
     130                 :          0 : void luaK_nil (FuncState *fs, int from, int n) {
     131                 :          0 :   int l = from + n - 1;  /* last register to set nil */
     132                 :          0 :   Instruction *previous = previousinstruction(fs);
     133         [ #  # ]:          0 :   if (GET_OPCODE(*previous) == OP_LOADNIL) {  /* previous is LOADNIL? */
     134                 :          0 :     int pfrom = GETARG_A(*previous);  /* get previous range */
     135                 :          0 :     int pl = pfrom + GETARG_B(*previous);
     136   [ #  #  #  # ]:          0 :     if ((pfrom <= from && from <= pl + 1) ||
     137         [ #  # ]:          0 :         (from <= pfrom && pfrom <= l + 1)) {  /* can connect both? */
     138         [ #  # ]:          0 :       if (pfrom < from) from = pfrom;  /* from = min(from, pfrom) */
     139         [ #  # ]:          0 :       if (pl > l) l = pl;  /* l = max(l, pl) */
     140                 :          0 :       SETARG_A(*previous, from);
     141                 :          0 :       SETARG_B(*previous, l - from);
     142                 :          0 :       return;
     143                 :            :     }  /* else go through */
     144                 :          0 :   }
     145                 :          0 :   luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0);  /* else no optimization */
     146                 :          0 : }
     147                 :            : 
     148                 :            : 
     149                 :            : /*
     150                 :            : ** Gets the destination address of a jump instruction. Used to traverse
     151                 :            : ** a list of jumps.
     152                 :            : */
     153                 :        203 : static int getjump (FuncState *fs, int pc) {
     154                 :        203 :   int offset = GETARG_sJ(fs->f->code[pc]);
     155         [ +  - ]:        203 :   if (offset == NO_JUMP)  /* point to itself represents end of list */
     156                 :        203 :     return NO_JUMP;  /* end of list */
     157                 :            :   else
     158                 :          0 :     return (pc+1)+offset;  /* turn offset into absolute position */
     159                 :        203 : }
     160                 :            : 
     161                 :            : 
     162                 :            : /*
     163                 :            : ** Fix jump instruction at position 'pc' to jump to 'dest'.
     164                 :            : ** (Jump addresses are relative in Lua)
     165                 :            : */
     166                 :        406 : static void fixjump (FuncState *fs, int pc, int dest) {
     167                 :        406 :   Instruction *jmp = &fs->f->code[pc];
     168                 :        406 :   int offset = dest - (pc + 1);
     169                 :            :   lua_assert(dest != NO_JUMP);
     170         [ +  - ]:        406 :   if (!(-OFFSET_sJ <= offset && offset <= MAXARG_sJ - OFFSET_sJ))
     171                 :          0 :     luaX_syntaxerror(fs->ls, "control structure too long");
     172                 :            :   lua_assert(GET_OPCODE(*jmp) == OP_JMP);
     173                 :        406 :   SETARG_sJ(*jmp, offset);
     174                 :        406 : }
     175                 :            : 
     176                 :            : 
     177                 :            : /*
     178                 :            : ** Concatenate jump-list 'l2' into jump-list 'l1'
     179                 :            : */
     180                 :        203 : void luaK_concat (FuncState *fs, int *l1, int l2) {
     181         [ +  - ]:        203 :   if (l2 == NO_JUMP) return;  /* nothing to concatenate? */
     182         [ +  - ]:        203 :   else if (*l1 == NO_JUMP)  /* no original list? */
     183                 :        203 :     *l1 = l2;  /* 'l1' points to 'l2' */
     184                 :            :   else {
     185                 :          0 :     int list = *l1;
     186                 :            :     int next;
     187         [ #  # ]:          0 :     while ((next = getjump(fs, list)) != NO_JUMP)  /* find last element */
     188                 :          0 :       list = next;
     189                 :          0 :     fixjump(fs, list, l2);  /* last element links to 'l2' */
     190                 :            :   }
     191                 :        203 : }
     192                 :            : 
     193                 :            : 
     194                 :            : /*
     195                 :            : ** Create a jump instruction and return its position, so its destination
     196                 :            : ** can be fixed later (with 'fixjump').
     197                 :            : */
     198                 :        203 : int luaK_jump (FuncState *fs) {
     199                 :        203 :   return codesJ(fs, OP_JMP, NO_JUMP, 0);
     200                 :            : }
     201                 :            : 
     202                 :            : 
     203                 :            : /*
     204                 :            : ** Code a 'return' instruction
     205                 :            : */
     206                 :        820 : void luaK_ret (FuncState *fs, int first, int nret) {
     207                 :            :   OpCode op;
     208      [ +  +  + ]:        820 :   switch (nret) {
     209                 :        652 :     case 0: op = OP_RETURN0; break;
     210                 :         90 :     case 1: op = OP_RETURN1; break;
     211                 :         78 :     default: op = OP_RETURN; break;
     212                 :            :   }
     213                 :        820 :   luaK_codeABC(fs, op, first, nret + 1, 0);
     214                 :        820 : }
     215                 :            : 
     216                 :            : 
     217                 :            : /*
     218                 :            : ** Code a "conditional jump", that is, a test or comparison opcode
     219                 :            : ** followed by a jump. Return jump position.
     220                 :            : */
     221                 :        203 : static int condjump (FuncState *fs, OpCode op, int A, int B, int C, int k) {
     222                 :        203 :   luaK_codeABCk(fs, op, A, B, C, k);
     223                 :        203 :   return luaK_jump(fs);
     224                 :            : }
     225                 :            : 
     226                 :            : 
     227                 :            : /*
     228                 :            : ** returns current 'pc' and marks it as a jump target (to avoid wrong
     229                 :            : ** optimizations with consecutive instructions not in the same basic block).
     230                 :            : */
     231                 :        625 : int luaK_getlabel (FuncState *fs) {
     232                 :        625 :   fs->lasttarget = fs->pc;
     233                 :        625 :   return fs->pc;
     234                 :            : }
     235                 :            : 
     236                 :            : 
     237                 :            : /*
     238                 :            : ** Returns the position of the instruction "controlling" a given
     239                 :            : ** jump (that is, its condition), or the jump itself if it is
     240                 :            : ** unconditional.
     241                 :            : */
     242                 :        390 : static Instruction *getjumpcontrol (FuncState *fs, int pc) {
     243                 :        390 :   Instruction *pi = &fs->f->code[pc];
     244   [ +  -  +  - ]:        390 :   if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
     245                 :        390 :     return pi-1;
     246                 :            :   else
     247                 :          0 :     return pi;
     248                 :        390 : }
     249                 :            : 
     250                 :            : 
     251                 :            : /*
     252                 :            : ** Patch destination register for a TESTSET instruction.
     253                 :            : ** If instruction in position 'node' is not a TESTSET, return 0 ("fails").
     254                 :            : ** Otherwise, if 'reg' is not 'NO_REG', set it as the destination
     255                 :            : ** register. Otherwise, change instruction to a simple 'TEST' (produces
     256                 :            : ** no register value)
     257                 :            : */
     258                 :        203 : static int patchtestreg (FuncState *fs, int node, int reg) {
     259                 :        203 :   Instruction *i = getjumpcontrol(fs, node);
     260         [ +  - ]:        203 :   if (GET_OPCODE(*i) != OP_TESTSET)
     261                 :        203 :     return 0;  /* cannot patch other instructions */
     262   [ #  #  #  # ]:          0 :   if (reg != NO_REG && reg != GETARG_B(*i))
     263                 :          0 :     SETARG_A(*i, reg);
     264                 :            :   else {
     265                 :            :      /* no register to put value or register already has the value;
     266                 :            :         change instruction to simple test */
     267                 :          0 :     *i = CREATE_ABCk(OP_TEST, GETARG_B(*i), 0, 0, GETARG_k(*i));
     268                 :            :   }
     269                 :          0 :   return 1;
     270                 :        203 : }
     271                 :            : 
     272                 :            : 
     273                 :            : /*
     274                 :            : ** Traverse a list of tests ensuring no one produces a value
     275                 :            : */
     276                 :         32 : static void removevalues (FuncState *fs, int list) {
     277         [ -  + ]:         32 :   for (; list != NO_JUMP; list = getjump(fs, list))
     278                 :          0 :       patchtestreg(fs, list, NO_REG);
     279                 :         32 : }
     280                 :            : 
     281                 :            : 
     282                 :            : /*
     283                 :            : ** Traverse a list of tests, patching their destination address and
     284                 :            : ** registers: tests producing values jump to 'vtarget' (and put their
     285                 :            : ** values in 'reg'), other tests jump to 'dtarget'.
     286                 :            : */
     287                 :        609 : static void patchlistaux (FuncState *fs, int list, int vtarget, int reg,
     288                 :            :                           int dtarget) {
     289         [ +  + ]:        812 :   while (list != NO_JUMP) {
     290                 :        203 :     int next = getjump(fs, list);
     291         [ -  + ]:        203 :     if (patchtestreg(fs, list, reg))
     292                 :          0 :       fixjump(fs, list, vtarget);
     293                 :            :     else
     294                 :        203 :       fixjump(fs, list, dtarget);  /* jump to default target */
     295                 :        203 :     list = next;
     296                 :            :   }
     297                 :        609 : }
     298                 :            : 
     299                 :            : 
     300                 :            : /*
     301                 :            : ** Path all jumps in 'list' to jump to 'target'.
     302                 :            : ** (The assert means that we cannot fix a jump to a forward address
     303                 :            : ** because we only know addresses once code is generated.)
     304                 :            : */
     305                 :        609 : void luaK_patchlist (FuncState *fs, int list, int target) {
     306                 :            :   lua_assert(target <= fs->pc);
     307                 :        609 :   patchlistaux(fs, list, target, NO_REG, target);
     308                 :        609 : }
     309                 :            : 
     310                 :            : 
     311                 :        609 : void luaK_patchtohere (FuncState *fs, int list) {
     312                 :        609 :   int hr = luaK_getlabel(fs);  /* mark "here" as a jump target */
     313                 :        609 :   luaK_patchlist(fs, list, hr);
     314                 :        609 : }
     315                 :            : 
     316                 :            : 
     317                 :            : /*
     318                 :            : ** MAXimum number of successive Instructions WiTHout ABSolute line
     319                 :            : ** information.
     320                 :            : */
     321                 :            : #if !defined(MAXIWTHABS)
     322                 :            : #define MAXIWTHABS      120
     323                 :            : #endif
     324                 :            : 
     325                 :            : 
     326                 :            : /* limit for difference between lines in relative line info. */
     327                 :            : #define LIMLINEDIFF     0x80
     328                 :            : 
     329                 :            : 
     330                 :            : /*
     331                 :            : ** Save line info for a new instruction. If difference from last line
     332                 :            : ** does not fit in a byte, of after that many instructions, save a new
     333                 :            : ** absolute line info; (in that case, the special value 'ABSLINEINFO'
     334                 :            : ** in 'lineinfo' signals the existence of this absolute information.)
     335                 :            : ** Otherwise, store the difference from last line in 'lineinfo'.
     336                 :            : */
     337                 :       7336 : static void savelineinfo (FuncState *fs, Proto *f, int line) {
     338                 :       7336 :   int linedif = line - fs->previousline;
     339                 :       7336 :   int pc = fs->pc - 1;  /* last instruction coded */
     340   [ +  -  -  + ]:       7336 :   if (abs(linedif) >= LIMLINEDIFF || fs->iwthabs++ > MAXIWTHABS) {
     341                 :          0 :     luaM_growvector(fs->ls->L, f->abslineinfo, fs->nabslineinfo,
     342                 :            :                     f->sizeabslineinfo, AbsLineInfo, MAX_INT, "lines");
     343                 :          0 :     f->abslineinfo[fs->nabslineinfo].pc = pc;
     344                 :          0 :     f->abslineinfo[fs->nabslineinfo++].line = line;
     345                 :          0 :     linedif = ABSLINEINFO;  /* signal that there is absolute information */
     346                 :          0 :     fs->iwthabs = 0;  /* restart counter */
     347                 :          0 :   }
     348                 :       7336 :   luaM_growvector(fs->ls->L, f->lineinfo, pc, f->sizelineinfo, ls_byte,
     349                 :            :                   MAX_INT, "opcodes");
     350                 :       7336 :   f->lineinfo[pc] = linedif;
     351                 :       7336 :   fs->previousline = line;  /* last line saved */
     352                 :       7336 : }
     353                 :            : 
     354                 :            : 
     355                 :            : /*
     356                 :            : ** Remove line information from the last instruction.
     357                 :            : ** If line information for that instruction is absolute, set 'iwthabs'
     358                 :            : ** above its max to force the new (replacing) instruction to have
     359                 :            : ** absolute line info, too.
     360                 :            : */
     361                 :       1102 : static void removelastlineinfo (FuncState *fs) {
     362                 :       1102 :   Proto *f = fs->f;
     363                 :       1102 :   int pc = fs->pc - 1;  /* last instruction coded */
     364         [ +  - ]:       1102 :   if (f->lineinfo[pc] != ABSLINEINFO) {  /* relative line info? */
     365                 :       1102 :     fs->previousline -= f->lineinfo[pc];  /* correct last line saved */
     366                 :       1102 :     fs->iwthabs--;  /* undo previous increment */
     367                 :       1102 :   }
     368                 :            :   else {  /* absolute line information */
     369                 :            :     lua_assert(f->abslineinfo[fs->nabslineinfo - 1].pc == pc);
     370                 :          0 :     fs->nabslineinfo--;  /* remove it */
     371                 :          0 :     fs->iwthabs = MAXIWTHABS + 1;  /* force next line info to be absolute */
     372                 :            :   }
     373                 :       1102 : }
     374                 :            : 
     375                 :            : 
     376                 :            : /*
     377                 :            : ** Remove the last instruction created, correcting line information
     378                 :            : ** accordingly.
     379                 :            : */
     380                 :         16 : static void removelastinstruction (FuncState *fs) {
     381                 :         16 :   removelastlineinfo(fs);
     382                 :         16 :   fs->pc--;
     383                 :         16 : }
     384                 :            : 
     385                 :            : 
     386                 :            : /*
     387                 :            : ** Emit instruction 'i', checking for array sizes and saving also its
     388                 :            : ** line information. Return 'i' position.
     389                 :            : */
     390                 :       6250 : int luaK_code (FuncState *fs, Instruction i) {
     391                 :       6250 :   Proto *f = fs->f;
     392                 :            :   /* put new instruction in code array */
     393                 :       6250 :   luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
     394                 :            :                   MAX_INT, "opcodes");
     395                 :       6250 :   f->code[fs->pc++] = i;
     396                 :       6250 :   savelineinfo(fs, f, fs->ls->lastline);
     397                 :       6250 :   return fs->pc - 1;  /* index of new instruction */
     398                 :            : }
     399                 :            : 
     400                 :            : 
     401                 :            : /*
     402                 :            : ** Format and emit an 'iABC' instruction. (Assertions check consistency
     403                 :            : ** of parameters versus opcode.)
     404                 :            : */
     405                 :       4946 : int luaK_codeABCk (FuncState *fs, OpCode o, int a, int b, int c, int k) {
     406                 :            :   lua_assert(getOpMode(o) == iABC);
     407                 :            :   lua_assert(a <= MAXARG_A && b <= MAXARG_B &&
     408                 :            :              c <= MAXARG_C && (k & ~1) == 0);
     409                 :       4946 :   return luaK_code(fs, CREATE_ABCk(o, a, b, c, k));
     410                 :            : }
     411                 :            : 
     412                 :            : 
     413                 :            : /*
     414                 :            : ** Format and emit an 'iABx' instruction.
     415                 :            : */
     416                 :        718 : int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
     417                 :            :   lua_assert(getOpMode(o) == iABx);
     418                 :            :   lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx);
     419                 :        718 :   return luaK_code(fs, CREATE_ABx(o, a, bc));
     420                 :            : }
     421                 :            : 
     422                 :            : 
     423                 :            : /*
     424                 :            : ** Format and emit an 'iAsBx' instruction.
     425                 :            : */
     426                 :        374 : int luaK_codeAsBx (FuncState *fs, OpCode o, int a, int bc) {
     427                 :        374 :   unsigned int b = bc + OFFSET_sBx;
     428                 :            :   lua_assert(getOpMode(o) == iAsBx);
     429                 :            :   lua_assert(a <= MAXARG_A && b <= MAXARG_Bx);
     430                 :        374 :   return luaK_code(fs, CREATE_ABx(o, a, b));
     431                 :            : }
     432                 :            : 
     433                 :            : 
     434                 :            : /*
     435                 :            : ** Format and emit an 'isJ' instruction.
     436                 :            : */
     437                 :        203 : static int codesJ (FuncState *fs, OpCode o, int sj, int k) {
     438                 :        203 :   unsigned int j = sj + OFFSET_sJ;
     439                 :            :   lua_assert(getOpMode(o) == isJ);
     440                 :            :   lua_assert(j <= MAXARG_sJ && (k & ~1) == 0);
     441                 :        203 :   return luaK_code(fs, CREATE_sJ(o, j, k));
     442                 :            : }
     443                 :            : 
     444                 :            : 
     445                 :            : /*
     446                 :            : ** Emit an "extra argument" instruction (format 'iAx')
     447                 :            : */
     448                 :          0 : static int codeextraarg (FuncState *fs, int a) {
     449                 :            :   lua_assert(a <= MAXARG_Ax);
     450                 :          0 :   return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a));
     451                 :            : }
     452                 :            : 
     453                 :            : 
     454                 :            : /*
     455                 :            : ** Emit a "load constant" instruction, using either 'OP_LOADK'
     456                 :            : ** (if constant index 'k' fits in 18 bits) or an 'OP_LOADKX'
     457                 :            : ** instruction with "extra argument".
     458                 :            : */
     459                 :        702 : static int luaK_codek (FuncState *fs, int reg, int k) {
     460         [ +  - ]:        702 :   if (k <= MAXARG_Bx)
     461                 :        702 :     return luaK_codeABx(fs, OP_LOADK, reg, k);
     462                 :            :   else {
     463                 :          0 :     int p = luaK_codeABx(fs, OP_LOADKX, reg, 0);
     464                 :          0 :     codeextraarg(fs, k);
     465                 :          0 :     return p;
     466                 :            :   }
     467                 :        702 : }
     468                 :            : 
     469                 :            : 
     470                 :            : /*
     471                 :            : ** Check register-stack level, keeping track of its maximum size
     472                 :            : ** in field 'maxstacksize'
     473                 :            : */
     474                 :       3312 : void luaK_checkstack (FuncState *fs, int n) {
     475                 :       3312 :   int newstack = fs->freereg + n;
     476         [ +  + ]:       3312 :   if (newstack > fs->f->maxstacksize) {
     477         [ -  + ]:        424 :     if (newstack >= MAXREGS)
     478                 :          0 :       luaX_syntaxerror(fs->ls,
     479                 :            :         "function or expression needs too many registers");
     480                 :        424 :     fs->f->maxstacksize = cast_byte(newstack);
     481                 :        424 :   }
     482                 :       3312 : }
     483                 :            : 
     484                 :            : 
     485                 :            : /*
     486                 :            : ** Reserve 'n' registers in register stack
     487                 :            : */
     488                 :       3312 : void luaK_reserveregs (FuncState *fs, int n) {
     489                 :       3312 :   luaK_checkstack(fs, n);
     490                 :       3312 :   fs->freereg += n;
     491                 :       3312 : }
     492                 :            : 
     493                 :            : 
     494                 :            : /*
     495                 :            : ** Free register 'reg', if it is neither a constant index nor
     496                 :            : ** a local variable.
     497                 :            : )
     498                 :            : */
     499                 :       1543 : static void freereg (FuncState *fs, int reg) {
     500         [ +  + ]:       1543 :   if (reg >= luaY_nvarstack(fs)) {
     501                 :       1364 :     fs->freereg--;
     502                 :            :     lua_assert(reg == fs->freereg);
     503                 :       1364 :   }
     504                 :       1543 : }
     505                 :            : 
     506                 :            : 
     507                 :            : /*
     508                 :            : ** Free two registers in proper order
     509                 :            : */
     510                 :        196 : static void freeregs (FuncState *fs, int r1, int r2) {
     511         [ +  + ]:        196 :   if (r1 > r2) {
     512                 :        179 :     freereg(fs, r1);
     513                 :        179 :     freereg(fs, r2);
     514                 :        179 :   }
     515                 :            :   else {
     516                 :         17 :     freereg(fs, r2);
     517                 :         17 :     freereg(fs, r1);
     518                 :            :   }
     519                 :        196 : }
     520                 :            : 
     521                 :            : 
     522                 :            : /*
     523                 :            : ** Free register used by expression 'e' (if any)
     524                 :            : */
     525                 :       3618 : static void freeexp (FuncState *fs, expdesc *e) {
     526         [ +  + ]:       3618 :   if (e->k == VNONRELOC)
     527                 :        380 :     freereg(fs, e->u.info);
     528                 :       3618 : }
     529                 :            : 
     530                 :            : 
     531                 :            : /*
     532                 :            : ** Free registers used by expressions 'e1' and 'e2' (if any) in proper
     533                 :            : ** order.
     534                 :            : */
     535                 :        187 : static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) {
     536         [ +  - ]:        187 :   int r1 = (e1->k == VNONRELOC) ? e1->u.info : -1;
     537         [ +  + ]:        187 :   int r2 = (e2->k == VNONRELOC) ? e2->u.info : -1;
     538                 :        187 :   freeregs(fs, r1, r2);
     539                 :        187 : }
     540                 :            : 
     541                 :            : 
     542                 :            : /*
     543                 :            : ** Add constant 'v' to prototype's list of constants (field 'k').
     544                 :            : ** Use scanner's table to cache position of constants in constant list
     545                 :            : ** and try to reuse constants. Because some values should not be used
     546                 :            : ** as keys (nil cannot be a key, integer keys can collapse with float
     547                 :            : ** keys), the caller must provide a useful 'key' for indexing the cache.
     548                 :            : */
     549                 :       2955 : static int addk (FuncState *fs, TValue *key, TValue *v) {
     550                 :       2955 :   lua_State *L = fs->ls->L;
     551                 :       2955 :   Proto *f = fs->f;
     552                 :       2955 :   TValue *idx = luaH_set(L, fs->ls->h, key);  /* index scanner table */
     553                 :            :   int k, oldsize;
     554         [ +  + ]:       2955 :   if (ttisinteger(idx)) {  /* is there an index there? */
     555                 :        301 :     k = cast_int(ivalue(idx));
     556                 :            :     /* correct value? (warning: must distinguish floats from integers!) */
     557   [ +  -  +  -  :        301 :     if (k < fs->nk && ttypetag(&f->k[k]) == ttypetag(v) &&
                   +  - ]
     558                 :        301 :                       luaV_rawequalobj(&f->k[k], v))
     559                 :        301 :       return k;  /* reuse index */
     560                 :          0 :   }
     561                 :            :   /* constant not found; create a new entry */
     562                 :       2654 :   oldsize = f->sizek;
     563                 :       2654 :   k = fs->nk;
     564                 :            :   /* numerical value does not need GC barrier;
     565                 :            :      table has no metatable, so it does not need to invalidate cache */
     566                 :       2654 :   setivalue(idx, k);
     567                 :       2654 :   luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
     568         [ +  + ]:       6322 :   while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
     569                 :       2654 :   setobj(L, &f->k[k], v);
     570                 :       2654 :   fs->nk++;
     571   [ +  +  -  +  :       2654 :   luaC_barrier(L, f, v);
                   #  # ]
     572                 :       2654 :   return k;
     573                 :       2955 : }
     574                 :            : 
     575                 :            : 
     576                 :            : /*
     577                 :            : ** Add a string to list of constants and return its index.
     578                 :            : */
     579                 :       2800 : static int stringK (FuncState *fs, TString *s) {
     580                 :            :   TValue o;
     581                 :       2800 :   setsvalue(fs->ls->L, &o, s);
     582                 :       2800 :   return addk(fs, &o, &o);  /* use string itself as key */
     583                 :            : }
     584                 :            : 
     585                 :            : 
     586                 :            : /*
     587                 :            : ** Add an integer to list of constants and return its index.
     588                 :            : ** Integers use userdata as keys to avoid collision with floats with
     589                 :            : ** same value; conversion to 'void*' is used only for hashing, so there
     590                 :            : ** are no "precision" problems.
     591                 :            : */
     592                 :          0 : static int luaK_intK (FuncState *fs, lua_Integer n) {
     593                 :            :   TValue k, o;
     594                 :          0 :   setpvalue(&k, cast_voidp(cast_sizet(n)));
     595                 :          0 :   setivalue(&o, n);
     596                 :          0 :   return addk(fs, &k, &o);
     597                 :            : }
     598                 :            : 
     599                 :            : /*
     600                 :            : ** Add a float to list of constants and return its index.
     601                 :            : */
     602                 :          0 : static int luaK_numberK (FuncState *fs, lua_Number r) {
     603                 :            :   TValue o;
     604                 :          0 :   setfltvalue(&o, r);
     605                 :          0 :   return addk(fs, &o, &o);  /* use number itself as key */
     606                 :            : }
     607                 :            : 
     608                 :            : 
     609                 :            : /*
     610                 :            : ** Add a false to list of constants and return its index.
     611                 :            : */
     612                 :          8 : static int boolF (FuncState *fs) {
     613                 :            :   TValue o;
     614                 :          8 :   setbfvalue(&o);
     615                 :          8 :   return addk(fs, &o, &o);  /* use boolean itself as key */
     616                 :            : }
     617                 :            : 
     618                 :            : 
     619                 :            : /*
     620                 :            : ** Add a true to list of constants and return its index.
     621                 :            : */
     622                 :          8 : static int boolT (FuncState *fs) {
     623                 :            :   TValue o;
     624                 :          8 :   setbtvalue(&o);
     625                 :          8 :   return addk(fs, &o, &o);  /* use boolean itself as key */
     626                 :            : }
     627                 :            : 
     628                 :            : 
     629                 :            : /*
     630                 :            : ** Add nil to list of constants and return its index.
     631                 :            : */
     632                 :        139 : static int nilK (FuncState *fs) {
     633                 :            :   TValue k, v;
     634                 :        139 :   setnilvalue(&v);
     635                 :            :   /* cannot use nil as key; instead use table itself to represent nil */
     636                 :        139 :   sethvalue(fs->ls->L, &k, fs->ls->h);
     637                 :        139 :   return addk(fs, &k, &v);
     638                 :            : }
     639                 :            : 
     640                 :            : 
     641                 :            : /*
     642                 :            : ** Check whether 'i' can be stored in an 'sC' operand. Equivalent to
     643                 :            : ** (0 <= int2sC(i) && int2sC(i) <= MAXARG_C) but without risk of
     644                 :            : ** overflows in the hidden addition inside 'int2sC'.
     645                 :            : */
     646                 :         32 : static int fitsC (lua_Integer i) {
     647                 :         32 :   return (l_castS2U(i) + OFFSET_sC <= cast_uint(MAXARG_C));
     648                 :            : }
     649                 :            : 
     650                 :            : 
     651                 :            : /*
     652                 :            : ** Check whether 'i' can be stored in an 'sBx' operand.
     653                 :            : */
     654                 :        374 : static int fitsBx (lua_Integer i) {
     655         [ -  + ]:        374 :   return (-OFFSET_sBx <= i && i <= MAXARG_Bx - OFFSET_sBx);
     656                 :            : }
     657                 :            : 
     658                 :            : 
     659                 :        374 : void luaK_int (FuncState *fs, int reg, lua_Integer i) {
     660         [ +  - ]:        374 :   if (fitsBx(i))
     661                 :        374 :     luaK_codeAsBx(fs, OP_LOADI, reg, cast_int(i));
     662                 :            :   else
     663                 :          0 :     luaK_codek(fs, reg, luaK_intK(fs, i));
     664                 :        374 : }
     665                 :            : 
     666                 :            : 
     667                 :          0 : static void luaK_float (FuncState *fs, int reg, lua_Number f) {
     668                 :            :   lua_Integer fi;
     669   [ #  #  #  # ]:          0 :   if (luaV_flttointeger(f, &fi, F2Ieq) && fitsBx(fi))
     670                 :          0 :     luaK_codeAsBx(fs, OP_LOADF, reg, cast_int(fi));
     671                 :            :   else
     672                 :          0 :     luaK_codek(fs, reg, luaK_numberK(fs, f));
     673                 :          0 : }
     674                 :            : 
     675                 :            : 
     676                 :            : /*
     677                 :            : ** Convert a constant in 'v' into an expression description 'e'
     678                 :            : */
     679                 :          0 : static void const2exp (TValue *v, expdesc *e) {
     680   [ #  #  #  #  :          0 :   switch (ttypetag(v)) {
                #  #  # ]
     681                 :            :     case LUA_VNUMINT:
     682                 :          0 :       e->k = VKINT; e->u.ival = ivalue(v);
     683                 :          0 :       break;
     684                 :            :     case LUA_VNUMFLT:
     685                 :          0 :       e->k = VKFLT; e->u.nval = fltvalue(v);
     686                 :          0 :       break;
     687                 :            :     case LUA_VFALSE:
     688                 :          0 :       e->k = VFALSE;
     689                 :          0 :       break;
     690                 :            :     case LUA_VTRUE:
     691                 :          0 :       e->k = VTRUE;
     692                 :          0 :       break;
     693                 :            :     case LUA_VNIL:
     694                 :          0 :       e->k = VNIL;
     695                 :          0 :       break;
     696                 :            :     case LUA_VSHRSTR:  case LUA_VLNGSTR:
     697                 :          0 :       e->k = VKSTR; e->u.strval = tsvalue(v);
     698                 :          0 :       break;
     699                 :            :     default: lua_assert(0);
     700                 :          0 :   }
     701                 :          0 : }
     702                 :            : 
     703                 :            : 
     704                 :            : /*
     705                 :            : ** Fix an expression to return the number of results 'nresults'.
     706                 :            : ** 'e' must be a multi-ret expression (function call or vararg).
     707                 :            : */
     708                 :        112 : void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) {
     709                 :        112 :   Instruction *pc = &getinstruction(fs, e);
     710         [ +  - ]:        112 :   if (e->k == VCALL)  /* expression is an open function call? */
     711                 :        112 :     SETARG_C(*pc, nresults + 1);
     712                 :            :   else {
     713                 :            :     lua_assert(e->k == VVARARG);
     714                 :          0 :     SETARG_C(*pc, nresults + 1);
     715                 :          0 :     SETARG_A(*pc, fs->freereg);
     716                 :          0 :     luaK_reserveregs(fs, 1);
     717                 :            :   }
     718                 :        112 : }
     719                 :            : 
     720                 :            : 
     721                 :            : /*
     722                 :            : ** Convert a VKSTR to a VK
     723                 :            : */
     724                 :       2752 : static void str2K (FuncState *fs, expdesc *e) {
     725                 :            :   lua_assert(e->k == VKSTR);
     726                 :       2752 :   e->u.info = stringK(fs, e->u.strval);
     727                 :       2752 :   e->k = VK;
     728                 :       2752 : }
     729                 :            : 
     730                 :            : 
     731                 :            : /*
     732                 :            : ** Fix an expression to return one result.
     733                 :            : ** If expression is not a multi-ret expression (function call or
     734                 :            : ** vararg), it already returns one result, so nothing needs to be done.
     735                 :            : ** Function calls become VNONRELOC expressions (as its result comes
     736                 :            : ** fixed in the base register of the call), while vararg expressions
     737                 :            : ** become VRELOC (as OP_VARARG puts its results where it wants).
     738                 :            : ** (Calls are created returning one result, so that does not need
     739                 :            : ** to be fixed.)
     740                 :            : */
     741                 :        232 : void luaK_setoneret (FuncState *fs, expdesc *e) {
     742         [ +  + ]:        232 :   if (e->k == VCALL) {  /* expression is an open function call? */
     743                 :            :     /* already returns 1 value */
     744                 :            :     lua_assert(GETARG_C(getinstruction(fs, e)) == 2);
     745                 :        215 :     e->k = VNONRELOC;  /* result has fixed position */
     746                 :        215 :     e->u.info = GETARG_A(getinstruction(fs, e));
     747                 :        215 :   }
     748         [ +  - ]:         17 :   else if (e->k == VVARARG) {
     749                 :          0 :     SETARG_C(getinstruction(fs, e), 2);
     750                 :          0 :     e->k = VRELOC;  /* can relocate its simple result */
     751                 :          0 :   }
     752                 :        232 : }
     753                 :            : 
     754                 :            : 
     755                 :            : /*
     756                 :            : ** Ensure that expression 'e' is not a variable (nor a <const>).
     757                 :            : ** (Expression still may have jump lists.)
     758                 :            : */
     759                 :       8879 : void luaK_dischargevars (FuncState *fs, expdesc *e) {
     760   [ +  +  -  +  :       8879 :   switch (e->k) {
             -  +  +  +  
                      + ]
     761                 :            :     case VCONST: {
     762                 :          0 :       const2exp(const2val(fs, e), e);
     763                 :          0 :       break;
     764                 :            :     }
     765                 :            :     case VLOCAL: {  /* already in a register */
     766                 :          8 :       e->u.info = e->u.var.sidx;
     767                 :          8 :       e->k = VNONRELOC;  /* becomes a non-relocatable value */
     768                 :          8 :       break;
     769                 :            :     }
     770                 :            :     case VUPVAL: {  /* move value to some (pending) register */
     771                 :          0 :       e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0);
     772                 :          0 :       e->k = VRELOC;
     773                 :          0 :       break;
     774                 :            :     }
     775                 :            :     case VINDEXUP: {
     776                 :       1217 :       e->u.info = luaK_codeABC(fs, OP_GETTABUP, 0, e->u.ind.t, e->u.ind.idx);
     777                 :       1217 :       e->k = VRELOC;
     778                 :       1217 :       break;
     779                 :            :     }
     780                 :            :     case VINDEXI: {
     781                 :         48 :       freereg(fs, e->u.ind.t);
     782                 :         48 :       e->u.info = luaK_codeABC(fs, OP_GETI, 0, e->u.ind.t, e->u.ind.idx);
     783                 :         48 :       e->k = VRELOC;
     784                 :         48 :       break;
     785                 :            :     }
     786                 :            :     case VINDEXSTR: {
     787                 :        723 :       freereg(fs, e->u.ind.t);
     788                 :        723 :       e->u.info = luaK_codeABC(fs, OP_GETFIELD, 0, e->u.ind.t, e->u.ind.idx);
     789                 :        723 :       e->k = VRELOC;
     790                 :        723 :       break;
     791                 :            :     }
     792                 :            :     case VINDEXED: {
     793                 :          9 :       freeregs(fs, e->u.ind.t, e->u.ind.idx);
     794                 :          9 :       e->u.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.ind.t, e->u.ind.idx);
     795                 :          9 :       e->k = VRELOC;
     796                 :          9 :       break;
     797                 :            :     }
     798                 :            :     case VVARARG: case VCALL: {
     799                 :        122 :       luaK_setoneret(fs, e);
     800                 :        122 :       break;
     801                 :            :     }
     802                 :       6752 :     default: break;  /* there is one value available (somewhere) */
     803                 :            :   }
     804                 :       8879 : }
     805                 :            : 
     806                 :            : 
     807                 :            : /*
     808                 :            : ** Ensure expression value is in register 'reg', making 'e' a
     809                 :            : ** non-relocatable expression.
     810                 :            : ** (Expression still may have jump lists.)
     811                 :            : */
     812                 :       3239 : static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
     813                 :       3239 :   luaK_dischargevars(fs, e);
     814   [ +  -  -  -  :       3239 :   switch (e->k) {
          -  -  +  -  +  
                      + ]
     815                 :            :     case VNIL: {
     816                 :          0 :       luaK_nil(fs, reg, 1);
     817                 :          0 :       break;
     818                 :            :     }
     819                 :            :     case VFALSE: {
     820                 :          0 :       luaK_codeABC(fs, OP_LOADFALSE, reg, 0, 0);
     821                 :          0 :       break;
     822                 :            :     }
     823                 :            :     case VTRUE: {
     824                 :          0 :       luaK_codeABC(fs, OP_LOADTRUE, reg, 0, 0);
     825                 :          0 :       break;
     826                 :            :     }
     827                 :            :     case VKSTR: {
     828                 :        702 :       str2K(fs, e);
     829                 :        702 :     }  /* FALLTHROUGH */
     830                 :            :     case VK: {
     831                 :        702 :       luaK_codek(fs, reg, e->u.info);
     832                 :        702 :       break;
     833                 :            :     }
     834                 :            :     case VKFLT: {
     835                 :          0 :       luaK_float(fs, reg, e->u.nval);
     836                 :          0 :       break;
     837                 :            :     }
     838                 :            :     case VKINT: {
     839                 :        366 :       luaK_int(fs, reg, e->u.ival);
     840                 :        366 :       break;
     841                 :            :     }
     842                 :            :     case VRELOC: {
     843                 :       2114 :       Instruction *pc = &getinstruction(fs, e);
     844                 :       2114 :       SETARG_A(*pc, reg);  /* instruction will put result in 'reg' */
     845                 :       2114 :       break;
     846                 :            :     }
     847                 :            :     case VNONRELOC: {
     848         [ +  - ]:         57 :       if (reg != e->u.info)
     849                 :          0 :         luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0);
     850                 :         57 :       break;
     851                 :            :     }
     852                 :            :     default: {
     853                 :            :       lua_assert(e->k == VJMP);
     854                 :          0 :       return;  /* nothing to do... */
     855                 :            :     }
     856                 :            :   }
     857                 :       3239 :   e->u.info = reg;
     858                 :       3239 :   e->k = VNONRELOC;
     859                 :       3239 : }
     860                 :            : 
     861                 :            : 
     862                 :            : /*
     863                 :            : ** Ensure expression value is in a register, making 'e' a
     864                 :            : ** non-relocatable expression.
     865                 :            : ** (Expression still may have jump lists.)
     866                 :            : */
     867                 :         16 : static void discharge2anyreg (FuncState *fs, expdesc *e) {
     868         [ +  + ]:         16 :   if (e->k != VNONRELOC) {  /* no fixed register yet? */
     869                 :          8 :     luaK_reserveregs(fs, 1);  /* get a register */
     870                 :          8 :     discharge2reg(fs, e, fs->freereg-1);  /* put value there */
     871                 :          8 :   }
     872                 :         16 : }
     873                 :            : 
     874                 :            : 
     875                 :          0 : static int code_loadbool (FuncState *fs, int A, OpCode op) {
     876                 :          0 :   luaK_getlabel(fs);  /* those instructions may be jump targets */
     877                 :          0 :   return luaK_codeABC(fs, op, A, 0, 0);
     878                 :            : }
     879                 :            : 
     880                 :            : 
     881                 :            : /*
     882                 :            : ** check whether list has any jump that do not produce a value
     883                 :            : ** or produce an inverted value
     884                 :            : */
     885                 :          0 : static int need_value (FuncState *fs, int list) {
     886         [ #  # ]:          0 :   for (; list != NO_JUMP; list = getjump(fs, list)) {
     887                 :          0 :     Instruction i = *getjumpcontrol(fs, list);
     888         [ #  # ]:          0 :     if (GET_OPCODE(i) != OP_TESTSET) return 1;
     889                 :          0 :   }
     890                 :          0 :   return 0;  /* not found */
     891                 :          0 : }
     892                 :            : 
     893                 :            : 
     894                 :            : /*
     895                 :            : ** Ensures final expression result (which includes results from its
     896                 :            : ** jump lists) is in register 'reg'.
     897                 :            : ** If expression has jumps, need to patch these jumps either to
     898                 :            : ** its final position or to "load" instructions (for those tests
     899                 :            : ** that do not produce values).
     900                 :            : */
     901                 :       3231 : static void exp2reg (FuncState *fs, expdesc *e, int reg) {
     902                 :       3231 :   discharge2reg(fs, e, reg);
     903         [ +  - ]:       3231 :   if (e->k == VJMP)  /* expression itself is a test? */
     904                 :          0 :     luaK_concat(fs, &e->t, e->u.info);  /* put this jump in 't' list */
     905         [ +  - ]:       3231 :   if (hasjumps(e)) {
     906                 :            :     int final;  /* position after whole expression */
     907                 :          0 :     int p_f = NO_JUMP;  /* position of an eventual LOAD false */
     908                 :          0 :     int p_t = NO_JUMP;  /* position of an eventual LOAD true */
     909   [ #  #  #  # ]:          0 :     if (need_value(fs, e->t) || need_value(fs, e->f)) {
     910         [ #  # ]:          0 :       int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs);
     911                 :          0 :       p_f = code_loadbool(fs, reg, OP_LFALSESKIP);  /* skip next inst. */
     912                 :          0 :       p_t = code_loadbool(fs, reg, OP_LOADTRUE);
     913                 :            :       /* jump around these booleans if 'e' is not a test */
     914                 :          0 :       luaK_patchtohere(fs, fj);
     915                 :          0 :     }
     916                 :          0 :     final = luaK_getlabel(fs);
     917                 :          0 :     patchlistaux(fs, e->f, final, reg, p_f);
     918                 :          0 :     patchlistaux(fs, e->t, final, reg, p_t);
     919                 :          0 :   }
     920                 :       3231 :   e->f = e->t = NO_JUMP;
     921                 :       3231 :   e->u.info = reg;
     922                 :       3231 :   e->k = VNONRELOC;
     923                 :       3231 : }
     924                 :            : 
     925                 :            : 
     926                 :            : /*
     927                 :            : ** Ensures final expression result is in next available register.
     928                 :            : */
     929                 :       3231 : void luaK_exp2nextreg (FuncState *fs, expdesc *e) {
     930                 :       3231 :   luaK_dischargevars(fs, e);
     931                 :       3231 :   freeexp(fs, e);
     932                 :       3231 :   luaK_reserveregs(fs, 1);
     933                 :       3231 :   exp2reg(fs, e, fs->freereg - 1);
     934                 :       3231 : }
     935                 :            : 
     936                 :            : 
     937                 :            : /*
     938                 :            : ** Ensures final expression result is in some (any) register
     939                 :            : ** and return that register.
     940                 :            : */
     941                 :       1544 : int luaK_exp2anyreg (FuncState *fs, expdesc *e) {
     942                 :       1544 :   luaK_dischargevars(fs, e);
     943         [ +  + ]:       1544 :   if (e->k == VNONRELOC) {  /* expression already has a register? */
     944         [ -  + ]:        418 :     if (!hasjumps(e))  /* no jumps? */
     945                 :        418 :       return e->u.info;  /* result is already in a register */
     946         [ #  # ]:          0 :     if (e->u.info >= luaY_nvarstack(fs)) {  /* reg. is not a local? */
     947                 :          0 :       exp2reg(fs, e, e->u.info);  /* put final result in it */
     948                 :          0 :       return e->u.info;
     949                 :            :     }
     950                 :            :     /* else expression has jumps and cannot change its register
     951                 :            :        to hold the jump values, because it is a local variable.
     952                 :            :        Go through to the default case. */
     953                 :          0 :   }
     954                 :       1126 :   luaK_exp2nextreg(fs, e);  /* default: use next available register */
     955                 :       1126 :   return e->u.info;
     956                 :       1544 : }
     957                 :            : 
     958                 :            : 
     959                 :            : /*
     960                 :            : ** Ensures final expression result is either in a register
     961                 :            : ** or in an upvalue.
     962                 :            : */
     963                 :        780 : void luaK_exp2anyregup (FuncState *fs, expdesc *e) {
     964   [ -  +  #  # ]:        780 :   if (e->k != VUPVAL || hasjumps(e))
     965                 :        780 :     luaK_exp2anyreg(fs, e);
     966                 :        780 : }
     967                 :            : 
     968                 :            : 
     969                 :            : /*
     970                 :            : ** Ensures final expression result is either in a register
     971                 :            : ** or it is a constant.
     972                 :            : */
     973                 :         57 : void luaK_exp2val (FuncState *fs, expdesc *e) {
     974         [ -  + ]:         57 :   if (hasjumps(e))
     975                 :          0 :     luaK_exp2anyreg(fs, e);
     976                 :            :   else
     977                 :         57 :     luaK_dischargevars(fs, e);
     978                 :         57 : }
     979                 :            : 
     980                 :            : 
     981                 :            : /*
     982                 :            : ** Try to make 'e' a K expression with an index in the range of R/K
     983                 :            : ** indices. Return true iff succeeded.
     984                 :            : */
     985                 :        500 : static int luaK_exp2K (FuncState *fs, expdesc *e) {
     986         [ -  + ]:        500 :   if (!hasjumps(e)) {
     987                 :            :     int info;
     988   [ +  +  +  +  :        500 :     switch (e->k) {  /* move constants to 'k' */
             -  -  +  - ]
     989                 :          8 :       case VTRUE: info = boolT(fs); break;
     990                 :          8 :       case VFALSE: info = boolF(fs); break;
     991                 :        139 :       case VNIL: info = nilK(fs); break;
     992                 :          0 :       case VKINT: info = luaK_intK(fs, e->u.ival); break;
     993                 :          0 :       case VKFLT: info = luaK_numberK(fs, e->u.nval); break;
     994                 :         48 :       case VKSTR: info = stringK(fs, e->u.strval); break;
     995                 :          0 :       case VK: info = e->u.info; break;
     996                 :        297 :       default: return 0;  /* not a constant */
     997                 :            :     }
     998         [ +  - ]:        203 :     if (info <= MAXINDEXRK) {  /* does constant fit in 'argC'? */
     999                 :        203 :       e->k = VK;  /* make expression a 'K' expression */
    1000                 :        203 :       e->u.info = info;
    1001                 :        203 :       return 1;
    1002                 :            :     }
    1003                 :          0 :   }
    1004                 :            :   /* else, expression doesn't fit; leave it unchanged */
    1005                 :          0 :   return 0;
    1006                 :        500 : }
    1007                 :            : 
    1008                 :            : 
    1009                 :            : /*
    1010                 :            : ** Ensures final expression result is in a valid R/K index
    1011                 :            : ** (that is, it is either in a register or in 'k' with an index
    1012                 :            : ** in the range of R/K indices).
    1013                 :            : ** Returns 1 iff expression is K.
    1014                 :            : */
    1015                 :        500 : int luaK_exp2RK (FuncState *fs, expdesc *e) {
    1016         [ +  + ]:        500 :   if (luaK_exp2K(fs, e))
    1017                 :        203 :     return 1;
    1018                 :            :   else {  /* not a constant in the right range: put it in a register */
    1019                 :        297 :     luaK_exp2anyreg(fs, e);
    1020                 :        297 :     return 0;
    1021                 :            :   }
    1022                 :        500 : }
    1023                 :            : 
    1024                 :            : 
    1025                 :        158 : static void codeABRK (FuncState *fs, OpCode o, int a, int b,
    1026                 :            :                       expdesc *ec) {
    1027                 :        158 :   int k = luaK_exp2RK(fs, ec);
    1028                 :        158 :   luaK_codeABCk(fs, o, a, b, ec->u.info, k);
    1029                 :        158 : }
    1030                 :            : 
    1031                 :            : 
    1032                 :            : /*
    1033                 :            : ** Generate code to store result of expression 'ex' into variable 'var'.
    1034                 :            : */
    1035                 :        110 : void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) {
    1036   [ -  -  +  -  :        110 :   switch (var->k) {
                -  -  - ]
    1037                 :            :     case VLOCAL: {
    1038                 :          0 :       freeexp(fs, ex);
    1039                 :          0 :       exp2reg(fs, ex, var->u.var.sidx);  /* compute 'ex' into proper place */
    1040                 :          0 :       return;
    1041                 :            :     }
    1042                 :            :     case VUPVAL: {
    1043                 :          0 :       int e = luaK_exp2anyreg(fs, ex);
    1044                 :          0 :       luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0);
    1045                 :          0 :       break;
    1046                 :            :     }
    1047                 :            :     case VINDEXUP: {
    1048                 :        110 :       codeABRK(fs, OP_SETTABUP, var->u.ind.t, var->u.ind.idx, ex);
    1049                 :        110 :       break;
    1050                 :            :     }
    1051                 :            :     case VINDEXI: {
    1052                 :          0 :       codeABRK(fs, OP_SETI, var->u.ind.t, var->u.ind.idx, ex);
    1053                 :          0 :       break;
    1054                 :            :     }
    1055                 :            :     case VINDEXSTR: {
    1056                 :          0 :       codeABRK(fs, OP_SETFIELD, var->u.ind.t, var->u.ind.idx, ex);
    1057                 :          0 :       break;
    1058                 :            :     }
    1059                 :            :     case VINDEXED: {
    1060                 :          0 :       codeABRK(fs, OP_SETTABLE, var->u.ind.t, var->u.ind.idx, ex);
    1061                 :          0 :       break;
    1062                 :            :     }
    1063                 :            :     default: lua_assert(0);  /* invalid var kind to store */
    1064                 :          0 :   }
    1065                 :        110 :   freeexp(fs, ex);
    1066                 :        110 : }
    1067                 :            : 
    1068                 :            : 
    1069                 :            : /*
    1070                 :            : ** Emit SELF instruction (convert expression 'e' into 'e:key(e,').
    1071                 :            : */
    1072                 :         48 : void luaK_self (FuncState *fs, expdesc *e, expdesc *key) {
    1073                 :            :   int ereg;
    1074                 :         48 :   luaK_exp2anyreg(fs, e);
    1075                 :         48 :   ereg = e->u.info;  /* register where 'e' was placed */
    1076                 :         48 :   freeexp(fs, e);
    1077                 :         48 :   e->u.info = fs->freereg;  /* base register for op_self */
    1078                 :         48 :   e->k = VNONRELOC;  /* self expression has a fixed register */
    1079                 :         48 :   luaK_reserveregs(fs, 2);  /* function and 'self' produced by op_self */
    1080                 :         48 :   codeABRK(fs, OP_SELF, e->u.info, ereg, key);
    1081                 :         48 :   freeexp(fs, key);
    1082                 :         48 : }
    1083                 :            : 
    1084                 :            : 
    1085                 :            : /*
    1086                 :            : ** Negate condition 'e' (where 'e' is a comparison).
    1087                 :            : */
    1088                 :        187 : static void negatecondition (FuncState *fs, expdesc *e) {
    1089                 :        187 :   Instruction *pc = getjumpcontrol(fs, e->u.info);
    1090                 :            :   lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET &&
    1091                 :            :                                            GET_OPCODE(*pc) != OP_TEST);
    1092                 :        187 :   SETARG_k(*pc, (GETARG_k(*pc) ^ 1));
    1093                 :        187 : }
    1094                 :            : 
    1095                 :            : 
    1096                 :            : /*
    1097                 :            : ** Emit instruction to jump if 'e' is 'cond' (that is, if 'cond'
    1098                 :            : ** is true, code will jump if 'e' is true.) Return jump position.
    1099                 :            : ** Optimize when 'e' is 'not' something, inverting the condition
    1100                 :            : ** and removing the 'not'.
    1101                 :            : */
    1102                 :         16 : static int jumponcond (FuncState *fs, expdesc *e, int cond) {
    1103         [ -  + ]:         16 :   if (e->k == VRELOC) {
    1104                 :         16 :     Instruction ie = getinstruction(fs, e);
    1105         [ +  - ]:         16 :     if (GET_OPCODE(ie) == OP_NOT) {
    1106                 :         16 :       removelastinstruction(fs);  /* remove previous OP_NOT */
    1107                 :         16 :       return condjump(fs, OP_TEST, GETARG_B(ie), 0, 0, !cond);
    1108                 :            :     }
    1109                 :            :     /* else go through */
    1110                 :          0 :   }
    1111                 :          0 :   discharge2anyreg(fs, e);
    1112                 :          0 :   freeexp(fs, e);
    1113                 :          0 :   return condjump(fs, OP_TESTSET, NO_REG, e->u.info, 0, cond);
    1114                 :         16 : }
    1115                 :            : 
    1116                 :            : 
    1117                 :            : /*
    1118                 :            : ** Emit code to go through if 'e' is true, jump otherwise.
    1119                 :            : */
    1120                 :        203 : void luaK_goiftrue (FuncState *fs, expdesc *e) {
    1121                 :            :   int pc;  /* pc of new jump */
    1122                 :        203 :   luaK_dischargevars(fs, e);
    1123      [ +  +  - ]:        203 :   switch (e->k) {
    1124                 :            :     case VJMP: {  /* condition? */
    1125                 :        187 :       negatecondition(fs, e);  /* jump when it is false */
    1126                 :        187 :       pc = e->u.info;  /* save jump position */
    1127                 :        187 :       break;
    1128                 :            :     }
    1129                 :            :     case VK: case VKFLT: case VKINT: case VKSTR: case VTRUE: {
    1130                 :          0 :       pc = NO_JUMP;  /* always true; do nothing */
    1131                 :          0 :       break;
    1132                 :            :     }
    1133                 :            :     default: {
    1134                 :         16 :       pc = jumponcond(fs, e, 0);  /* jump when false */
    1135                 :         16 :       break;
    1136                 :            :     }
    1137                 :            :   }
    1138                 :        203 :   luaK_concat(fs, &e->f, pc);  /* insert new jump in false list */
    1139                 :        203 :   luaK_patchtohere(fs, e->t);  /* true list jumps to here (to go through) */
    1140                 :        203 :   e->t = NO_JUMP;
    1141                 :        203 : }
    1142                 :            : 
    1143                 :            : 
    1144                 :            : /*
    1145                 :            : ** Emit code to go through if 'e' is false, jump otherwise.
    1146                 :            : */
    1147                 :          0 : void luaK_goiffalse (FuncState *fs, expdesc *e) {
    1148                 :            :   int pc;  /* pc of new jump */
    1149                 :          0 :   luaK_dischargevars(fs, e);
    1150      [ #  #  # ]:          0 :   switch (e->k) {
    1151                 :            :     case VJMP: {
    1152                 :          0 :       pc = e->u.info;  /* already jump if true */
    1153                 :          0 :       break;
    1154                 :            :     }
    1155                 :            :     case VNIL: case VFALSE: {
    1156                 :          0 :       pc = NO_JUMP;  /* always false; do nothing */
    1157                 :          0 :       break;
    1158                 :            :     }
    1159                 :            :     default: {
    1160                 :          0 :       pc = jumponcond(fs, e, 1);  /* jump if true */
    1161                 :          0 :       break;
    1162                 :            :     }
    1163                 :            :   }
    1164                 :          0 :   luaK_concat(fs, &e->t, pc);  /* insert new jump in 't' list */
    1165                 :          0 :   luaK_patchtohere(fs, e->f);  /* false list jumps to here (to go through) */
    1166                 :          0 :   e->f = NO_JUMP;
    1167                 :          0 : }
    1168                 :            : 
    1169                 :            : 
    1170                 :            : /*
    1171                 :            : ** Code 'not e', doing constant folding.
    1172                 :            : */
    1173                 :         16 : static void codenot (FuncState *fs, expdesc *e) {
    1174   [ -  -  -  -  :         16 :   switch (e->k) {
                      + ]
    1175                 :            :     case VNIL: case VFALSE: {
    1176                 :          0 :       e->k = VTRUE;  /* true == not nil == not false */
    1177                 :          0 :       break;
    1178                 :            :     }
    1179                 :            :     case VK: case VKFLT: case VKINT: case VKSTR: case VTRUE: {
    1180                 :          0 :       e->k = VFALSE;  /* false == not "x" == not 0.5 == not 1 == not true */
    1181                 :          0 :       break;
    1182                 :            :     }
    1183                 :            :     case VJMP: {
    1184                 :          0 :       negatecondition(fs, e);
    1185                 :          0 :       break;
    1186                 :            :     }
    1187                 :            :     case VRELOC:
    1188                 :            :     case VNONRELOC: {
    1189                 :         16 :       discharge2anyreg(fs, e);
    1190                 :         16 :       freeexp(fs, e);
    1191                 :         16 :       e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0);
    1192                 :         16 :       e->k = VRELOC;
    1193                 :         16 :       break;
    1194                 :            :     }
    1195                 :            :     default: lua_assert(0);  /* cannot happen */
    1196                 :          0 :   }
    1197                 :            :   /* interchange true and false lists */
    1198                 :         16 :   { int temp = e->f; e->f = e->t; e->t = temp; }
    1199                 :         16 :   removevalues(fs, e->f);  /* values are useless when negated */
    1200                 :         16 :   removevalues(fs, e->t);
    1201                 :         16 : }
    1202                 :            : 
    1203                 :            : 
    1204                 :            : /*
    1205                 :            : ** Check whether expression 'e' is a small literal string
    1206                 :            : */
    1207                 :       2107 : static int isKstr (FuncState *fs, expdesc *e) {
    1208   [ +  +  +  -  :       4157 :   return (e->k == VK && !hasjumps(e) && e->u.info <= MAXARG_B &&
                   -  + ]
    1209                 :       2050 :           ttisshrstring(&fs->f->k[e->u.info]));
    1210                 :            : }
    1211                 :            : 
    1212                 :            : /*
    1213                 :            : ** Check whether expression 'e' is a literal integer.
    1214                 :            : */
    1215                 :         57 : int luaK_isKint (expdesc *e) {
    1216         [ +  + ]:         57 :   return (e->k == VKINT && !hasjumps(e));
    1217                 :            : }
    1218                 :            : 
    1219                 :            : 
    1220                 :            : /*
    1221                 :            : ** Check whether expression 'e' is a literal integer in
    1222                 :            : ** proper range to fit in register C
    1223                 :            : */
    1224                 :         57 : static int isCint (expdesc *e) {
    1225         [ +  + ]:         57 :   return luaK_isKint(e) && (l_castS2U(e->u.ival) <= l_castS2U(MAXARG_C));
    1226                 :            : }
    1227                 :            : 
    1228                 :            : 
    1229                 :            : /*
    1230                 :            : ** Check whether expression 'e' is a literal integer in
    1231                 :            : ** proper range to fit in register sC
    1232                 :            : */
    1233                 :          0 : static int isSCint (expdesc *e) {
    1234         [ #  # ]:          0 :   return luaK_isKint(e) && fitsC(e->u.ival);
    1235                 :            : }
    1236                 :            : 
    1237                 :            : 
    1238                 :            : /*
    1239                 :            : ** Check whether expression 'e' is a literal integer or float in
    1240                 :            : ** proper range to fit in a register (sB or sC).
    1241                 :            : */
    1242                 :        187 : static int isSCnumber (expdesc *e, int *pi, int *isfloat) {
    1243                 :            :   lua_Integer i;
    1244         [ +  + ]:        187 :   if (e->k == VKINT)
    1245                 :         32 :     i = e->u.ival;
    1246   [ -  +  #  # ]:        155 :   else if (e->k == VKFLT && luaV_flttointeger(e->u.nval, &i, F2Ieq))
    1247                 :          0 :     *isfloat = 1;
    1248                 :            :   else
    1249                 :        155 :     return 0;  /* not a number */
    1250   [ +  -  -  + ]:         32 :   if (!hasjumps(e) && fitsC(i)) {
    1251                 :         32 :     *pi = int2sC(cast_int(i));
    1252                 :         32 :     return 1;
    1253                 :            :   }
    1254                 :            :   else
    1255                 :          0 :     return 0;
    1256                 :        187 : }
    1257                 :            : 
    1258                 :            : 
    1259                 :            : /*
    1260                 :            : ** Create expression 't[k]'. 't' must have its final result already in a
    1261                 :            : ** register or upvalue. Upvalues can only be indexed by literal strings.
    1262                 :            : ** Keys can be literal strings in the constant table or arbitrary
    1263                 :            : ** values in registers.
    1264                 :            : */
    1265                 :       2107 : void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
    1266         [ +  + ]:       2107 :   if (k->k == VKSTR)
    1267                 :       2050 :     str2K(fs, k);
    1268                 :            :   lua_assert(!hasjumps(t) &&
    1269                 :            :              (t->k == VLOCAL || t->k == VNONRELOC || t->k == VUPVAL));
    1270   [ +  +  +  - ]:       2107 :   if (t->k == VUPVAL && !isKstr(fs, k))  /* upvalue indexed by non 'Kstr'? */
    1271                 :          0 :     luaK_exp2anyreg(fs, t);  /* put it in a register */
    1272         [ +  + ]:       2107 :   if (t->k == VUPVAL) {
    1273                 :       1327 :     t->u.ind.t = t->u.info;  /* upvalue index */
    1274                 :       1327 :     t->u.ind.idx = k->u.info;  /* literal string */
    1275                 :       1327 :     t->k = VINDEXUP;
    1276                 :       1327 :   }
    1277                 :            :   else {
    1278                 :            :     /* register index of the table */
    1279         [ -  + ]:        780 :     t->u.ind.t = (t->k == VLOCAL) ? t->u.var.sidx: t->u.info;
    1280         [ +  + ]:        780 :     if (isKstr(fs, k)) {
    1281                 :        723 :       t->u.ind.idx = k->u.info;  /* literal string */
    1282                 :        723 :       t->k = VINDEXSTR;
    1283                 :        723 :     }
    1284         [ +  + ]:         57 :     else if (isCint(k)) {
    1285                 :         48 :       t->u.ind.idx = cast_int(k->u.ival);  /* int. constant in proper range */
    1286                 :         48 :       t->k = VINDEXI;
    1287                 :         48 :     }
    1288                 :            :     else {
    1289                 :          9 :       t->u.ind.idx = luaK_exp2anyreg(fs, k);  /* register */
    1290                 :          9 :       t->k = VINDEXED;
    1291                 :            :     }
    1292                 :            :   }
    1293                 :       2107 : }
    1294                 :            : 
    1295                 :            : 
    1296                 :            : /*
    1297                 :            : ** Return false if folding can raise an error.
    1298                 :            : ** Bitwise operations need operands convertible to integers; division
    1299                 :            : ** operations cannot have 0 as divisor.
    1300                 :            : */
    1301                 :          0 : static int validop (int op, TValue *v1, TValue *v2) {
    1302      [ #  #  # ]:          0 :   switch (op) {
    1303                 :            :     case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
    1304                 :            :     case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: {  /* conversion errors */
    1305                 :            :       lua_Integer i;
    1306   [ #  #  #  #  :          0 :       return (tointegerns(v1, &i) && tointegerns(v2, &i));
                   #  # ]
    1307                 :            :     }
    1308                 :            :     case LUA_OPDIV: case LUA_OPIDIV: case LUA_OPMOD:  /* division by 0 */
    1309         [ #  # ]:          0 :       return (nvalue(v2) != 0);
    1310                 :          0 :     default: return 1;  /* everything else is valid */
    1311                 :            :   }
    1312                 :          0 : }
    1313                 :            : 
    1314                 :            : 
    1315                 :            : /*
    1316                 :            : ** Try to "constant-fold" an operation; return 1 iff successful.
    1317                 :            : ** (In this case, 'e1' has the final result.)
    1318                 :            : */
    1319                 :          0 : static int constfolding (FuncState *fs, int op, expdesc *e1,
    1320                 :            :                                         const expdesc *e2) {
    1321                 :            :   TValue v1, v2, res;
    1322   [ #  #  #  #  :          0 :   if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2))
                   #  # ]
    1323                 :          0 :     return 0;  /* non-numeric operands or not safe to fold */
    1324                 :          0 :   luaO_rawarith(fs->ls->L, op, &v1, &v2, &res);  /* does operation */
    1325         [ #  # ]:          0 :   if (ttisinteger(&res)) {
    1326                 :          0 :     e1->k = VKINT;
    1327                 :          0 :     e1->u.ival = ivalue(&res);
    1328                 :          0 :   }
    1329                 :            :   else {  /* folds neither NaN nor 0.0 (to avoid problems with -0.0) */
    1330                 :          0 :     lua_Number n = fltvalue(&res);
    1331   [ #  #  #  # ]:          0 :     if (luai_numisnan(n) || n == 0)
    1332                 :          0 :       return 0;
    1333                 :          0 :     e1->k = VKFLT;
    1334                 :          0 :     e1->u.nval = n;
    1335                 :            :   }
    1336                 :          0 :   return 1;
    1337                 :          0 : }
    1338                 :            : 
    1339                 :            : 
    1340                 :            : /*
    1341                 :            : ** Emit code for unary expressions that "produce values"
    1342                 :            : ** (everything but 'not').
    1343                 :            : ** Expression to produce final result will be encoded in 'e'.
    1344                 :            : */
    1345                 :        117 : static void codeunexpval (FuncState *fs, OpCode op, expdesc *e, int line) {
    1346                 :        117 :   int r = luaK_exp2anyreg(fs, e);  /* opcodes operate only on registers */
    1347                 :        117 :   freeexp(fs, e);
    1348                 :        117 :   e->u.info = luaK_codeABC(fs, op, 0, r, 0);  /* generate opcode */
    1349                 :        117 :   e->k = VRELOC;  /* all those operations are relocatable */
    1350                 :        117 :   luaK_fixline(fs, line);
    1351                 :        117 : }
    1352                 :            : 
    1353                 :            : 
    1354                 :            : /*
    1355                 :            : ** Emit code for binary expressions that "produce values"
    1356                 :            : ** (everything but logical operators 'and'/'or' and comparison
    1357                 :            : ** operators).
    1358                 :            : ** Expression to produce final result will be encoded in 'e1'.
    1359                 :            : */
    1360                 :          0 : static void finishbinexpval (FuncState *fs, expdesc *e1, expdesc *e2,
    1361                 :            :                              OpCode op, int v2, int flip, int line,
    1362                 :            :                              OpCode mmop, TMS event) {
    1363                 :          0 :   int v1 = luaK_exp2anyreg(fs, e1);
    1364                 :          0 :   int pc = luaK_codeABCk(fs, op, 0, v1, v2, 0);
    1365                 :          0 :   freeexps(fs, e1, e2);
    1366                 :          0 :   e1->u.info = pc;
    1367                 :          0 :   e1->k = VRELOC;  /* all those operations are relocatable */
    1368                 :          0 :   luaK_fixline(fs, line);
    1369                 :          0 :   luaK_codeABCk(fs, mmop, v1, v2, event, flip);  /* to call metamethod */
    1370                 :          0 :   luaK_fixline(fs, line);
    1371                 :          0 : }
    1372                 :            : 
    1373                 :            : 
    1374                 :            : /*
    1375                 :            : ** Emit code for binary expressions that "produce values" over
    1376                 :            : ** two registers.
    1377                 :            : */
    1378                 :          0 : static void codebinexpval (FuncState *fs, OpCode op,
    1379                 :            :                            expdesc *e1, expdesc *e2, int line) {
    1380                 :          0 :   int v2 = luaK_exp2anyreg(fs, e2);  /* both operands are in registers */
    1381                 :            :   lua_assert(OP_ADD <= op && op <= OP_SHR);
    1382                 :          0 :   finishbinexpval(fs, e1, e2, op, v2, 0, line, OP_MMBIN,
    1383                 :          0 :                   cast(TMS, (op - OP_ADD) + TM_ADD));
    1384                 :          0 : }
    1385                 :            : 
    1386                 :            : 
    1387                 :            : /*
    1388                 :            : ** Code binary operators with immediate operands.
    1389                 :            : */
    1390                 :          0 : static void codebini (FuncState *fs, OpCode op,
    1391                 :            :                        expdesc *e1, expdesc *e2, int flip, int line,
    1392                 :            :                        TMS event) {
    1393                 :          0 :   int v2 = int2sC(cast_int(e2->u.ival));  /* immediate operand */
    1394                 :            :   lua_assert(e2->k == VKINT);
    1395                 :          0 :   finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINI, event);
    1396                 :          0 : }
    1397                 :            : 
    1398                 :            : 
    1399                 :            : /* Try to code a binary operator negating its second operand.
    1400                 :            : ** For the metamethod, 2nd operand must keep its original value.
    1401                 :            : */
    1402                 :          0 : static int finishbinexpneg (FuncState *fs, expdesc *e1, expdesc *e2,
    1403                 :            :                              OpCode op, int line, TMS event) {
    1404         [ #  # ]:          0 :   if (!luaK_isKint(e2))
    1405                 :          0 :     return 0;  /* not an integer constant */
    1406                 :            :   else {
    1407                 :          0 :     lua_Integer i2 = e2->u.ival;
    1408   [ #  #  #  # ]:          0 :     if (!(fitsC(i2) && fitsC(-i2)))
    1409                 :          0 :       return 0;  /* not in the proper range */
    1410                 :            :     else {  /* operating a small integer constant */
    1411                 :          0 :       int v2 = cast_int(i2);
    1412                 :          0 :       finishbinexpval(fs, e1, e2, op, int2sC(-v2), 0, line, OP_MMBINI, event);
    1413                 :            :       /* correct metamethod argument */
    1414                 :          0 :       SETARG_B(fs->f->code[fs->pc - 1], int2sC(v2));
    1415                 :          0 :       return 1;  /* successfully coded */
    1416                 :            :     }
    1417                 :            :   }
    1418                 :          0 : }
    1419                 :            : 
    1420                 :            : 
    1421                 :          0 : static void swapexps (expdesc *e1, expdesc *e2) {
    1422                 :          0 :   expdesc temp = *e1; *e1 = *e2; *e2 = temp;  /* swap 'e1' and 'e2' */
    1423                 :          0 : }
    1424                 :            : 
    1425                 :            : 
    1426                 :            : /*
    1427                 :            : ** Code arithmetic operators ('+', '-', ...). If second operand is a
    1428                 :            : ** constant in the proper range, use variant opcodes with K operands.
    1429                 :            : */
    1430                 :          0 : static void codearith (FuncState *fs, BinOpr opr,
    1431                 :            :                        expdesc *e1, expdesc *e2, int flip, int line) {
    1432                 :          0 :   TMS event = cast(TMS, opr + TM_ADD);
    1433   [ #  #  #  # ]:          0 :   if (tonumeral(e2, NULL) && luaK_exp2K(fs, e2)) {  /* K operand? */
    1434                 :          0 :     int v2 = e2->u.info;  /* K index */
    1435                 :          0 :     OpCode op = cast(OpCode, opr + OP_ADDK);
    1436                 :          0 :     finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK, event);
    1437                 :          0 :   }
    1438                 :            :   else {  /* 'e2' is neither an immediate nor a K operand */
    1439                 :          0 :     OpCode op = cast(OpCode, opr + OP_ADD);
    1440         [ #  # ]:          0 :     if (flip)
    1441                 :          0 :       swapexps(e1, e2);  /* back to original order */
    1442                 :          0 :     codebinexpval(fs, op, e1, e2, line);  /* use standard operators */
    1443                 :            :   }
    1444                 :          0 : }
    1445                 :            : 
    1446                 :            : 
    1447                 :            : /*
    1448                 :            : ** Code commutative operators ('+', '*'). If first operand is a
    1449                 :            : ** numeric constant, change order of operands to try to use an
    1450                 :            : ** immediate or K operator.
    1451                 :            : */
    1452                 :          0 : static void codecommutative (FuncState *fs, BinOpr op,
    1453                 :            :                              expdesc *e1, expdesc *e2, int line) {
    1454                 :          0 :   int flip = 0;
    1455         [ #  # ]:          0 :   if (tonumeral(e1, NULL)) {  /* is first operand a numeric constant? */
    1456                 :          0 :     swapexps(e1, e2);  /* change order */
    1457                 :          0 :     flip = 1;
    1458                 :          0 :   }
    1459   [ #  #  #  # ]:          0 :   if (op == OPR_ADD && isSCint(e2))  /* immediate operand? */
    1460                 :          0 :     codebini(fs, cast(OpCode, OP_ADDI), e1, e2, flip, line, TM_ADD);
    1461                 :            :   else
    1462                 :          0 :     codearith(fs, op, e1, e2, flip, line);
    1463                 :          0 : }
    1464                 :            : 
    1465                 :            : 
    1466                 :            : /*
    1467                 :            : ** Code bitwise operations; they are all associative, so the function
    1468                 :            : ** tries to put an integer constant as the 2nd operand (a K operand).
    1469                 :            : */
    1470                 :          0 : static void codebitwise (FuncState *fs, BinOpr opr,
    1471                 :            :                          expdesc *e1, expdesc *e2, int line) {
    1472                 :          0 :   int flip = 0;
    1473                 :            :   int v2;
    1474                 :            :   OpCode op;
    1475   [ #  #  #  # ]:          0 :   if (e1->k == VKINT && luaK_exp2RK(fs, e1)) {
    1476                 :          0 :     swapexps(e1, e2);  /* 'e2' will be the constant operand */
    1477                 :          0 :     flip = 1;
    1478                 :          0 :   }
    1479   [ #  #  #  # ]:          0 :   else if (!(e2->k == VKINT && luaK_exp2RK(fs, e2))) {  /* no constants? */
    1480                 :          0 :     op = cast(OpCode, opr + OP_ADD);
    1481                 :          0 :     codebinexpval(fs, op, e1, e2, line);  /* all-register opcodes */
    1482                 :          0 :     return;
    1483                 :            :   }
    1484                 :          0 :   v2 = e2->u.info;  /* index in K array */
    1485                 :          0 :   op = cast(OpCode, opr + OP_ADDK);
    1486                 :            :   lua_assert(ttisinteger(&fs->f->k[v2]));
    1487                 :          0 :   finishbinexpval(fs, e1, e2, op, v2, flip, line, OP_MMBINK,
    1488                 :          0 :                   cast(TMS, opr + TM_ADD));
    1489                 :          0 : }
    1490                 :            : 
    1491                 :            : 
    1492                 :            : /*
    1493                 :            : ** Emit code for order comparisons. When using an immediate operand,
    1494                 :            : ** 'isfloat' tells whether the original value was a float.
    1495                 :            : */
    1496                 :          0 : static void codeorder (FuncState *fs, OpCode op, expdesc *e1, expdesc *e2) {
    1497                 :            :   int r1, r2;
    1498                 :            :   int im;
    1499                 :          0 :   int isfloat = 0;
    1500         [ #  # ]:          0 :   if (isSCnumber(e2, &im, &isfloat)) {
    1501                 :            :     /* use immediate operand */
    1502                 :          0 :     r1 = luaK_exp2anyreg(fs, e1);
    1503                 :          0 :     r2 = im;
    1504                 :          0 :     op = cast(OpCode, (op - OP_LT) + OP_LTI);
    1505                 :          0 :   }
    1506         [ #  # ]:          0 :   else if (isSCnumber(e1, &im, &isfloat)) {
    1507                 :            :     /* transform (A < B) to (B > A) and (A <= B) to (B >= A) */
    1508                 :          0 :     r1 = luaK_exp2anyreg(fs, e2);
    1509                 :          0 :     r2 = im;
    1510                 :          0 :     op = (op == OP_LT) ? OP_GTI : OP_GEI;
    1511                 :          0 :   }
    1512                 :            :   else {  /* regular case, compare two registers */
    1513                 :          0 :     r1 = luaK_exp2anyreg(fs, e1);
    1514                 :          0 :     r2 = luaK_exp2anyreg(fs, e2);
    1515                 :            :   }
    1516                 :          0 :   freeexps(fs, e1, e2);
    1517                 :          0 :   e1->u.info = condjump(fs, op, r1, r2, isfloat, 1);
    1518                 :          0 :   e1->k = VJMP;
    1519                 :          0 : }
    1520                 :            : 
    1521                 :            : 
    1522                 :            : /*
    1523                 :            : ** Emit code for equality comparisons ('==', '~=').
    1524                 :            : ** 'e1' was already put as RK by 'luaK_infix'.
    1525                 :            : */
    1526                 :        187 : static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
    1527                 :            :   int r1, r2;
    1528                 :            :   int im;
    1529                 :        187 :   int isfloat = 0;  /* not needed here, but kept for symmetry */
    1530                 :            :   OpCode op;
    1531         [ +  - ]:        187 :   if (e1->k != VNONRELOC) {
    1532                 :            :     lua_assert(e1->k == VK || e1->k == VKINT || e1->k == VKFLT);
    1533                 :          0 :     swapexps(e1, e2);
    1534                 :          0 :   }
    1535                 :        187 :   r1 = luaK_exp2anyreg(fs, e1);  /* 1st expression must be in register */
    1536         [ +  + ]:        187 :   if (isSCnumber(e2, &im, &isfloat)) {
    1537                 :         32 :     op = OP_EQI;
    1538                 :         32 :     r2 = im;  /* immediate operand */
    1539                 :         32 :   }
    1540         [ +  + ]:        155 :   else if (luaK_exp2RK(fs, e2)) {  /* 1st expression is constant? */
    1541                 :        139 :     op = OP_EQK;
    1542                 :        139 :     r2 = e2->u.info;  /* constant index */
    1543                 :        139 :   }
    1544                 :            :   else {
    1545                 :         16 :     op = OP_EQ;  /* will compare two registers */
    1546                 :         16 :     r2 = luaK_exp2anyreg(fs, e2);
    1547                 :            :   }
    1548                 :        187 :   freeexps(fs, e1, e2);
    1549                 :        187 :   e1->u.info = condjump(fs, op, r1, r2, isfloat, (opr == OPR_EQ));
    1550                 :        187 :   e1->k = VJMP;
    1551                 :        187 : }
    1552                 :            : 
    1553                 :            : 
    1554                 :            : /*
    1555                 :            : ** Apply prefix operation 'op' to expression 'e'.
    1556                 :            : */
    1557                 :        133 : void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
    1558                 :            :   static const expdesc ef = {VKINT, {0}, NO_JUMP, NO_JUMP};
    1559                 :        133 :   luaK_dischargevars(fs, e);
    1560   [ -  +  -  + ]:        133 :   switch (op) {
    1561                 :            :     case OPR_MINUS: case OPR_BNOT:  /* use 'ef' as fake 2nd operand */
    1562         [ #  # ]:          0 :       if (constfolding(fs, op + LUA_OPUNM, e, &ef))
    1563                 :          0 :         break;
    1564                 :            :       /* else */ /* FALLTHROUGH */
    1565                 :            :     case OPR_LEN:
    1566                 :        117 :       codeunexpval(fs, cast(OpCode, op + OP_UNM), e, line);
    1567                 :        117 :       break;
    1568                 :         16 :     case OPR_NOT: codenot(fs, e); break;
    1569                 :            :     default: lua_assert(0);
    1570                 :          0 :   }
    1571                 :        133 : }
    1572                 :            : 
    1573                 :            : 
    1574                 :            : /*
    1575                 :            : ** Process 1st operand 'v' of binary operation 'op' before reading
    1576                 :            : ** 2nd operand.
    1577                 :            : */
    1578                 :        235 : void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
    1579                 :        235 :   luaK_dischargevars(fs, v);
    1580   [ -  -  +  -  :        235 :   switch (op) {
                -  -  + ]
    1581                 :            :     case OPR_AND: {
    1582                 :          0 :       luaK_goiftrue(fs, v);  /* go ahead only if 'v' is true */
    1583                 :          0 :       break;
    1584                 :            :     }
    1585                 :            :     case OPR_OR: {
    1586                 :          0 :       luaK_goiffalse(fs, v);  /* go ahead only if 'v' is false */
    1587                 :          0 :       break;
    1588                 :            :     }
    1589                 :            :     case OPR_CONCAT: {
    1590                 :         48 :       luaK_exp2nextreg(fs, v);  /* operand must be on the stack */
    1591                 :         48 :       break;
    1592                 :            :     }
    1593                 :            :     case OPR_ADD: case OPR_SUB:
    1594                 :            :     case OPR_MUL: case OPR_DIV: case OPR_IDIV:
    1595                 :            :     case OPR_MOD: case OPR_POW:
    1596                 :            :     case OPR_BAND: case OPR_BOR: case OPR_BXOR:
    1597                 :            :     case OPR_SHL: case OPR_SHR: {
    1598         [ #  # ]:          0 :       if (!tonumeral(v, NULL))
    1599                 :          0 :         luaK_exp2anyreg(fs, v);
    1600                 :            :       /* else keep numeral, which may be folded with 2nd operand */
    1601                 :          0 :       break;
    1602                 :            :     }
    1603                 :            :     case OPR_EQ: case OPR_NE: {
    1604         [ +  - ]:        187 :       if (!tonumeral(v, NULL))
    1605                 :        187 :         luaK_exp2RK(fs, v);
    1606                 :            :       /* else keep numeral, which may be an immediate operand */
    1607                 :        187 :       break;
    1608                 :            :     }
    1609                 :            :     case OPR_LT: case OPR_LE:
    1610                 :            :     case OPR_GT: case OPR_GE: {
    1611                 :            :       int dummy, dummy2;
    1612         [ #  # ]:          0 :       if (!isSCnumber(v, &dummy, &dummy2))
    1613                 :          0 :         luaK_exp2anyreg(fs, v);
    1614                 :            :       /* else keep numeral, which may be an immediate operand */
    1615                 :          0 :       break;
    1616                 :            :     }
    1617                 :            :     default: lua_assert(0);
    1618                 :          0 :   }
    1619                 :        235 : }
    1620                 :            : 
    1621                 :            : /*
    1622                 :            : ** Create code for '(e1 .. e2)'.
    1623                 :            : ** For '(e1 .. e2.1 .. e2.2)' (which is '(e1 .. (e2.1 .. e2.2))',
    1624                 :            : ** because concatenation is right associative), merge both CONCATs.
    1625                 :            : */
    1626                 :         48 : static void codeconcat (FuncState *fs, expdesc *e1, expdesc *e2, int line) {
    1627                 :         48 :   Instruction *ie2 = previousinstruction(fs);
    1628         [ +  + ]:         48 :   if (GET_OPCODE(*ie2) == OP_CONCAT) {  /* is 'e2' a concatenation? */
    1629                 :         16 :     int n = GETARG_B(*ie2);  /* # of elements concatenated in 'e2' */
    1630                 :            :     lua_assert(e1->u.info + 1 == GETARG_A(*ie2));
    1631                 :         16 :     freeexp(fs, e2);
    1632                 :         16 :     SETARG_A(*ie2, e1->u.info);  /* correct first element ('e1') */
    1633                 :         16 :     SETARG_B(*ie2, n + 1);  /* will concatenate one more element */
    1634                 :         16 :   }
    1635                 :            :   else {  /* 'e2' is not a concatenation */
    1636                 :         32 :     luaK_codeABC(fs, OP_CONCAT, e1->u.info, 2, 0);  /* new concat opcode */
    1637                 :         32 :     freeexp(fs, e2);
    1638                 :         32 :     luaK_fixline(fs, line);
    1639                 :            :   }
    1640                 :         48 : }
    1641                 :            : 
    1642                 :            : 
    1643                 :            : /*
    1644                 :            : ** Finalize code for binary operation, after reading 2nd operand.
    1645                 :            : */
    1646                 :        235 : void luaK_posfix (FuncState *fs, BinOpr opr,
    1647                 :            :                   expdesc *e1, expdesc *e2, int line) {
    1648                 :        235 :   luaK_dischargevars(fs, e2);
    1649   [ -  +  #  # ]:        235 :   if (foldbinop(opr) && constfolding(fs, opr + LUA_OPADD, e1, e2))
    1650                 :          0 :     return;  /* done by folding */
    1651   [ -  -  -  +  :        235 :   switch (opr) {
          -  -  -  -  -  
             +  -  -  - ]
    1652                 :            :     case OPR_AND: {
    1653                 :            :       lua_assert(e1->t == NO_JUMP);  /* list closed by 'luaK_infix' */
    1654                 :          0 :       luaK_concat(fs, &e2->f, e1->f);
    1655                 :          0 :       *e1 = *e2;
    1656                 :          0 :       break;
    1657                 :            :     }
    1658                 :            :     case OPR_OR: {
    1659                 :            :       lua_assert(e1->f == NO_JUMP);  /* list closed by 'luaK_infix' */
    1660                 :          0 :       luaK_concat(fs, &e2->t, e1->t);
    1661                 :          0 :       *e1 = *e2;
    1662                 :          0 :       break;
    1663                 :            :     }
    1664                 :            :     case OPR_CONCAT: {  /* e1 .. e2 */
    1665                 :         48 :       luaK_exp2nextreg(fs, e2);
    1666                 :         48 :       codeconcat(fs, e1, e2, line);
    1667                 :         48 :       break;
    1668                 :            :     }
    1669                 :            :     case OPR_ADD: case OPR_MUL: {
    1670                 :          0 :       codecommutative(fs, opr, e1, e2, line);
    1671                 :          0 :       break;
    1672                 :            :     }
    1673                 :            :     case OPR_SUB: {
    1674         [ #  # ]:          0 :       if (finishbinexpneg(fs, e1, e2, OP_ADDI, line, TM_SUB))
    1675                 :          0 :         break; /* coded as (r1 + -I) */
    1676                 :            :       /* ELSE */
    1677                 :          0 :     }  /* FALLTHROUGH */
    1678                 :            :     case OPR_DIV: case OPR_IDIV: case OPR_MOD: case OPR_POW: {
    1679                 :          0 :       codearith(fs, opr, e1, e2, 0, line);
    1680                 :          0 :       break;
    1681                 :            :     }
    1682                 :            :     case OPR_BAND: case OPR_BOR: case OPR_BXOR: {
    1683                 :          0 :       codebitwise(fs, opr, e1, e2, line);
    1684                 :          0 :       break;
    1685                 :            :     }
    1686                 :            :     case OPR_SHL: {
    1687         [ #  # ]:          0 :       if (isSCint(e1)) {
    1688                 :          0 :         swapexps(e1, e2);
    1689                 :          0 :         codebini(fs, OP_SHLI, e1, e2, 1, line, TM_SHL);  /* I << r2 */
    1690                 :          0 :       }
    1691         [ #  # ]:          0 :       else if (finishbinexpneg(fs, e1, e2, OP_SHRI, line, TM_SHL)) {
    1692                 :            :         /* coded as (r1 >> -I) */;
    1693                 :          0 :       }
    1694                 :            :       else  /* regular case (two registers) */
    1695                 :          0 :        codebinexpval(fs, OP_SHL, e1, e2, line);
    1696                 :          0 :       break;
    1697                 :            :     }
    1698                 :            :     case OPR_SHR: {
    1699         [ #  # ]:          0 :       if (isSCint(e2))
    1700                 :          0 :         codebini(fs, OP_SHRI, e1, e2, 0, line, TM_SHR);  /* r1 >> I */
    1701                 :            :       else  /* regular case (two registers) */
    1702                 :          0 :         codebinexpval(fs, OP_SHR, e1, e2, line);
    1703                 :          0 :       break;
    1704                 :            :     }
    1705                 :            :     case OPR_EQ: case OPR_NE: {
    1706                 :        187 :       codeeq(fs, opr, e1, e2);
    1707                 :        187 :       break;
    1708                 :            :     }
    1709                 :            :     case OPR_LT: case OPR_LE: {
    1710                 :          0 :       OpCode op = cast(OpCode, (opr - OPR_EQ) + OP_EQ);
    1711                 :          0 :       codeorder(fs, op, e1, e2);
    1712                 :          0 :       break;
    1713                 :            :     }
    1714                 :            :     case OPR_GT: case OPR_GE: {
    1715                 :            :       /* '(a > b)' <=> '(b < a)';  '(a >= b)' <=> '(b <= a)' */
    1716                 :          0 :       OpCode op = cast(OpCode, (opr - OPR_NE) + OP_EQ);
    1717                 :          0 :       swapexps(e1, e2);
    1718                 :          0 :       codeorder(fs, op, e1, e2);
    1719                 :          0 :       break;
    1720                 :            :     }
    1721                 :            :     default: lua_assert(0);
    1722                 :          0 :   }
    1723                 :        235 : }
    1724                 :            : 
    1725                 :            : 
    1726                 :            : /*
    1727                 :            : ** Change line information associated with current position, by removing
    1728                 :            : ** previous info and adding it again with new line.
    1729                 :            : */
    1730                 :       1086 : void luaK_fixline (FuncState *fs, int line) {
    1731                 :       1086 :   removelastlineinfo(fs);
    1732                 :       1086 :   savelineinfo(fs, fs->f, line);
    1733                 :       1086 : }
    1734                 :            : 
    1735                 :            : 
    1736                 :          9 : void luaK_settablesize (FuncState *fs, int pc, int ra, int asize, int hsize) {
    1737                 :          9 :   Instruction *inst = &fs->f->code[pc];
    1738         [ -  + ]:          9 :   int rb = (hsize != 0) ? luaO_ceillog2(hsize) + 1 : 0;  /* hash size */
    1739                 :          9 :   int extra = asize / (MAXARG_C + 1);  /* higher bits of array size */
    1740                 :          9 :   int rc = asize % (MAXARG_C + 1);  /* lower bits of array size */
    1741                 :          9 :   int k = (extra > 0);  /* true iff needs extra argument */
    1742                 :          9 :   *inst = CREATE_ABCk(OP_NEWTABLE, ra, rb, rc, k);
    1743                 :          9 :   *(inst + 1) = CREATE_Ax(OP_EXTRAARG, extra);
    1744                 :          9 : }
    1745                 :            : 
    1746                 :            : 
    1747                 :            : /*
    1748                 :            : ** Emit a SETLIST instruction.
    1749                 :            : ** 'base' is register that keeps table;
    1750                 :            : ** 'nelems' is #table plus those to be stored now;
    1751                 :            : ** 'tostore' is number of values (in registers 'base + 1',...) to add to
    1752                 :            : ** table (or LUA_MULTRET to add up to stack top).
    1753                 :            : */
    1754                 :          9 : void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) {
    1755                 :            :   lua_assert(tostore != 0 && tostore <= LFIELDS_PER_FLUSH);
    1756         [ -  + ]:          9 :   if (tostore == LUA_MULTRET)
    1757                 :          0 :     tostore = 0;
    1758         [ +  - ]:          9 :   if (nelems <= MAXARG_C)
    1759                 :          9 :     luaK_codeABC(fs, OP_SETLIST, base, tostore, nelems);
    1760                 :            :   else {
    1761                 :          0 :     int extra = nelems / (MAXARG_C + 1);
    1762                 :          0 :     nelems %= (MAXARG_C + 1);
    1763                 :          0 :     luaK_codeABCk(fs, OP_SETLIST, base, tostore, nelems, 1);
    1764                 :          0 :     codeextraarg(fs, extra);
    1765                 :            :   }
    1766                 :          9 :   fs->freereg = base + 1;  /* free registers with list values */
    1767                 :          9 : }
    1768                 :            : 
    1769                 :            : 
    1770                 :            : /*
    1771                 :            : ** return the final target of a jump (skipping jumps to jumps)
    1772                 :            : */
    1773                 :        203 : static int finaltarget (Instruction *code, int i) {
    1774                 :            :   int count;
    1775         [ -  + ]:        406 :   for (count = 0; count < 100; count++) {  /* avoid infinite loops */
    1776                 :        406 :     Instruction pc = code[i];
    1777         [ +  + ]:        406 :     if (GET_OPCODE(pc) != OP_JMP)
    1778                 :        203 :       break;
    1779                 :            :      else
    1780                 :        203 :        i += GETARG_sJ(pc) + 1;
    1781                 :        203 :   }
    1782                 :        203 :   return i;
    1783                 :            : }
    1784                 :            : 
    1785                 :            : 
    1786                 :            : /*
    1787                 :            : ** Do a final pass over the code of a function, doing small peephole
    1788                 :            : ** optimizations and adjustments.
    1789                 :            : */
    1790                 :        652 : void luaK_finish (FuncState *fs) {
    1791                 :            :   int i;
    1792                 :        652 :   Proto *p = fs->f;
    1793         [ +  + ]:       6864 :   for (i = 0; i < fs->pc; i++) {
    1794                 :       6212 :     Instruction *pc = &p->code[i];
    1795                 :            :     lua_assert(i == 0 || isOT(*(pc - 1)) == isIT(*pc));
    1796   [ +  +  +  + ]:       6212 :     switch (GET_OPCODE(*pc)) {
    1797                 :            :       case OP_RETURN0: case OP_RETURN1: {
    1798   [ +  -  +  - ]:        742 :         if (!(fs->needclose || p->is_vararg))
    1799                 :          0 :           break;  /* no extra work */
    1800                 :            :         /* else use OP_RETURN to do the extra work */
    1801                 :        742 :         SET_OPCODE(*pc, OP_RETURN);
    1802                 :        742 :       }  /* FALLTHROUGH */
    1803                 :            :       case OP_RETURN: case OP_TAILCALL: {
    1804         [ -  + ]:        898 :         if (fs->needclose)
    1805                 :          0 :           SETARG_k(*pc, 1);  /* signal that it needs to close */
    1806         [ +  - ]:        898 :         if (p->is_vararg)
    1807                 :        898 :           SETARG_C(*pc, p->numparams + 1);  /* signal that it is vararg */
    1808                 :        898 :         break;
    1809                 :            :       }
    1810                 :            :       case OP_JMP: {
    1811                 :        203 :         int target = finaltarget(p->code, i);
    1812                 :        203 :         fixjump(fs, i, target);
    1813                 :        203 :         break;
    1814                 :            :       }
    1815                 :       5111 :       default: break;
    1816                 :            :     }
    1817                 :       6212 :   }
    1818                 :        652 : }

Generated by: LCOV version 1.15