diff options
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 43 |
1 files changed, 29 insertions, 14 deletions
@@ -171,6 +171,24 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { | |||
171 | ** =================================================================== | 171 | ** =================================================================== |
172 | */ | 172 | */ |
173 | 173 | ||
174 | /* some stack space for error handling */ | ||
175 | #define STACKERRSPACE 200 | ||
176 | |||
177 | |||
178 | /* maximum stack size that respects size_t */ | ||
179 | #define MAXSTACK_BYSIZET ((MAX_SIZET / sizeof(StackValue)) - STACKERRSPACE) | ||
180 | |||
181 | /* | ||
182 | ** Minimum between LUAI_MAXSTACK and MAXSTACK_BYSIZET | ||
183 | ** (Maximum size for the stack must respect size_t.) | ||
184 | */ | ||
185 | #define MAXSTACK cast_int(LUAI_MAXSTACK < MAXSTACK_BYSIZET \ | ||
186 | ? LUAI_MAXSTACK : MAXSTACK_BYSIZET) | ||
187 | |||
188 | |||
189 | /* stack size with extra space for error handling */ | ||
190 | #define ERRORSTACKSIZE (MAXSTACK + STACKERRSPACE) | ||
191 | |||
174 | 192 | ||
175 | /* | 193 | /* |
176 | ** Change all pointers to the stack into offsets. | 194 | ** Change all pointers to the stack into offsets. |
@@ -208,9 +226,6 @@ static void correctstack (lua_State *L) { | |||
208 | } | 226 | } |
209 | 227 | ||
210 | 228 | ||
211 | /* some space for error handling */ | ||
212 | #define ERRORSTACKSIZE (LUAI_MAXSTACK + 200) | ||
213 | |||
214 | /* | 229 | /* |
215 | ** Reallocate the stack to a new size, correcting all pointers into it. | 230 | ** Reallocate the stack to a new size, correcting all pointers into it. |
216 | ** In ISO C, any pointer use after the pointer has been deallocated is | 231 | ** In ISO C, any pointer use after the pointer has been deallocated is |
@@ -227,7 +242,7 @@ int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { | |||
227 | int i; | 242 | int i; |
228 | StkId newstack; | 243 | StkId newstack; |
229 | int oldgcstop = G(L)->gcstopem; | 244 | int oldgcstop = G(L)->gcstopem; |
230 | lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); | 245 | lua_assert(newsize <= MAXSTACK || newsize == ERRORSTACKSIZE); |
231 | relstack(L); /* change pointers to offsets */ | 246 | relstack(L); /* change pointers to offsets */ |
232 | G(L)->gcstopem = 1; /* stop emergency collection */ | 247 | G(L)->gcstopem = 1; /* stop emergency collection */ |
233 | newstack = luaM_reallocvector(L, L->stack.p, oldsize + EXTRA_STACK, | 248 | newstack = luaM_reallocvector(L, L->stack.p, oldsize + EXTRA_STACK, |
@@ -254,7 +269,7 @@ int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { | |||
254 | */ | 269 | */ |
255 | int luaD_growstack (lua_State *L, int n, int raiseerror) { | 270 | int luaD_growstack (lua_State *L, int n, int raiseerror) { |
256 | int size = stacksize(L); | 271 | int size = stacksize(L); |
257 | if (l_unlikely(size > LUAI_MAXSTACK)) { | 272 | if (l_unlikely(size > MAXSTACK)) { |
258 | /* if stack is larger than maximum, thread is already using the | 273 | /* if stack is larger than maximum, thread is already using the |
259 | extra space reserved for errors, that is, thread is handling | 274 | extra space reserved for errors, that is, thread is handling |
260 | a stack error; cannot grow further than that. */ | 275 | a stack error; cannot grow further than that. */ |
@@ -263,14 +278,14 @@ int luaD_growstack (lua_State *L, int n, int raiseerror) { | |||
263 | luaD_throw(L, LUA_ERRERR); /* error inside message handler */ | 278 | luaD_throw(L, LUA_ERRERR); /* error inside message handler */ |
264 | return 0; /* if not 'raiseerror', just signal it */ | 279 | return 0; /* if not 'raiseerror', just signal it */ |
265 | } | 280 | } |
266 | else if (n < LUAI_MAXSTACK) { /* avoids arithmetic overflows */ | 281 | else if (n < MAXSTACK) { /* avoids arithmetic overflows */ |
267 | int newsize = 2 * size; /* tentative new size */ | 282 | int newsize = 2 * size; /* tentative new size */ |
268 | int needed = cast_int(L->top.p - L->stack.p) + n; | 283 | int needed = cast_int(L->top.p - L->stack.p) + n; |
269 | if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */ | 284 | if (newsize > MAXSTACK) /* cannot cross the limit */ |
270 | newsize = LUAI_MAXSTACK; | 285 | newsize = MAXSTACK; |
271 | if (newsize < needed) /* but must respect what was asked for */ | 286 | if (newsize < needed) /* but must respect what was asked for */ |
272 | newsize = needed; | 287 | newsize = needed; |
273 | if (l_likely(newsize <= LUAI_MAXSTACK)) | 288 | if (l_likely(newsize <= MAXSTACK)) |
274 | return luaD_reallocstack(L, newsize, raiseerror); | 289 | return luaD_reallocstack(L, newsize, raiseerror); |
275 | } | 290 | } |
276 | /* else stack overflow */ | 291 | /* else stack overflow */ |
@@ -306,17 +321,17 @@ static int stackinuse (lua_State *L) { | |||
306 | ** to twice the current use. (So, the final stack size is at most 2/3 the | 321 | ** to twice the current use. (So, the final stack size is at most 2/3 the |
307 | ** previous size, and half of its entries are empty.) | 322 | ** previous size, and half of its entries are empty.) |
308 | ** As a particular case, if stack was handling a stack overflow and now | 323 | ** As a particular case, if stack was handling a stack overflow and now |
309 | ** it is not, 'max' (limited by LUAI_MAXSTACK) will be smaller than | 324 | ** it is not, 'max' (limited by MAXSTACK) will be smaller than |
310 | ** stacksize (equal to ERRORSTACKSIZE in this case), and so the stack | 325 | ** stacksize (equal to ERRORSTACKSIZE in this case), and so the stack |
311 | ** will be reduced to a "regular" size. | 326 | ** will be reduced to a "regular" size. |
312 | */ | 327 | */ |
313 | void luaD_shrinkstack (lua_State *L) { | 328 | void luaD_shrinkstack (lua_State *L) { |
314 | int inuse = stackinuse(L); | 329 | int inuse = stackinuse(L); |
315 | int max = (inuse > LUAI_MAXSTACK / 3) ? LUAI_MAXSTACK : inuse * 3; | 330 | int max = (inuse > MAXSTACK / 3) ? MAXSTACK : inuse * 3; |
316 | /* if thread is currently not handling a stack overflow and its | 331 | /* if thread is currently not handling a stack overflow and its |
317 | size is larger than maximum "reasonable" size, shrink it */ | 332 | size is larger than maximum "reasonable" size, shrink it */ |
318 | if (inuse <= LUAI_MAXSTACK && stacksize(L) > max) { | 333 | if (inuse <= MAXSTACK && stacksize(L) > max) { |
319 | int nsize = (inuse > LUAI_MAXSTACK / 2) ? LUAI_MAXSTACK : inuse * 2; | 334 | int nsize = (inuse > MAXSTACK / 2) ? MAXSTACK : inuse * 2; |
320 | luaD_reallocstack(L, nsize, 0); /* ok if that fails */ | 335 | luaD_reallocstack(L, nsize, 0); /* ok if that fails */ |
321 | } | 336 | } |
322 | else /* don't change stack */ | 337 | else /* don't change stack */ |
@@ -408,7 +423,7 @@ static void rethook (lua_State *L, CallInfo *ci, int nres) { | |||
408 | delta = ci->u.l.nextraargs + p->numparams + 1; | 423 | delta = ci->u.l.nextraargs + p->numparams + 1; |
409 | } | 424 | } |
410 | ci->func.p += delta; /* if vararg, back to virtual 'func' */ | 425 | ci->func.p += delta; /* if vararg, back to virtual 'func' */ |
411 | ftransfer = cast(unsigned short, firstres - ci->func.p); | 426 | ftransfer = cast_int(firstres - ci->func.p); |
412 | luaD_hook(L, LUA_HOOKRET, -1, ftransfer, nres); /* call it */ | 427 | luaD_hook(L, LUA_HOOKRET, -1, ftransfer, nres); /* call it */ |
413 | ci->func.p -= delta; | 428 | ci->func.p -= delta; |
414 | } | 429 | } |