LCOV - code coverage report
Current view: top level - src - ldebug.c Coverage Total Hit
Test: Lua 5.3.6 Lines: 79.4 % 379 301
Test Date: 2024-04-28 10:23:15
Legend: Lines: hit not hit

            Line data    Source code
       1              : /*
       2              : ** $Id: ldebug.c,v 2.121.1.2 2017/07/10 17:21:50 roberto Exp $
       3              : ** Debug Interface
       4              : ** See Copyright Notice in lua.h
       5              : */
       6              : 
       7              : #define ldebug_c
       8              : #define LUA_CORE
       9              : 
      10              : #include "lprefix.h"
      11              : 
      12              : 
      13              : #include <stdarg.h>
      14              : #include <stddef.h>
      15              : #include <string.h>
      16              : 
      17              : #include "lua.h"
      18              : 
      19              : #include "lapi.h"
      20              : #include "lcode.h"
      21              : #include "ldebug.h"
      22              : #include "ldo.h"
      23              : #include "lfunc.h"
      24              : #include "lobject.h"
      25              : #include "lopcodes.h"
      26              : #include "lstate.h"
      27              : #include "lstring.h"
      28              : #include "ltable.h"
      29              : #include "ltm.h"
      30              : #include "lvm.h"
      31              : 
      32              : 
      33              : 
      34              : #define noLuaClosure(f)         ((f) == NULL || (f)->c.tt == LUA_TCCL)
      35              : 
      36              : 
      37              : /* Active Lua function (given call info) */
      38              : #define ci_func(ci)             (clLvalue((ci)->func))
      39              : 
      40              : 
      41              : static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
      42              :                                     const char **name);
      43              : 
      44              : 
      45          589 : static int currentpc (CallInfo *ci) {
      46              :   lua_assert(isLua(ci));
      47          589 :   return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
      48              : }
      49              : 
      50              : 
      51          407 : static int currentline (CallInfo *ci) {
      52          407 :   return getfuncline(ci_func(ci)->p, currentpc(ci));
      53              : }
      54              : 
      55              : 
      56              : /*
      57              : ** If function yielded, its 'func' can be in the 'extra' field. The
      58              : ** next function restores 'func' to its correct value for debugging
      59              : ** purposes. (It exchanges 'func' and 'extra'; so, when called again,
      60              : ** after debugging, it also "re-restores" ** 'func' to its altered value.
      61              : */
      62          566 : static void swapextra (lua_State *L) {
      63          566 :   if (L->status == LUA_YIELD) {
      64            0 :     CallInfo *ci = L->ci;  /* get function that yielded */
      65            0 :     StkId temp = ci->func;  /* exchange its 'func' and 'extra' values */
      66            0 :     ci->func = restorestack(L, ci->extra);
      67            0 :     ci->extra = savestack(L, temp);
      68              :   }
      69          566 : }
      70              : 
      71              : 
      72              : /*
      73              : ** This function can be called asynchronously (e.g. during a signal).
      74              : ** Fields 'oldpc', 'basehookcount', and 'hookcount' (set by
      75              : ** 'resethookcount') are for debug only, and it is no problem if they
      76              : ** get arbitrary values (causes at most one wrong hook call). 'hookmask'
      77              : ** is an atomic value. We assume that pointers are atomic too (e.g., gcc
      78              : ** ensures that for all platforms where it runs). Moreover, 'hook' is
      79              : ** always checked before being called (see 'luaD_hook').
      80              : */
      81            2 : LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
      82            2 :   if (func == NULL || mask == 0) {  /* turn off hooks? */
      83            1 :     mask = 0;
      84            1 :     func = NULL;
      85              :   }
      86            2 :   if (isLua(L->ci))
      87            0 :     L->oldpc = L->ci->u.l.savedpc;
      88            2 :   L->hook = func;
      89            2 :   L->basehookcount = count;
      90            2 :   resethookcount(L);
      91            2 :   L->hookmask = cast_byte(mask);
      92            2 : }
      93              : 
      94              : 
      95            3 : LUA_API lua_Hook lua_gethook (lua_State *L) {
      96            3 :   return L->hook;
      97              : }
      98              : 
      99              : 
     100            3 : LUA_API int lua_gethookmask (lua_State *L) {
     101            3 :   return L->hookmask;
     102              : }
     103              : 
     104              : 
     105            3 : LUA_API int lua_gethookcount (lua_State *L) {
     106            3 :   return L->basehookcount;
     107              : }
     108              : 
     109              : 
     110          297 : LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
     111              :   int status;
     112              :   CallInfo *ci;
     113          297 :   if (level < 0) return 0;  /* invalid (negative) level */
     114              :   lua_lock(L);
     115          586 :   for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous)
     116          289 :     level--;
     117          297 :   if (level == 0 && ci != &L->base_ci) {  /* level found? */
     118          280 :     status = 1;
     119          280 :     ar->i_ci = ci;
     120              :   }
     121           17 :   else status = 0;  /* no such level */
     122              :   lua_unlock(L);
     123          297 :   return status;
     124              : }
     125              : 
     126              : 
     127           86 : static const char *upvalname (Proto *p, int uv) {
     128           86 :   TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
     129           86 :   if (s == NULL) return "?";
     130           86 :   else return getstr(s);
     131              : }
     132              : 
     133              : 
     134            0 : static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
     135            0 :   int nparams = clLvalue(ci->func)->p->numparams;
     136            0 :   int nvararg = cast_int(ci->u.l.base - ci->func) - nparams;
     137            0 :   if (n <= -nvararg)
     138            0 :     return NULL;  /* no such vararg */
     139              :   else {
     140            0 :     *pos = ci->func + nparams - n;
     141            0 :     return "(*vararg)";  /* generic name for any vararg */
     142              :   }
     143              : }
     144              : 
     145              : 
     146            3 : static const char *findlocal (lua_State *L, CallInfo *ci, int n,
     147              :                               StkId *pos) {
     148            3 :   const char *name = NULL;
     149              :   StkId base;
     150            3 :   if (isLua(ci)) {
     151            0 :     if (n < 0)  /* access to vararg values? */
     152            0 :       return findvararg(ci, n, pos);
     153              :     else {
     154            0 :       base = ci->u.l.base;
     155            0 :       name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
     156              :     }
     157              :   }
     158              :   else
     159            3 :     base = ci->func + 1;
     160            3 :   if (name == NULL) {  /* no 'standard' name? */
     161            3 :     StkId limit = (ci == L->ci) ? L->top : ci->next->func;
     162            3 :     if (limit - base >= n && n > 0)  /* is 'n' inside 'ci' stack? */
     163            2 :       name = "(*temporary)";  /* generic name for any valid slot */
     164              :     else
     165            1 :       return NULL;  /* no name */
     166              :   }
     167            2 :   *pos = base + (n - 1);
     168            2 :   return name;
     169              : }
     170              : 
     171              : 
     172            2 : LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
     173              :   const char *name;
     174              :   lua_lock(L);
     175            2 :   swapextra(L);
     176            2 :   if (ar == NULL) {  /* information about non-active function? */
     177            1 :     if (!isLfunction(L->top - 1))  /* not a Lua function? */
     178            0 :       name = NULL;
     179              :     else  /* consider live variables at function start (parameters) */
     180            1 :       name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
     181              :   }
     182              :   else {  /* active function; get information through 'ar' */
     183            1 :     StkId pos = NULL;  /* to avoid warnings */
     184            1 :     name = findlocal(L, ar->i_ci, n, &pos);
     185            1 :     if (name) {
     186            1 :       setobj2s(L, L->top, pos);
     187            1 :       api_incr_top(L);
     188              :     }
     189              :   }
     190            2 :   swapextra(L);
     191              :   lua_unlock(L);
     192            2 :   return name;
     193              : }
     194              : 
     195              : 
     196            2 : LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
     197            2 :   StkId pos = NULL;  /* to avoid warnings */
     198              :   const char *name;
     199              :   lua_lock(L);
     200            2 :   swapextra(L);
     201            2 :   name = findlocal(L, ar->i_ci, n, &pos);
     202            2 :   if (name) {
     203            1 :     setobjs2s(L, pos, L->top - 1);
     204            1 :     L->top--;  /* pop value */
     205              :   }
     206            2 :   swapextra(L);
     207              :   lua_unlock(L);
     208            2 :   return name;
     209              : }
     210              : 
     211              : 
     212          192 : static void funcinfo (lua_Debug *ar, Closure *cl) {
     213          192 :   if (noLuaClosure(cl)) {
     214           58 :     ar->source = "=[C]";
     215           58 :     ar->linedefined = -1;
     216           58 :     ar->lastlinedefined = -1;
     217           58 :     ar->what = "C";
     218              :   }
     219              :   else {
     220          134 :     Proto *p = cl->l.p;
     221          134 :     ar->source = p->source ? getstr(p->source) : "=?";
     222          134 :     ar->linedefined = p->linedefined;
     223          134 :     ar->lastlinedefined = p->lastlinedefined;
     224          134 :     ar->what = (ar->linedefined == 0) ? "main" : "Lua";
     225              :   }
     226          192 :   luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
     227          192 : }
     228              : 
     229              : 
     230            1 : static void collectvalidlines (lua_State *L, Closure *f) {
     231            1 :   if (noLuaClosure(f)) {
     232            0 :     setnilvalue(L->top);
     233            0 :     api_incr_top(L);
     234              :   }
     235              :   else {
     236              :     int i;
     237              :     TValue v;
     238            1 :     int *lineinfo = f->l.p->lineinfo;
     239            1 :     Table *t = luaH_new(L);  /* new table to store active lines */
     240            1 :     sethvalue(L, L->top, t);  /* push it on stack */
     241            1 :     api_incr_top(L);
     242            1 :     setbvalue(&v, 1);  /* boolean 'true' to be the value of all indices */
     243           26 :     for (i = 0; i < f->l.p->sizelineinfo; i++)  /* for all lines with code */
     244           25 :       luaH_setint(L, t, lineinfo[i], &v);  /* table[line] = true */
     245              :   }
     246            1 : }
     247              : 
     248              : 
     249           86 : static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
     250           86 :   if (ci == NULL)  /* no 'ci'? */
     251            1 :     return NULL;  /* no info */
     252           85 :   else if (ci->callstatus & CIST_FIN) {  /* is this a finalizer? */
     253            0 :     *name = "__gc";
     254            0 :     return "metamethod";  /* report it as such */
     255              :   }
     256              :   /* calling function is a known Lua function? */
     257           85 :   else if (!(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
     258           73 :     return funcnamefromcode(L, ci->previous, name);
     259           12 :   else return NULL;  /* no way to find a name */
     260              : }
     261              : 
     262              : 
     263          279 : static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
     264              :                        Closure *f, CallInfo *ci) {
     265          279 :   int status = 1;
     266          784 :   for (; *what; what++) {
     267          505 :     switch (*what) {
     268          192 :       case 'S': {
     269          192 :         funcinfo(ar, f);
     270          192 :         break;
     271              :       }
     272          192 :       case 'l': {
     273          192 :         ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1;
     274          192 :         break;
     275              :       }
     276            2 :       case 'u': {
     277            2 :         ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
     278            2 :         if (noLuaClosure(f)) {
     279            0 :           ar->isvararg = 1;
     280            0 :           ar->nparams = 0;
     281              :         }
     282              :         else {
     283            2 :           ar->isvararg = f->l.p->is_vararg;
     284            2 :           ar->nparams = f->l.p->numparams;
     285              :         }
     286            2 :         break;
     287              :       }
     288           15 :       case 't': {
     289           15 :         ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0;
     290           15 :         break;
     291              :       }
     292           86 :       case 'n': {
     293           86 :         ar->namewhat = getfuncname(L, ci, &ar->name);
     294           86 :         if (ar->namewhat == NULL) {
     295           13 :           ar->namewhat = "";  /* not found */
     296           13 :           ar->name = NULL;
     297              :         }
     298           86 :         break;
     299              :       }
     300           17 :       case 'L':
     301              :       case 'f':  /* handled by lua_getinfo */
     302           17 :         break;
     303            1 :       default: status = 0;  /* invalid option */
     304              :     }
     305              :   }
     306          279 :   return status;
     307              : }
     308              : 
     309              : 
     310          279 : LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
     311              :   int status;
     312              :   Closure *cl;
     313              :   CallInfo *ci;
     314              :   StkId func;
     315              :   lua_lock(L);
     316          279 :   swapextra(L);
     317          279 :   if (*what == '>') {
     318            3 :     ci = NULL;
     319            3 :     func = L->top - 1;
     320              :     api_check(L, ttisfunction(func), "function expected");
     321            3 :     what++;  /* skip the '>' */
     322            3 :     L->top--;  /* pop function */
     323              :   }
     324              :   else {
     325          276 :     ci = ar->i_ci;
     326          276 :     func = ci->func;
     327              :     lua_assert(ttisfunction(ci->func));
     328              :   }
     329          279 :   cl = ttisclosure(func) ? clvalue(func) : NULL;
     330          279 :   status = auxgetinfo(L, what, ar, cl, ci);
     331          279 :   if (strchr(what, 'f')) {
     332           16 :     setobjs2s(L, L->top, func);
     333           16 :     api_incr_top(L);
     334              :   }
     335          279 :   swapextra(L);  /* correct before option 'L', which can raise a mem. error */
     336          279 :   if (strchr(what, 'L'))
     337            1 :     collectvalidlines(L, cl);
     338              :   lua_unlock(L);
     339          279 :   return status;
     340              : }
     341              : 
     342              : 
     343              : /*
     344              : ** {======================================================
     345              : ** Symbolic Execution
     346              : ** =======================================================
     347              : */
     348              : 
     349              : static const char *getobjname (Proto *p, int lastpc, int reg,
     350              :                                const char **name);
     351              : 
     352              : 
     353              : /*
     354              : ** find a "name" for the RK value 'c'
     355              : */
     356           73 : static void kname (Proto *p, int pc, int c, const char **name) {
     357           73 :   if (ISK(c)) {  /* is 'c' a constant? */
     358           73 :     TValue *kvalue = &p->k[INDEXK(c)];
     359           73 :     if (ttisstring(kvalue)) {  /* literal constant? */
     360           73 :       *name = svalue(kvalue);  /* it is its own name */
     361           73 :       return;
     362              :     }
     363              :     /* else no reasonable name found */
     364              :   }
     365              :   else {  /* 'c' is a register */
     366            0 :     const char *what = getobjname(p, pc, c, name); /* search for 'c' */
     367            0 :     if (what && *what == 'c') {  /* found a constant name? */
     368            0 :       return;  /* 'name' already filled */
     369              :     }
     370              :     /* else no reasonable name found */
     371              :   }
     372            0 :   *name = "?";  /* no reasonable name found */
     373              : }
     374              : 
     375              : 
     376          545 : static int filterpc (int pc, int jmptarget) {
     377          545 :   if (pc < jmptarget)  /* is code conditional (inside a jump)? */
     378          172 :     return -1;  /* cannot know who sets that register */
     379          373 :   else return pc;  /* current position sets that register */
     380              : }
     381              : 
     382              : 
     383              : /*
     384              : ** try to find last instruction before 'lastpc' that modified register 'reg'
     385              : */
     386          172 : static int findsetreg (Proto *p, int lastpc, int reg) {
     387              :   int pc;
     388          172 :   int setreg = -1;  /* keep last instruction that changed 'reg' */
     389          172 :   int jmptarget = 0;  /* any code before this address is conditional */
     390         1589 :   for (pc = 0; pc < lastpc; pc++) {
     391         1417 :     Instruction i = p->code[pc];
     392         1417 :     OpCode op = GET_OPCODE(i);
     393         1417 :     int a = GETARG_A(i);
     394         1417 :     switch (op) {
     395           17 :       case OP_LOADNIL: {
     396           17 :         int b = GETARG_B(i);
     397           17 :         if (a <= reg && reg <= a + b)  /* set registers from 'a' to 'a+b' */
     398            5 :           setreg = filterpc(pc, jmptarget);
     399           17 :         break;
     400              :       }
     401            0 :       case OP_TFORCALL: {
     402            0 :         if (reg >= a + 2)  /* affect all regs above its base */
     403            0 :           setreg = filterpc(pc, jmptarget);
     404            0 :         break;
     405              :       }
     406          248 :       case OP_CALL:
     407              :       case OP_TAILCALL: {
     408          248 :         if (reg >= a)  /* affect all registers above base */
     409          247 :           setreg = filterpc(pc, jmptarget);
     410          248 :         break;
     411              :       }
     412           47 :       case OP_JMP: {
     413           47 :         int b = GETARG_sBx(i);
     414           47 :         int dest = pc + 1 + b;
     415              :         /* jump is forward and do not skip 'lastpc'? */
     416           47 :         if (pc < dest && dest <= lastpc) {
     417           47 :           if (dest > jmptarget)
     418           35 :             jmptarget = dest;  /* update 'jmptarget' */
     419              :         }
     420           47 :         break;
     421              :       }
     422         1105 :       default:
     423         1105 :         if (testAMode(op) && reg == a)  /* any instruction that set A */
     424          293 :           setreg = filterpc(pc, jmptarget);
     425         1105 :         break;
     426              :     }
     427              :   }
     428          172 :   return setreg;
     429              : }
     430              : 
     431              : 
     432          182 : static const char *getobjname (Proto *p, int lastpc, int reg,
     433              :                                const char **name) {
     434              :   int pc;
     435          182 :   *name = luaF_getlocalname(p, reg + 1, lastpc);
     436          182 :   if (*name)  /* is a local? */
     437           10 :     return "local";
     438              :   /* else try symbolic execution */
     439          172 :   pc = findsetreg(p, lastpc, reg);
     440          172 :   if (pc != -1) {  /* could find instruction? */
     441          172 :     Instruction i = p->code[pc];
     442          172 :     OpCode op = GET_OPCODE(i);
     443          172 :     switch (op) {
     444            0 :       case OP_MOVE: {
     445            0 :         int b = GETARG_B(i);  /* move from 'b' to 'a' */
     446            0 :         if (b < GETARG_A(i))
     447            0 :           return getobjname(p, pc, b, name);  /* get name for 'b' */
     448            0 :         break;
     449              :       }
     450           71 :       case OP_GETTABUP:
     451              :       case OP_GETTABLE: {
     452           71 :         int k = GETARG_C(i);  /* key index */
     453           71 :         int t = GETARG_B(i);  /* table index */
     454           71 :         const char *vn = (op == OP_GETTABLE)  /* name of indexed variable */
     455           54 :                          ? luaF_getlocalname(p, t + 1, pc)
     456           71 :                          : upvalname(p, t);
     457           71 :         kname(p, pc, k, name);
     458           71 :         return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
     459              :       }
     460           65 :       case OP_GETUPVAL: {
     461           65 :         *name = upvalname(p, GETARG_B(i));
     462           65 :         return "upvalue";
     463              :       }
     464            3 :       case OP_LOADK:
     465              :       case OP_LOADKX: {
     466            6 :         int b = (op == OP_LOADK) ? GETARG_Bx(i)
     467            3 :                                  : GETARG_Ax(p->code[pc + 1]);
     468            3 :         if (ttisstring(&p->k[b])) {
     469            2 :           *name = svalue(&p->k[b]);
     470            2 :           return "constant";
     471              :         }
     472            1 :         break;
     473              :       }
     474            2 :       case OP_SELF: {
     475            2 :         int k = GETARG_C(i);  /* key index */
     476            2 :         kname(p, pc, k, name);
     477            2 :         return "method";
     478              :       }
     479           31 :       default: break;  /* go through to return NULL */
     480              :     }
     481              :   }
     482           32 :   return NULL;  /* could not find reasonable name */
     483              : }
     484              : 
     485              : 
     486              : /*
     487              : ** Try to find a name for a function based on the code that called it.
     488              : ** (Only works when function was called by a Lua function.)
     489              : ** Returns what the name is (e.g., "for iterator", "method",
     490              : ** "metamethod") and sets '*name' to point to the name.
     491              : */
     492           73 : static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
     493              :                                      const char **name) {
     494           73 :   TMS tm = (TMS)0;  /* (initial value avoids warnings) */
     495           73 :   Proto *p = ci_func(ci)->p;  /* calling function */
     496           73 :   int pc = currentpc(ci);  /* calling instruction index */
     497           73 :   Instruction i = p->code[pc];  /* calling instruction */
     498           73 :   if (ci->callstatus & CIST_HOOKED) {  /* was it called inside a hook? */
     499            0 :     *name = "?";
     500            0 :     return "hook";
     501              :   }
     502           73 :   switch (GET_OPCODE(i)) {
     503           73 :     case OP_CALL:
     504              :     case OP_TAILCALL:
     505           73 :       return getobjname(p, pc, GETARG_A(i), name);  /* get function name */
     506            0 :     case OP_TFORCALL: {  /* for iterator */
     507            0 :       *name = "for iterator";
     508            0 :        return "for iterator";
     509              :     }
     510              :     /* other instructions can do calls through metamethods */
     511            0 :     case OP_SELF: case OP_GETTABUP: case OP_GETTABLE:
     512            0 :       tm = TM_INDEX;
     513            0 :       break;
     514            0 :     case OP_SETTABUP: case OP_SETTABLE:
     515            0 :       tm = TM_NEWINDEX;
     516            0 :       break;
     517            0 :     case OP_ADD: case OP_SUB: case OP_MUL: case OP_MOD:
     518              :     case OP_POW: case OP_DIV: case OP_IDIV: case OP_BAND:
     519              :     case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR: {
     520            0 :       int offset = cast_int(GET_OPCODE(i)) - cast_int(OP_ADD);  /* ORDER OP */
     521            0 :       tm = cast(TMS, offset + cast_int(TM_ADD));  /* ORDER TM */
     522            0 :       break;
     523              :     }
     524            0 :     case OP_UNM: tm = TM_UNM; break;
     525            0 :     case OP_BNOT: tm = TM_BNOT; break;
     526            0 :     case OP_LEN: tm = TM_LEN; break;
     527            0 :     case OP_CONCAT: tm = TM_CONCAT; break;
     528            0 :     case OP_EQ: tm = TM_EQ; break;
     529            0 :     case OP_LT: tm = TM_LT; break;
     530            0 :     case OP_LE: tm = TM_LE; break;
     531            0 :     default:
     532            0 :       return NULL;  /* cannot find a reasonable name */
     533              :   }
     534            0 :   *name = getstr(G(L)->tmname[tm]);
     535            0 :   return "metamethod";
     536              : }
     537              : 
     538              : /* }====================================================== */
     539              : 
     540              : 
     541              : 
     542              : /*
     543              : ** The subtraction of two potentially unrelated pointers is
     544              : ** not ISO C, but it should not crash a program; the subsequent
     545              : ** checks are ISO C and ensure a correct result.
     546              : */
     547          189 : static int isinstack (CallInfo *ci, const TValue *o) {
     548          189 :   ptrdiff_t i = o - ci->u.l.base;
     549          189 :   return (0 <= i && i < (ci->top - ci->u.l.base) && ci->u.l.base + i == o);
     550              : }
     551              : 
     552              : 
     553              : /*
     554              : ** Checks whether value 'o' came from an upvalue. (That can only happen
     555              : ** with instructions OP_GETTABUP/OP_SETTABUP, which operate directly on
     556              : ** upvalues.)
     557              : */
     558          193 : static const char *getupvalname (CallInfo *ci, const TValue *o,
     559              :                                  const char **name) {
     560          193 :   LClosure *c = ci_func(ci);
     561              :   int i;
     562          278 :   for (i = 0; i < c->nupvalues; i++) {
     563           89 :     if (c->upvals[i]->v == o) {
     564            4 :       *name = upvalname(c->p, i);
     565            4 :       return "upvalue";
     566              :     }
     567              :   }
     568          189 :   return NULL;
     569              : }
     570              : 
     571              : 
     572          195 : static const char *varinfo (lua_State *L, const TValue *o) {
     573          195 :   const char *name = NULL;  /* to avoid warnings */
     574          195 :   CallInfo *ci = L->ci;
     575          195 :   const char *kind = NULL;
     576          195 :   if (isLua(ci)) {
     577          193 :     kind = getupvalname(ci, o, &name);  /* check whether 'o' is an upvalue */
     578          193 :     if (!kind && isinstack(ci, o))  /* no? try a register */
     579          109 :       kind = getobjname(ci_func(ci)->p, currentpc(ci),
     580          109 :                         cast_int(o - ci->u.l.base), &name);
     581              :   }
     582          195 :   return (kind) ? luaO_pushfstring(L, " (%s '%s')", kind, name) : "";
     583              : }
     584              : 
     585              : 
     586          184 : l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
     587          184 :   const char *t = luaT_objtypename(L, o);
     588          184 :   luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o));
     589              : }
     590              : 
     591              : 
     592            9 : l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) {
     593            9 :   if (ttisstring(p1) || cvt2str(p1)) p1 = p2;
     594            9 :   luaG_typeerror(L, p1, "concatenate");
     595              : }
     596              : 
     597              : 
     598          152 : l_noret luaG_opinterror (lua_State *L, const TValue *p1,
     599              :                          const TValue *p2, const char *msg) {
     600              :   lua_Number temp;
     601          152 :   if (!tonumber(p1, &temp))  /* first operand is wrong? */
     602          101 :     p2 = p1;  /* now second is wrong */
     603          152 :   luaG_typeerror(L, p2, msg);
     604              : }
     605              : 
     606              : 
     607              : /*
     608              : ** Error when both values are convertible to numbers, but not to integers
     609              : */
     610           11 : l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) {
     611              :   lua_Integer temp;
     612           11 :   if (!tointeger(p1, &temp))
     613            6 :     p2 = p1;
     614           11 :   luaG_runerror(L, "number%s has no integer representation", varinfo(L, p2));
     615              : }
     616              : 
     617              : 
     618           74 : l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
     619           74 :   const char *t1 = luaT_objtypename(L, p1);
     620           74 :   const char *t2 = luaT_objtypename(L, p2);
     621           74 :   if (strcmp(t1, t2) == 0)
     622           28 :     luaG_runerror(L, "attempt to compare two %s values", t1);
     623              :   else
     624           46 :     luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
     625              : }
     626              : 
     627              : 
     628              : /* add src:line information to 'msg' */
     629          315 : const char *luaG_addinfo (lua_State *L, const char *msg, TString *src,
     630              :                                         int line) {
     631              :   char buff[LUA_IDSIZE];
     632          315 :   if (src)
     633          315 :     luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
     634              :   else {  /* no source available; use "?" instead */
     635            0 :     buff[0] = '?'; buff[1] = '\0';
     636              :   }
     637          315 :   return luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
     638              : }
     639              : 
     640              : 
     641          466 : l_noret luaG_errormsg (lua_State *L) {
     642          466 :   if (L->errfunc != 0) {  /* is there an error handling function? */
     643            8 :     StkId errfunc = restorestack(L, L->errfunc);
     644            8 :     setobjs2s(L, L->top, L->top - 1);  /* move argument */
     645            8 :     setobjs2s(L, L->top - 1, errfunc);  /* push function */
     646            8 :     L->top++;  /* assume EXTRA_STACK */
     647            8 :     luaD_callnoyield(L, L->top - 2, 1);  /* call it */
     648              :   }
     649          466 :   luaD_throw(L, LUA_ERRRUN);
     650              : }
     651              : 
     652              : 
     653          279 : l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
     654          279 :   CallInfo *ci = L->ci;
     655              :   const char *msg;
     656              :   va_list argp;
     657          279 :   luaC_checkGC(L);  /* error message uses memory */
     658          279 :   va_start(argp, fmt);
     659          279 :   msg = luaO_pushvfstring(L, fmt, argp);  /* format message */
     660          279 :   va_end(argp);
     661          279 :   if (isLua(ci))  /* if Lua function, add source:line information */
     662          274 :     luaG_addinfo(L, msg, ci_func(ci)->p->source, currentline(ci));
     663          279 :   luaG_errormsg(L);
     664              : }
     665              : 
     666              : 
     667         1345 : void luaG_traceexec (lua_State *L) {
     668         1345 :   CallInfo *ci = L->ci;
     669         1345 :   lu_byte mask = L->hookmask;
     670         1345 :   int counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT));
     671         1345 :   if (counthook)
     672           32 :     resethookcount(L);  /* reset count */
     673         1313 :   else if (!(mask & LUA_MASKLINE))
     674         1313 :     return;  /* no line hook and count != 0; nothing to be done */
     675           32 :   if (ci->callstatus & CIST_HOOKYIELD) {  /* called hook last time? */
     676            0 :     ci->callstatus &= ~CIST_HOOKYIELD;  /* erase mark */
     677            0 :     return;  /* do not call hook again (VM yielded, so it did not move) */
     678              :   }
     679           32 :   if (counthook)
     680           32 :     luaD_hook(L, LUA_HOOKCOUNT, -1);  /* call count hook */
     681           32 :   if (mask & LUA_MASKLINE) {
     682            0 :     Proto *p = ci_func(ci)->p;
     683            0 :     int npc = pcRel(ci->u.l.savedpc, p);
     684            0 :     int newline = getfuncline(p, npc);
     685            0 :     if (npc == 0 ||  /* call linehook when enter a new function, */
     686            0 :         ci->u.l.savedpc <= L->oldpc ||  /* when jump back (loop), or when */
     687            0 :         newline != getfuncline(p, pcRel(L->oldpc, p)))  /* enter a new line */
     688            0 :       luaD_hook(L, LUA_HOOKLINE, newline);  /* call line hook */
     689              :   }
     690           32 :   L->oldpc = ci->u.l.savedpc;
     691           32 :   if (L->status == LUA_YIELD) {  /* did hook yield? */
     692            0 :     if (counthook)
     693            0 :       L->hookcount = 1;  /* undo decrement to zero */
     694            0 :     ci->u.l.savedpc--;  /* undo increment (resume will increment it again) */
     695            0 :     ci->callstatus |= CIST_HOOKYIELD;  /* mark that it yielded */
     696            0 :     ci->func = L->top - 1;  /* protect stack below results */
     697            0 :     luaD_throw(L, LUA_YIELD);
     698              :   }
     699              : }
     700              : 
        

Generated by: LCOV version 2.0-1