LCOV - code coverage report
Current view: top level - src - ldebug.c Coverage Total Hit
Test: Lua 5.1.5 Lines: 87.8 % 369 324
Test Date: 2024-04-28 10:23:09
Legend: Lines: hit not hit

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

Generated by: LCOV version 2.0-1