LCOV - code coverage report
Current view: directory - src - ldebug.c Found Hit Coverage
Test: Lua 5.1.4 Lines: 334 185 55.4 %
Date: 2009-09-13
Colors: not hit hit

       1                 : /*
       2                 : ** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 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                 : static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
      34                 : 
      35                 : 
      36             324 : static int currentpc (lua_State *L, CallInfo *ci) {
      37             324 :   if (!isLua(ci)) return -1;  /* function is not a Lua function? */
      38             316 :   if (ci == L->ci)
      39             229 :     ci->savedpc = L->savedpc;
      40             316 :   return pcRel(ci->savedpc, ci_func(ci)->l.p);
      41                 : }
      42                 : 
      43                 : 
      44             222 : static int currentline (lua_State *L, CallInfo *ci) {
      45             222 :   int pc = currentpc(L, ci);
      46             222 :   if (pc < 0)
      47               8 :     return -1;  /* only active lua functions have current-line information */
      48                 :   else
      49             214 :     return getline(ci_func(ci)->l.p, pc);
      50                 : }
      51                 : 
      52                 : 
      53                 : /*
      54                 : ** this function can be called asynchronous (e.g. during a signal)
      55                 : */
      56               0 : LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
      57               0 :   if (func == NULL || mask == 0) {  /* turn off hooks? */
      58               0 :     mask = 0;
      59               0 :     func = NULL;
      60                 :   }
      61               0 :   L->hook = func;
      62               0 :   L->basehookcount = count;
      63               0 :   resethookcount(L);
      64               0 :   L->hookmask = cast_byte(mask);
      65               0 :   return 1;
      66                 : }
      67                 : 
      68                 : 
      69               0 : LUA_API lua_Hook lua_gethook (lua_State *L) {
      70               0 :   return L->hook;
      71                 : }
      72                 : 
      73                 : 
      74               0 : LUA_API int lua_gethookmask (lua_State *L) {
      75               0 :   return L->hookmask;
      76                 : }
      77                 : 
      78                 : 
      79               0 : LUA_API int lua_gethookcount (lua_State *L) {
      80               0 :   return L->basehookcount;
      81                 : }
      82                 : 
      83                 : 
      84             174 : LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
      85                 :   int status;
      86                 :   CallInfo *ci;
      87                 :   lua_lock(L);
      88             322 :   for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
      89             148 :     level--;
      90             148 :     if (f_isLua(ci))  /* Lua function? */
      91              12 :       level -= ci->tailcalls;  /* skip lost tail calls */
      92                 :   }
      93             325 :   if (level == 0 && ci > L->base_ci) {  /* level found? */
      94             151 :     status = 1;
      95             151 :     ar->i_ci = cast_int(ci - L->base_ci);
      96                 :   }
      97              23 :   else if (level < 0) {  /* level is of a lost tail call? */
      98               0 :     status = 1;
      99               0 :     ar->i_ci = 0;
     100                 :   }
     101              23 :   else status = 0;  /* no such level */
     102                 :   lua_unlock(L);
     103             174 :   return status;
     104                 : }
     105                 : 
     106                 : 
     107             165 : static Proto *getluaproto (CallInfo *ci) {
     108             165 :   return (isLua(ci) ? ci_func(ci)->l.p : NULL);
     109                 : }
     110                 : 
     111                 : 
     112               0 : static const char *findlocal (lua_State *L, CallInfo *ci, int n) {
     113                 :   const char *name;
     114               0 :   Proto *fp = getluaproto(ci);
     115               0 :   if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL)
     116               0 :     return name;  /* is a local variable in a Lua function */
     117                 :   else {
     118               0 :     StkId limit = (ci == L->ci) ? L->top : (ci+1)->func;
     119               0 :     if (limit - ci->base >= n && n > 0)  /* is 'n' inside 'ci' stack? */
     120               0 :       return "(*temporary)";
     121                 :     else
     122               0 :       return NULL;
     123                 :   }
     124                 : }
     125                 : 
     126                 : 
     127               0 : LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
     128               0 :   CallInfo *ci = L->base_ci + ar->i_ci;
     129               0 :   const char *name = findlocal(L, ci, n);
     130                 :   lua_lock(L);
     131               0 :   if (name)
     132               0 :       luaA_pushobject(L, ci->base + (n - 1));
     133                 :   lua_unlock(L);
     134               0 :   return name;
     135                 : }
     136                 : 
     137                 : 
     138               0 : LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
     139               0 :   CallInfo *ci = L->base_ci + ar->i_ci;
     140               0 :   const char *name = findlocal(L, ci, n);
     141                 :   lua_lock(L);
     142               0 :   if (name)
     143               0 :       setobjs2s(L, ci->base + (n - 1), L->top - 1);
     144               0 :   L->top--;  /* pop value */
     145                 :   lua_unlock(L);
     146               0 :   return name;
     147                 : }
     148                 : 
     149                 : 
     150              57 : static void funcinfo (lua_Debug *ar, Closure *cl) {
     151              57 :   if (cl->c.isC) {
     152               8 :     ar->source = "=[C]";
     153               8 :     ar->linedefined = -1;
     154               8 :     ar->lastlinedefined = -1;
     155               8 :     ar->what = "C";
     156                 :   }
     157                 :   else {
     158              49 :     ar->source = getstr(cl->l.p->source);
     159              49 :     ar->linedefined = cl->l.p->linedefined;
     160              49 :     ar->lastlinedefined = cl->l.p->lastlinedefined;
     161              49 :     ar->what = (ar->linedefined == 0) ? "main" : "Lua";
     162                 :   }
     163              57 :   luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
     164              57 : }
     165                 : 
     166                 : 
     167               0 : static void info_tailcall (lua_Debug *ar) {
     168               0 :   ar->name = ar->namewhat = "";
     169               0 :   ar->what = "tail";
     170               0 :   ar->lastlinedefined = ar->linedefined = ar->currentline = -1;
     171               0 :   ar->source = "=(tail call)";
     172               0 :   luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
     173               0 :   ar->nups = 0;
     174               0 : }
     175                 : 
     176                 : 
     177               0 : static void collectvalidlines (lua_State *L, Closure *f) {
     178               0 :   if (f == NULL || f->c.isC) {
     179               0 :     setnilvalue(L->top);
     180                 :   }
     181                 :   else {
     182               0 :     Table *t = luaH_new(L, 0, 0);
     183               0 :     int *lineinfo = f->l.p->lineinfo;
     184                 :     int i;
     185               0 :     for (i=0; i<f->l.p->sizelineinfo; i++)
     186               0 :       setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
     187               0 :     sethvalue(L, L->top, t); 
     188                 :   }
     189               0 :   incr_top(L);
     190               0 : }
     191                 : 
     192                 : 
     193                 : static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
     194             151 :                     Closure *f, CallInfo *ci) {
     195             151 :   int status = 1;
     196             151 :   if (f == NULL) {
     197               0 :     info_tailcall(ar);
     198               0 :     return status;
     199                 :   }
     200             363 :   for (; *what; what++) {
     201             212 :     switch (*what) {
     202                 :       case 'S': {
     203              57 :         funcinfo(ar, f);
     204              57 :         break;
     205                 :       }
     206                 :       case 'l': {
     207              57 :         ar->currentline = (ci) ? currentline(L, ci) : -1;
     208              57 :         break;
     209                 :       }
     210                 :       case 'u': {
     211               0 :         ar->nups = f->c.nupvalues;
     212               0 :         break;
     213                 :       }
     214                 :       case 'n': {
     215              27 :         ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL;
     216              27 :         if (ar->namewhat == NULL) {
     217               8 :           ar->namewhat = "";  /* not found */
     218               8 :           ar->name = NULL;
     219                 :         }
     220              27 :         break;
     221                 :       }
     222                 :       case 'L':
     223                 :       case 'f':  /* handled by lua_getinfo */
     224              71 :         break;
     225               0 :       default: status = 0;  /* invalid option */
     226                 :     }
     227                 :   }
     228             151 :   return status;
     229                 : }
     230                 : 
     231                 : 
     232             151 : LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
     233                 :   int status;
     234             151 :   Closure *f = NULL;
     235             151 :   CallInfo *ci = NULL;
     236                 :   lua_lock(L);
     237             151 :   if (*what == '>') {
     238               0 :     StkId func = L->top - 1;
     239                 :     luai_apicheck(L, ttisfunction(func));
     240               0 :     what++;  /* skip the '>' */
     241               0 :     f = clvalue(func);
     242               0 :     L->top--;  /* pop function */
     243                 :   }
     244             151 :   else if (ar->i_ci != 0) {  /* no tail call? */
     245             151 :     ci = L->base_ci + ar->i_ci;
     246                 :     lua_assert(ttisfunction(ci->func));
     247             151 :     f = clvalue(ci->func);
     248                 :   }
     249             151 :   status = auxgetinfo(L, what, ar, f, ci);
     250             151 :   if (strchr(what, 'f')) {
     251              71 :     if (f == NULL) setnilvalue(L->top);
     252              71 :     else setclvalue(L, L->top, f);
     253              71 :     incr_top(L);
     254                 :   }
     255             151 :   if (strchr(what, 'L'))
     256               0 :     collectvalidlines(L, f);
     257                 :   lua_unlock(L);
     258             151 :   return status;
     259                 : }
     260                 : 
     261                 : 
     262                 : /*
     263                 : ** {======================================================
     264                 : ** Symbolic Execution and code checker
     265                 : ** =======================================================
     266                 : */
     267                 : 
     268                 : #define check(x)                if (!(x)) return 0;
     269                 : 
     270                 : #define checkjump(pt,pc)        check(0 <= pc && pc < pt->sizecode)
     271                 : 
     272                 : #define checkreg(pt,reg)        check((reg) < (pt)->maxstacksize)
     273                 : 
     274                 : 
     275                 : 
     276              82 : static int precheck (const Proto *pt) {
     277              82 :   check(pt->maxstacksize <= MAXSTACK);
     278              82 :   check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize);
     279              82 :   check(!(pt->is_vararg & VARARG_NEEDSARG) ||
     280                 :               (pt->is_vararg & VARARG_HASARG));
     281              82 :   check(pt->sizeupvalues <= pt->nups);
     282              82 :   check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0);
     283              82 :   check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
     284              82 :   return 1;
     285                 : }
     286                 : 
     287                 : 
     288                 : #define checkopenop(pt,pc)      luaG_checkopenop((pt)->code[(pc)+1])
     289                 : 
     290               0 : int luaG_checkopenop (Instruction i) {
     291               0 :   switch (GET_OPCODE(i)) {
     292                 :     case OP_CALL:
     293                 :     case OP_TAILCALL:
     294                 :     case OP_RETURN:
     295                 :     case OP_SETLIST: {
     296               0 :       check(GETARG_B(i) == 0);
     297               0 :       return 1;
     298                 :     }
     299               0 :     default: return 0;  /* invalid instruction after an open call */
     300                 :   }
     301                 : }
     302                 : 
     303                 : 
     304              40 : static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) {
     305              40 :   switch (mode) {
     306               0 :     case OpArgN: check(r == 0); break;
     307              26 :     case OpArgU: break;
     308               7 :     case OpArgR: checkreg(pt, r); break;
     309                 :     case OpArgK:
     310               7 :       check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize);
     311                 :       break;
     312                 :   }
     313              40 :   return 1;
     314                 : }
     315                 : 
     316                 : 
     317              82 : static Instruction symbexec (const Proto *pt, int lastpc, int reg) {
     318                 :   int pc;
     319                 :   int last;  /* stores position of last instruction that changed `reg' */
     320              82 :   last = pt->sizecode-1;  /* points to final return (a `neutral' instruction) */
     321              82 :   check(precheck(pt));
     322             239 :   for (pc = 0; pc < lastpc; pc++) {
     323             157 :     Instruction i = pt->code[pc];
     324             157 :     OpCode op = GET_OPCODE(i);
     325             157 :     int a = GETARG_A(i);
     326             157 :     int b = 0;
     327             157 :     int c = 0;
     328             157 :     check(op < NUM_OPCODES);
     329             157 :     checkreg(pt, a);
     330             157 :     switch (getOpMode(op)) {
     331                 :       case iABC: {
     332              20 :         b = GETARG_B(i);
     333              20 :         c = GETARG_C(i);
     334              20 :         check(checkArgMode(pt, b, getBMode(op)));
     335              20 :         check(checkArgMode(pt, c, getCMode(op)));
     336              20 :         break;
     337                 :       }
     338                 :       case iABx: {
     339             137 :         b = GETARG_Bx(i);
     340             137 :         if (getBMode(op) == OpArgK) check(b < pt->sizek);
     341             137 :         break;
     342                 :       }
     343                 :       case iAsBx: {
     344               0 :         b = GETARG_sBx(i);
     345               0 :         if (getBMode(op) == OpArgR) {
     346               0 :           int dest = pc+1+b;
     347               0 :           check(0 <= dest && dest < pt->sizecode);
     348               0 :           if (dest > 0) {
     349                 :             int j;
     350                 :             /* check that it does not jump to a setlist count; this
     351                 :                is tricky, because the count from a previous setlist may
     352                 :                have the same value of an invalid setlist; so, we must
     353                 :                go all the way back to the first of them (if any) */
     354               0 :             for (j = 0; j < dest; j++) {
     355               0 :               Instruction d = pt->code[dest-1-j];
     356               0 :               if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break;
     357                 :             }
     358                 :             /* if 'j' is even, previous value is not a setlist (even if
     359                 :                it looks like one) */
     360               0 :             check((j&1) == 0);
     361                 :           }
     362                 :         }
     363                 :         break;
     364                 :       }
     365                 :     }
     366             157 :     if (testAMode(op)) {
     367             137 :       if (a == reg) last = pc;  /* change register `a' */
     368                 :     }
     369             157 :     if (testTMode(op)) {
     370               0 :       check(pc+2 < pt->sizecode);  /* check skip */
     371               0 :       check(GET_OPCODE(pt->code[pc+1]) == OP_JMP);
     372                 :     }
     373             157 :     switch (op) {
     374                 :       case OP_LOADBOOL: {
     375               8 :         if (c == 1) {  /* does it jump? */
     376               0 :           check(pc+2 < pt->sizecode);  /* check its jump */
     377               0 :           check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST ||
     378                 :                 GETARG_C(pt->code[pc+1]) != 0);
     379                 :         }
     380               8 :         break;
     381                 :       }
     382                 :       case OP_LOADNIL: {
     383               0 :         if (a <= reg && reg <= b)
     384               0 :           last = pc;  /* set registers from `a' to `b' */
     385               0 :         break;
     386                 :       }
     387                 :       case OP_GETUPVAL:
     388                 :       case OP_SETUPVAL: {
     389               0 :         check(b < pt->nups);
     390               0 :         break;
     391                 :       }
     392                 :       case OP_GETGLOBAL:
     393                 :       case OP_SETGLOBAL: {
     394             104 :         check(ttisstring(&pt->k[b]));
     395             104 :         break;
     396                 :       }
     397                 :       case OP_SELF: {
     398               2 :         checkreg(pt, a+1);
     399               2 :         if (reg == a+1) last = pc;
     400               2 :         break;
     401                 :       }
     402                 :       case OP_CONCAT: {
     403               0 :         check(b < c);  /* at least two operands */
     404               0 :         break;
     405                 :       }
     406                 :       case OP_TFORLOOP: {
     407               0 :         check(c >= 1);  /* at least one result (control variable) */
     408               0 :         checkreg(pt, a+2+c);  /* space for results */
     409               0 :         if (reg >= a+2) last = pc;  /* affect all regs above its base */
     410               0 :         break;
     411                 :       }
     412                 :       case OP_FORLOOP:
     413                 :       case OP_FORPREP:
     414               0 :         checkreg(pt, a+3);
     415                 :         /* go through */
     416                 :       case OP_JMP: {
     417               0 :         int dest = pc+1+b;
     418                 :         /* not full check and jump is forward and do not skip `lastpc'? */
     419               0 :         if (reg != NO_REG && pc < dest && dest <= lastpc)
     420               0 :           pc += b;  /* do the jump */
     421               0 :         break;
     422                 :       }
     423                 :       case OP_CALL:
     424                 :       case OP_TAILCALL: {
     425               0 :         if (b != 0) {
     426               0 :           checkreg(pt, a+b-1);
     427                 :         }
     428               0 :         c--;  /* c = num. returns */
     429               0 :         if (c == LUA_MULTRET) {
     430               0 :           check(checkopenop(pt, pc));
     431                 :         }
     432               0 :         else if (c != 0)
     433               0 :           checkreg(pt, a+c-1);
     434               0 :         if (reg >= a) last = pc;  /* affect all registers above base */
     435               0 :         break;
     436                 :       }
     437                 :       case OP_RETURN: {
     438               0 :         b--;  /* b = num. returns */
     439               0 :         if (b > 0) checkreg(pt, a+b-1);
     440               0 :         break;
     441                 :       }
     442                 :       case OP_SETLIST: {
     443               0 :         if (b > 0) checkreg(pt, a + b);
     444               0 :         if (c == 0) {
     445               0 :           pc++;
     446               0 :           check(pc < pt->sizecode - 1);
     447                 :         }
     448               0 :         break;
     449                 :       }
     450                 :       case OP_CLOSURE: {
     451                 :         int nup, j;
     452               0 :         check(b < pt->sizep);
     453               0 :         nup = pt->p[b]->nups;
     454               0 :         check(pc + nup < pt->sizecode);
     455               0 :         for (j = 1; j <= nup; j++) {
     456               0 :           OpCode op1 = GET_OPCODE(pt->code[pc + j]);
     457               0 :           check(op1 == OP_GETUPVAL || op1 == OP_MOVE);
     458                 :         }
     459               0 :         if (reg != NO_REG)  /* tracing? */
     460               0 :           pc += nup;  /* do not 'execute' these pseudo-instructions */
     461               0 :         break;
     462                 :       }
     463                 :       case OP_VARARG: {
     464               0 :         check((pt->is_vararg & VARARG_ISVARARG) &&
     465                 :              !(pt->is_vararg & VARARG_NEEDSARG));
     466               0 :         b--;
     467               0 :         if (b == LUA_MULTRET) check(checkopenop(pt, pc));
     468               0 :         checkreg(pt, a+b-1);
     469                 :         break;
     470                 :       }
     471                 :       default: break;
     472                 :     }
     473                 :   }
     474              82 :   return pt->code[last];
     475                 : }
     476                 : 
     477                 : #undef check
     478                 : #undef checkjump
     479                 : #undef checkreg
     480                 : 
     481                 : /* }====================================================== */
     482                 : 
     483                 : 
     484               0 : int luaG_checkcode (const Proto *pt) {
     485               0 :   return (symbexec(pt, pt->sizecode, NO_REG) != 0);
     486                 : }
     487                 : 
     488                 : 
     489               7 : static const char *kname (Proto *p, int c) {
     490               7 :   if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
     491               7 :     return svalue(&p->k[INDEXK(c)]);
     492                 :   else
     493               0 :     return "?";
     494                 : }
     495                 : 
     496                 : 
     497                 : static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
     498              84 :                                const char **name) {
     499              84 :   if (isLua(ci)) {  /* a Lua function? */
     500              83 :     Proto *p = ci_func(ci)->l.p;
     501              83 :     int pc = currentpc(L, ci);
     502                 :     Instruction i;
     503              83 :     *name = luaF_getlocalname(p, stackpos+1, pc);
     504              83 :     if (*name)  /* is a local? */
     505               1 :       return "local";
     506              82 :     i = symbexec(p, pc, stackpos);  /* try symbolic execution */
     507                 :     lua_assert(pc != -1);
     508              82 :     switch (GET_OPCODE(i)) {
     509                 :       case OP_GETGLOBAL: {
     510              63 :         int g = GETARG_Bx(i);  /* global index */
     511                 :         lua_assert(ttisstring(&p->k[g]));
     512              63 :         *name = svalue(&p->k[g]);
     513              63 :         return "global";
     514                 :       }
     515                 :       case OP_MOVE: {
     516               0 :         int a = GETARG_A(i);
     517               0 :         int b = GETARG_B(i);  /* move from `b' to `a' */
     518               0 :         if (b < a)
     519               0 :           return getobjname(L, ci, b, name);  /* get name for `b' */
     520               0 :         break;
     521                 :       }
     522                 :       case OP_GETTABLE: {
     523               5 :         int k = GETARG_C(i);  /* key index */
     524               5 :         *name = kname(p, k);
     525               5 :         return "field";
     526                 :       }
     527                 :       case OP_GETUPVAL: {
     528               0 :         int u = GETARG_B(i);  /* upvalue index */
     529               0 :         *name = p->upvalues ? getstr(p->upvalues[u]) : "?";
     530               0 :         return "upvalue";
     531                 :       }
     532                 :       case OP_SELF: {
     533               2 :         int k = GETARG_C(i);  /* key index */
     534               2 :         *name = kname(p, k);
     535               2 :         return "method";
     536                 :       }
     537                 :       default: break;
     538                 :     }
     539                 :   }
     540              13 :   return NULL;  /* no useful name found */
     541                 : }
     542                 : 
     543                 : 
     544              27 : static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
     545                 :   Instruction i;
     546              27 :   if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1))
     547               8 :     return NULL;  /* calling function is not Lua (or is unknown) */
     548              19 :   ci--;  /* calling function */
     549              19 :   i = ci_func(ci)->l.p->code[currentpc(L, ci)];
     550              19 :   if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL ||
     551                 :       GET_OPCODE(i) == OP_TFORLOOP)
     552              19 :     return getobjname(L, ci, GETARG_A(i), name);
     553                 :   else
     554               0 :     return NULL;  /* no useful name can be found */
     555                 : }
     556                 : 
     557                 : 
     558                 : /* only ANSI way to check whether a pointer points to an array */
     559             100 : static int isinstack (CallInfo *ci, const TValue *o) {
     560                 :   StkId p;
     561             173 :   for (p = ci->base; p < ci->top; p++)
     562             138 :     if (o == p) return 1;
     563              35 :   return 0;
     564                 : }
     565                 : 
     566                 : 
     567             100 : void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
     568             100 :   const char *name = NULL;
     569             100 :   const char *t = luaT_typenames[ttype(o)];
     570                 :   const char *kind = (isinstack(L->ci, o)) ?
     571                 :                          getobjname(L, L->ci, cast_int(o - L->base), &name) :
     572             100 :                          NULL;
     573             100 :   if (kind)
     574              52 :     luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
     575                 :                 op, kind, name, t);
     576                 :   else
     577              48 :     luaG_runerror(L, "attempt to %s a %s value", op, t);
     578               0 : }
     579                 : 
     580                 : 
     581               8 : void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
     582               8 :   if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
     583                 :   lua_assert(!ttisstring(p1) && !ttisnumber(p1));
     584               8 :   luaG_typeerror(L, p1, "concatenate");
     585               0 : }
     586                 : 
     587                 : 
     588              68 : void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
     589                 :   TValue temp;
     590              68 :   if (luaV_tonumber(p1, &temp) == NULL)
     591              44 :     p2 = p1;  /* first operand is wrong */
     592              68 :   luaG_typeerror(L, p2, "perform arithmetic on");
     593               0 : }
     594                 : 
     595                 : 
     596              66 : int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
     597              66 :   const char *t1 = luaT_typenames[ttype(p1)];
     598              66 :   const char *t2 = luaT_typenames[ttype(p2)];
     599              66 :   if (t1[2] == t2[2])
     600              24 :     luaG_runerror(L, "attempt to compare two %s values", t1);
     601                 :   else
     602              42 :     luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
     603               0 :   return 0;
     604                 : }
     605                 : 
     606                 : 
     607             167 : static void addinfo (lua_State *L, const char *msg) {
     608             167 :   CallInfo *ci = L->ci;
     609             167 :   if (isLua(ci)) {  /* is Lua code? */
     610                 :     char buff[LUA_IDSIZE];  /* add file:line information */
     611             165 :     int line = currentline(L, ci);
     612             165 :     luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE);
     613             165 :     luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
     614                 :   }
     615             167 : }
     616                 : 
     617                 : 
     618             222 : void luaG_errormsg (lua_State *L) {
     619             222 :   if (L->errfunc != 0) {  /* is there an error handling function? */
     620               2 :     StkId errfunc = restorestack(L, L->errfunc);
     621               2 :     if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
     622               1 :     setobjs2s(L, L->top, L->top - 1);  /* move argument */
     623               1 :     setobjs2s(L, L->top - 1, errfunc);  /* push function */
     624               1 :     incr_top(L);
     625               1 :     luaD_call(L, L->top - 2, 1);  /* call it */
     626                 :   }
     627             221 :   luaD_throw(L, LUA_ERRRUN);
     628               0 : }
     629                 : 
     630                 : 
     631             167 : void luaG_runerror (lua_State *L, const char *fmt, ...) {
     632                 :   va_list argp;
     633             167 :   va_start(argp, fmt);
     634             167 :   addinfo(L, luaO_pushvfstring(L, fmt, argp));
     635             167 :   va_end(argp);
     636             167 :   luaG_errormsg(L);
     637               0 : }
     638                 : 

Generated by: LCOV version 1.7