LCOV - code coverage report
Current view: top level - src - lvm.c Coverage Total Hit
Test: Lua 5.1.5 Lines: 96.4 % 476 459
Test Date: 2024-04-28 10:23:09
Legend: Lines: hit not hit

            Line data    Source code
       1              : /*
       2              : ** $Id: lvm.c,v 2.63.1.5 2011/08/17 20:43:11 roberto Exp $
       3              : ** Lua virtual machine
       4              : ** See Copyright Notice in lua.h
       5              : */
       6              : 
       7              : 
       8              : #include <stdio.h>
       9              : #include <stdlib.h>
      10              : #include <string.h>
      11              : 
      12              : #define lvm_c
      13              : #define LUA_CORE
      14              : 
      15              : #include "lua.h"
      16              : 
      17              : #include "ldebug.h"
      18              : #include "ldo.h"
      19              : #include "lfunc.h"
      20              : #include "lgc.h"
      21              : #include "lobject.h"
      22              : #include "lopcodes.h"
      23              : #include "lstate.h"
      24              : #include "lstring.h"
      25              : #include "ltable.h"
      26              : #include "ltm.h"
      27              : #include "lvm.h"
      28              : 
      29              : 
      30              : 
      31              : /* limit for table tag-method chains (to avoid loops) */
      32              : #define MAXTAGLOOP      100
      33              : 
      34              : 
      35          322 : const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
      36              :   lua_Number num;
      37          322 :   if (ttisnumber(obj)) return obj;
      38          275 :   if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
      39           87 :     setnvalue(n, num);
      40           87 :     return n;
      41              :   }
      42              :   else
      43          188 :     return NULL;
      44              : }
      45              : 
      46              : 
      47         2202 : int luaV_tostring (lua_State *L, StkId obj) {
      48         2202 :   if (!ttisnumber(obj))
      49           12 :     return 0;
      50              :   else {
      51              :     char s[LUAI_MAXNUMBER2STR];
      52         2190 :     lua_Number n = nvalue(obj);
      53         2190 :     lua_number2str(s, n);
      54         2190 :     setsvalue2s(L, obj, luaS_new(L, s));
      55         2190 :     return 1;
      56              :   }
      57              : }
      58              : 
      59              : 
      60           34 : static void traceexec (lua_State *L, const Instruction *pc) {
      61           34 :   lu_byte mask = L->hookmask;
      62           34 :   const Instruction *oldpc = L->savedpc;
      63           34 :   L->savedpc = pc;
      64           34 :   if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) {
      65           34 :     resethookcount(L);
      66           34 :     luaD_callhook(L, LUA_HOOKCOUNT, -1);
      67              :   }
      68           34 :   if (mask & LUA_MASKLINE) {
      69            0 :     Proto *p = ci_func(L->ci)->l.p;
      70            0 :     int npc = pcRel(pc, p);
      71            0 :     int newline = getline(p, npc);
      72              :     /* call linehook when enter a new function, when jump back (loop),
      73              :        or when enter a new line */
      74            0 :     if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p)))
      75            0 :       luaD_callhook(L, LUA_HOOKLINE, newline);
      76              :   }
      77           34 : }
      78              : 
      79              : 
      80           44 : static void callTMres (lua_State *L, StkId res, const TValue *f,
      81              :                         const TValue *p1, const TValue *p2) {
      82           44 :   ptrdiff_t result = savestack(L, res);
      83           44 :   setobj2s(L, L->top, f);  /* push function */
      84           44 :   setobj2s(L, L->top+1, p1);  /* 1st argument */
      85           44 :   setobj2s(L, L->top+2, p2);  /* 2nd argument */
      86           44 :   luaD_checkstack(L, 3);
      87           44 :   L->top += 3;
      88           44 :   luaD_call(L, L->top - 3, 1);
      89           44 :   res = restorestack(L, result);
      90           44 :   L->top--;
      91           44 :   setobjs2s(L, res, L->top);
      92           44 : }
      93              : 
      94              : 
      95              : 
      96            4 : static void callTM (lua_State *L, const TValue *f, const TValue *p1,
      97              :                     const TValue *p2, const TValue *p3) {
      98            4 :   setobj2s(L, L->top, f);  /* push function */
      99            4 :   setobj2s(L, L->top+1, p1);  /* 1st argument */
     100            4 :   setobj2s(L, L->top+2, p2);  /* 2nd argument */
     101            4 :   setobj2s(L, L->top+3, p3);  /* 3th argument */
     102            4 :   luaD_checkstack(L, 4);
     103            4 :   L->top += 4;
     104            4 :   luaD_call(L, L->top - 4, 0);
     105            2 : }
     106              : 
     107              : 
     108       133884 : void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
     109              :   int loop;
     110       141022 :   for (loop = 0; loop < MAXTAGLOOP; loop++) {
     111              :     const TValue *tm;
     112       141022 :     if (ttistable(t)) {  /* `t' is a table? */
     113       133917 :       Table *h = hvalue(t);
     114       133917 :       const TValue *res = luaH_get(h, key); /* do a primitive get */
     115       133917 :       if (!ttisnil(res) ||  /* result is no nil? */
     116         1672 :           (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
     117       133865 :         setobj2s(L, val, res);
     118       133865 :         return;
     119              :       }
     120              :       /* else will try the tag method */
     121              :     }
     122         7105 :     else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
     123            7 :       luaG_typeerror(L, t, "index");
     124         7150 :     if (ttisfunction(tm)) {
     125           12 :       callTMres(L, val, tm, t, key);
     126           12 :       return;
     127              :     }
     128         7138 :     t = tm;  /* else repeat with `tm' */ 
     129              :   }
     130            0 :   luaG_runerror(L, "loop in gettable");
     131              : }
     132              : 
     133              : 
     134        99216 : void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
     135              :   int loop;
     136              :   TValue temp;
     137        99217 :   for (loop = 0; loop < MAXTAGLOOP; loop++) {
     138              :     const TValue *tm;
     139        99217 :     if (ttistable(t)) {  /* `t' is a table? */
     140        99209 :       Table *h = hvalue(t);
     141        99209 :       TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
     142        99207 :       if (!ttisnil(oldval) ||  /* result is no nil? */
     143        58190 :           (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
     144        99202 :         setobj2t(L, oldval, val);
     145        99202 :         h->flags = 0;
     146        99202 :         luaC_barriert(L, h, val);
     147        99204 :         return;
     148              :       }
     149              :       /* else will try the tag method */
     150              :     }
     151            8 :     else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
     152            8 :       luaG_typeerror(L, t, "index");
     153            5 :     if (ttisfunction(tm)) {
     154            4 :       callTM(L, tm, t, key, val);
     155            2 :       return;
     156              :     }
     157              :     /* else repeat with `tm' */
     158            1 :     setobj(L, &temp, tm);  /* avoid pointing inside table (may rehash) */
     159            1 :     t = &temp;
     160              :   }
     161            0 :   luaG_runerror(L, "loop in settable");
     162              : }
     163              : 
     164              : 
     165          117 : static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
     166              :                        StkId res, TMS event) {
     167          117 :   const TValue *tm = luaT_gettmbyobj(L, p1, event);  /* try first operand */
     168          117 :   if (ttisnil(tm))
     169          101 :     tm = luaT_gettmbyobj(L, p2, event);  /* try second operand */
     170          117 :   if (ttisnil(tm)) return 0;
     171           24 :   callTMres(L, res, tm, p1, p2);
     172           24 :   return 1;
     173              : }
     174              : 
     175              : 
     176            7 : static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2,
     177              :                                   TMS event) {
     178            7 :   const TValue *tm1 = fasttm(L, mt1, event);
     179              :   const TValue *tm2;
     180            7 :   if (tm1 == NULL) return NULL;  /* no metamethod */
     181            2 :   if (mt1 == mt2) return tm1;  /* same metatables => same metamethods */
     182            0 :   tm2 = fasttm(L, mt2, event);
     183            0 :   if (tm2 == NULL) return NULL;  /* no metamethod */
     184            0 :   if (luaO_rawequalObj(tm1, tm2))  /* same metamethods? */
     185            0 :     return tm1;
     186            0 :   return NULL;
     187              : }
     188              : 
     189              : 
     190           48 : static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
     191              :                          TMS event) {
     192           48 :   const TValue *tm1 = luaT_gettmbyobj(L, p1, event);
     193              :   const TValue *tm2;
     194           48 :   if (ttisnil(tm1)) return -1;  /* no metamethod? */
     195            6 :   tm2 = luaT_gettmbyobj(L, p2, event);
     196            6 :   if (!luaO_rawequalObj(tm1, tm2))  /* different metamethods? */
     197            0 :     return -1;
     198            6 :   callTMres(L, L->top, tm1, p1, p2);
     199            6 :   return !l_isfalse(L->top);
     200              : }
     201              : 
     202              : 
     203        91706 : static int l_strcmp (const TString *ls, const TString *rs) {
     204        91706 :   const char *l = getstr(ls);
     205        91706 :   size_t ll = ls->tsv.len;
     206        91706 :   const char *r = getstr(rs);
     207        91706 :   size_t lr = rs->tsv.len;
     208            1 :   for (;;) {
     209        91707 :     int temp = strcoll(l, r);
     210        91707 :     if (temp != 0) return temp;
     211              :     else {  /* strings are equal up to a `\0' */
     212         2642 :       size_t len = strlen(l);  /* index of first `\0' in both strings */
     213         2642 :       if (len == lr)  /* r is finished? */
     214         2640 :         return (len == ll) ? 0 : 1;
     215            2 :       else if (len == ll)  /* l is finished? */
     216            1 :         return -1;  /* l is smaller than r (because r is not finished) */
     217              :       /* both strings longer than `len'; go on comparing (after the `\0') */
     218            1 :       len++;
     219            1 :       l += len; ll -= len; r += len; lr -= len;
     220              :     }
     221              :   }
     222              : }
     223              : 
     224              : 
     225        91721 : int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
     226              :   int res;
     227        91721 :   if (ttype(l) != ttype(r))
     228           28 :     return luaG_ordererror(L, l, r);
     229        91693 :   else if (ttisnumber(l))
     230           54 :     return luai_numlt(nvalue(l), nvalue(r));
     231        91639 :   else if (ttisstring(l))
     232        91620 :     return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
     233           19 :   else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
     234            4 :     return res;
     235           15 :   return luaG_ordererror(L, l, r);
     236              : }
     237              : 
     238              : 
     239        11456 : static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
     240              :   int res;
     241        11456 :   if (ttype(l) != ttype(r))
     242           18 :     return luaG_ordererror(L, l, r);
     243        11438 :   else if (ttisnumber(l))
     244        11337 :     return luai_numle(nvalue(l), nvalue(r));
     245          101 :   else if (ttisstring(l))
     246           86 :     return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
     247           15 :   else if ((res = call_orderTM(L, l, r, TM_LE)) != -1)  /* first try `le' */
     248            1 :     return res;
     249           14 :   else if ((res = call_orderTM(L, r, l, TM_LT)) != -1)  /* else try `lt' */
     250            1 :     return !res;
     251           13 :   return luaG_ordererror(L, l, r);
     252              : }
     253              : 
     254              : 
     255        25160 : int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
     256              :   const TValue *tm;
     257              :   lua_assert(ttype(t1) == ttype(t2));
     258        25160 :   switch (ttype(t1)) {
     259          153 :     case LUA_TNIL: return 1;
     260          877 :     case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
     261          145 :     case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2);  /* true must be 1 !! */
     262            0 :     case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
     263            8 :     case LUA_TUSERDATA: {
     264            8 :       if (uvalue(t1) == uvalue(t2)) return 1;
     265            1 :       tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable,
     266              :                          TM_EQ);
     267            1 :       break;  /* will try TM */
     268              :     }
     269           44 :     case LUA_TTABLE: {
     270           44 :       if (hvalue(t1) == hvalue(t2)) return 1;
     271            6 :       tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
     272            6 :       break;  /* will try TM */
     273              :     }
     274        23933 :     default: return gcvalue(t1) == gcvalue(t2);
     275              :   }
     276            7 :   if (tm == NULL) return 0;  /* no TM? */
     277            2 :   callTMres(L, L->top, tm, t1, t2);  /* call TM */
     278            2 :   return !l_isfalse(L->top);
     279              : }
     280              : 
     281              : 
     282        10907 : void luaV_concat (lua_State *L, int total, int last) {
     283              :   do {
     284        11454 :     StkId top = L->base + last + 1;
     285        11454 :     int n = 2;  /* number of elements handled in this pass (at least 2) */
     286        11454 :     if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
     287           12 :       if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
     288            9 :         luaG_concaterror(L, top-2, top-1);
     289        11442 :     } else if (tsvalue(top-1)->len == 0)  /* second op is empty? */
     290          545 :       (void)tostring(L, top - 2);  /* result is first op (as string) */
     291              :     else {
     292              :       /* at least two string values; get as many as possible */
     293        10897 :       size_t tl = tsvalue(top-1)->len;
     294              :       char *buffer;
     295              :       int i;
     296              :       /* collect total length */
     297        30094 :       for (n = 1; n < total && tostring(L, top-n-1); n++) {
     298        19197 :         size_t l = tsvalue(top-n-1)->len;
     299        19197 :         if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow");
     300        19197 :         tl += l;
     301              :       }
     302        10897 :       buffer = luaZ_openspace(L, &G(L)->buff, tl);
     303        10897 :       tl = 0;
     304        40991 :       for (i=n; i>0; i--) {  /* concat all strings */
     305        30094 :         size_t l = tsvalue(top-i)->len;
     306        30094 :         memcpy(buffer+tl, svalue(top-i), l);
     307        30094 :         tl += l;
     308              :       }
     309        10897 :       setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
     310              :     }
     311        11445 :     total -= n-1;  /* got `n' strings to create 1 new */
     312        11445 :     last -= n-1;
     313        11445 :   } while (total > 1);  /* repeat until only 1 result left */
     314        10898 : }
     315              : 
     316              : 
     317          123 : static void Arith (lua_State *L, StkId ra, const TValue *rb,
     318              :                    const TValue *rc, TMS op) {
     319              :   TValue tempb, tempc;
     320              :   const TValue *b, *c;
     321          182 :   if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
     322           83 :       (c = luaV_tonumber(rc, &tempc)) != NULL) {
     323           24 :     lua_Number nb = nvalue(b), nc = nvalue(c);
     324           24 :     switch (op) {
     325            4 :       case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
     326            3 :       case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
     327            7 :       case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
     328            3 :       case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
     329            3 :       case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
     330            3 :       case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
     331            1 :       case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
     332            0 :       default: lua_assert(0); break;
     333              :     }
     334              :   }
     335           99 :   else if (!call_binTM(L, rb, rc, ra, op))
     336           78 :     luaG_aritherror(L, rb, rc);
     337           45 : }
     338              : 
     339              : 
     340              : 
     341              : /*
     342              : ** some macros for common tasks in `luaV_execute'
     343              : */
     344              : 
     345              : #define runtime_check(L, c)     { if (!(c)) break; }
     346              : 
     347              : #define RA(i)   (base+GETARG_A(i))
     348              : /* to be used after possible stack reallocation */
     349              : #define RB(i)   check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i))
     350              : #define RC(i)   check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i))
     351              : #define RKB(i)  check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \
     352              :         ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
     353              : #define RKC(i)  check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
     354              :         ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
     355              : #define KBx(i)  check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
     356              : 
     357              : 
     358              : #define dojump(L,pc,i)  {(pc) += (i); luai_threadyield(L);}
     359              : 
     360              : 
     361              : #define Protect(x)      { L->savedpc = pc; {x;}; base = L->base; }
     362              : 
     363              : 
     364              : #define arith_op(op,tm) { \
     365              :         TValue *rb = RKB(i); \
     366              :         TValue *rc = RKC(i); \
     367              :         if (ttisnumber(rb) && ttisnumber(rc)) { \
     368              :           lua_Number nb = nvalue(rb), nc = nvalue(rc); \
     369              :           setnvalue(ra, op(nb, nc)); \
     370              :         } \
     371              :         else \
     372              :           Protect(Arith(L, ra, rb, rc, tm)); \
     373              :       }
     374              : 
     375              : 
     376              : 
     377        12981 : void luaV_execute (lua_State *L, int nexeccalls) {
     378              :   LClosure *cl;
     379              :   StkId base;
     380              :   TValue *k;
     381              :   const Instruction *pc;
     382        32210 :  reentry:  /* entry point */
     383              :   lua_assert(isLua(L->ci));
     384        45191 :   pc = L->savedpc;
     385        45191 :   cl = &clvalue(L->ci->func)->l;
     386        45191 :   base = L->base;
     387        45191 :   k = cl->p->k;
     388              :   /* main loop of interpreter */
     389       616935 :   for (;;) {
     390       662126 :     const Instruction i = *pc++;
     391              :     StkId ra;
     392       662126 :     if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
     393         1445 :         (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
     394           34 :       traceexec(L, pc);
     395           34 :       if (L->status == LUA_YIELD) {  /* did hook yield? */
     396            0 :         L->savedpc = pc - 1;
     397            0 :         return;
     398              :       }
     399           34 :       base = L->base;
     400              :     }
     401              :     /* warning!! several calls may realloc the stack and invalidate `ra' */
     402       662126 :     ra = RA(i);
     403              :     lua_assert(base == L->base && L->base == L->ci->base);
     404              :     lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
     405              :     lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
     406       662126 :     switch (GET_OPCODE(i)) {
     407        88434 :       case OP_MOVE: {
     408        88434 :         setobjs2s(L, ra, RB(i));
     409        88434 :         continue;
     410              :       }
     411        32312 :       case OP_LOADK: {
     412        32312 :         setobj2s(L, ra, KBx(i));
     413        32312 :         continue;
     414              :       }
     415         7571 :       case OP_LOADBOOL: {
     416         7571 :         setbvalue(ra, GETARG_B(i));
     417         7571 :         if (GETARG_C(i)) pc++;  /* skip next instruction (if C) */
     418         7571 :         continue;
     419              :       }
     420         1108 :       case OP_LOADNIL: {
     421          554 :         TValue *rb = RB(i);
     422              :         do {
     423          723 :           setnilvalue(rb--);
     424          723 :         } while (rb >= ra);
     425          554 :         continue;
     426              :       }
     427        32657 :       case OP_GETUPVAL: {
     428        32657 :         int b = GETARG_B(i);
     429        32657 :         setobj2s(L, ra, cl->upvals[b]->v);
     430        32657 :         continue;
     431              :       }
     432        96394 :       case OP_GETGLOBAL: {
     433              :         TValue g;
     434        48197 :         TValue *rb = KBx(i);
     435        48197 :         sethvalue(L, &g, cl->env);
     436              :         lua_assert(ttisstring(rb));
     437        48197 :         Protect(luaV_gettable(L, &g, rb, ra));
     438        48197 :         continue;
     439              :       }
     440        72960 :       case OP_GETTABLE: {
     441        72960 :         Protect(luaV_gettable(L, RB(i), RKC(i), ra));
     442        72953 :         continue;
     443              :       }
     444         2983 :       case OP_SETGLOBAL: {
     445              :         TValue g;
     446         1492 :         sethvalue(L, &g, cl->env);
     447              :         lua_assert(ttisstring(KBx(i)));
     448         1492 :         Protect(luaV_settable(L, &g, KBx(i), ra));
     449         1491 :         continue;
     450              :       }
     451         5282 :       case OP_SETUPVAL: {
     452         2641 :         UpVal *uv = cl->upvals[GETARG_B(i)];
     453         2641 :         setobj(L, uv->v, ra);
     454         2641 :         luaC_barrier(L, uv, ra);
     455         2641 :         continue;
     456              :       }
     457        82817 :       case OP_SETTABLE: {
     458        82817 :         Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
     459        82806 :         continue;
     460              :       }
     461        13162 :       case OP_NEWTABLE: {
     462         6581 :         int b = GETARG_B(i);
     463         6581 :         int c = GETARG_C(i);
     464         6581 :         sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
     465         6581 :         Protect(luaC_checkGC(L));
     466         6581 :         continue;
     467              :       }
     468        14228 :       case OP_SELF: {
     469         7114 :         StkId rb = RB(i);
     470         7114 :         setobjs2s(L, ra+1, rb);
     471         7114 :         Protect(luaV_gettable(L, rb, RKC(i), ra));
     472         7114 :         continue;
     473              :       }
     474        14376 :       case OP_ADD: {
     475        14376 :         arith_op(luai_numadd, TM_ADD);
     476        14364 :         continue;
     477              :       }
     478        11099 :       case OP_SUB: {
     479        11099 :         arith_op(luai_numsub, TM_SUB);
     480        11088 :         continue;
     481              :       }
     482         1159 :       case OP_MUL: {
     483         1159 :         arith_op(luai_nummul, TM_MUL);
     484         1145 :         continue;
     485              :       }
     486           37 :       case OP_DIV: {
     487           37 :         arith_op(luai_numdiv, TM_DIV);
     488           26 :         continue;
     489              :       }
     490           16 :       case OP_MOD: {
     491           16 :         arith_op(luai_nummod, TM_MOD);
     492            5 :         continue;
     493              :       }
     494           20 :       case OP_POW: {
     495           20 :         arith_op(luai_numpow, TM_POW);
     496            9 :         continue;
     497              :       }
     498           18 :       case OP_UNM: {
     499           13 :         TValue *rb = RB(i);
     500           13 :         if (ttisnumber(rb)) {
     501            3 :           lua_Number nb = nvalue(rb);
     502            3 :           setnvalue(ra, luai_numunm(nb));
     503              :         }
     504              :         else {
     505           10 :           Protect(Arith(L, ra, rb, rb, TM_UNM));
     506              :         }
     507            5 :         continue;
     508              :       }
     509           24 :       case OP_NOT: {
     510           12 :         int res = l_isfalse(RB(i));  /* next assignment may change this value */
     511           12 :         setbvalue(ra, res);
     512           12 :         continue;
     513              :       }
     514         1226 :       case OP_LEN: {
     515          616 :         const TValue *rb = RB(i);
     516          616 :         switch (ttype(rb)) {
     517          609 :           case LUA_TTABLE: {
     518          609 :             setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
     519          609 :             break;
     520              :           }
     521            1 :           case LUA_TSTRING: {
     522            1 :             setnvalue(ra, cast_num(tsvalue(rb)->len));
     523            1 :             break;
     524              :           }
     525            6 :           default: {  /* try metamethod */
     526            6 :             Protect(
     527              :               if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN))
     528              :                 luaG_typeerror(L, rb, "get length of");
     529              :             )
     530              :           }
     531              :         }
     532          610 :         continue;
     533              :       }
     534        15875 :       case OP_CONCAT: {
     535         7942 :         int b = GETARG_B(i);
     536         7942 :         int c = GETARG_C(i);
     537         7942 :         Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
     538         7933 :         setobjs2s(L, RA(i), base+b);
     539         7933 :         continue;
     540              :       }
     541        18297 :       case OP_JMP: {
     542        18297 :         dojump(L, pc, GETARG_sBx(i));
     543        18297 :         continue;
     544              :       }
     545        50508 :       case OP_EQ: {
     546        25254 :         TValue *rb = RKB(i);
     547        25254 :         TValue *rc = RKC(i);
     548        25254 :         Protect(
     549              :           if (equalobj(L, rb, rc) == GETARG_A(i))
     550              :             dojump(L, pc, GETARG_sBx(*pc));
     551              :         )
     552        25254 :         pc++;
     553        25254 :         continue;
     554              :       }
     555          113 :       case OP_LT: {
     556          113 :         Protect(
     557              :           if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
     558              :             dojump(L, pc, GETARG_sBx(*pc));
     559              :         )
     560           70 :         pc++;
     561           70 :         continue;
     562              :       }
     563        11456 :       case OP_LE: {
     564        11456 :         Protect(
     565              :           if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
     566              :             dojump(L, pc, GETARG_sBx(*pc));
     567              :         )
     568        11425 :         pc++;
     569        11425 :         continue;
     570              :       }
     571        17766 :       case OP_TEST: {
     572        17766 :         if (l_isfalse(ra) != GETARG_C(i))
     573        16074 :           dojump(L, pc, GETARG_sBx(*pc));
     574        17766 :         pc++;
     575        17766 :         continue;
     576              :       }
     577           10 :       case OP_TESTSET: {
     578            5 :         TValue *rb = RB(i);
     579            5 :         if (l_isfalse(rb) != GETARG_C(i)) {
     580            4 :           setobjs2s(L, ra, rb);
     581            4 :           dojump(L, pc, GETARG_sBx(*pc));
     582              :         }
     583            5 :         pc++;
     584            5 :         continue;
     585              :       }
     586        70450 :       case OP_CALL: {
     587        70450 :         int b = GETARG_B(i);
     588        70450 :         int nresults = GETARG_C(i) - 1;
     589        70450 :         if (b != 0) L->top = ra+b;  /* else previous instruction set top */
     590        70450 :         L->savedpc = pc;
     591        70450 :         switch (luaD_precall(L, ra, nresults)) {
     592        15534 :           case PCRLUA: {
     593        15534 :             nexeccalls++;
     594        15534 :             goto reentry;  /* restart luaV_execute over new Lua function */
     595              :           }
     596        48859 :           case PCRC: {
     597              :             /* it was a C function (`precall' called it); adjust results */
     598        48859 :             if (nresults >= 0) L->top = L->ci->top;
     599        48859 :             base = L->base;
     600        48859 :             continue;
     601              :           }
     602         5947 :           default: {
     603         5947 :             return;  /* yield */
     604              :           }
     605              :         }
     606              :       }
     607         1262 :       case OP_TAILCALL: {
     608         1262 :         int b = GETARG_B(i);
     609         1262 :         if (b != 0) L->top = ra+b;  /* else previous instruction set top */
     610         1262 :         L->savedpc = pc;
     611              :         lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
     612         1262 :         switch (luaD_precall(L, ra, LUA_MULTRET)) {
     613         1151 :           case PCRLUA: {
     614              :             /* tail call: put new frame in place of previous one */
     615         1151 :             CallInfo *ci = L->ci - 1;  /* previous frame */
     616              :             int aux;
     617         1151 :             StkId func = ci->func;
     618         1151 :             StkId pfunc = (ci+1)->func;  /* previous function index */
     619         1151 :             if (L->openupval) luaF_close(L, ci->base);
     620         1151 :             L->base = ci->base = ci->func + ((ci+1)->base - pfunc);
     621        11773 :             for (aux = 0; pfunc+aux < L->top; aux++)  /* move frame down */
     622        10622 :               setobjs2s(L, func+aux, pfunc+aux);
     623         1151 :             ci->top = L->top = func+aux;  /* correct top */
     624              :             lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize);
     625         1151 :             ci->savedpc = L->savedpc;
     626         1151 :             ci->tailcalls++;  /* one more call lost */
     627         1151 :             L->ci--;  /* remove new frame */
     628         1151 :             goto reentry;
     629              :           }
     630          108 :           case PCRC: {  /* it was a C function (`precall' called it) */
     631          108 :             base = L->base;
     632          108 :             continue;
     633              :           }
     634            1 :           default: {
     635            1 :             return;  /* yield */
     636              :           }
     637              :         }
     638              :       }
     639        22257 :       case OP_RETURN: {
     640        22257 :         int b = GETARG_B(i);
     641        22257 :         if (b != 0) L->top = ra+b-1;
     642        22257 :         if (L->openupval) luaF_close(L, base);
     643        22257 :         L->savedpc = pc;
     644        22257 :         b = luaD_poscall(L, ra);
     645        22257 :         if (--nexeccalls == 0)  /* was previous function running `here'? */
     646         6732 :           return;  /* no: return */
     647              :         else {  /* yes: continue its execution */
     648        15525 :           if (b) L->top = L->ci->top;
     649              :           lua_assert(isLua(L->ci));
     650              :           lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL);
     651        15525 :           goto reentry;
     652              :         }
     653              :       }
     654        32106 :       case OP_FORLOOP: {
     655        16053 :         lua_Number step = nvalue(ra+2);
     656        16053 :         lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
     657        16053 :         lua_Number limit = nvalue(ra+1);
     658        16053 :         if (luai_numlt(0, step) ? luai_numle(idx, limit)
     659              :                                 : luai_numle(limit, idx)) {
     660        11601 :           dojump(L, pc, GETARG_sBx(i));  /* jump back */
     661        11601 :           setnvalue(ra, idx);  /* update internal index... */
     662        11601 :           setnvalue(ra+3, idx);  /* ...and external index */
     663              :         }
     664        16053 :         continue;
     665              :       }
     666         8921 :       case OP_FORPREP: {
     667         4462 :         const TValue *init = ra;
     668         4462 :         const TValue *plimit = ra+1;
     669         4462 :         const TValue *pstep = ra+2;
     670         4462 :         L->savedpc = pc;  /* next steps may throw errors */
     671         4462 :         if (!tonumber(init, ra))
     672            1 :           luaG_runerror(L, LUA_QL("for") " initial value must be a number");
     673         4461 :         else if (!tonumber(plimit, ra+1))
     674            1 :           luaG_runerror(L, LUA_QL("for") " limit must be a number");
     675         4460 :         else if (!tonumber(pstep, ra+2))
     676            1 :           luaG_runerror(L, LUA_QL("for") " step must be a number");
     677         4459 :         setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
     678         4459 :         dojump(L, pc, GETARG_sBx(i));
     679         4459 :         continue;
     680              :       }
     681       104914 :       case OP_TFORLOOP: {
     682        52457 :         StkId cb = ra + 3;  /* call base */
     683        52457 :         setobjs2s(L, cb+2, ra+2);
     684        52457 :         setobjs2s(L, cb+1, ra+1);
     685        52457 :         setobjs2s(L, cb, ra);
     686        52457 :         L->top = cb+3;  /* func. + 2 args (state and index) */
     687        52457 :         Protect(luaD_call(L, cb, GETARG_C(i)));
     688        52457 :         L->top = L->ci->top;
     689        52457 :         cb = RA(i) + 3;  /* previous call may change the stack */
     690        52457 :         if (!ttisnil(cb)) {  /* continue loop? */
     691        46505 :           setobjs2s(L, cb-1, cb);  /* save control variable */
     692        46505 :           dojump(L, pc, GETARG_sBx(*pc));  /* jump back */
     693              :         }
     694        52457 :         pc++;
     695        52457 :         continue;
     696              :       }
     697          714 :       case OP_SETLIST: {
     698          357 :         int n = GETARG_B(i);
     699          357 :         int c = GETARG_C(i);
     700              :         int last;
     701              :         Table *h;
     702          357 :         if (n == 0) {
     703          220 :           n = cast_int(L->top - ra) - 1;
     704          220 :           L->top = L->ci->top;
     705              :         }
     706          357 :         if (c == 0) c = cast_int(*pc++);
     707          357 :         runtime_check(L, ttistable(ra));
     708          357 :         h = hvalue(ra);
     709          357 :         last = ((c-1)*LFIELDS_PER_FLUSH) + n;
     710          357 :         if (last > h->sizearray)  /* needs more space? */
     711          213 :           luaH_resizearray(L, h, last);  /* pre-alloc it at once */
     712         1377 :         for (; n > 0; n--) {
     713         1020 :           TValue *val = ra+n;
     714         1020 :           setobj2t(L, luaH_setnum(L, h, last--), val);
     715         1020 :           luaC_barriert(L, h, val);
     716              :         }
     717          357 :         continue;
     718              :       }
     719          401 :       case OP_CLOSE: {
     720          401 :         luaF_close(L, ra);
     721          401 :         continue;
     722              :       }
     723         5800 :       case OP_CLOSURE: {
     724              :         Proto *p;
     725              :         Closure *ncl;
     726              :         int nup, j;
     727         2900 :         p = cl->p->p[GETARG_Bx(i)];
     728         2900 :         nup = p->nups;
     729         2900 :         ncl = luaF_newLclosure(L, nup, cl->env);
     730         2900 :         ncl->l.p = p;
     731        11325 :         for (j=0; j<nup; j++, pc++) {
     732         8425 :           if (GET_OPCODE(*pc) == OP_GETUPVAL)
     733         1551 :             ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
     734              :           else {
     735              :             lua_assert(GET_OPCODE(*pc) == OP_MOVE);
     736         6874 :             ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
     737              :           }
     738              :         }
     739         2900 :         setclvalue(L, ra, ncl);
     740         2900 :         Protect(luaC_checkGC(L));
     741         2900 :         continue;
     742              :       }
     743           32 :       case OP_VARARG: {
     744           16 :         int b = GETARG_B(i) - 1;
     745              :         int j;
     746           16 :         CallInfo *ci = L->ci;
     747           16 :         int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1;
     748           16 :         if (b == LUA_MULTRET) {
     749           12 :           Protect(luaD_checkstack(L, n));
     750           12 :           ra = RA(i);  /* previous call may change the stack */
     751           12 :           b = n;
     752           12 :           L->top = ra + n;
     753              :         }
     754           39 :         for (j = 0; j < b; j++) {
     755           23 :           if (j < n) {
     756           16 :             setobjs2s(L, ra + j, ci->base - n + j);
     757              :           }
     758              :           else {
     759            7 :             setnilvalue(ra + j);
     760              :           }
     761              :         }
     762           16 :         continue;
     763              :       }
     764              :     }
     765              :   }
     766              : }
     767              : 
        

Generated by: LCOV version 2.0-1