LCOV - code coverage report
Current view: top level - src - lcode.c Coverage Total Hit
Test: Lua 5.1.5 Lines: 97.1 % 511 496
Test Date: 2024-04-28 10:23:09
Legend: Lines: hit not hit

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

Generated by: LCOV version 2.0-1