LCOV - code coverage report
Current view: directory - src - lvm.c Found Hit Coverage
Test: Lua 5.1.4 Lines: 419 382 91.2 %
Date: 2009-09-13
Colors: not hit hit

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

Generated by: LCOV version 1.7