aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-11-25 13:27:51 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-11-25 13:27:51 -0200
commitb0f2b288a6b860374b9578d4c51329fc9cd43022 (patch)
tree82bacf246458c8f97ec22424ff40832df67a52e5 /ldo.c
parent2b25489b47ad94e6f970f5d9150937734322f24c (diff)
downloadlua-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 'ldo.c')
-rw-r--r--ldo.c54
1 files changed, 26 insertions, 28 deletions
diff --git a/ldo.c b/ldo.c
index 72c92e21..7e8f2cdb 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.71 2009/11/17 16:33:38 roberto Exp roberto $ 2** $Id: ldo.c,v 2.72 2009/11/17 16:46:44 roberto Exp roberto $
3** Stack and Call structure of Lua 3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -184,7 +184,7 @@ void luaD_shrinkstack (lua_State *L) {
184} 184}
185 185
186 186
187void luaD_callhook (lua_State *L, int event, int line) { 187void luaD_hook (lua_State *L, int event, int line) {
188 lua_Hook hook = L->hook; 188 lua_Hook hook = L->hook;
189 if (hook && L->allowhook) { 189 if (hook && L->allowhook) {
190 CallInfo *ci = L->ci; 190 CallInfo *ci = L->ci;
@@ -193,10 +193,7 @@ void luaD_callhook (lua_State *L, int event, int line) {
193 lua_Debug ar; 193 lua_Debug ar;
194 ar.event = event; 194 ar.event = event;
195 ar.currentline = line; 195 ar.currentline = line;
196 if (event == LUA_HOOKTAILRET) 196 ar.i_ci = ci;
197 ar.i_ci = NULL; /* tail call; no debug information about it */
198 else
199 ar.i_ci = ci;
200 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ 197 luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */
201 ci->top = L->top + LUA_MINSTACK; 198 ci->top = L->top + LUA_MINSTACK;
202 lua_assert(ci->top <= L->stack_last); 199 lua_assert(ci->top <= L->stack_last);
@@ -214,6 +211,19 @@ void luaD_callhook (lua_State *L, int event, int line) {
214} 211}
215 212
216 213
214static void callhook (lua_State *L, CallInfo *ci) {
215 int hook = LUA_HOOKCALL;
216 ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */
217 if (isLua(ci->previous) &&
218 GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) {
219 ci->callstatus |= CIST_TAIL;
220 hook = LUA_HOOKTAILCALL;
221 }
222 luaD_hook(L, hook, -1);
223 ci->u.l.savedpc--; /* correct 'pc' */
224}
225
226
217static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { 227static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
218 int i; 228 int i;
219 int nfixargs = p->numparams; 229 int nfixargs = p->numparams;
@@ -281,14 +291,10 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
281 ci->top = base + p->maxstacksize; 291 ci->top = base + p->maxstacksize;
282 lua_assert(ci->top <= L->stack_last); 292 lua_assert(ci->top <= L->stack_last);
283 ci->u.l.savedpc = p->code; /* starting point */ 293 ci->u.l.savedpc = p->code; /* starting point */
284 ci->u.l.tailcalls = 0;
285 ci->callstatus = CIST_LUA; 294 ci->callstatus = CIST_LUA;
286 L->top = ci->top; 295 L->top = ci->top;
287 if (L->hookmask & LUA_MASKCALL) { 296 if (L->hookmask & LUA_MASKCALL)
288 ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ 297 callhook(L, ci);
289 luaD_callhook(L, LUA_HOOKCALL, -1);
290 ci->u.l.savedpc--; /* correct 'pc' */
291 }
292 return 0; 298 return 0;
293 } 299 }
294 else { /* if is a C function, call it */ 300 else { /* if is a C function, call it */
@@ -301,7 +307,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
301 lua_assert(ci->top <= L->stack_last); 307 lua_assert(ci->top <= L->stack_last);
302 ci->callstatus = 0; 308 ci->callstatus = 0;
303 if (L->hookmask & LUA_MASKCALL) 309 if (L->hookmask & LUA_MASKCALL)
304 luaD_callhook(L, LUA_HOOKCALL, -1); 310 luaD_hook(L, LUA_HOOKCALL, -1);
305 lua_unlock(L); 311 lua_unlock(L);
306 n = (*curr_func(L)->c.f)(L); /* do the actual call */ 312 n = (*curr_func(L)->c.f)(L); /* do the actual call */
307 lua_lock(L); 313 lua_lock(L);
@@ -311,25 +317,17 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
311} 317}
312 318
313 319
314static StkId callrethooks (lua_State *L, StkId firstResult) {
315 ptrdiff_t fr = savestack(L, firstResult); /* next call may change stack */
316 luaD_callhook(L, LUA_HOOKRET, -1);
317 if (isLua(L->ci)) { /* Lua function? */
318 while ((L->hookmask & LUA_MASKRET) && L->ci->u.l.tailcalls--)
319 luaD_callhook(L, LUA_HOOKTAILRET, -1); /* ret. hooks for tail calls */
320 }
321 return restorestack(L, fr);
322}
323
324
325int luaD_poscall (lua_State *L, StkId firstResult) { 320int luaD_poscall (lua_State *L, StkId firstResult) {
326 StkId res; 321 StkId res;
327 int wanted, i; 322 int wanted, i;
328 CallInfo *ci = L->ci; 323 CallInfo *ci = L->ci;
329 if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { 324 if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) {
330 if (L->hookmask & LUA_MASKRET) 325 if (L->hookmask & LUA_MASKRET) {
331 firstResult = callrethooks(L, firstResult); 326 ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */
332 L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for returning function */ 327 luaD_hook(L, LUA_HOOKRET, -1);
328 firstResult = restorestack(L, fr);
329 }
330 L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */
333 } 331 }
334 res = ci->func; /* res == final position of 1st result */ 332 res = ci->func; /* res == final position of 1st result */
335 L->ci = ci = ci->previous; /* back to caller */ 333 L->ci = ci = ci->previous; /* back to caller */
@@ -529,7 +527,7 @@ LUA_API int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k) {
529 } 527 }
530 lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ 528 lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */
531 lua_unlock(L); 529 lua_unlock(L);
532 return 0; /* otherwise, return to 'luaD_callhook' */ 530 return 0; /* return to 'luaD_hook' */
533} 531}
534 532
535 533