From 8511e90b7df5daf139aba290b9c9c1595927e7b3 Mon Sep 17 00:00:00 2001 From: Roberto I Date: Wed, 22 Jul 2026 14:42:55 -0300 Subject: Bug: GC checks stack space before running finalizer If some stack does not have a minimum available space, the GC defers calling a finalizer until the next cycle. That avoids errors while running a finalizer that the programmer cannot control. --- ldo.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'ldo.c') diff --git a/ldo.c b/ldo.c index c92573d6..8085b735 100644 --- a/ldo.c +++ b/ldo.c @@ -205,6 +205,25 @@ l_noret luaD_errerr (lua_State *L) { } +/* +** Check whether stacks have enough space to run a simple function (such +** as a finalizer): At least BASIC_STACK_SIZE in the Lua stack, two +** available CallInfos, and two "slots" in the C stack. +*/ +int luaD_checkminstack (lua_State *L) { + if (getCcalls(L) >= LUAI_MAXCCALLS - 2) + return 0; /* not enough C-stack slots */ + if (L->ci->next == NULL && luaE_extendCI(L, 0) == NULL) + return 0; /* unable to allocate first ci */ + if (L->ci->next->next == NULL && luaE_extendCI(L, 0) == NULL) + return 0; /* unable to allocate second ci */ + if (L->stack_last.p - L->top.p >= BASIC_STACK_SIZE) + return 1; /* enough (BASIC_STACK_SIZE) free slots in the Lua stack */ + else /* try to grow stack to a size with enough free slots */ + return luaD_growstack(L, BASIC_STACK_SIZE, 0); +} + + /* ** Reallocate the stack to a new size, correcting all pointers into it. ** In ISO C, any pointer use after the pointer has been deallocated is @@ -503,7 +522,7 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) { -#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L)) +#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L, 1)) l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret, -- cgit v1.2.3-55-g6feb