summaryrefslogtreecommitdiff
path: root/src/ldebug.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ldebug.c')
-rw-r--r--[-rwxr-xr-x]src/ldebug.c204
1 files changed, 106 insertions, 98 deletions
diff --git a/src/ldebug.c b/src/ldebug.c
index a2565cf..31b7ae4 100755..100644
--- a/src/ldebug.c
+++ b/src/ldebug.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.c,v 2.82 2011/06/02 19:31:40 roberto Exp $
+** $Id: ldebug.c,v 2.88 2011/11/30 12:43:51 roberto Exp $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -94,6 +94,13 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
}
+static const char *upvalname (Proto *p, int uv) {
+ TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
+ if (s == NULL) return "?";
+ else return getstr(s);
+}
+
+
static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
int nparams = clLvalue(ci->func)->p->numparams;
if (n >= ci->u.l.base - ci->func - nparams)
@@ -190,12 +197,14 @@ static void collectvalidlines (lua_State *L, Closure *f) {
}
else {
int i;
+ TValue v;
int *lineinfo = f->l.p->lineinfo;
- Table *t = luaH_new(L);
- sethvalue(L, L->top, t);
+ Table *t = luaH_new(L); /* new table to store active lines */
+ sethvalue(L, L->top, t); /* push it on stack */
incr_top(L);
- for (i=0; i<f->l.p->sizelineinfo; i++)
- setbvalue(luaH_setint(L, t, lineinfo[i]), 1);
+ setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */
+ for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */
+ luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */
}
}
@@ -230,7 +239,11 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
break;
}
case 'n': {
- ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL;
+ /* calling function is a known Lua function? */
+ if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
+ ar->namewhat = getfuncname(L, ci->previous, &ar->name);
+ else
+ ar->namewhat = NULL;
if (ar->namewhat == NULL) {
ar->namewhat = ""; /* not found */
ar->name = NULL;
@@ -284,17 +297,16 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
** =======================================================
*/
-static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
+static const char *getobjname (Proto *p, int lastpc, int reg,
const char **name);
/*
** find a "name" for the RK value 'c'
*/
-static void kname (lua_State *L, CallInfo *ci, int c, int oreg,
- const char *what, const char **name) {
+static void kname (Proto *p, int pc, int c, const char **name) {
if (ISK(c)) { /* is 'c' a constant? */
- TValue *kvalue = &ci_func(ci)->p->k[INDEXK(c)];
+ TValue *kvalue = &p->k[INDEXK(c)];
if (ttisstring(kvalue)) { /* literal constant? */
*name = svalue(kvalue); /* it is its own name */
return;
@@ -302,8 +314,7 @@ static void kname (lua_State *L, CallInfo *ci, int c, int oreg,
/* else no reasonable name found */
}
else { /* 'c' is a register */
- if (c != oreg) /* not the original register? */
- what = getobjname(L, ci, c, name); /* search for 'c' */
+ const char *what = getobjname(p, pc, c, name); /* search for 'c' */
if (what && *what == 'c') { /* found a constant name? */
return; /* 'name' already filled */
}
@@ -313,85 +324,30 @@ static void kname (lua_State *L, CallInfo *ci, int c, int oreg,
}
-static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
- const char **name) {
- Proto *p = ci_func(ci)->p;
- const char *what = NULL;
- int lastpc = currentpc(ci);
+/*
+** try to find last instruction before 'lastpc' that modified register 'reg'
+*/
+static int findsetreg (Proto *p, int lastpc, int reg) {
int pc;
- *name = luaF_getlocalname(p, reg + 1, lastpc);
- if (*name) /* is a local? */
- return "local";
- /* else try symbolic execution */
+ int setreg = -1; /* keep last instruction that changed 'reg' */
for (pc = 0; pc < lastpc; pc++) {
Instruction i = p->code[pc];
OpCode op = GET_OPCODE(i);
int a = GETARG_A(i);
switch (op) {
- case OP_MOVE: {
- if (reg == a) {
- int b = GETARG_B(i); /* move from 'b' to 'a' */
- if (b < a)
- what = getobjname(L, ci, b, name); /* get name for 'b' */
- else what = NULL;
- }
- break;
- }
- case OP_GETTABUP:
- case OP_GETTABLE: {
- if (reg == a) {
- int k = GETARG_C(i); /* key index */
- int t = GETARG_B(i);
- const char *vn = (op == OP_GETTABLE) /* name of indexed variable */
- ? luaF_getlocalname(p, t + 1, pc)
- : getstr(p->upvalues[t].name);
- kname(L, ci, k, a, what, name);
- what = (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
- }
- break;
- }
- case OP_GETUPVAL: {
- if (reg == a) {
- int u = GETARG_B(i); /* upvalue index */
- TString *tn = p->upvalues[u].name;
- *name = tn ? getstr(tn) : "?";
- what = "upvalue";
- }
- break;
- }
- case OP_LOADK:
- case OP_LOADKX: {
- if (reg == a) {
- int b = (op == OP_LOADK) ? GETARG_Bx(i)
- : GETARG_Ax(p->code[pc + 1]);
- if (ttisstring(&p->k[b])) {
- what = "constant";
- *name = svalue(&p->k[b]);
- }
- }
- break;
- }
case OP_LOADNIL: {
int b = GETARG_B(i);
if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */
- what = NULL;
- break;
- }
- case OP_SELF: {
- if (reg == a) {
- int k = GETARG_C(i); /* key index */
- kname(L, ci, k, a, what, name);
- what = "method";
- }
+ setreg = pc;
break;
}
case OP_TFORCALL: {
- if (reg >= a + 2) what = NULL; /* affect all regs above its base */
+ if (reg >= a + 2) setreg = pc; /* affect all regs above its base */
break;
}
case OP_CALL:
case OP_TAILCALL: {
- if (reg >= a) what = NULL; /* affect all registers above base */
+ if (reg >= a) setreg = pc; /* affect all registers above base */
break;
}
case OP_JMP: {
@@ -403,35 +359,87 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
break;
}
case OP_TEST: {
- if (reg == a) what = NULL; /* jumped code can change 'a' */
+ if (reg == a) setreg = pc; /* jumped code can change 'a' */
break;
}
default:
- if (testAMode(op) && reg == a) what = NULL;
+ if (testAMode(op) && reg == a) /* any instruction that set A */
+ setreg = pc;
break;
}
}
- return what;
+ return setreg;
+}
+
+
+static const char *getobjname (Proto *p, int lastpc, int reg,
+ const char **name) {
+ int pc;
+ *name = luaF_getlocalname(p, reg + 1, lastpc);
+ if (*name) /* is a local? */
+ return "local";
+ /* else try symbolic execution */
+ pc = findsetreg(p, lastpc, reg);
+ if (pc != -1) { /* could find instruction? */
+ Instruction i = p->code[pc];
+ OpCode op = GET_OPCODE(i);
+ switch (op) {
+ case OP_MOVE: {
+ int b = GETARG_B(i); /* move from 'b' to 'a' */
+ if (b < GETARG_A(i))
+ return getobjname(p, pc, b, name); /* get name for 'b' */
+ break;
+ }
+ case OP_GETTABUP:
+ case OP_GETTABLE: {
+ int k = GETARG_C(i); /* key index */
+ int t = GETARG_B(i); /* table index */
+ const char *vn = (op == OP_GETTABLE) /* name of indexed variable */
+ ? luaF_getlocalname(p, t + 1, pc)
+ : upvalname(p, t);
+ kname(p, pc, k, name);
+ return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
+ }
+ case OP_GETUPVAL: {
+ *name = upvalname(p, GETARG_B(i));
+ return "upvalue";
+ }
+ case OP_LOADK:
+ case OP_LOADKX: {
+ int b = (op == OP_LOADK) ? GETARG_Bx(i)
+ : GETARG_Ax(p->code[pc + 1]);
+ if (ttisstring(&p->k[b])) {
+ *name = svalue(&p->k[b]);
+ return "constant";
+ }
+ break;
+ }
+ case OP_SELF: {
+ int k = GETARG_C(i); /* key index */
+ kname(p, pc, k, name);
+ return "method";
+ }
+ default: break; /* go through to return NULL */
+ }
+ }
+ return NULL; /* could not find reasonable name */
}
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
TMS tm;
- Instruction i;
- if ((ci->callstatus & CIST_TAIL) || !isLua(ci->previous))
- return NULL; /* calling function is not Lua (or is unknown) */
- ci = ci->previous; /* calling function */
- i = ci_func(ci)->p->code[currentpc(ci)];
- if (GET_OPCODE(i) == OP_EXTRAARG) /* extra argument? */
- i = ci_func(ci)->p->code[currentpc(ci) - 1]; /* get 'real' instruction */
+ Proto *p = ci_func(ci)->p; /* calling function */
+ int pc = currentpc(ci); /* calling instruction index */
+ Instruction i = p->code[pc]; /* calling instruction */
switch (GET_OPCODE(i)) {
case OP_CALL:
- case OP_TAILCALL:
- return getobjname(L, ci, GETARG_A(i), name);
- case OP_TFORCALL: {
+ case OP_TAILCALL: /* get function name */
+ return getobjname(p, pc, GETARG_A(i), name);
+ case OP_TFORCALL: { /* for iterator */
*name = "for iterator";
return "for iterator";
}
+ /* all other instructions can call only through metamethods */
case OP_SELF:
case OP_GETTABUP:
case OP_GETTABLE: tm = TM_INDEX; break;
@@ -473,12 +481,12 @@ static int isinstack (CallInfo *ci, const TValue *o) {
static const char *getupvalname (CallInfo *ci, const TValue *o,
- const char **name) {
+ const char **name) {
LClosure *c = ci_func(ci);
int i;
for (i = 0; i < c->nupvalues; i++) {
if (c->upvals[i]->v == o) {
- *name = getstr(c->p->upvalues[i].name);
+ *name = upvalname(c->p, i);
return "upvalue";
}
}
@@ -486,7 +494,7 @@ static const char *getupvalname (CallInfo *ci, const TValue *o,
}
-void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
+l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
CallInfo *ci = L->ci;
const char *name = NULL;
const char *t = objtypename(o);
@@ -494,7 +502,8 @@ void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
if (isLua(ci)) {
kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
if (!kind && isinstack(ci, o)) /* no? try a register */
- kind = getobjname(L, ci, cast_int(o - ci->u.l.base), &name);
+ kind = getobjname(ci_func(ci)->p, currentpc(ci),
+ cast_int(o - ci->u.l.base), &name);
}
if (kind)
luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
@@ -504,14 +513,14 @@ void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
}
-void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
+l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
lua_assert(!ttisstring(p1) && !ttisnumber(p2));
luaG_typeerror(L, p1, "concatenate");
}
-void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
+l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
TValue temp;
if (luaV_tonumber(p1, &temp) == NULL)
p2 = p1; /* first operand is wrong */
@@ -519,14 +528,13 @@ void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
}
-int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
+l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
const char *t1 = objtypename(p1);
const char *t2 = objtypename(p2);
if (t1 == t2)
luaG_runerror(L, "attempt to compare two %s values", t1);
else
luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
- return 0;
}
@@ -546,7 +554,7 @@ static void addinfo (lua_State *L, const char *msg) {
}
-void luaG_errormsg (lua_State *L) {
+l_noret luaG_errormsg (lua_State *L) {
if (L->errfunc != 0) { /* is there an error handling function? */
StkId errfunc = restorestack(L, L->errfunc);
if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
@@ -559,7 +567,7 @@ void luaG_errormsg (lua_State *L) {
}
-void luaG_runerror (lua_State *L, const char *fmt, ...) {
+l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
va_list argp;
va_start(argp, fmt);
addinfo(L, luaO_pushvfstring(L, fmt, argp));