diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2005-05-16 15:45:15 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2005-05-16 15:45:15 -0300 |
commit | a2b78aad49388c1fd5286773085ef8a35545faa6 (patch) | |
tree | 305bc6c5316472b17fb668e9688e72b6652c79f8 | |
parent | c6293a76ccedbfc79f60261128e43fe95b350842 (diff) | |
download | lua-a2b78aad49388c1fd5286773085ef8a35545faa6.tar.gz lua-a2b78aad49388c1fd5286773085ef8a35545faa6.tar.bz2 lua-a2b78aad49388c1fd5286773085ef8a35545faa6.zip |
debug information for active lines
-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 | } |