|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
-** $Id: ldebug.c,v 2.16 2005/05/04 20:42:28 roberto Exp roberto $
|
|
|
+** $Id: ldebug.c,v 2.17 2005/05/05 20:47:02 roberto Exp roberto $
|
|
|
** Debug Interface
|
|
|
** See Copyright Notice in lua.h
|
|
|
*/
|
|
@@ -148,8 +148,7 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
|
|
|
}
|
|
|
|
|
|
|
|
|
-static void funcinfo (lua_Debug *ar, StkId func) {
|
|
|
- Closure *cl = clvalue(func);
|
|
|
+static void funcinfo (lua_Debug *ar, Closure *cl) {
|
|
|
if (cl->c.isC) {
|
|
|
ar->source = "=[C]";
|
|
|
ar->linedefined = -1;
|
|
@@ -168,17 +167,36 @@ static void funcinfo (lua_Debug *ar, StkId func) {
|
|
|
static void info_tailcall (lua_State *L, lua_Debug *ar) {
|
|
|
ar->name = ar->namewhat = "";
|
|
|
ar->what = "tail";
|
|
|
- ar->linedefined = ar->currentline = -1;
|
|
|
+ ar->lastlinedefined = ar->linedefined = ar->currentline = -1;
|
|
|
ar->source = "=(tail call)";
|
|
|
luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
|
|
|
ar->nups = 0;
|
|
|
- setnilvalue(L->top);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static void collectvalidlines (lua_State *L, Closure *f) {
|
|
|
+ if (f == NULL || f->c.isC) {
|
|
|
+ setnilvalue(L->top);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ Table *t = luaH_new(L, 0, 0);
|
|
|
+ int *lineinfo = f->l.p->lineinfo;
|
|
|
+ int i;
|
|
|
+ for (i=0; i<f->l.p->sizelineinfo; i++)
|
|
|
+ setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
|
|
|
+ sethvalue(L, L->top, t);
|
|
|
+ }
|
|
|
+ incr_top(L);
|
|
|
}
|
|
|
|
|
|
|
|
|
static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
|
|
|
- StkId f, CallInfo *ci) {
|
|
|
+ Closure *f, CallInfo *ci) {
|
|
|
int status = 1;
|
|
|
+ if (f == NULL) {
|
|
|
+ info_tailcall(L, ar);
|
|
|
+ return status;
|
|
|
+ }
|
|
|
for (; *what; what++) {
|
|
|
switch (*what) {
|
|
|
case 'S': {
|
|
@@ -190,7 +208,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
|
|
|
break;
|
|
|
}
|
|
|
case 'u': {
|
|
|
- ar->nups = clvalue(f)->c.nupvalues;
|
|
|
+ ar->nups = f->c.nupvalues;
|
|
|
break;
|
|
|
}
|
|
|
case 'n': {
|
|
@@ -201,10 +219,9 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
- case 'f': {
|
|
|
- setobj2s(L, L->top, f);
|
|
|
+ case 'L':
|
|
|
+ case 'f': /* handled by lua_getinfo */
|
|
|
break;
|
|
|
- }
|
|
|
default: status = 0; /* invalid option */
|
|
|
}
|
|
|
}
|
|
@@ -213,23 +230,31 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
|
|
|
|
|
|
|
|
|
LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
|
|
|
- int status = 1;
|
|
|
+ int status;
|
|
|
+ Closure *f = NULL;
|
|
|
+ CallInfo *ci = NULL;
|
|
|
lua_lock(L);
|
|
|
if (*what == '>') {
|
|
|
- StkId f = L->top - 1;
|
|
|
- if (!ttisfunction(f))
|
|
|
+ StkId func = L->top - 1;
|
|
|
+ if (!ttisfunction(func))
|
|
|
luaG_runerror(L, "value for `lua_getinfo' is not a function");
|
|
|
- status = auxgetinfo(L, what + 1, ar, f, NULL);
|
|
|
+ what++; /* skip the '>' */
|
|
|
+ f = clvalue(func);
|
|
|
L->top--; /* pop function */
|
|
|
}
|
|
|
else if (ar->i_ci != 0) { /* no tail call? */
|
|
|
- CallInfo *ci = L->base_ci + ar->i_ci;
|
|
|
+ ci = L->base_ci + ar->i_ci;
|
|
|
lua_assert(ttisfunction(ci->func));
|
|
|
- status = auxgetinfo(L, what, ar, ci->func, ci);
|
|
|
+ f = clvalue(ci->func);
|
|
|
}
|
|
|
- else
|
|
|
- info_tailcall(L, ar);
|
|
|
- if (strchr(what, 'f')) incr_top(L);
|
|
|
+ status = auxgetinfo(L, what, ar, f, ci);
|
|
|
+ if (strchr(what, 'f')) {
|
|
|
+ if (f == NULL) setnilvalue(L->top);
|
|
|
+ else setclvalue(L, L->top, f);
|
|
|
+ incr_top(L);
|
|
|
+ }
|
|
|
+ if (strchr(what, 'L'))
|
|
|
+ collectvalidlines(L, f);
|
|
|
lua_unlock(L);
|
|
|
return status;
|
|
|
}
|