aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c6
-rw-r--r--ldebug.c24
-rw-r--r--ldo.c69
-rw-r--r--ldo.h5
-rw-r--r--lgc.c39
-rw-r--r--lstate.c61
-rw-r--r--lstate.h13
-rw-r--r--ltests.c18
-rw-r--r--lua.h4
-rw-r--r--lvm.c14
10 files changed, 127 insertions, 126 deletions
diff --git a/lapi.c b/lapi.c
index ea2b7c88..0e3ef071 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.73 2009/03/30 18:39:20 roberto Exp roberto $ 2** $Id: lapi.c,v 2.74 2009/04/08 18:04:33 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -72,7 +72,7 @@ static TValue *index2adr (lua_State *L, int idx) {
72 72
73 73
74static Table *getcurrenv (lua_State *L) { 74static Table *getcurrenv (lua_State *L) {
75 if (L->ci == L->base_ci) /* no enclosing function? */ 75 if (L->ci->previous == NULL) /* no enclosing function? */
76 return hvalue(gt(L)); /* use global table as environment */ 76 return hvalue(gt(L)); /* use global table as environment */
77 else { 77 else {
78 Closure *func = curr_func(L); 78 Closure *func = curr_func(L);
@@ -185,7 +185,7 @@ LUA_API void lua_replace (lua_State *L, int idx) {
185 StkId o; 185 StkId o;
186 lua_lock(L); 186 lua_lock(L);
187 /* explicit test for incompatible code */ 187 /* explicit test for incompatible code */
188 if (idx == LUA_ENVIRONINDEX && L->ci == L->base_ci) 188 if (idx == LUA_ENVIRONINDEX && L->ci->previous == NULL)
189 luaG_runerror(L, "no calling environment"); 189 luaG_runerror(L, "no calling environment");
190 api_checknelems(L, 1); 190 api_checknelems(L, 1);
191 o = index2adr(L, idx); 191 o = index2adr(L, idx);
diff --git a/ldebug.c b/ldebug.c
index 8492a97b..bcb7eaf3 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 2.44 2009/03/10 17:14:37 roberto Exp roberto $ 2** $Id: ldebug.c,v 2.45 2009/03/26 12:56:38 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*/
@@ -86,18 +86,18 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
86 int status; 86 int status;
87 CallInfo *ci; 87 CallInfo *ci;
88 lua_lock(L); 88 lua_lock(L);
89 for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { 89 for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous) {
90 level--; 90 level--;
91 if (isLua(ci)) /* Lua function? */ 91 if (isLua(ci)) /* Lua function? */
92 level -= ci->u.l.tailcalls; /* skip lost tail calls */ 92 level -= ci->u.l.tailcalls; /* skip lost tail calls */
93 } 93 }
94 if (level == 0 && ci > L->base_ci) { /* level found? */ 94 if (level == 0 && ci != &L->base_ci) { /* level found? */
95 status = 1; 95 status = 1;
96 ar->i_ci = cast_int(ci - L->base_ci); 96 ar->i_ci = ci;
97 } 97 }
98 else if (level < 0) { /* level is of a lost tail call? */ 98 else if (level < 0) { /* level is of a lost tail call? */
99 status = 1; 99 status = 1;
100 ar->i_ci = 0; 100 ar->i_ci = NULL;
101 } 101 }
102 else status = 0; /* no such level */ 102 else status = 0; /* no such level */
103 lua_unlock(L); 103 lua_unlock(L);
@@ -116,7 +116,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n) {
116 if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL) 116 if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL)
117 return name; /* is a local variable in a Lua function */ 117 return name; /* is a local variable in a Lua function */
118 else { 118 else {
119 StkId limit = (ci == L->ci) ? L->top : (ci+1)->func; 119 StkId limit = (ci == L->ci) ? L->top : ci->next->func;
120 if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */ 120 if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */
121 return "(*temporary)"; 121 return "(*temporary)";
122 else 122 else
@@ -126,7 +126,7 @@ static const char *findlocal (lua_State *L, CallInfo *ci, int n) {
126 126
127 127
128LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { 128LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
129 CallInfo *ci = L->base_ci + ar->i_ci; 129 CallInfo *ci = ar->i_ci;
130 const char *name = findlocal(L, ci, n); 130 const char *name = findlocal(L, ci, n);
131 lua_lock(L); 131 lua_lock(L);
132 if (name) { 132 if (name) {
@@ -139,7 +139,7 @@ LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
139 139
140 140
141LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { 141LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
142 CallInfo *ci = L->base_ci + ar->i_ci; 142 CallInfo *ci = ar->i_ci;
143 const char *name = findlocal(L, ci, n); 143 const char *name = findlocal(L, ci, n);
144 lua_lock(L); 144 lua_lock(L);
145 if (name) 145 if (name)
@@ -246,8 +246,8 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
246 f = clvalue(func); 246 f = clvalue(func);
247 L->top--; /* pop function */ 247 L->top--; /* pop function */
248 } 248 }
249 else if (ar->i_ci != 0) { /* no tail call? */ 249 else if (ar->i_ci != NULL) { /* no tail call? */
250 ci = L->base_ci + ar->i_ci; 250 ci = ar->i_ci;
251 lua_assert(ttisfunction(ci->func)); 251 lua_assert(ttisfunction(ci->func));
252 f = clvalue(ci->func); 252 f = clvalue(ci->func);
253 } 253 }
@@ -525,9 +525,9 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
525static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { 525static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
526 TMS tm = 0; 526 TMS tm = 0;
527 Instruction i; 527 Instruction i;
528 if ((isLua(ci) && ci->u.l.tailcalls > 0) || !isLua(ci - 1)) 528 if ((isLua(ci) && ci->u.l.tailcalls > 0) || !isLua(ci->previous))
529 return NULL; /* calling function is not Lua (or is unknown) */ 529 return NULL; /* calling function is not Lua (or is unknown) */
530 ci--; /* calling function */ 530 ci = ci->previous; /* calling function */
531 i = ci_func(ci)->l.p->code[currentpc(L, ci)]; 531 i = ci_func(ci)->l.p->code[currentpc(L, ci)];
532 switch (GET_OPCODE(i)) { 532 switch (GET_OPCODE(i)) {
533 case OP_CALL: 533 case OP_CALL:
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;
diff --git a/ldo.h b/ldo.h
index c600bfe4..57695b0a 100644
--- a/ldo.h
+++ b/ldo.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.h,v 2.10 2008/08/13 17:02:42 roberto Exp roberto $ 2** $Id: ldo.h,v 2.11 2009/03/10 17:14:37 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*/
@@ -24,9 +24,6 @@
24#define savestack(L,p) ((char *)(p) - (char *)L->stack) 24#define savestack(L,p) ((char *)(p) - (char *)L->stack)
25#define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) 25#define restorestack(L,n) ((TValue *)((char *)L->stack + (n)))
26 26
27#define saveci(L,p) ((char *)(p) - (char *)L->base_ci)
28#define restoreci(L,n) ((CallInfo *)((char *)L->base_ci + (n)))
29
30 27
31/* type of protected functions, to be ran by `runprotected' */ 28/* type of protected functions, to be ran by `runprotected' */
32typedef void (*Pfunc) (lua_State *L, void *ud); 29typedef void (*Pfunc) (lua_State *L, void *ud);
diff --git a/lgc.c b/lgc.c
index 482375d0..c15c4a09 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.48 2009/02/17 19:47:58 roberto Exp roberto $ 2** $Id: lgc.c,v 2.49 2009/03/10 17:14:37 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -379,38 +379,34 @@ static void traverseclosure (global_State *g, Closure *cl) {
379} 379}
380 380
381 381
382static void checkstacksizes (lua_State *L, StkId max) { 382static void checkstacksize (lua_State *L, StkId max) {
383 /* should not change the stack when handling overflow or 383 /* should not change the stack during an emergency gc cycle */
384 during an emergency gc cycle */ 384 if (G(L)->gckind == KGC_EMERGENCY)
385 if (L->size_ci > LUAI_MAXCALLS || G(L)->gckind == KGC_EMERGENCY) 385 return; /* do not touch the stack */
386 return; /* do not touch the stacks */
387 else { 386 else {
388 int ci_used = cast_int(L->ci - L->base_ci) + 1; /* number of `ci' in use */
389 int s_used = cast_int(max - L->stack) + 1; /* part of stack in use */ 387 int s_used = cast_int(max - L->stack) + 1; /* part of stack in use */
390 if (2*ci_used < L->size_ci)
391 luaD_reallocCI(L, 2*ci_used);
392 if (2*s_used < (L->stacksize - EXTRA_STACK)) 388 if (2*s_used < (L->stacksize - EXTRA_STACK))
393 luaD_reallocstack(L, 2*s_used); 389 luaD_reallocstack(L, 2*s_used);
394 } 390 }
395} 391}
396 392
397 393
398static void traversestack (global_State *g, lua_State *l) { 394static void traversestack (global_State *g, lua_State *L) {
399 StkId o, lim; 395 StkId o, lim;
400 CallInfo *ci; 396 CallInfo *ci;
401 if (l->stack == NULL || l->base_ci == NULL) 397 if (L->stack == NULL)
402 return; /* stack not completely built yet */ 398 return; /* stack not completely built yet */
403 markvalue(g, gt(l)); 399 markvalue(g, gt(L));
404 lim = l->top; 400 lim = L->top;
405 for (ci = l->base_ci; ci <= l->ci; ci++) { 401 for (ci = L->ci; ci != NULL; ci = ci->previous) {
406 lua_assert(ci->top <= l->stack_last); 402 lua_assert(ci->top <= L->stack_last);
407 if (lim < ci->top) lim = ci->top; 403 if (lim < ci->top) lim = ci->top;
408 } 404 }
409 for (o = l->stack; o < l->top; o++) 405 for (o = L->stack; o < L->top; o++)
410 markvalue(g, o); 406 markvalue(g, o);
411 for (; o <= lim; o++) 407 for (; o <= lim; o++)
412 setnilvalue(o); 408 setnilvalue(o);
413 checkstacksizes(l, lim); 409 checkstacksize(L, lim);
414} 410}
415 411
416 412
@@ -445,7 +441,7 @@ static l_mem propagatemark (global_State *g) {
445 black2gray(o); 441 black2gray(o);
446 traversestack(g, th); 442 traversestack(g, th);
447 return sizeof(lua_State) + sizeof(TValue) * th->stacksize + 443 return sizeof(lua_State) + sizeof(TValue) * th->stacksize +
448 sizeof(CallInfo) * th->size_ci; 444 sizeof(CallInfo) * th->nci;
449 } 445 }
450 case LUA_TPROTO: { 446 case LUA_TPROTO: {
451 Proto *p = gco2p(o); 447 Proto *p = gco2p(o);
@@ -554,8 +550,11 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
554 global_State *g = G(L); 550 global_State *g = G(L);
555 int deadmask = otherwhite(g); 551 int deadmask = otherwhite(g);
556 while ((curr = *p) != NULL && count-- > 0) { 552 while ((curr = *p) != NULL && count-- > 0) {
557 if (ttisthread(gch(curr))) /* sweep open upvalues of each thread */ 553 if (ttisthread(gch(curr))) {
558 sweepwholelist(L, &gco2th(curr)->openupval); 554 lua_State *L1 = gco2th(curr);
555 sweepwholelist(L, &L1->openupval); /* sweep open upvalues */
556 luaE_freeCI(L1); /* free extra CallInfo slots */
557 }
559 if ((gch(curr)->marked ^ WHITEBITS) & deadmask) { /* not dead? */ 558 if ((gch(curr)->marked ^ WHITEBITS) & deadmask) { /* not dead? */
560 lua_assert(!isdead(g, curr) || testbit(gch(curr)->marked, FIXEDBIT)); 559 lua_assert(!isdead(g, curr) || testbit(gch(curr)->marked, FIXEDBIT));
561 makewhite(g, curr); /* make it white (for next cycle) */ 560 makewhite(g, curr); /* make it white (for next cycle) */
diff --git a/lstate.c b/lstate.c
index df62f3e3..f9aa89c5 100644
--- a/lstate.c
+++ b/lstate.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.c,v 2.49 2009/02/18 17:20:56 roberto Exp roberto $ 2** $Id: lstate.c,v 2.50 2009/03/10 17:14:37 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*/
@@ -40,12 +40,41 @@ typedef struct LG {
40 40
41 41
42 42
43/*
44** maximum number of nested calls made by error-handling function
45*/
46#define LUAI_EXTRACALLS 10
47
48
49CallInfo *luaE_extendCI (lua_State *L) {
50 CallInfo *ci = luaM_new(L, CallInfo);
51 lua_assert(L->ci->next == NULL);
52 L->ci->next = ci;
53 ci->previous = L->ci;
54 ci->next = NULL;
55 if (++L->nci >= LUAI_MAXCALLS) {
56 if (L->nci == LUAI_MAXCALLS) /* overflow? */
57 luaG_runerror(L, "stack overflow");
58 if (L->nci >= LUAI_MAXCALLS + LUAI_EXTRACALLS) /* again? */
59 luaD_throw(L, LUA_ERRERR); /* error while handling overflow */
60 }
61 return ci;
62}
63
64
65void luaE_freeCI (lua_State *L) {
66 CallInfo *ci = L->ci;
67 CallInfo *next = ci->next;
68 ci->next = NULL;
69 while ((ci = next) != NULL) {
70 next = ci->next;
71 luaM_free(L, ci);
72 L->nci--;
73 }
74}
75
76
43static void stack_init (lua_State *L1, lua_State *L) { 77static void stack_init (lua_State *L1, lua_State *L) {
44 /* initialize CallInfo array */
45 L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
46 L1->ci = L1->base_ci;
47 L1->size_ci = BASIC_CI_SIZE;
48 L1->end_ci = L1->base_ci + L1->size_ci - 1;
49 /* initialize stack array */ 78 /* initialize stack array */
50 L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue); 79 L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue);
51 L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK; 80 L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
@@ -53,16 +82,18 @@ static void stack_init (lua_State *L1, lua_State *L) {
53 L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1; 82 L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
54 /* initialize first ci */ 83 /* initialize first ci */
55 L1->ci->func = L1->top; 84 L1->ci->func = L1->top;
56 setnilvalue(L1->top++); /* `function' entry for this `ci' */ 85 setnilvalue(L1->top++); /* 'function' entry for this 'ci' */
57 L1->base = L1->ci->base = L1->top; 86 L1->base = L1->ci->base = L1->top;
58 L1->ci->top = L1->top + LUA_MINSTACK; 87 L1->ci->top = L1->top + LUA_MINSTACK;
59 L1->ci->callstatus = 0; 88 L1->ci->callstatus = 0;
60} 89}
61 90
62 91
63static void freestack (lua_State *L, lua_State *L1) { 92static void freestack (lua_State *L) {
64 luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo); 93 L->ci = &L->base_ci; /* reset 'ci' list */
65 luaM_freearray(L, L1->stack, L1->stacksize, TValue); 94 luaE_freeCI(L);
95 lua_assert(L->nci == 0);
96 luaM_freearray(L, L->stack, L->stacksize, TValue);
66} 97}
67 98
68 99
@@ -94,10 +125,11 @@ static void preinit_state (lua_State *L, global_State *g) {
94 L->allowhook = 1; 125 L->allowhook = 1;
95 resethookcount(L); 126 resethookcount(L);
96 L->openupval = NULL; 127 L->openupval = NULL;
97 L->size_ci = 0;
98 L->nny = 1; 128 L->nny = 1;
99 L->status = LUA_OK; 129 L->status = LUA_OK;
100 L->base_ci = L->ci = NULL; 130 L->base_ci.next = L->base_ci.previous = NULL;
131 L->ci = &L->base_ci;
132 L->nci = 0;
101 L->savedpc = NULL; 133 L->savedpc = NULL;
102 L->errfunc = 0; 134 L->errfunc = 0;
103 setnilvalue(gt(L)); 135 setnilvalue(gt(L));
@@ -110,7 +142,7 @@ static void close_state (lua_State *L) {
110 luaC_freeall(L); /* collect all objects */ 142 luaC_freeall(L); /* collect all objects */
111 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *); 143 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
112 luaZ_freebuffer(L, &g->buff); 144 luaZ_freebuffer(L, &g->buff);
113 freestack(L, L); 145 freestack(L);
114 lua_assert(g->totalbytes == sizeof(LG)); 146 lua_assert(g->totalbytes == sizeof(LG));
115 (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0); 147 (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0);
116} 148}
@@ -142,7 +174,7 @@ void luaE_freethread (lua_State *L, lua_State *L1) {
142 luaF_close(L1, L1->stack); /* close all upvalues for this thread */ 174 luaF_close(L1, L1->stack); /* close all upvalues for this thread */
143 lua_assert(L1->openupval == NULL); 175 lua_assert(L1->openupval == NULL);
144 luai_userstatefree(L1); 176 luai_userstatefree(L1);
145 freestack(L, L1); 177 freestack(L1);
146 luaM_freemem(L, fromstate(L1), state_size(lua_State)); 178 luaM_freemem(L, fromstate(L1), state_size(lua_State));
147} 179}
148 180
@@ -211,3 +243,4 @@ LUA_API void lua_close (lua_State *L) {
211 close_state(L); 243 close_state(L);
212} 244}
213 245
246
diff --git a/lstate.h b/lstate.h
index c9155a94..0e34a54c 100644
--- a/lstate.h
+++ b/lstate.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lstate.h,v 2.40 2009/03/23 14:26:12 roberto Exp roberto $ 2** $Id: lstate.h,v 2.41 2009/04/08 18:04:33 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,8 +80,9 @@ typedef struct CallInfo {
80 StkId base; /* base for this function */ 80 StkId base; /* base for this function */
81 StkId func; /* function index in the stack */ 81 StkId func; /* function index in the stack */
82 StkId top; /* top for this function */ 82 StkId top; /* top for this function */
83 struct CallInfo *previous, *next; /* dynamic call link */
83 const Instruction *savedpc; 84 const Instruction *savedpc;
84 short nresults; /* expected number of results from this function */ 85 short nresults; /* expected number of results from a call */
85 lu_byte callstatus; 86 lu_byte callstatus;
86 union { 87 union {
87 struct { /* only for Lua functions */ 88 struct { /* only for Lua functions */
@@ -163,14 +164,12 @@ struct lua_State {
163 StkId base; /* base of current function */ 164 StkId base; /* base of current function */
164 global_State *l_G; 165 global_State *l_G;
165 CallInfo *ci; /* call info for current function */ 166 CallInfo *ci; /* call info for current function */
167 int nci; /* number of total CallInfo structures linked */
166 const Instruction *savedpc; /* `savedpc' of current function */ 168 const Instruction *savedpc; /* `savedpc' of current function */
167 const Instruction *oldpc; /* last pc traced */ 169 const Instruction *oldpc; /* last pc traced */
168 StkId stack_last; /* last free slot in the stack */ 170 StkId stack_last; /* last free slot in the stack */
169 StkId stack; /* stack base */ 171 StkId stack; /* stack base */
170 CallInfo *end_ci; /* points after end of ci array*/
171 CallInfo *base_ci; /* array of CallInfo's */
172 int stacksize; 172 int stacksize;
173 int size_ci; /* size of array `base_ci' */
174 unsigned short nny; /* number of non-yieldable calls in stack */ 173 unsigned short nny; /* number of non-yieldable calls in stack */
175 lu_byte hookmask; 174 lu_byte hookmask;
176 lu_byte allowhook; 175 lu_byte allowhook;
@@ -183,6 +182,7 @@ struct lua_State {
183 GCObject *gclist; 182 GCObject *gclist;
184 struct lua_longjmp *errorJmp; /* current error recover point */ 183 struct lua_longjmp *errorJmp; /* current error recover point */
185 ptrdiff_t errfunc; /* current error handling function (stack index) */ 184 ptrdiff_t errfunc; /* current error handling function (stack index) */
185 CallInfo base_ci; /* CallInfo for first level (C calling Lua) */
186}; 186};
187 187
188 188
@@ -223,6 +223,9 @@ union GCObject {
223 223
224 224
225LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); 225LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
226LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
227LUAI_FUNC void luaE_freeCI (lua_State *L);
228
226 229
227#endif 230#endif
228 231
diff --git a/ltests.c b/ltests.c
index e0de86f3..9a55f6da 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 2.59 2009/03/03 18:52:36 roberto Exp roberto $ 2** $Id: ltests.c,v 2.60 2009/04/14 19:10:17 roberto Exp roberto $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -296,13 +296,10 @@ static void checkstack (global_State *g, lua_State *L1) {
296 lua_assert(!isblack(uvo)); /* open upvalues cannot be black */ 296 lua_assert(!isblack(uvo)); /* open upvalues cannot be black */
297 } 297 }
298 checkliveness(g, gt(L1)); 298 checkliveness(g, gt(L1));
299 if (L1->base_ci) { 299 for (ci = L1->ci; ci != NULL; ci = ci->previous) {
300 for (ci = L1->base_ci; ci <= L1->ci; ci++) { 300 lua_assert(ci->top <= L1->stack_last);
301 lua_assert(ci->top <= L1->stack_last); 301 lua_assert(lua_checkpc(L1, ci));
302 lua_assert(lua_checkpc(L1, ci));
303 }
304 } 302 }
305 else lua_assert(L1->size_ci == 0);
306 if (L1->stack) { 303 if (L1->stack) {
307 for (o = L1->stack; o < L1->top; o++) 304 for (o = L1->stack; o < L1->top; o++)
308 checkliveness(g, o); 305 checkliveness(g, o);
@@ -356,10 +353,10 @@ printf(">>> %d %s %02x\n", g->gcstate, luaT_typenames[gch(o)->tt], gch(o)->mar
356 353
357 354
358int lua_checkpc (lua_State *L, pCallInfo ci) { 355int lua_checkpc (lua_State *L, pCallInfo ci) {
359 if (ci == L->base_ci || !isLua(ci)) return 1; 356 if (!isLua(ci)) return 1;
360 else { 357 else {
361 Proto *p = ci_func(ci)->l.p; 358 Proto *p = ci_func(ci)->l.p;
362 if (ci < L->ci) 359 if (ci != L->ci)
363 return p->code <= ci->savedpc && ci->savedpc <= p->code + p->sizecode; 360 return p->code <= ci->savedpc && ci->savedpc <= p->code + p->sizecode;
364 else 361 else
365 return p->code <= L->savedpc && L->savedpc <= p->code + p->sizecode; 362 return p->code <= L->savedpc && L->savedpc <= p->code + p->sizecode;
@@ -575,8 +572,7 @@ static int stacklevel (lua_State *L) {
575 unsigned long a = 0; 572 unsigned long a = 0;
576 lua_pushinteger(L, (L->top - L->stack)); 573 lua_pushinteger(L, (L->top - L->stack));
577 lua_pushinteger(L, (L->stack_last - L->stack)); 574 lua_pushinteger(L, (L->stack_last - L->stack));
578 lua_pushinteger(L, (L->ci - L->base_ci)); 575 lua_pushinteger(L, L->nci);
579 lua_pushinteger(L, (L->end_ci - L->base_ci));
580 lua_pushinteger(L, (unsigned long)&a); 576 lua_pushinteger(L, (unsigned long)&a);
581 return 5; 577 return 5;
582} 578}
diff --git a/lua.h b/lua.h
index a55e62b6..fb725765 100644
--- a/lua.h
+++ b/lua.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lua.h,v 1.234 2009/03/23 14:26:12 roberto Exp roberto $ 2** $Id: lua.h,v 1.235 2009/04/08 18:04:33 roberto Exp roberto $
3** Lua - An Extensible Extension Language 3** Lua - An Extensible Extension 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
@@ -367,7 +367,7 @@ struct lua_Debug {
367 int lastlinedefined; /* (S) */ 367 int lastlinedefined; /* (S) */
368 char short_src[LUA_IDSIZE]; /* (S) */ 368 char short_src[LUA_IDSIZE]; /* (S) */
369 /* private part */ 369 /* private part */
370 int i_ci; /* active function */ 370 struct CallInfo *i_ci; /* active function */
371}; 371};
372 372
373/* }====================================================================== */ 373/* }====================================================================== */
diff --git a/lvm.c b/lvm.c
index 494b40cd..0c70491d 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.83 2009/03/04 13:32:29 roberto Exp roberto $ 2** $Id: lvm.c,v 2.84 2009/03/10 17:14:37 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*/
@@ -663,19 +663,19 @@ void luaV_execute (lua_State *L) {
663 } 663 }
664 else { 664 else {
665 /* tail call: put new frame in place of previous one */ 665 /* tail call: put new frame in place of previous one */
666 CallInfo *ci = L->ci - 1; /* previous frame */ 666 StkId pfunc = L->ci->func; /* called function index */
667 int aux; 667 CallInfo *ci = L->ci->previous; /* caller frame */
668 StkId func = ci->func; 668 StkId func = ci->func;
669 StkId pfunc = (ci+1)->func; /* previous function index */ 669 int aux;
670 if (cl->p->sizep > 0) luaF_close(L, ci->base); 670 if (cl->p->sizep > 0) luaF_close(L, ci->base);
671 L->base = ci->base = ci->func + ((ci+1)->base - pfunc); 671 L->base = ci->base = ci->func + (L->ci->base - pfunc);
672 for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */ 672 for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */
673 setobjs2s(L, func+aux, pfunc+aux); 673 setobjs2s(L, func+aux, pfunc+aux);
674 ci->top = L->top = func+aux; /* correct top */ 674 ci->top = L->top = func+aux; /* correct top */
675 lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize); 675 lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize);
676 ci->savedpc = L->savedpc; 676 ci->savedpc = L->savedpc;
677 ci->u.l.tailcalls++; /* one more call lost */ 677 ci->u.l.tailcalls++; /* one more call lost */
678 L->ci--; /* remove new frame */ 678 L->ci = ci; /* remove new frame */
679 goto reentry; 679 goto reentry;
680 } 680 }
681 } 681 }
@@ -684,7 +684,7 @@ void luaV_execute (lua_State *L) {
684 if (b != 0) L->top = ra+b-1; 684 if (b != 0) L->top = ra+b-1;
685 if (cl->p->sizep > 0) luaF_close(L, base); 685 if (cl->p->sizep > 0) luaF_close(L, base);
686 b = luaD_poscall(L, ra); 686 b = luaD_poscall(L, ra);
687 if (!((L->ci + 1)->callstatus & CIST_REENTRY)) 687 if (!(L->ci->next->callstatus & CIST_REENTRY))
688 return; /* external invocation: return */ 688 return; /* external invocation: return */
689 else { /* invocation via reentry: continue execution */ 689 else { /* invocation via reentry: continue execution */
690 if (b) L->top = L->ci->top; 690 if (b) L->top = L->ci->top;