diff options
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 69 |
1 files changed, 21 insertions, 48 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 2.58 2009/04/08 18:04:33 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.59 2009/04/15 16:53:39 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 | */ |
@@ -70,12 +70,8 @@ void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) { | |||
70 | 70 | ||
71 | 71 | ||
72 | static void restore_stack_limit (lua_State *L) { | 72 | static void restore_stack_limit (lua_State *L) { |
73 | lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); | 73 | if (L->nci >= LUAI_MAXCALLS) /* stack overflow? */ |
74 | if (L->size_ci > LUAI_MAXCALLS) { /* there was an overflow? */ | 74 | luaE_freeCI(L); /* erase all extras CIs */ |
75 | int inuse = cast_int(L->ci - L->base_ci); | ||
76 | if (inuse + 1 < LUAI_MAXCALLS) /* can `undo' overflow? */ | ||
77 | luaD_reallocCI(L, LUAI_MAXCALLS); | ||
78 | } | ||
79 | } | 75 | } |
80 | 76 | ||
81 | 77 | ||
@@ -124,7 +120,7 @@ static void correctstack (lua_State *L, TValue *oldstack) { | |||
124 | L->top = (L->top - oldstack) + L->stack; | 120 | L->top = (L->top - oldstack) + L->stack; |
125 | for (up = L->openupval; up != NULL; up = up->gch.next) | 121 | for (up = L->openupval; up != NULL; up = up->gch.next) |
126 | gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; | 122 | gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; |
127 | for (ci = L->base_ci; ci <= L->ci; ci++) { | 123 | for (ci = L->ci; ci != NULL; ci = ci->previous) { |
128 | ci->top = (ci->top - oldstack) + L->stack; | 124 | ci->top = (ci->top - oldstack) + L->stack; |
129 | ci->base = (ci->base - oldstack) + L->stack; | 125 | ci->base = (ci->base - oldstack) + L->stack; |
130 | ci->func = (ci->func - oldstack) + L->stack; | 126 | ci->func = (ci->func - oldstack) + L->stack; |
@@ -144,15 +140,6 @@ void luaD_reallocstack (lua_State *L, int newsize) { | |||
144 | } | 140 | } |
145 | 141 | ||
146 | 142 | ||
147 | void luaD_reallocCI (lua_State *L, int newsize) { | ||
148 | CallInfo *oldci = L->base_ci; | ||
149 | luaM_reallocvector(L, L->base_ci, L->size_ci, newsize, CallInfo); | ||
150 | L->size_ci = newsize; | ||
151 | L->ci = (L->ci - oldci) + L->base_ci; | ||
152 | L->end_ci = L->base_ci + L->size_ci - 1; | ||
153 | } | ||
154 | |||
155 | |||
156 | void luaD_growstack (lua_State *L, int n) { | 143 | void luaD_growstack (lua_State *L, int n) { |
157 | if (n <= L->stacksize) /* double size is enough? */ | 144 | if (n <= L->stacksize) /* double size is enough? */ |
158 | luaD_reallocstack(L, 2*L->stacksize); | 145 | luaD_reallocstack(L, 2*L->stacksize); |
@@ -161,18 +148,6 @@ void luaD_growstack (lua_State *L, int n) { | |||
161 | } | 148 | } |
162 | 149 | ||
163 | 150 | ||
164 | static CallInfo *growCI (lua_State *L) { | ||
165 | if (L->size_ci > LUAI_MAXCALLS) /* overflow while handling overflow? */ | ||
166 | luaD_throw(L, LUA_ERRERR); | ||
167 | else { | ||
168 | luaD_reallocCI(L, 2*L->size_ci); | ||
169 | if (L->size_ci > LUAI_MAXCALLS) | ||
170 | luaG_runerror(L, "stack overflow"); | ||
171 | } | ||
172 | return ++L->ci; | ||
173 | } | ||
174 | |||
175 | |||
176 | void luaD_callhook (lua_State *L, int event, int line) { | 151 | void luaD_callhook (lua_State *L, int event, int line) { |
177 | lua_Hook hook = L->hook; | 152 | lua_Hook hook = L->hook; |
178 | if (hook && L->allowhook) { | 153 | if (hook && L->allowhook) { |
@@ -182,9 +157,9 @@ void luaD_callhook (lua_State *L, int event, int line) { | |||
182 | ar.event = event; | 157 | ar.event = event; |
183 | ar.currentline = line; | 158 | ar.currentline = line; |
184 | if (event == LUA_HOOKTAILRET) | 159 | if (event == LUA_HOOKTAILRET) |
185 | ar.i_ci = 0; /* tail call; no debug information about it */ | 160 | ar.i_ci = NULL; /* tail call; no debug information about it */ |
186 | else | 161 | else |
187 | ar.i_ci = cast_int(L->ci - L->base_ci); | 162 | ar.i_ci = L->ci; |
188 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | 163 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ |
189 | L->ci->top = L->top + LUA_MINSTACK; | 164 | L->ci->top = L->top + LUA_MINSTACK; |
190 | lua_assert(L->ci->top <= L->stack_last); | 165 | lua_assert(L->ci->top <= L->stack_last); |
@@ -235,9 +210,7 @@ static StkId tryfuncTM (lua_State *L, StkId func) { | |||
235 | 210 | ||
236 | 211 | ||
237 | 212 | ||
238 | #define inc_ci(L) \ | 213 | #define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) |
239 | ((L->ci == L->end_ci) ? growCI(L) : \ | ||
240 | (condhardstacktests(luaD_reallocCI(L, L->size_ci)), ++L->ci)) | ||
241 | 214 | ||
242 | 215 | ||
243 | /* | 216 | /* |
@@ -265,7 +238,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
265 | base = adjust_varargs(L, p, nargs); | 238 | base = adjust_varargs(L, p, nargs); |
266 | func = restorestack(L, funcr); /* previous call may change the stack */ | 239 | func = restorestack(L, funcr); /* previous call may change the stack */ |
267 | } | 240 | } |
268 | ci = inc_ci(L); /* now `enter' new function */ | 241 | ci = next_ci(L); /* now 'enter' new function */ |
269 | ci->func = func; | 242 | ci->func = func; |
270 | L->base = ci->base = base; | 243 | L->base = ci->base = base; |
271 | ci->top = L->base + p->maxstacksize; | 244 | ci->top = L->base + p->maxstacksize; |
@@ -287,7 +260,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
287 | CallInfo *ci; | 260 | CallInfo *ci; |
288 | int n; | 261 | int n; |
289 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | 262 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ |
290 | ci = inc_ci(L); /* now `enter' new function */ | 263 | ci = next_ci(L); /* now 'enter' new function */ |
291 | ci->func = restorestack(L, funcr); | 264 | ci->func = restorestack(L, funcr); |
292 | L->base = ci->base = ci->func + 1; | 265 | L->base = ci->base = ci->func + 1; |
293 | ci->top = L->top + LUA_MINSTACK; | 266 | ci->top = L->top + LUA_MINSTACK; |
@@ -318,17 +291,17 @@ static StkId callrethooks (lua_State *L, StkId firstResult) { | |||
318 | int luaD_poscall (lua_State *L, StkId firstResult) { | 291 | int luaD_poscall (lua_State *L, StkId firstResult) { |
319 | StkId res; | 292 | StkId res; |
320 | int wanted, i; | 293 | int wanted, i; |
321 | CallInfo *ci; | 294 | CallInfo *ci = L->ci; |
322 | if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { | 295 | if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { |
323 | if (L->hookmask & LUA_MASKRET) | 296 | if (L->hookmask & LUA_MASKRET) |
324 | firstResult = callrethooks(L, firstResult); | 297 | firstResult = callrethooks(L, firstResult); |
325 | L->oldpc = (L->ci - 1)->savedpc; /* set 'oldpc' for returning function */ | 298 | L->oldpc = L->ci->previous->savedpc; /* 'oldpc' for returning function */ |
326 | } | 299 | } |
327 | ci = L->ci--; | ||
328 | res = ci->func; /* res == final position of 1st result */ | 300 | res = ci->func; /* res == final position of 1st result */ |
329 | wanted = (ci - 1)->nresults; | 301 | L->ci = ci = L->ci->previous; /* back to caller */ |
330 | L->base = (ci - 1)->base; /* restore base */ | 302 | wanted = ci->nresults; |
331 | L->savedpc = (ci - 1)->savedpc; /* restore savedpc */ | 303 | L->base = ci->base; /* restore base */ |
304 | L->savedpc = ci->savedpc; /* restore savedpc */ | ||
332 | /* move results to correct place */ | 305 | /* move results to correct place */ |
333 | for (i = wanted; i != 0 && firstResult < L->top; i--) | 306 | for (i = wanted; i != 0 && firstResult < L->top; i--) |
334 | setobjs2s(L, res++, firstResult++); | 307 | setobjs2s(L, res++, firstResult++); |
@@ -387,7 +360,7 @@ static void finishCcall (lua_State *L) { | |||
387 | static void unroll (lua_State *L, void *ud) { | 360 | static void unroll (lua_State *L, void *ud) { |
388 | UNUSED(ud); | 361 | UNUSED(ud); |
389 | for (;;) { | 362 | for (;;) { |
390 | if (L->ci == L->base_ci) /* stack is empty? */ | 363 | if (L->ci == &L->base_ci) /* stack is empty? */ |
391 | return; /* coroutine finished normally */ | 364 | return; /* coroutine finished normally */ |
392 | if (!isLua(L->ci)) /* C function? */ | 365 | if (!isLua(L->ci)) /* C function? */ |
393 | finishCcall(L); | 366 | finishCcall(L); |
@@ -403,7 +376,7 @@ static void resume (lua_State *L, void *ud) { | |||
403 | StkId firstArg = cast(StkId, ud); | 376 | StkId firstArg = cast(StkId, ud); |
404 | CallInfo *ci = L->ci; | 377 | CallInfo *ci = L->ci; |
405 | if (L->status == LUA_OK) { /* start coroutine? */ | 378 | if (L->status == LUA_OK) { /* start coroutine? */ |
406 | lua_assert(ci == L->base_ci && firstArg > L->base); | 379 | lua_assert(ci == &L->base_ci && firstArg > L->base); |
407 | if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ | 380 | if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ |
408 | luaV_execute(L); /* call it */ | 381 | luaV_execute(L); /* call it */ |
409 | } | 382 | } |
@@ -437,7 +410,7 @@ static int resume_error (lua_State *L, const char *msg) { | |||
437 | */ | 410 | */ |
438 | static CallInfo *findpcall (lua_State *L) { | 411 | static CallInfo *findpcall (lua_State *L) { |
439 | CallInfo *ci; | 412 | CallInfo *ci; |
440 | for (ci = L->ci; ci > L->base_ci; ci--) { /* search for first pcall */ | 413 | for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */ |
441 | if (ci->callstatus & CIST_YPCALL) | 414 | if (ci->callstatus & CIST_YPCALL) |
442 | return ci; | 415 | return ci; |
443 | } | 416 | } |
@@ -471,7 +444,7 @@ LUA_API int lua_resume (lua_State *L, int nargs) { | |||
471 | if (L->status != LUA_YIELD) { | 444 | if (L->status != LUA_YIELD) { |
472 | if (L->status != LUA_OK) | 445 | if (L->status != LUA_OK) |
473 | return resume_error(L, "cannot resume dead coroutine"); | 446 | return resume_error(L, "cannot resume dead coroutine"); |
474 | else if (L->ci != L->base_ci) | 447 | else if (L->ci != &L->base_ci) |
475 | return resume_error(L, "cannot resume non-suspended coroutine"); | 448 | return resume_error(L, "cannot resume non-suspended coroutine"); |
476 | } | 449 | } |
477 | luai_userstateresume(L, nargs); | 450 | luai_userstateresume(L, nargs); |
@@ -515,7 +488,7 @@ LUA_API int lua_yield (lua_State *L, int nresults) { | |||
515 | int luaD_pcall (lua_State *L, Pfunc func, void *u, | 488 | int luaD_pcall (lua_State *L, Pfunc func, void *u, |
516 | ptrdiff_t old_top, ptrdiff_t ef) { | 489 | ptrdiff_t old_top, ptrdiff_t ef) { |
517 | int status; | 490 | int status; |
518 | ptrdiff_t old_ci = saveci(L, L->ci); | 491 | CallInfo *old_ci = L->ci; |
519 | lu_byte old_allowhooks = L->allowhook; | 492 | lu_byte old_allowhooks = L->allowhook; |
520 | unsigned short old_nny = L->nny; | 493 | unsigned short old_nny = L->nny; |
521 | ptrdiff_t old_errfunc = L->errfunc; | 494 | ptrdiff_t old_errfunc = L->errfunc; |
@@ -525,7 +498,7 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u, | |||
525 | StkId oldtop = restorestack(L, old_top); | 498 | StkId oldtop = restorestack(L, old_top); |
526 | luaF_close(L, oldtop); /* close possible pending closures */ | 499 | luaF_close(L, oldtop); /* close possible pending closures */ |
527 | luaD_seterrorobj(L, status, oldtop); | 500 | luaD_seterrorobj(L, status, oldtop); |
528 | L->ci = restoreci(L, old_ci); | 501 | L->ci = old_ci; |
529 | L->base = L->ci->base; | 502 | L->base = L->ci->base; |
530 | L->savedpc = L->ci->savedpc; | 503 | L->savedpc = L->ci->savedpc; |
531 | L->allowhook = old_allowhooks; | 504 | L->allowhook = old_allowhooks; |