diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-11-25 13:27:51 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-11-25 13:27:51 -0200 |
commit | b0f2b288a6b860374b9578d4c51329fc9cd43022 (patch) | |
tree | 82bacf246458c8f97ec22424ff40832df67a52e5 /ldebug.c | |
parent | 2b25489b47ad94e6f970f5d9150937734322f24c (diff) | |
download | lua-b0f2b288a6b860374b9578d4c51329fc9cd43022.tar.gz lua-b0f2b288a6b860374b9578d4c51329fc9cd43022.tar.bz2 lua-b0f2b288a6b860374b9578d4c51329fc9cd43022.zip |
new scheme for debug info about tail calls: no more 'fake' stack entries,
but stack entry knows whether it was tail called
Diffstat (limited to 'ldebug.c')
-rw-r--r-- | ldebug.c | 42 |
1 files changed, 10 insertions, 32 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.c,v 2.56 2009/09/28 16:32:50 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 2.57 2009/10/13 19:07:40 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 | */ |
@@ -83,23 +83,14 @@ LUA_API int lua_gethookcount (lua_State *L) { | |||
83 | LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { | 83 | LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { |
84 | int status; | 84 | int status; |
85 | CallInfo *ci; | 85 | CallInfo *ci; |
86 | if (level < 0) return 0; /* invalid (negative) level */ | ||
86 | lua_lock(L); | 87 | lua_lock(L); |
87 | for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous) { | 88 | for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous) |
88 | level--; | 89 | level--; |
89 | if (isLua(ci)) /* Lua function? */ | ||
90 | level -= ci->u.l.tailcalls; /* skip lost tail calls */ | ||
91 | } | ||
92 | if (level == 0 && ci != &L->base_ci) { /* level found? */ | 90 | if (level == 0 && ci != &L->base_ci) { /* level found? */ |
93 | status = 1; | 91 | status = 1; |
94 | ar->i_ci = ci; | 92 | ar->i_ci = ci; |
95 | } | 93 | } |
96 | else if (level < 0) { | ||
97 | if (ci == L->ci) status = 0; /* level was negative? */ | ||
98 | else { /* level is of a lost tail call */ | ||
99 | status = 1; | ||
100 | ar->i_ci = NULL; | ||
101 | } | ||
102 | } | ||
103 | else status = 0; /* no such level */ | 94 | else status = 0; /* no such level */ |
104 | lua_unlock(L); | 95 | lua_unlock(L); |
105 | return status; | 96 | return status; |
@@ -110,7 +101,6 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n, | |||
110 | StkId *pos) { | 101 | StkId *pos) { |
111 | const char *name = NULL; | 102 | const char *name = NULL; |
112 | StkId base; | 103 | StkId base; |
113 | if (ci == NULL) return NULL; /* tail call? */ | ||
114 | if (isLua(ci)) { | 104 | if (isLua(ci)) { |
115 | base = ci->u.l.base; | 105 | base = ci->u.l.base; |
116 | name = luaF_getlocalname(ci_func(ci)->l.p, n, currentpc(ci)); | 106 | name = luaF_getlocalname(ci_func(ci)->l.p, n, currentpc(ci)); |
@@ -170,17 +160,6 @@ static void funcinfo (lua_Debug *ar, Closure *cl) { | |||
170 | } | 160 | } |
171 | 161 | ||
172 | 162 | ||
173 | static void info_tailcall (lua_Debug *ar) { | ||
174 | ar->name = NULL; | ||
175 | ar->namewhat = ""; | ||
176 | ar->what = "tail"; | ||
177 | ar->lastlinedefined = ar->linedefined = ar->currentline = -1; | ||
178 | ar->source = "=(tail call)"; | ||
179 | luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); | ||
180 | ar->nups = 0; | ||
181 | } | ||
182 | |||
183 | |||
184 | static void collectvalidlines (lua_State *L, Closure *f) { | 163 | static void collectvalidlines (lua_State *L, Closure *f) { |
185 | if (f == NULL || f->c.isC) { | 164 | if (f == NULL || f->c.isC) { |
186 | setnilvalue(L->top); | 165 | setnilvalue(L->top); |
@@ -201,10 +180,6 @@ static void collectvalidlines (lua_State *L, Closure *f) { | |||
201 | static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | 180 | static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, |
202 | Closure *f, CallInfo *ci) { | 181 | Closure *f, CallInfo *ci) { |
203 | int status = 1; | 182 | int status = 1; |
204 | if (f == NULL) { | ||
205 | info_tailcall(ar); | ||
206 | return status; | ||
207 | } | ||
208 | for (; *what; what++) { | 183 | for (; *what; what++) { |
209 | switch (*what) { | 184 | switch (*what) { |
210 | case 'S': { | 185 | case 'S': { |
@@ -219,6 +194,10 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | |||
219 | ar->nups = f->c.nupvalues; | 194 | ar->nups = f->c.nupvalues; |
220 | break; | 195 | break; |
221 | } | 196 | } |
197 | case 't': { | ||
198 | ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0; | ||
199 | break; | ||
200 | } | ||
222 | case 'n': { | 201 | case 'n': { |
223 | ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL; | 202 | ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL; |
224 | if (ar->namewhat == NULL) { | 203 | if (ar->namewhat == NULL) { |
@@ -249,15 +228,14 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | |||
249 | f = clvalue(func); | 228 | f = clvalue(func); |
250 | L->top--; /* pop function */ | 229 | L->top--; /* pop function */ |
251 | } | 230 | } |
252 | else if (ar->i_ci != NULL) { /* no tail call? */ | 231 | else { |
253 | ci = ar->i_ci; | 232 | ci = ar->i_ci; |
254 | lua_assert(ttisfunction(ci->func)); | 233 | lua_assert(ttisfunction(ci->func)); |
255 | f = clvalue(ci->func); | 234 | f = clvalue(ci->func); |
256 | } | 235 | } |
257 | status = auxgetinfo(L, what, ar, f, ci); | 236 | status = auxgetinfo(L, what, ar, f, ci); |
258 | if (strchr(what, 'f')) { | 237 | if (strchr(what, 'f')) { |
259 | if (f == NULL) setnilvalue(L->top); | 238 | setclvalue(L, L->top, f); |
260 | else setclvalue(L, L->top, f); | ||
261 | incr_top(L); | 239 | incr_top(L); |
262 | } | 240 | } |
263 | if (strchr(what, 'L')) | 241 | if (strchr(what, 'L')) |
@@ -379,7 +357,7 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg, | |||
379 | static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { | 357 | static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { |
380 | TMS tm = 0; | 358 | TMS tm = 0; |
381 | Instruction i; | 359 | Instruction i; |
382 | if ((isLua(ci) && ci->u.l.tailcalls > 0) || !isLua(ci->previous)) | 360 | if ((ci->callstatus & CIST_TAIL) || !isLua(ci->previous)) |
383 | return NULL; /* calling function is not Lua (or is unknown) */ | 361 | return NULL; /* calling function is not Lua (or is unknown) */ |
384 | ci = ci->previous; /* calling function */ | 362 | ci = ci->previous; /* calling function */ |
385 | i = ci_func(ci)->l.p->code[currentpc(ci)]; | 363 | i = ci_func(ci)->l.p->code[currentpc(ci)]; |