lua/ldebug.c

Go to the documentation of this file.
00001 /*
00002 ** $Id: ldebug.c,v 2.88 2011/11/30 12:43:51 roberto Exp $
00003 ** Debug Interface
00004 ** See Copyright Notice in lua.h
00005 */
00006 
00007 
00008 #include <stdarg.h>
00009 #include <stddef.h>
00010 #include <string.h>
00011 
00012 
00013 #define ldebug_c
00014 #define LUA_CORE
00015 
00016 #include "lua.h"
00017 
00018 #include "lapi.h"
00019 #include "lcode.h"
00020 #include "ldebug.h"
00021 #include "ldo.h"
00022 #include "lfunc.h"
00023 #include "lobject.h"
00024 #include "lopcodes.h"
00025 #include "lstate.h"
00026 #include "lstring.h"
00027 #include "ltable.h"
00028 #include "ltm.h"
00029 #include "lvm.h"
00030 
00031 
00032 
00033 static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
00034 
00035 
00036 static int currentpc (CallInfo *ci) {
00037   lua_assert(isLua(ci));
00038   return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
00039 }
00040 
00041 
00042 static int currentline (CallInfo *ci) {
00043   return getfuncline(ci_func(ci)->p, currentpc(ci));
00044 }
00045 
00046 
00047 /*
00048 ** this function can be called asynchronous (e.g. during a signal)
00049 */
00050 LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
00051   if (func == NULL || mask == 0) {  /* turn off hooks? */
00052     mask = 0;
00053     func = NULL;
00054   }
00055   if (isLua(L->ci))
00056     L->oldpc = L->ci->u.l.savedpc;
00057   L->hook = func;
00058   L->basehookcount = count;
00059   resethookcount(L);
00060   L->hookmask = cast_byte(mask);
00061   return 1;
00062 }
00063 
00064 
00065 LUA_API lua_Hook lua_gethook (lua_State *L) {
00066   return L->hook;
00067 }
00068 
00069 
00070 LUA_API int lua_gethookmask (lua_State *L) {
00071   return L->hookmask;
00072 }
00073 
00074 
00075 LUA_API int lua_gethookcount (lua_State *L) {
00076   return L->basehookcount;
00077 }
00078 
00079 
00080 LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
00081   int status;
00082   CallInfo *ci;
00083   if (level < 0) return 0;  /* invalid (negative) level */
00084   lua_lock(L);
00085   for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous)
00086     level--;
00087   if (level == 0 && ci != &L->base_ci) {  /* level found? */
00088     status = 1;
00089     ar->i_ci = ci;
00090   }
00091   else status = 0;  /* no such level */
00092   lua_unlock(L);
00093   return status;
00094 }
00095 
00096 
00097 static const char *upvalname (Proto *p, int uv) {
00098   TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
00099   if (s == NULL) return "?";
00100   else return getstr(s);
00101 }
00102 
00103 
00104 static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
00105   int nparams = clLvalue(ci->func)->p->numparams;
00106   if (n >= ci->u.l.base - ci->func - nparams)
00107     return NULL;  /* no such vararg */
00108   else {
00109     *pos = ci->func + nparams + n;
00110     return "(*vararg)";  /* generic name for any vararg */
00111   }
00112 }
00113 
00114 
00115 static const char *findlocal (lua_State *L, CallInfo *ci, int n,
00116                               StkId *pos) {
00117   const char *name = NULL;
00118   StkId base;
00119   if (isLua(ci)) {
00120     if (n < 0)  /* access to vararg values? */
00121       return findvararg(ci, -n, pos);
00122     else {
00123       base = ci->u.l.base;
00124       name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
00125     }
00126   }
00127   else
00128     base = ci->func + 1;
00129   if (name == NULL) {  /* no 'standard' name? */
00130     StkId limit = (ci == L->ci) ? L->top : ci->next->func;
00131     if (limit - base >= n && n > 0)  /* is 'n' inside 'ci' stack? */
00132       name = "(*temporary)";  /* generic name for any valid slot */
00133     else
00134       return NULL;  /* no name */
00135   }
00136   *pos = base + (n - 1);
00137   return name;
00138 }
00139 
00140 
00141 LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
00142   const char *name;
00143   lua_lock(L);
00144   if (ar == NULL) {  /* information about non-active function? */
00145     if (!isLfunction(L->top - 1))  /* not a Lua function? */
00146       name = NULL;
00147     else  /* consider live variables at function start (parameters) */
00148       name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
00149   }
00150   else {  /* active function; get information through 'ar' */
00151     StkId pos = 0;  /* to avoid warnings */
00152     name = findlocal(L, ar->i_ci, n, &pos);
00153     if (name) {
00154       setobj2s(L, L->top, pos);
00155       api_incr_top(L);
00156     }
00157   }
00158   lua_unlock(L);
00159   return name;
00160 }
00161 
00162 
00163 LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
00164   StkId pos = 0;  /* to avoid warnings */
00165   const char *name = findlocal(L, ar->i_ci, n, &pos);
00166   lua_lock(L);
00167   if (name)
00168     setobjs2s(L, pos, L->top - 1);
00169   L->top--;  /* pop value */
00170   lua_unlock(L);
00171   return name;
00172 }
00173 
00174 
00175 static void funcinfo (lua_Debug *ar, Closure *cl) {
00176   if (cl == NULL || cl->c.isC) {
00177     ar->source = "=[C]";
00178     ar->linedefined = -1;
00179     ar->lastlinedefined = -1;
00180     ar->what = "C";
00181   }
00182   else {
00183     Proto *p = cl->l.p;
00184     ar->source = p->source ? getstr(p->source) : "=?";
00185     ar->linedefined = p->linedefined;
00186     ar->lastlinedefined = p->lastlinedefined;
00187     ar->what = (ar->linedefined == 0) ? "main" : "Lua";
00188   }
00189   luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
00190 }
00191 
00192 
00193 static void collectvalidlines (lua_State *L, Closure *f) {
00194   if (f == NULL || f->c.isC) {
00195     setnilvalue(L->top);
00196     incr_top(L);
00197   }
00198   else {
00199     int i;
00200     TValue v;
00201     int *lineinfo = f->l.p->lineinfo;
00202     Table *t = luaH_new(L);  /* new table to store active lines */
00203     sethvalue(L, L->top, t);  /* push it on stack */
00204     incr_top(L);
00205     setbvalue(&v, 1);  /* boolean 'true' to be the value of all indices */
00206     for (i = 0; i < f->l.p->sizelineinfo; i++)  /* for all lines with code */
00207       luaH_setint(L, t, lineinfo[i], &v);  /* table[line] = true */
00208   }
00209 }
00210 
00211 
00212 static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
00213                     Closure *f, CallInfo *ci) {
00214   int status = 1;
00215   for (; *what; what++) {
00216     switch (*what) {
00217       case 'S': {
00218         funcinfo(ar, f);
00219         break;
00220       }
00221       case 'l': {
00222         ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1;
00223         break;
00224       }
00225       case 'u': {
00226         ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
00227         if (f == NULL || f->c.isC) {
00228           ar->isvararg = 1;
00229           ar->nparams = 0;
00230         }
00231         else {
00232           ar->isvararg = f->l.p->is_vararg;
00233           ar->nparams = f->l.p->numparams;
00234         }
00235         break;
00236       }
00237       case 't': {
00238         ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0;
00239         break;
00240       }
00241       case 'n': {
00242         /* calling function is a known Lua function? */
00243         if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
00244           ar->namewhat = getfuncname(L, ci->previous, &ar->name);
00245         else
00246           ar->namewhat = NULL;
00247         if (ar->namewhat == NULL) {
00248           ar->namewhat = "";  /* not found */
00249           ar->name = NULL;
00250         }
00251         break;
00252       }
00253       case 'L':
00254       case 'f':  /* handled by lua_getinfo */
00255         break;
00256       default: status = 0;  /* invalid option */
00257     }
00258   }
00259   return status;
00260 }
00261 
00262 
00263 LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
00264   int status;
00265   Closure *cl;
00266   CallInfo *ci;
00267   StkId func;
00268   lua_lock(L);
00269   if (*what == '>') {
00270     ci = NULL;
00271     func = L->top - 1;
00272     api_check(L, ttisfunction(func), "function expected");
00273     what++;  /* skip the '>' */
00274     L->top--;  /* pop function */
00275   }
00276   else {
00277     ci = ar->i_ci;
00278     func = ci->func;
00279     lua_assert(ttisfunction(ci->func));
00280   }
00281   cl = ttisclosure(func) ? clvalue(func) : NULL;
00282   status = auxgetinfo(L, what, ar, cl, ci);
00283   if (strchr(what, 'f')) {
00284     setobjs2s(L, L->top, func);
00285     incr_top(L);
00286   }
00287   if (strchr(what, 'L'))
00288     collectvalidlines(L, cl);
00289   lua_unlock(L);
00290   return status;
00291 }
00292 
00293 
00294 /*
00295 ** {======================================================
00296 ** Symbolic Execution
00297 ** =======================================================
00298 */
00299 
00300 static const char *getobjname (Proto *p, int lastpc, int reg,
00301                                const char **name);
00302 
00303 
00304 /*
00305 ** find a "name" for the RK value 'c'
00306 */
00307 static void kname (Proto *p, int pc, int c, const char **name) {
00308   if (ISK(c)) {  /* is 'c' a constant? */
00309     TValue *kvalue = &p->k[INDEXK(c)];
00310     if (ttisstring(kvalue)) {  /* literal constant? */
00311       *name = svalue(kvalue);  /* it is its own name */
00312       return;
00313     }
00314     /* else no reasonable name found */
00315   }
00316   else {  /* 'c' is a register */
00317     const char *what = getobjname(p, pc, c, name); /* search for 'c' */
00318     if (what && *what == 'c') {  /* found a constant name? */
00319       return;  /* 'name' already filled */
00320     }
00321     /* else no reasonable name found */
00322   }
00323   *name = "?";  /* no reasonable name found */
00324 }
00325 
00326 
00327 /*
00328 ** try to find last instruction before 'lastpc' that modified register 'reg'
00329 */
00330 static int findsetreg (Proto *p, int lastpc, int reg) {
00331   int pc;
00332   int setreg = -1;  /* keep last instruction that changed 'reg' */
00333   for (pc = 0; pc < lastpc; pc++) {
00334     Instruction i = p->code[pc];
00335     OpCode op = GET_OPCODE(i);
00336     int a = GETARG_A(i);
00337     switch (op) {
00338       case OP_LOADNIL: {
00339         int b = GETARG_B(i);
00340         if (a <= reg && reg <= a + b)  /* set registers from 'a' to 'a+b' */
00341           setreg = pc;
00342         break;
00343       }
00344       case OP_TFORCALL: {
00345         if (reg >= a + 2) setreg = pc;  /* affect all regs above its base */
00346         break;
00347       }
00348       case OP_CALL:
00349       case OP_TAILCALL: {
00350         if (reg >= a) setreg = pc;  /* affect all registers above base */
00351         break;
00352       }
00353       case OP_JMP: {
00354         int b = GETARG_sBx(i);
00355         int dest = pc + 1 + b;
00356         /* jump is forward and do not skip `lastpc'? */
00357         if (pc < dest && dest <= lastpc)
00358           pc += b;  /* do the jump */
00359         break;
00360       }
00361       case OP_TEST: {
00362         if (reg == a) setreg = pc;  /* jumped code can change 'a' */
00363         break;
00364       }
00365       default:
00366         if (testAMode(op) && reg == a)  /* any instruction that set A */
00367           setreg = pc;
00368         break;
00369     }
00370   }
00371   return setreg;
00372 }
00373 
00374 
00375 static const char *getobjname (Proto *p, int lastpc, int reg,
00376                                const char **name) {
00377   int pc;
00378   *name = luaF_getlocalname(p, reg + 1, lastpc);
00379   if (*name)  /* is a local? */
00380     return "local";
00381   /* else try symbolic execution */
00382   pc = findsetreg(p, lastpc, reg);
00383   if (pc != -1) {  /* could find instruction? */
00384     Instruction i = p->code[pc];
00385     OpCode op = GET_OPCODE(i);
00386     switch (op) {
00387       case OP_MOVE: {
00388         int b = GETARG_B(i);  /* move from 'b' to 'a' */
00389         if (b < GETARG_A(i))
00390           return getobjname(p, pc, b, name);  /* get name for 'b' */
00391         break;
00392       }
00393       case OP_GETTABUP:
00394       case OP_GETTABLE: {
00395         int k = GETARG_C(i);  /* key index */
00396         int t = GETARG_B(i);  /* table index */
00397         const char *vn = (op == OP_GETTABLE)  /* name of indexed variable */
00398                          ? luaF_getlocalname(p, t + 1, pc)
00399                          : upvalname(p, t);
00400         kname(p, pc, k, name);
00401         return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
00402       }
00403       case OP_GETUPVAL: {
00404         *name = upvalname(p, GETARG_B(i));
00405         return "upvalue";
00406       }
00407       case OP_LOADK:
00408       case OP_LOADKX: {
00409         int b = (op == OP_LOADK) ? GETARG_Bx(i)
00410                                  : GETARG_Ax(p->code[pc + 1]);
00411         if (ttisstring(&p->k[b])) {
00412           *name = svalue(&p->k[b]);
00413           return "constant";
00414         }
00415         break;
00416       }
00417       case OP_SELF: {
00418         int k = GETARG_C(i);  /* key index */
00419         kname(p, pc, k, name);
00420         return "method";
00421       }
00422       default: break;  /* go through to return NULL */
00423     }
00424   }
00425   return NULL;  /* could not find reasonable name */
00426 }
00427 
00428 
00429 static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
00430   TMS tm;
00431   Proto *p = ci_func(ci)->p;  /* calling function */
00432   int pc = currentpc(ci);  /* calling instruction index */
00433   Instruction i = p->code[pc];  /* calling instruction */
00434   switch (GET_OPCODE(i)) {
00435     case OP_CALL:
00436     case OP_TAILCALL:  /* get function name */
00437       return getobjname(p, pc, GETARG_A(i), name);
00438     case OP_TFORCALL: {  /* for iterator */
00439       *name = "for iterator";
00440        return "for iterator";
00441     }
00442     /* all other instructions can call only through metamethods */
00443     case OP_SELF:
00444     case OP_GETTABUP:
00445     case OP_GETTABLE: tm = TM_INDEX; break;
00446     case OP_SETTABUP:
00447     case OP_SETTABLE: tm = TM_NEWINDEX; break;
00448     case OP_EQ: tm = TM_EQ; break;
00449     case OP_ADD: tm = TM_ADD; break;
00450     case OP_SUB: tm = TM_SUB; break;
00451     case OP_MUL: tm = TM_MUL; break;
00452     case OP_DIV: tm = TM_DIV; break;
00453     case OP_MOD: tm = TM_MOD; break;
00454     case OP_POW: tm = TM_POW; break;
00455     case OP_UNM: tm = TM_UNM; break;
00456     case OP_LEN: tm = TM_LEN; break;
00457     case OP_LT: tm = TM_LT; break;
00458     case OP_LE: tm = TM_LE; break;
00459     case OP_CONCAT: tm = TM_CONCAT; break;
00460     default:
00461       return NULL;  /* else no useful name can be found */
00462   }
00463   *name = getstr(G(L)->tmname[tm]);
00464   return "metamethod";
00465 }
00466 
00467 /* }====================================================== */
00468 
00469 
00470 
00471 /*
00472 ** only ANSI way to check whether a pointer points to an array
00473 ** (used only for error messages, so efficiency is not a big concern)
00474 */
00475 static int isinstack (CallInfo *ci, const TValue *o) {
00476   StkId p;
00477   for (p = ci->u.l.base; p < ci->top; p++)
00478     if (o == p) return 1;
00479   return 0;
00480 }
00481 
00482 
00483 static const char *getupvalname (CallInfo *ci, const TValue *o,
00484                                  const char **name) {
00485   LClosure *c = ci_func(ci);
00486   int i;
00487   for (i = 0; i < c->nupvalues; i++) {
00488     if (c->upvals[i]->v == o) {
00489       *name = upvalname(c->p, i);
00490       return "upvalue";
00491     }
00492   }
00493   return NULL;
00494 }
00495 
00496 
00497 l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
00498   CallInfo *ci = L->ci;
00499   const char *name = NULL;
00500   const char *t = objtypename(o);
00501   const char *kind = NULL;
00502   if (isLua(ci)) {
00503     kind = getupvalname(ci, o, &name);  /* check whether 'o' is an upvalue */
00504     if (!kind && isinstack(ci, o))  /* no? try a register */
00505       kind = getobjname(ci_func(ci)->p, currentpc(ci),
00506                         cast_int(o - ci->u.l.base), &name);
00507   }
00508   if (kind)
00509     luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
00510                 op, kind, name, t);
00511   else
00512     luaG_runerror(L, "attempt to %s a %s value", op, t);
00513 }
00514 
00515 
00516 l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
00517   if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
00518   lua_assert(!ttisstring(p1) && !ttisnumber(p2));
00519   luaG_typeerror(L, p1, "concatenate");
00520 }
00521 
00522 
00523 l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
00524   TValue temp;
00525   if (luaV_tonumber(p1, &temp) == NULL)
00526     p2 = p1;  /* first operand is wrong */
00527   luaG_typeerror(L, p2, "perform arithmetic on");
00528 }
00529 
00530 
00531 l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
00532   const char *t1 = objtypename(p1);
00533   const char *t2 = objtypename(p2);
00534   if (t1 == t2)
00535     luaG_runerror(L, "attempt to compare two %s values", t1);
00536   else
00537     luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
00538 }
00539 
00540 
00541 static void addinfo (lua_State *L, const char *msg) {
00542   CallInfo *ci = L->ci;
00543   if (isLua(ci)) {  /* is Lua code? */
00544     char buff[LUA_IDSIZE];  /* add file:line information */
00545     int line = currentline(ci);
00546     TString *src = ci_func(ci)->p->source;
00547     if (src)
00548       luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
00549     else {  /* no source available; use "?" instead */
00550       buff[0] = '?'; buff[1] = '\0';
00551     }
00552     luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
00553   }
00554 }
00555 
00556 
00557 l_noret luaG_errormsg (lua_State *L) {
00558   if (L->errfunc != 0) {  /* is there an error handling function? */
00559     StkId errfunc = restorestack(L, L->errfunc);
00560     if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
00561     setobjs2s(L, L->top, L->top - 1);  /* move argument */
00562     setobjs2s(L, L->top - 1, errfunc);  /* push function */
00563     incr_top(L);
00564     luaD_call(L, L->top - 2, 1, 0);  /* call it */
00565   }
00566   luaD_throw(L, LUA_ERRRUN);
00567 }
00568 
00569 
00570 l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
00571   va_list argp;
00572   va_start(argp, fmt);
00573   addinfo(L, luaO_pushvfstring(L, fmt, argp));
00574   va_end(argp);
00575   luaG_errormsg(L);
00576 }
00577 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:03 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs