summaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-07-15 14:26:14 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-07-15 14:26:14 -0300
commitf76f4cb79d84af4a7be9e0d75553bbe05a3ae90c (patch)
treedd9d1f8f3fb8c69f7617fe5688d7b1178bb7190e /ldo.c
parentabb85fc059a5d6427b9dc36edee1619f2c7a1da8 (diff)
downloadlua-f76f4cb79d84af4a7be9e0d75553bbe05a3ae90c.tar.gz
lua-f76f4cb79d84af4a7be9e0d75553bbe05a3ae90c.tar.bz2
lua-f76f4cb79d84af4a7be9e0d75553bbe05a3ae90c.zip
new way to control stack overflow, controling only total size of the stack
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c68
1 files changed, 50 insertions, 18 deletions
diff --git a/ldo.c b/ldo.c
index dc9112a1..e93f68e3 100644
--- a/ldo.c
+++ b/ldo.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldo.c,v 2.64 2009/05/21 20:06:11 roberto Exp roberto $ 2** $Id: ldo.c,v 2.65 2009/06/01 19:09:26 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,6 @@ void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop) {
70} 70}
71 71
72 72
73static void restore_stack_limit (lua_State *L) {
74 if (L->nci >= LUAI_MAXCALLS) /* stack overflow? */
75 luaE_freeCI(L); /* erase all extras CIs */
76}
77
78
79void luaD_throw (lua_State *L, int errcode) { 73void luaD_throw (lua_State *L, int errcode) {
80 if (L->errorJmp) { /* thread has an error handler? */ 74 if (L->errorJmp) { /* thread has an error handler? */
81 L->errorJmp->status = errcode; /* set status */ 75 L->errorJmp->status = errcode; /* set status */
@@ -130,25 +124,63 @@ static void correctstack (lua_State *L, TValue *oldstack) {
130} 124}
131 125
132 126
127/* some space for error handling */
128#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200)
129
130
133void luaD_reallocstack (lua_State *L, int newsize) { 131void luaD_reallocstack (lua_State *L, int newsize) {
134 TValue *oldstack = L->stack; 132 TValue *oldstack = L->stack;
135 int lim = L->stacksize; 133 int lim = L->stacksize;
136 int realsize = newsize + 1 + EXTRA_STACK; 134 lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
137 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK - 1); 135 lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK);
138 luaM_reallocvector(L, L->stack, L->stacksize, realsize, TValue); 136 luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue);
139 for (; lim < realsize; lim++) 137 for (; lim < newsize; lim++)
140 setnilvalue(L->stack + lim); /* erase new segment */ 138 setnilvalue(L->stack + lim); /* erase new segment */
141 L->stacksize = realsize; 139 L->stacksize = newsize;
142 L->stack_last = L->stack+newsize; 140 L->stack_last = L->stack + newsize - EXTRA_STACK;
143 correctstack(L, oldstack); 141 correctstack(L, oldstack);
144} 142}
145 143
146 144
147void luaD_growstack (lua_State *L, int n) { 145void luaD_growstack (lua_State *L, int n) {
148 if (n <= L->stacksize) /* double size is enough? */ 146 int size = L->stacksize;
149 luaD_reallocstack(L, 2*L->stacksize); 147 if (size > LUAI_MAXSTACK) /* error after extra size? */
148 luaD_throw(L, LUA_ERRERR);
149 else {
150 int needed = L->top - L->stack + n + EXTRA_STACK;
151 int newsize = 2 * size;
152 if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK;
153 if (newsize < needed) newsize = needed;
154 if (newsize > LUAI_MAXSTACK) { /* stack overflow? */
155 luaD_reallocstack(L, ERRORSTACKSIZE);
156 luaG_runerror(L, "stack overflow");
157 }
158 else
159 luaD_reallocstack(L, newsize);
160 }
161}
162
163
164static int stackinuse (lua_State *L) {
165 CallInfo *ci;
166 StkId lim = L->top;
167 for (ci = L->ci; ci != NULL; ci = ci->previous) {
168 lua_assert(ci->top <= L->stack_last);
169 if (lim < ci->top) lim = ci->top;
170 }
171 return cast_int(lim - L->stack) + 1; /* part of stack in use */
172}
173
174
175void luaD_shrinkstack (lua_State *L) {
176 int inuse = stackinuse(L);
177 int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
178 if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK;
179 if (inuse > LUAI_MAXSTACK || /* handling stack overflow? */
180 goodsize >= L->stacksize) /* would grow instead of shrink? */
181 condmovestack(L); /* don't change stack (change only for debugging) */
150 else 182 else
151 luaD_reallocstack(L, L->stacksize + n); 183 luaD_reallocstack(L, goodsize); /* shrink it */
152} 184}
153 185
154 186
@@ -427,7 +459,7 @@ static int recover (lua_State *L, int status) {
427 L->ci = ci; 459 L->ci = ci;
428 L->allowhook = ci->u.c.old_allowhook; 460 L->allowhook = ci->u.c.old_allowhook;
429 L->nny = 0; /* should be zero to be yieldable */ 461 L->nny = 0; /* should be zero to be yieldable */
430 restore_stack_limit(L); 462 luaD_shrinkstack(L);
431 L->errfunc = ci->u.c.old_errfunc; 463 L->errfunc = ci->u.c.old_errfunc;
432 ci->callstatus |= CIST_STAT; /* call has error status */ 464 ci->callstatus |= CIST_STAT; /* call has error status */
433 ci->u.c.status = status; /* (here it is) */ 465 ci->u.c.status = status; /* (here it is) */
@@ -499,7 +531,7 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u,
499 L->ci = old_ci; 531 L->ci = old_ci;
500 L->allowhook = old_allowhooks; 532 L->allowhook = old_allowhooks;
501 L->nny = old_nny; 533 L->nny = old_nny;
502 restore_stack_limit(L); 534 luaD_shrinkstack(L);
503 } 535 }
504 L->errfunc = old_errfunc; 536 L->errfunc = old_errfunc;
505 return status; 537 return status;