aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
authorRoberto I <roberto@inf.puc-rio.br>2026-01-11 15:36:03 -0300
committerRoberto I <roberto@inf.puc-rio.br>2026-01-11 15:36:03 -0300
commit2a7cf4f319fc276f4554a8f6364e6b1ba4eb2ded (patch)
treea99a8361664b0adda83186f04e2e9c98afd86b44 /ldo.c
parent5cfc725a8b61a6f96c7324f60ac26739315095ba (diff)
downloadlua-2a7cf4f319fc276f4554a8f6364e6b1ba4eb2ded.tar.gz
lua-2a7cf4f319fc276f4554a8f6364e6b1ba4eb2ded.tar.bz2
lua-2a7cf4f319fc276f4554a8f6364e6b1ba4eb2ded.zip
More effort in avoiding errors in finalizersHEADmaster
Before calling a finalizer, Lua not only checks stack limits, but actually ensures that a minimum number of slots are already allocated for the call. (If it cannot ensure that, it postpones the finalizer.) That avoids finalizers not running due to memory errors that the programmer cannot control.
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/ldo.c b/ldo.c
index 6d0184ec..12e0364b 100644
--- a/ldo.c
+++ b/ldo.c
@@ -221,13 +221,21 @@ l_noret luaD_errerr (lua_State *L) {
221 221
222 222
223/* 223/*
224** Check whether stack has enough space to run a simple function (such 224** Check whether stacks have enough space to run a simple function (such
225** as a finalizer): At least BASIC_STACK_SIZE in the Lua stack and 225** as a finalizer): At least BASIC_STACK_SIZE in the Lua stack, two
226** 2 slots in the C stack. 226** available CallInfos, and two "slots" in the C stack.
227*/ 227*/
228int luaD_checkminstack (lua_State *L) { 228int luaD_checkminstack (lua_State *L) {
229 return ((stacksize(L) < MAXSTACK - BASIC_STACK_SIZE) && 229 if (getCcalls(L) >= LUAI_MAXCCALLS - 2)
230 (getCcalls(L) < LUAI_MAXCCALLS - 2)); 230 return 0; /* not enough C-stack slots */
231 if (L->ci->next == NULL && luaE_extendCI(L, 0) == NULL)
232 return 0; /* unable to allocate first ci */
233 if (L->ci->next->next == NULL && luaE_extendCI(L, 0) == NULL)
234 return 0; /* unable to allocate second ci */
235 if (L->stack_last.p - L->top.p >= BASIC_STACK_SIZE)
236 return 1; /* enough (BASIC_STACK_SIZE) free slots in the Lua stack */
237 else /* try to grow stack to a size with enough free slots */
238 return luaD_growstack(L, BASIC_STACK_SIZE, 0);
231} 239}
232 240
233 241
@@ -616,7 +624,7 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
616 624
617 625
618 626
619#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L)) 627#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L, 1))
620 628
621 629
622/* 630/*