aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c69
1 files changed, 21 insertions, 48 deletions
diff --git a/ldo.c b/ldo.c
index 28560e0a..1a051222 100644
--- a/ldo.c
+++ b/ldo.c
@@ -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
72static void restore_stack_limit (lua_State *L) { 72static 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
147void 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
156void luaD_growstack (lua_State *L, int n) { 143void 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
164static 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
176void luaD_callhook (lua_State *L, int event, int line) { 151void 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) {
318int luaD_poscall (lua_State *L, StkId firstResult) { 291int 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) {
387static void unroll (lua_State *L, void *ud) { 360static 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*/
438static CallInfo *findpcall (lua_State *L) { 411static 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) {
515int luaD_pcall (lua_State *L, Pfunc func, void *u, 488int 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;