Forráskód Böngészése

debug information for active lines

Roberto Ierusalimschy 20 éve
szülő
commit
a2b78aad49
2 módosított fájl, 74 hozzáadás és 47 törlés
  1. 30 28
      ldblib.c
  2. 44 19
      ldebug.c

+ 30 - 28
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 */
 }
     

+ 44 - 19
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; 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;
 }