diff options
-rw-r--r-- | lauxlib.c | 8 | ||||
-rw-r--r-- | lbaselib.c | 4 | ||||
-rw-r--r-- | ldblib.c | 10 | ||||
-rw-r--r-- | ldebug.c | 42 | ||||
-rw-r--r-- | ldo.c | 54 | ||||
-rw-r--r-- | ldo.h | 4 | ||||
-rw-r--r-- | lstate.h | 4 | ||||
-rw-r--r-- | lua.h | 5 | ||||
-rw-r--r-- | lvm.c | 8 |
9 files changed, 60 insertions, 79 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lauxlib.c,v 1.192 2009/09/28 12:36:40 roberto Exp roberto $ | 2 | ** $Id: lauxlib.c,v 1.193 2009/10/05 16:44:33 roberto Exp roberto $ |
3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -97,7 +97,7 @@ static void pushfuncname (lua_State *L, lua_Debug *ar) { | |||
97 | lua_remove(L, -2); /* remove name */ | 97 | lua_remove(L, -2); /* remove name */ |
98 | } | 98 | } |
99 | else | 99 | else |
100 | lua_pushliteral(L, "?"); /* C function or tail call */ | 100 | lua_pushliteral(L, "?"); |
101 | } | 101 | } |
102 | else | 102 | else |
103 | lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); | 103 | lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); |
@@ -133,12 +133,14 @@ LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, | |||
133 | level = numlevels - LEVELS2; /* and skip to last ones */ | 133 | level = numlevels - LEVELS2; /* and skip to last ones */ |
134 | } | 134 | } |
135 | else { | 135 | else { |
136 | lua_getinfo(L1, "Sln", &ar); | 136 | lua_getinfo(L1, "Slnt", &ar); |
137 | lua_pushfstring(L, "\n\t%s:", ar.short_src); | 137 | lua_pushfstring(L, "\n\t%s:", ar.short_src); |
138 | if (ar.currentline > 0) | 138 | if (ar.currentline > 0) |
139 | lua_pushfstring(L, "%d:", ar.currentline); | 139 | lua_pushfstring(L, "%d:", ar.currentline); |
140 | lua_pushliteral(L, " in "); | 140 | lua_pushliteral(L, " in "); |
141 | pushfuncname(L, &ar); | 141 | pushfuncname(L, &ar); |
142 | if (ar.istailcall) | ||
143 | lua_pushliteral(L, "\n\t(...tail calls...)"); | ||
142 | lua_concat(L, lua_gettop(L) - top); | 144 | lua_concat(L, lua_gettop(L) - top); |
143 | } | 145 | } |
144 | } | 146 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lbaselib.c,v 1.225 2009/11/19 16:26:29 roberto Exp roberto $ | 2 | ** $Id: lbaselib.c,v 1.226 2009/11/24 12:05:44 roberto Exp roberto $ |
3 | ** Basic library | 3 | ** Basic library |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -119,8 +119,6 @@ static void getfunc (lua_State *L, int opt) { | |||
119 | if (lua_getstack(L, level, &ar) == 0) | 119 | if (lua_getstack(L, level, &ar) == 0) |
120 | luaL_argerror(L, 1, "invalid level"); | 120 | luaL_argerror(L, 1, "invalid level"); |
121 | lua_getinfo(L, "f", &ar); | 121 | lua_getinfo(L, "f", &ar); |
122 | if (lua_isnil(L, -1)) | ||
123 | luaL_error(L, "no function environment for tail call at level %d", level); | ||
124 | } | 122 | } |
125 | } | 123 | } |
126 | 124 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldblib.c,v 1.116 2009/11/18 15:50:18 roberto Exp roberto $ | 2 | ** $Id: ldblib.c,v 1.117 2009/11/24 12:05:44 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 | */ |
@@ -100,7 +100,7 @@ static int db_getinfo (lua_State *L) { | |||
100 | lua_Debug ar; | 100 | lua_Debug ar; |
101 | int arg; | 101 | int arg; |
102 | lua_State *L1 = getthread(L, &arg); | 102 | lua_State *L1 = getthread(L, &arg); |
103 | const char *options = luaL_optstring(L, arg+2, "flnSu"); | 103 | const char *options = luaL_optstring(L, arg+2, "flnStu"); |
104 | if (lua_isnumber(L, arg+1)) { | 104 | if (lua_isnumber(L, arg+1)) { |
105 | if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) { | 105 | if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) { |
106 | lua_pushnil(L); /* level out of range */ | 106 | lua_pushnil(L); /* level out of range */ |
@@ -133,6 +133,10 @@ static int db_getinfo (lua_State *L) { | |||
133 | settabss(L, "name", ar.name); | 133 | settabss(L, "name", ar.name); |
134 | settabss(L, "namewhat", ar.namewhat); | 134 | settabss(L, "namewhat", ar.namewhat); |
135 | } | 135 | } |
136 | if (strchr(options, 't')) { | ||
137 | lua_pushboolean(L, ar.istailcall); | ||
138 | lua_setfield(L, -2, "istailcall"); | ||
139 | } | ||
136 | if (strchr(options, 'L')) | 140 | if (strchr(options, 'L')) |
137 | treatstackoption(L, L1, "activelines"); | 141 | treatstackoption(L, L1, "activelines"); |
138 | if (strchr(options, 'f')) | 142 | if (strchr(options, 'f')) |
@@ -232,7 +236,7 @@ static const char KEY_HOOK = 'h'; | |||
232 | 236 | ||
233 | static void hookf (lua_State *L, lua_Debug *ar) { | 237 | static void hookf (lua_State *L, lua_Debug *ar) { |
234 | static const char *const hooknames[] = | 238 | static const char *const hooknames[] = |
235 | {"call", "return", "line", "count", "tail return"}; | 239 | {"call", "return", "line", "count", "tail call"}; |
236 | lua_pushlightuserdata(L, (void *)&KEY_HOOK); | 240 | lua_pushlightuserdata(L, (void *)&KEY_HOOK); |
237 | lua_rawget(L, LUA_REGISTRYINDEX); | 241 | lua_rawget(L, LUA_REGISTRYINDEX); |
238 | lua_pushlightuserdata(L, L); | 242 | lua_pushlightuserdata(L, L); |
@@ -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)]; |
@@ -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 | ||
187 | void luaD_callhook (lua_State *L, int event, int line) { | 187 | void 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 | ||
214 | static 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 | |||
217 | static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { | 227 | static 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 | ||
314 | static 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 | |||
325 | int luaD_poscall (lua_State *L, StkId firstResult) { | 320 | int 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 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.h,v 2.15 2009/07/15 17:26:14 roberto Exp roberto $ | 2 | ** $Id: ldo.h,v 2.16 2009/11/19 16:24:41 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 | */ |
@@ -27,7 +27,7 @@ | |||
27 | typedef void (*Pfunc) (lua_State *L, void *ud); | 27 | typedef void (*Pfunc) (lua_State *L, void *ud); |
28 | 28 | ||
29 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); | 29 | LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name); |
30 | LUAI_FUNC void luaD_callhook (lua_State *L, int event, int line); | 30 | LUAI_FUNC void luaD_hook (lua_State *L, int event, int line); |
31 | LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); | 31 | LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); |
32 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults, | 32 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults, |
33 | int allowyield); | 33 | int allowyield); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.h,v 2.47 2009/10/23 19:12:19 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 2.48 2009/11/18 13:13:47 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -80,7 +80,6 @@ typedef struct CallInfo { | |||
80 | struct { /* only for Lua functions */ | 80 | struct { /* only for Lua functions */ |
81 | StkId base; /* base for this function */ | 81 | StkId base; /* base for this function */ |
82 | const Instruction *savedpc; | 82 | const Instruction *savedpc; |
83 | int tailcalls; /* number of tail calls lost under this entry */ | ||
84 | } l; | 83 | } l; |
85 | struct { /* only for C functions */ | 84 | struct { /* only for C functions */ |
86 | int ctx; /* context info. in case of yields */ | 85 | int ctx; /* context info. in case of yields */ |
@@ -104,6 +103,7 @@ typedef struct CallInfo { | |||
104 | #define CIST_YIELDED (1<<3) /* call reentered after suspension */ | 103 | #define CIST_YIELDED (1<<3) /* call reentered after suspension */ |
105 | #define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ | 104 | #define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ |
106 | #define CIST_STAT (1<<5) /* call has an error status (pcall) */ | 105 | #define CIST_STAT (1<<5) /* call has an error status (pcall) */ |
106 | #define CIST_TAIL (1<<6) /* call was tail called */ | ||
107 | 107 | ||
108 | 108 | ||
109 | #define curr_func(L) (clvalue(L->ci->func)) | 109 | #define curr_func(L) (clvalue(L->ci->func)) |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lua.h,v 1.249 2009/11/09 18:55:17 roberto Exp roberto $ | 2 | ** $Id: lua.h,v 1.250 2009/11/09 19:10:48 roberto Exp roberto $ |
3 | ** Lua - A Scripting Language | 3 | ** Lua - A Scripting Language |
4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) | 4 | ** Lua.org, PUC-Rio, Brazil (http://www.lua.org) |
5 | ** See Copyright Notice at the end of this file | 5 | ** See Copyright Notice at the end of this file |
@@ -356,7 +356,7 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); | |||
356 | #define LUA_HOOKRET 1 | 356 | #define LUA_HOOKRET 1 |
357 | #define LUA_HOOKLINE 2 | 357 | #define LUA_HOOKLINE 2 |
358 | #define LUA_HOOKCOUNT 3 | 358 | #define LUA_HOOKCOUNT 3 |
359 | #define LUA_HOOKTAILRET 4 | 359 | #define LUA_HOOKTAILCALL 4 |
360 | 360 | ||
361 | 361 | ||
362 | /* | 362 | /* |
@@ -401,6 +401,7 @@ struct lua_Debug { | |||
401 | int nups; /* (u) number of upvalues */ | 401 | int nups; /* (u) number of upvalues */ |
402 | int linedefined; /* (S) */ | 402 | int linedefined; /* (S) */ |
403 | int lastlinedefined; /* (S) */ | 403 | int lastlinedefined; /* (S) */ |
404 | char istailcall; /* (t) */ | ||
404 | char short_src[LUA_IDSIZE]; /* (S) */ | 405 | char short_src[LUA_IDSIZE]; /* (S) */ |
405 | /* private part */ | 406 | /* private part */ |
406 | struct CallInfo *i_ci; /* active function */ | 407 | struct CallInfo *i_ci; /* active function */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.99 2009/09/30 15:38:37 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.100 2009/10/28 12:20:07 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -62,7 +62,7 @@ static void traceexec (lua_State *L) { | |||
62 | lu_byte mask = L->hookmask; | 62 | lu_byte mask = L->hookmask; |
63 | if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { | 63 | if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) { |
64 | resethookcount(L); | 64 | resethookcount(L); |
65 | luaD_callhook(L, LUA_HOOKCOUNT, -1); | 65 | luaD_hook(L, LUA_HOOKCOUNT, -1); |
66 | } | 66 | } |
67 | if (mask & LUA_MASKLINE) { | 67 | if (mask & LUA_MASKLINE) { |
68 | Proto *p = ci_func(ci)->l.p; | 68 | Proto *p = ci_func(ci)->l.p; |
@@ -71,7 +71,7 @@ static void traceexec (lua_State *L) { | |||
71 | if (npc == 0 || /* call linehook when enter a new function, */ | 71 | if (npc == 0 || /* call linehook when enter a new function, */ |
72 | ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ | 72 | ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ |
73 | newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ | 73 | newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ |
74 | luaD_callhook(L, LUA_HOOKLINE, newline); | 74 | luaD_hook(L, LUA_HOOKLINE, newline); |
75 | } | 75 | } |
76 | L->oldpc = ci->u.l.savedpc; | 76 | L->oldpc = ci->u.l.savedpc; |
77 | } | 77 | } |
@@ -679,7 +679,7 @@ void luaV_execute (lua_State *L) { | |||
679 | oci->u.l.base = ofunc + (nci->u.l.base - nfunc); /* correct base */ | 679 | oci->u.l.base = ofunc + (nci->u.l.base - nfunc); /* correct base */ |
680 | oci->top = L->top = ofunc + (L->top - nfunc); /* correct top */ | 680 | oci->top = L->top = ofunc + (L->top - nfunc); /* correct top */ |
681 | oci->u.l.savedpc = nci->u.l.savedpc; | 681 | oci->u.l.savedpc = nci->u.l.savedpc; |
682 | oci->u.l.tailcalls++; /* one more call lost */ | 682 | oci->callstatus |= CIST_TAIL; /* function was tail called */ |
683 | ci = L->ci = oci; /* remove new frame */ | 683 | ci = L->ci = oci; /* remove new frame */ |
684 | lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize); | 684 | lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize); |
685 | break; /* restart luaV_execute over new Lua function */ | 685 | break; /* restart luaV_execute over new Lua function */ |