LCOV - code coverage report
Current view: top level - AP_Scripting/lua/src - ldebug.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 129 379 34.0 %
Date: 2026-09-09 11:02:08 Functions: 19 35 54.3 %

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

Generated by: LCOV version 1.14