diff --git a/ldblib.c b/ldblib.c index 80c49ea5..ffe781a6 100644 --- a/ldblib.c +++ b/ldblib.c @@ -1,5 +1,5 @@ /* -** $Id: ldblib.c,v 1.94 2005/03/08 20:10:05 roberto Exp roberto $ +** $Id: ldblib.c,v 1.95 2005/05/05 20:47:02 roberto Exp roberto $ ** Interface from Lua to its debug API ** See Copyright Notice in lua.h */ @@ -77,6 +77,17 @@ static lua_State *getthread (lua_State *L, int *arg) { } +static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { + if (L == L1) { + lua_pushvalue(L, -2); + lua_remove(L, -3); + } + else + lua_xmove(L1, L, 1); + lua_setfield(L, -2, fname); +} + + static int db_getinfo (lua_State *L) { lua_Debug ar; int arg; @@ -99,34 +110,25 @@ static int db_getinfo (lua_State *L) { if (!lua_getinfo(L1, options, &ar)) return luaL_argerror(L, arg+2, "invalid option"); lua_newtable(L); - for (; *options; options++) { - switch (*options) { - case 'S': - settabss(L, "source", ar.source); - settabss(L, "short_src", ar.short_src); - settabsi(L, "linedefined", ar.linedefined); - settabsi(L, "lastlinedefined", ar.lastlinedefined); - settabss(L, "what", ar.what); - break; - case 'l': - settabsi(L, "currentline", ar.currentline); - break; - case 'u': - settabsi(L, "nups", ar.nups); - break; - case 'n': - settabss(L, "name", ar.name); - settabss(L, "namewhat", ar.namewhat); - break; - case 'f': - if (L == L1) - lua_pushvalue(L, -2); - else - lua_xmove(L1, L, 1); - lua_setfield(L, -2, "func"); - break; - } + if (strchr(options, 'S')) { + settabss(L, "source", ar.source); + settabss(L, "short_src", ar.short_src); + settabsi(L, "linedefined", ar.linedefined); + settabsi(L, "lastlinedefined", ar.lastlinedefined); + settabss(L, "what", ar.what); } + if (strchr(options, 'l')) + settabsi(L, "currentline", ar.currentline); + if (strchr(options, 'u')) + settabsi(L, "nups", ar.nups); + if (strchr(options, 'n')) { + settabss(L, "name", ar.name); + settabss(L, "namewhat", ar.namewhat); + } + if (strchr(options, 'L')) + treatstackoption(L, L1, "activelines"); + if (strchr(options, 'f')) + treatstackoption(L, L1, "func"); return 1; /* return table */ } diff --git a/ldebug.c b/ldebug.c index 4108aaae..45bd03c6 100644 --- a/ldebug.c +++ b/ldebug.c @@ -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; il.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; }