diff options
| -rw-r--r-- | ldblib.c | 58 | ||||
| -rw-r--r-- | ldebug.c | 63 |
2 files changed, 74 insertions, 47 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldblib.c,v 1.94 2005/03/08 20:10:05 roberto Exp roberto $ | 2 | ** $Id: ldblib.c,v 1.95 2005/05/05 20:47:02 roberto Exp roberto $ |
| 3 | ** Interface from Lua to its debug API | 3 | ** Interface from Lua to its debug API |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -77,6 +77,17 @@ static lua_State *getthread (lua_State *L, int *arg) { | |||
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | 79 | ||
| 80 | static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { | ||
| 81 | if (L == L1) { | ||
| 82 | lua_pushvalue(L, -2); | ||
| 83 | lua_remove(L, -3); | ||
| 84 | } | ||
| 85 | else | ||
| 86 | lua_xmove(L1, L, 1); | ||
| 87 | lua_setfield(L, -2, fname); | ||
| 88 | } | ||
| 89 | |||
| 90 | |||
| 80 | static int db_getinfo (lua_State *L) { | 91 | static int db_getinfo (lua_State *L) { |
| 81 | lua_Debug ar; | 92 | lua_Debug ar; |
| 82 | int arg; | 93 | int arg; |
| @@ -99,34 +110,25 @@ static int db_getinfo (lua_State *L) { | |||
| 99 | if (!lua_getinfo(L1, options, &ar)) | 110 | if (!lua_getinfo(L1, options, &ar)) |
| 100 | return luaL_argerror(L, arg+2, "invalid option"); | 111 | return luaL_argerror(L, arg+2, "invalid option"); |
| 101 | lua_newtable(L); | 112 | lua_newtable(L); |
| 102 | for (; *options; options++) { | 113 | if (strchr(options, 'S')) { |
| 103 | switch (*options) { | 114 | settabss(L, "source", ar.source); |
| 104 | case 'S': | 115 | settabss(L, "short_src", ar.short_src); |
| 105 | settabss(L, "source", ar.source); | 116 | settabsi(L, "linedefined", ar.linedefined); |
| 106 | settabss(L, "short_src", ar.short_src); | 117 | settabsi(L, "lastlinedefined", ar.lastlinedefined); |
| 107 | settabsi(L, "linedefined", ar.linedefined); | 118 | settabss(L, "what", ar.what); |
| 108 | settabsi(L, "lastlinedefined", ar.lastlinedefined); | 119 | } |
| 109 | settabss(L, "what", ar.what); | 120 | if (strchr(options, 'l')) |
| 110 | break; | 121 | settabsi(L, "currentline", ar.currentline); |
| 111 | case 'l': | 122 | if (strchr(options, 'u')) |
| 112 | settabsi(L, "currentline", ar.currentline); | 123 | settabsi(L, "nups", ar.nups); |
| 113 | break; | 124 | if (strchr(options, 'n')) { |
| 114 | case 'u': | 125 | settabss(L, "name", ar.name); |
| 115 | settabsi(L, "nups", ar.nups); | 126 | settabss(L, "namewhat", ar.namewhat); |
| 116 | break; | ||
| 117 | case 'n': | ||
| 118 | settabss(L, "name", ar.name); | ||
| 119 | settabss(L, "namewhat", ar.namewhat); | ||
| 120 | break; | ||
| 121 | case 'f': | ||
| 122 | if (L == L1) | ||
| 123 | lua_pushvalue(L, -2); | ||
| 124 | else | ||
| 125 | lua_xmove(L1, L, 1); | ||
| 126 | lua_setfield(L, -2, "func"); | ||
| 127 | break; | ||
| 128 | } | ||
| 129 | } | 127 | } |
| 128 | if (strchr(options, 'L')) | ||
| 129 | treatstackoption(L, L1, "activelines"); | ||
| 130 | if (strchr(options, 'f')) | ||
| 131 | treatstackoption(L, L1, "func"); | ||
| 130 | return 1; /* return table */ | 132 | return 1; /* return table */ |
| 131 | } | 133 | } |
| 132 | 134 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.c,v 2.16 2005/05/04 20:42:28 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 2.17 2005/05/05 20:47:02 roberto Exp roberto $ |
| 3 | ** Debug Interface | 3 | ** Debug Interface |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -148,8 +148,7 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { | |||
| 148 | } | 148 | } |
| 149 | 149 | ||
| 150 | 150 | ||
| 151 | static void funcinfo (lua_Debug *ar, StkId func) { | 151 | static void funcinfo (lua_Debug *ar, Closure *cl) { |
| 152 | Closure *cl = clvalue(func); | ||
| 153 | if (cl->c.isC) { | 152 | if (cl->c.isC) { |
| 154 | ar->source = "=[C]"; | 153 | ar->source = "=[C]"; |
| 155 | ar->linedefined = -1; | 154 | ar->linedefined = -1; |
| @@ -168,17 +167,36 @@ static void funcinfo (lua_Debug *ar, StkId func) { | |||
| 168 | static void info_tailcall (lua_State *L, lua_Debug *ar) { | 167 | static void info_tailcall (lua_State *L, lua_Debug *ar) { |
| 169 | ar->name = ar->namewhat = ""; | 168 | ar->name = ar->namewhat = ""; |
| 170 | ar->what = "tail"; | 169 | ar->what = "tail"; |
| 171 | ar->linedefined = ar->currentline = -1; | 170 | ar->lastlinedefined = ar->linedefined = ar->currentline = -1; |
| 172 | ar->source = "=(tail call)"; | 171 | ar->source = "=(tail call)"; |
| 173 | luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); | 172 | luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); |
| 174 | ar->nups = 0; | 173 | ar->nups = 0; |
| 175 | setnilvalue(L->top); | 174 | } |
| 175 | |||
| 176 | |||
| 177 | static void collectvalidlines (lua_State *L, Closure *f) { | ||
| 178 | if (f == NULL || f->c.isC) { | ||
| 179 | setnilvalue(L->top); | ||
| 180 | } | ||
| 181 | else { | ||
| 182 | Table *t = luaH_new(L, 0, 0); | ||
| 183 | int *lineinfo = f->l.p->lineinfo; | ||
| 184 | int i; | ||
| 185 | for (i=0; i<f->l.p->sizelineinfo; i++) | ||
| 186 | setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); | ||
| 187 | sethvalue(L, L->top, t); | ||
| 188 | } | ||
| 189 | incr_top(L); | ||
| 176 | } | 190 | } |
| 177 | 191 | ||
| 178 | 192 | ||
| 179 | static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | 193 | static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, |
| 180 | StkId f, CallInfo *ci) { | 194 | Closure *f, CallInfo *ci) { |
| 181 | int status = 1; | 195 | int status = 1; |
| 196 | if (f == NULL) { | ||
| 197 | info_tailcall(L, ar); | ||
| 198 | return status; | ||
| 199 | } | ||
| 182 | for (; *what; what++) { | 200 | for (; *what; what++) { |
| 183 | switch (*what) { | 201 | switch (*what) { |
| 184 | case 'S': { | 202 | case 'S': { |
| @@ -190,7 +208,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | |||
| 190 | break; | 208 | break; |
| 191 | } | 209 | } |
| 192 | case 'u': { | 210 | case 'u': { |
| 193 | ar->nups = clvalue(f)->c.nupvalues; | 211 | ar->nups = f->c.nupvalues; |
| 194 | break; | 212 | break; |
| 195 | } | 213 | } |
| 196 | case 'n': { | 214 | case 'n': { |
| @@ -201,10 +219,9 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | |||
| 201 | } | 219 | } |
| 202 | break; | 220 | break; |
| 203 | } | 221 | } |
| 204 | case 'f': { | 222 | case 'L': |
| 205 | setobj2s(L, L->top, f); | 223 | case 'f': /* handled by lua_getinfo */ |
| 206 | break; | 224 | break; |
| 207 | } | ||
| 208 | default: status = 0; /* invalid option */ | 225 | default: status = 0; /* invalid option */ |
| 209 | } | 226 | } |
| 210 | } | 227 | } |
| @@ -213,23 +230,31 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | |||
| 213 | 230 | ||
| 214 | 231 | ||
| 215 | LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | 232 | LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { |
| 216 | int status = 1; | 233 | int status; |
| 234 | Closure *f = NULL; | ||
| 235 | CallInfo *ci = NULL; | ||
| 217 | lua_lock(L); | 236 | lua_lock(L); |
| 218 | if (*what == '>') { | 237 | if (*what == '>') { |
| 219 | StkId f = L->top - 1; | 238 | StkId func = L->top - 1; |
| 220 | if (!ttisfunction(f)) | 239 | if (!ttisfunction(func)) |
| 221 | luaG_runerror(L, "value for `lua_getinfo' is not a function"); | 240 | luaG_runerror(L, "value for `lua_getinfo' is not a function"); |
| 222 | status = auxgetinfo(L, what + 1, ar, f, NULL); | 241 | what++; /* skip the '>' */ |
| 242 | f = clvalue(func); | ||
| 223 | L->top--; /* pop function */ | 243 | L->top--; /* pop function */ |
| 224 | } | 244 | } |
| 225 | else if (ar->i_ci != 0) { /* no tail call? */ | 245 | else if (ar->i_ci != 0) { /* no tail call? */ |
| 226 | CallInfo *ci = L->base_ci + ar->i_ci; | 246 | ci = L->base_ci + ar->i_ci; |
| 227 | lua_assert(ttisfunction(ci->func)); | 247 | lua_assert(ttisfunction(ci->func)); |
| 228 | status = auxgetinfo(L, what, ar, ci->func, ci); | 248 | f = clvalue(ci->func); |
| 229 | } | 249 | } |
| 230 | else | 250 | status = auxgetinfo(L, what, ar, f, ci); |
| 231 | info_tailcall(L, ar); | 251 | if (strchr(what, 'f')) { |
| 232 | if (strchr(what, 'f')) incr_top(L); | 252 | if (f == NULL) setnilvalue(L->top); |
| 253 | else setclvalue(L, L->top, f); | ||
| 254 | incr_top(L); | ||
| 255 | } | ||
| 256 | if (strchr(what, 'L')) | ||
| 257 | collectvalidlines(L, f); | ||
| 233 | lua_unlock(L); | 258 | lua_unlock(L); |
| 234 | return status; | 259 | return status; |
| 235 | } | 260 | } |
