LCOV - code coverage report
Current view: top level - src - ldebug.c Coverage Total Hit
Test: Lua 5.2.4 Lines: 82.9 % 340 282
Test Date: 2024-04-28 10:23:12
Legend: Lines: hit not hit

            Line data    Source code
       1              : /*
       2              : ** $Id: ldebug.c,v 2.90.1.4 2015/02/19 17:05:13 roberto Exp $
       3              : ** Debug Interface
       4              : ** See Copyright Notice in lua.h
       5              : */
       6              : 
       7              : 
       8              : #include <stdarg.h>
       9              : #include <stddef.h>
      10              : #include <string.h>
      11              : 
      12              : 
      13              : #define ldebug_c
      14              : #define LUA_CORE
      15              : 
      16              : #include "lua.h"
      17              : 
      18              : #include "lapi.h"
      19              : #include "lcode.h"
      20              : #include "ldebug.h"
      21              : #include "ldo.h"
      22              : #include "lfunc.h"
      23              : #include "lobject.h"
      24              : #include "lopcodes.h"
      25              : #include "lstate.h"
      26              : #include "lstring.h"
      27              : #include "ltable.h"
      28              : #include "ltm.h"
      29              : #include "lvm.h"
      30              : 
      31              : 
      32              : 
      33              : #define noLuaClosure(f)         ((f) == NULL || (f)->c.tt == LUA_TCCL)
      34              : 
      35              : 
      36              : static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
      37              : 
      38              : 
      39          410 : static int currentpc (CallInfo *ci) {
      40              :   lua_assert(isLua(ci));
      41          410 :   return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
      42              : }
      43              : 
      44              : 
      45          292 : static int currentline (CallInfo *ci) {
      46          292 :   return getfuncline(ci_func(ci)->p, currentpc(ci));
      47              : }
      48              : 
      49              : 
      50          452 : static void swapextra (lua_State *L) {
      51          452 :   if (L->status == LUA_YIELD) {
      52            0 :     CallInfo *ci = L->ci;  /* get function that yielded */
      53            0 :     StkId temp = ci->func;  /* exchange its 'func' and 'extra' values */
      54            0 :     ci->func = restorestack(L, ci->extra);
      55            0 :     ci->extra = savestack(L, temp);
      56              :   }
      57          452 : }
      58              : 
      59              : 
      60              : /*
      61              : ** this function can be called asynchronous (e.g. during a signal)
      62              : */
      63            2 : LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
      64            2 :   if (func == NULL || mask == 0) {  /* turn off hooks? */
      65            1 :     mask = 0;
      66            1 :     func = NULL;
      67              :   }
      68            2 :   if (isLua(L->ci))
      69            0 :     L->oldpc = L->ci->u.l.savedpc;
      70            2 :   L->hook = func;
      71            2 :   L->basehookcount = count;
      72            2 :   resethookcount(L);
      73            2 :   L->hookmask = cast_byte(mask);
      74            2 :   return 1;
      75              : }
      76              : 
      77              : 
      78            3 : LUA_API lua_Hook lua_gethook (lua_State *L) {
      79            3 :   return L->hook;
      80              : }
      81              : 
      82              : 
      83            3 : LUA_API int lua_gethookmask (lua_State *L) {
      84            3 :   return L->hookmask;
      85              : }
      86              : 
      87              : 
      88            3 : LUA_API int lua_gethookcount (lua_State *L) {
      89            3 :   return L->basehookcount;
      90              : }
      91              : 
      92              : 
      93          241 : LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
      94              :   int status;
      95              :   CallInfo *ci;
      96          241 :   if (level < 0) return 0;  /* invalid (negative) level */
      97              :   lua_lock(L);
      98          485 :   for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous)
      99          244 :     level--;
     100          241 :   if (level == 0 && ci != &L->base_ci) {  /* level found? */
     101          226 :     status = 1;
     102          226 :     ar->i_ci = ci;
     103              :   }
     104           15 :   else status = 0;  /* no such level */
     105              :   lua_unlock(L);
     106          241 :   return status;
     107              : }
     108              : 
     109              : 
     110           56 : static const char *upvalname (Proto *p, int uv) {
     111           56 :   TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
     112           56 :   if (s == NULL) return "?";
     113           56 :   else return getstr(s);
     114              : }
     115              : 
     116              : 
     117            0 : static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
     118            0 :   int nparams = clLvalue(ci->func)->p->numparams;
     119            0 :   if (n >= ci->u.l.base - ci->func - nparams)
     120            0 :     return NULL;  /* no such vararg */
     121              :   else {
     122            0 :     *pos = ci->func + nparams + n;
     123            0 :     return "(*vararg)";  /* generic name for any vararg */
     124              :   }
     125              : }
     126              : 
     127              : 
     128            3 : static const char *findlocal (lua_State *L, CallInfo *ci, int n,
     129              :                               StkId *pos) {
     130            3 :   const char *name = NULL;
     131              :   StkId base;
     132            3 :   if (isLua(ci)) {
     133            0 :     if (n < 0)  /* access to vararg values? */
     134            0 :       return findvararg(ci, -n, pos);
     135              :     else {
     136            0 :       base = ci->u.l.base;
     137            0 :       name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
     138              :     }
     139              :   }
     140              :   else
     141            3 :     base = ci->func + 1;
     142            3 :   if (name == NULL) {  /* no 'standard' name? */
     143            3 :     StkId limit = (ci == L->ci) ? L->top : ci->next->func;
     144            3 :     if (limit - base >= n && n > 0)  /* is 'n' inside 'ci' stack? */
     145            2 :       name = "(*temporary)";  /* generic name for any valid slot */
     146              :     else
     147            1 :       return NULL;  /* no name */
     148              :   }
     149            2 :   *pos = base + (n - 1);
     150            2 :   return name;
     151              : }
     152              : 
     153              : 
     154            2 : LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
     155              :   const char *name;
     156              :   lua_lock(L);
     157            2 :   swapextra(L);
     158            2 :   if (ar == NULL) {  /* information about non-active function? */
     159            1 :     if (!isLfunction(L->top - 1))  /* not a Lua function? */
     160            0 :       name = NULL;
     161              :     else  /* consider live variables at function start (parameters) */
     162            1 :       name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
     163              :   }
     164              :   else {  /* active function; get information through 'ar' */
     165            1 :     StkId pos = 0;  /* to avoid warnings */
     166            1 :     name = findlocal(L, ar->i_ci, n, &pos);
     167            1 :     if (name) {
     168            1 :       setobj2s(L, L->top, pos);
     169            1 :       api_incr_top(L);
     170              :     }
     171              :   }
     172            2 :   swapextra(L);
     173              :   lua_unlock(L);
     174            2 :   return name;
     175              : }
     176              : 
     177              : 
     178            2 : LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
     179            2 :   StkId pos = 0;  /* to avoid warnings */
     180              :   const char *name;
     181              :   lua_lock(L);
     182            2 :   swapextra(L);
     183            2 :   name = findlocal(L, ar->i_ci, n, &pos);
     184            2 :   if (name)
     185            1 :     setobjs2s(L, pos, L->top - 1);
     186            2 :   L->top--;  /* pop value */
     187            2 :   swapextra(L);
     188              :   lua_unlock(L);
     189            2 :   return name;
     190              : }
     191              : 
     192              : 
     193          162 : static void funcinfo (lua_Debug *ar, Closure *cl) {
     194          162 :   if (noLuaClosure(cl)) {
     195           56 :     ar->source = "=[C]";
     196           56 :     ar->linedefined = -1;
     197           56 :     ar->lastlinedefined = -1;
     198           56 :     ar->what = "C";
     199              :   }
     200              :   else {
     201          106 :     Proto *p = cl->l.p;
     202          106 :     ar->source = p->source ? getstr(p->source) : "=?";
     203          106 :     ar->linedefined = p->linedefined;
     204          106 :     ar->lastlinedefined = p->lastlinedefined;
     205          106 :     ar->what = (ar->linedefined == 0) ? "main" : "Lua";
     206              :   }
     207          162 :   luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
     208          162 : }
     209              : 
     210              : 
     211            1 : static void collectvalidlines (lua_State *L, Closure *f) {
     212            1 :   if (noLuaClosure(f)) {
     213            0 :     setnilvalue(L->top);
     214            0 :     api_incr_top(L);
     215              :   }
     216              :   else {
     217              :     int i;
     218              :     TValue v;
     219            1 :     int *lineinfo = f->l.p->lineinfo;
     220            1 :     Table *t = luaH_new(L);  /* new table to store active lines */
     221            1 :     sethvalue(L, L->top, t);  /* push it on stack */
     222            1 :     api_incr_top(L);
     223            1 :     setbvalue(&v, 1);  /* boolean 'true' to be the value of all indices */
     224           26 :     for (i = 0; i < f->l.p->sizelineinfo; i++)  /* for all lines with code */
     225           25 :       luaH_setint(L, t, lineinfo[i], &v);  /* table[line] = true */
     226              :   }
     227            1 : }
     228              : 
     229              : 
     230          222 : static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
     231              :                        Closure *f, CallInfo *ci) {
     232          222 :   int status = 1;
     233          634 :   for (; *what; what++) {
     234          412 :     switch (*what) {
     235          162 :       case 'S': {
     236          162 :         funcinfo(ar, f);
     237          162 :         break;
     238              :       }
     239          162 :       case 'l': {
     240          162 :         ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1;
     241          162 :         break;
     242              :       }
     243            6 :       case 'u': {
     244            6 :         ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
     245            6 :         if (noLuaClosure(f)) {
     246            0 :           ar->isvararg = 1;
     247            0 :           ar->nparams = 0;
     248              :         }
     249              :         else {
     250            6 :           ar->isvararg = f->l.p->is_vararg;
     251            6 :           ar->nparams = f->l.p->numparams;
     252              :         }
     253            6 :         break;
     254              :       }
     255           12 :       case 't': {
     256           12 :         ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0;
     257           12 :         break;
     258              :       }
     259           60 :       case 'n': {
     260              :         /* calling function is a known Lua function? */
     261           60 :         if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
     262           50 :           ar->namewhat = getfuncname(L, ci->previous, &ar->name);
     263              :         else
     264           10 :           ar->namewhat = NULL;
     265           60 :         if (ar->namewhat == NULL) {
     266           10 :           ar->namewhat = "";  /* not found */
     267           10 :           ar->name = NULL;
     268              :         }
     269           60 :         break;
     270              :       }
     271            9 :       case 'L':
     272              :       case 'f':  /* handled by lua_getinfo */
     273            9 :         break;
     274            1 :       default: status = 0;  /* invalid option */
     275              :     }
     276              :   }
     277          222 :   return status;
     278              : }
     279              : 
     280              : 
     281          222 : LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
     282              :   int status;
     283              :   Closure *cl;
     284              :   CallInfo *ci;
     285              :   StkId func;
     286              :   lua_lock(L);
     287          222 :   swapextra(L);
     288          222 :   if (*what == '>') {
     289            7 :     ci = NULL;
     290            7 :     func = L->top - 1;
     291              :     api_check(L, ttisfunction(func), "function expected");
     292            7 :     what++;  /* skip the '>' */
     293            7 :     L->top--;  /* pop function */
     294              :   }
     295              :   else {
     296          215 :     ci = ar->i_ci;
     297          215 :     func = ci->func;
     298              :     lua_assert(ttisfunction(ci->func));
     299              :   }
     300          222 :   cl = ttisclosure(func) ? clvalue(func) : NULL;
     301          222 :   status = auxgetinfo(L, what, ar, cl, ci);
     302          222 :   if (strchr(what, 'f')) {
     303            8 :     setobjs2s(L, L->top, func);
     304            8 :     api_incr_top(L);
     305              :   }
     306          222 :   swapextra(L);
     307          222 :   if (strchr(what, 'L'))
     308            1 :     collectvalidlines(L, cl);
     309              :   lua_unlock(L);
     310          222 :   return status;
     311              : }
     312              : 
     313              : 
     314              : /*
     315              : ** {======================================================
     316              : ** Symbolic Execution
     317              : ** =======================================================
     318              : */
     319              : 
     320              : static const char *getobjname (Proto *p, int lastpc, int reg,
     321              :                                const char **name);
     322              : 
     323              : 
     324              : /*
     325              : ** find a "name" for the RK value 'c'
     326              : */
     327           50 : static void kname (Proto *p, int pc, int c, const char **name) {
     328           50 :   if (ISK(c)) {  /* is 'c' a constant? */
     329           50 :     TValue *kvalue = &p->k[INDEXK(c)];
     330           50 :     if (ttisstring(kvalue)) {  /* literal constant? */
     331           50 :       *name = svalue(kvalue);  /* it is its own name */
     332           50 :       return;
     333              :     }
     334              :     /* else no reasonable name found */
     335              :   }
     336              :   else {  /* 'c' is a register */
     337            0 :     const char *what = getobjname(p, pc, c, name); /* search for 'c' */
     338            0 :     if (what && *what == 'c') {  /* found a constant name? */
     339            0 :       return;  /* 'name' already filled */
     340              :     }
     341              :     /* else no reasonable name found */
     342              :   }
     343            0 :   *name = "?";  /* no reasonable name found */
     344              : }
     345              : 
     346              : 
     347          454 : static int filterpc (int pc, int jmptarget) {
     348          454 :   if (pc < jmptarget)  /* is code conditional (inside a jump)? */
     349          173 :     return -1;  /* cannot know who sets that register */
     350          281 :   else return pc;  /* current position sets that register */
     351              : }
     352              : 
     353              : 
     354              : /*
     355              : ** try to find last instruction before 'lastpc' that modified register 'reg'
     356              : */
     357          108 : static int findsetreg (Proto *p, int lastpc, int reg) {
     358              :   int pc;
     359          108 :   int setreg = -1;  /* keep last instruction that changed 'reg' */
     360          108 :   int jmptarget = 0;  /* any code before this address is conditional */
     361         1382 :   for (pc = 0; pc < lastpc; pc++) {
     362         1274 :     Instruction i = p->code[pc];
     363         1274 :     OpCode op = GET_OPCODE(i);
     364         1274 :     int a = GETARG_A(i);
     365         1274 :     switch (op) {
     366           17 :       case OP_LOADNIL: {
     367           17 :         int b = GETARG_B(i);
     368           17 :         if (a <= reg && reg <= a + b)  /* set registers from 'a' to 'a+b' */
     369            4 :           setreg = filterpc(pc, jmptarget);
     370           17 :         break;
     371              :       }
     372            0 :       case OP_TFORCALL: {
     373            0 :         if (reg >= a + 2)  /* affect all regs above its base */
     374            0 :           setreg = filterpc(pc, jmptarget);
     375            0 :         break;
     376              :       }
     377          248 :       case OP_CALL:
     378              :       case OP_TAILCALL: {
     379          248 :         if (reg >= a)  /* affect all registers above base */
     380          247 :           setreg = filterpc(pc, jmptarget);
     381          248 :         break;
     382              :       }
     383           47 :       case OP_JMP: {
     384           47 :         int b = GETARG_sBx(i);
     385           47 :         int dest = pc + 1 + b;
     386              :         /* jump is forward and do not skip `lastpc'? */
     387           47 :         if (pc < dest && dest <= lastpc) {
     388           47 :           if (dest > jmptarget)
     389           35 :             jmptarget = dest;  /* update 'jmptarget' */
     390              :         }
     391           47 :         break;
     392              :       }
     393           12 :       case OP_TEST: {
     394           12 :         if (reg == a)  /* jumped code can change 'a' */
     395            1 :           setreg = filterpc(pc, jmptarget);
     396           12 :         break;
     397              :       }
     398          950 :       default:
     399          950 :         if (testAMode(op) && reg == a)  /* any instruction that set A */
     400          202 :           setreg = filterpc(pc, jmptarget);
     401          950 :         break;
     402              :     }
     403              :   }
     404          108 :   return setreg;
     405              : }
     406              : 
     407              : 
     408          118 : static const char *getobjname (Proto *p, int lastpc, int reg,
     409              :                                const char **name) {
     410              :   int pc;
     411          118 :   *name = luaF_getlocalname(p, reg + 1, lastpc);
     412          118 :   if (*name)  /* is a local? */
     413           10 :     return "local";
     414              :   /* else try symbolic execution */
     415          108 :   pc = findsetreg(p, lastpc, reg);
     416          108 :   if (pc != -1) {  /* could find instruction? */
     417          108 :     Instruction i = p->code[pc];
     418          108 :     OpCode op = GET_OPCODE(i);
     419          108 :     switch (op) {
     420            0 :       case OP_MOVE: {
     421            0 :         int b = GETARG_B(i);  /* move from 'b' to 'a' */
     422            0 :         if (b < GETARG_A(i))
     423            0 :           return getobjname(p, pc, b, name);  /* get name for 'b' */
     424            0 :         break;
     425              :       }
     426           48 :       case OP_GETTABUP:
     427              :       case OP_GETTABLE: {
     428           48 :         int k = GETARG_C(i);  /* key index */
     429           48 :         int t = GETARG_B(i);  /* table index */
     430           48 :         const char *vn = (op == OP_GETTABLE)  /* name of indexed variable */
     431           33 :                          ? luaF_getlocalname(p, t + 1, pc)
     432           48 :                          : upvalname(p, t);
     433           48 :         kname(p, pc, k, name);
     434           48 :         return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
     435              :       }
     436           37 :       case OP_GETUPVAL: {
     437           37 :         *name = upvalname(p, GETARG_B(i));
     438           37 :         return "upvalue";
     439              :       }
     440            1 :       case OP_LOADK:
     441              :       case OP_LOADKX: {
     442            2 :         int b = (op == OP_LOADK) ? GETARG_Bx(i)
     443            1 :                                  : GETARG_Ax(p->code[pc + 1]);
     444            1 :         if (ttisstring(&p->k[b])) {
     445            1 :           *name = svalue(&p->k[b]);
     446            1 :           return "constant";
     447              :         }
     448            0 :         break;
     449              :       }
     450            2 :       case OP_SELF: {
     451            2 :         int k = GETARG_C(i);  /* key index */
     452            2 :         kname(p, pc, k, name);
     453            2 :         return "method";
     454              :       }
     455           20 :       default: break;  /* go through to return NULL */
     456              :     }
     457              :   }
     458           20 :   return NULL;  /* could not find reasonable name */
     459              : }
     460              : 
     461              : 
     462           50 : static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
     463              :   TMS tm;
     464           50 :   Proto *p = ci_func(ci)->p;  /* calling function */
     465           50 :   int pc = currentpc(ci);  /* calling instruction index */
     466           50 :   Instruction i = p->code[pc];  /* calling instruction */
     467           50 :   switch (GET_OPCODE(i)) {
     468           50 :     case OP_CALL:
     469              :     case OP_TAILCALL:  /* get function name */
     470           50 :       return getobjname(p, pc, GETARG_A(i), name);
     471            0 :     case OP_TFORCALL: {  /* for iterator */
     472            0 :       *name = "for iterator";
     473            0 :        return "for iterator";
     474              :     }
     475              :     /* all other instructions can call only through metamethods */
     476            0 :     case OP_SELF:
     477              :     case OP_GETTABUP:
     478            0 :     case OP_GETTABLE: tm = TM_INDEX; break;
     479            0 :     case OP_SETTABUP:
     480            0 :     case OP_SETTABLE: tm = TM_NEWINDEX; break;
     481            0 :     case OP_EQ: tm = TM_EQ; break;
     482            0 :     case OP_ADD: tm = TM_ADD; break;
     483            0 :     case OP_SUB: tm = TM_SUB; break;
     484            0 :     case OP_MUL: tm = TM_MUL; break;
     485            0 :     case OP_DIV: tm = TM_DIV; break;
     486            0 :     case OP_MOD: tm = TM_MOD; break;
     487            0 :     case OP_POW: tm = TM_POW; break;
     488            0 :     case OP_UNM: tm = TM_UNM; break;
     489            0 :     case OP_LEN: tm = TM_LEN; break;
     490            0 :     case OP_LT: tm = TM_LT; break;
     491            0 :     case OP_LE: tm = TM_LE; break;
     492            0 :     case OP_CONCAT: tm = TM_CONCAT; break;
     493            0 :     default:
     494            0 :       return NULL;  /* else no useful name can be found */
     495              :   }
     496            0 :   *name = getstr(G(L)->tmname[tm]);
     497            0 :   return "metamethod";
     498              : }
     499              : 
     500              : /* }====================================================== */
     501              : 
     502              : 
     503              : 
     504              : /*
     505              : ** only ANSI way to check whether a pointer points to an array
     506              : ** (used only for error messages, so efficiency is not a big concern)
     507              : */
     508          104 : static int isinstack (CallInfo *ci, const TValue *o) {
     509              :   StkId p;
     510          178 :   for (p = ci->u.l.base; p < ci->top; p++)
     511          142 :     if (o == p) return 1;
     512           36 :   return 0;
     513              : }
     514              : 
     515              : 
     516          108 : static const char *getupvalname (CallInfo *ci, const TValue *o,
     517              :                                  const char **name) {
     518          108 :   LClosure *c = ci_func(ci);
     519              :   int i;
     520          158 :   for (i = 0; i < c->nupvalues; i++) {
     521           54 :     if (c->upvals[i]->v == o) {
     522            4 :       *name = upvalname(c->p, i);
     523            4 :       return "upvalue";
     524              :     }
     525              :   }
     526          104 :   return NULL;
     527              : }
     528              : 
     529              : 
     530          110 : l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
     531          110 :   CallInfo *ci = L->ci;
     532          110 :   const char *name = NULL;
     533          110 :   const char *t = objtypename(o);
     534          110 :   const char *kind = NULL;
     535          110 :   if (isLua(ci)) {
     536          108 :     kind = getupvalname(ci, o, &name);  /* check whether 'o' is an upvalue */
     537          108 :     if (!kind && isinstack(ci, o))  /* no? try a register */
     538           68 :       kind = getobjname(ci_func(ci)->p, currentpc(ci),
     539           68 :                         cast_int(o - ci->u.l.base), &name);
     540              :   }
     541          110 :   if (kind)
     542           52 :     luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
     543              :                 op, kind, name, t);
     544              :   else
     545           58 :     luaG_runerror(L, "attempt to %s a %s value", op, t);
     546              : }
     547              : 
     548              : 
     549            9 : l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
     550            9 :   if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
     551              :   lua_assert(!ttisstring(p1) && !ttisnumber(p1));
     552            9 :   luaG_typeerror(L, p1, "concatenate");
     553              : }
     554              : 
     555              : 
     556           78 : l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
     557              :   TValue temp;
     558           78 :   if (luaV_tonumber(p1, &temp) == NULL)
     559           51 :     p2 = p1;  /* first operand is wrong */
     560           78 :   luaG_typeerror(L, p2, "perform arithmetic on");
     561              : }
     562              : 
     563              : 
     564           74 : l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
     565           74 :   const char *t1 = objtypename(p1);
     566           74 :   const char *t2 = objtypename(p2);
     567           74 :   if (t1 == t2)
     568           28 :     luaG_runerror(L, "attempt to compare two %s values", t1);
     569              :   else
     570           46 :     luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
     571              : }
     572              : 
     573              : 
     574          192 : static void addinfo (lua_State *L, const char *msg) {
     575          192 :   CallInfo *ci = L->ci;
     576          192 :   if (isLua(ci)) {  /* is Lua code? */
     577              :     char buff[LUA_IDSIZE];  /* add file:line information */
     578          187 :     int line = currentline(ci);
     579          187 :     TString *src = ci_func(ci)->p->source;
     580          187 :     if (src)
     581          187 :       luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
     582              :     else {  /* no source available; use "?" instead */
     583            0 :       buff[0] = '?'; buff[1] = '\0';
     584              :     }
     585          187 :     luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
     586              :   }
     587          192 : }
     588              : 
     589              : 
     590          349 : l_noret luaG_errormsg (lua_State *L) {
     591          349 :   if (L->errfunc != 0) {  /* is there an error handling function? */
     592            9 :     StkId errfunc = restorestack(L, L->errfunc);
     593            9 :     if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
     594            8 :     setobjs2s(L, L->top, L->top - 1);  /* move argument */
     595            8 :     setobjs2s(L, L->top - 1, errfunc);  /* push function */
     596            8 :     L->top++;
     597            8 :     luaD_call(L, L->top - 2, 1, 0);  /* call it */
     598              :   }
     599          348 :   luaD_throw(L, LUA_ERRRUN);
     600              : }
     601              : 
     602              : 
     603          192 : l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
     604              :   va_list argp;
     605          192 :   va_start(argp, fmt);
     606          192 :   addinfo(L, luaO_pushvfstring(L, fmt, argp));
     607          192 :   va_end(argp);
     608          192 :   luaG_errormsg(L);
     609              : }
     610              : 
        

Generated by: LCOV version 2.0-1