aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto I <roberto@inf.puc-rio.br>2026-07-22 14:42:55 -0300
committerRoberto I <roberto@inf.puc-rio.br>2026-07-22 14:42:55 -0300
commit8511e90b7df5daf139aba290b9c9c1595927e7b3 (patch)
treec785e4595f212d9972fe9f40d2bb58a980a9257b /lgc.c
parent0f781f836ab348716eb9232d3831a871b9821a3c (diff)
downloadlua-8511e90b7df5daf139aba290b9c9c1595927e7b3.tar.gz
lua-8511e90b7df5daf139aba290b9c9c1595927e7b3.tar.bz2
lua-8511e90b7df5daf139aba290b9c9c1595927e7b3.zip
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.
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/lgc.c b/lgc.c
index c01660ab..52cea240 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1242,7 +1242,7 @@ static void finishgencycle (lua_State *L, global_State *g) {
1242 correctgraylists(g); 1242 correctgraylists(g);
1243 checkSizes(L, g); 1243 checkSizes(L, g);
1244 g->gcstate = GCSpropagate; /* skip restart */ 1244 g->gcstate = GCSpropagate; /* skip restart */
1245 if (!g->gcemergency) 1245 if (g->tobefnz != NULL && !g->gcemergency && luaD_checkminstack(L))
1246 callallpendingfinalizers(L); 1246 callallpendingfinalizers(L);
1247} 1247}
1248 1248
@@ -1632,11 +1632,12 @@ static lu_mem singlestep (lua_State *L) {
1632 break; 1632 break;
1633 } 1633 }
1634 case GCScallfin: { /* call remaining finalizers */ 1634 case GCScallfin: { /* call remaining finalizers */
1635 if (g->tobefnz && !g->gcemergency) { 1635 if (g->tobefnz && !g->gcemergency && luaD_checkminstack(L)) {
1636 g->gcstopem = 0; /* ok collections during finalizers */ 1636 g->gcstopem = 0; /* ok collections during finalizers */
1637 work = runafewfinalizers(L, GCFINMAX) * GCFINALIZECOST; 1637 work = runafewfinalizers(L, GCFINMAX) * GCFINALIZECOST;
1638 } 1638 }
1639 else { /* emergency mode or no more finalizers */ 1639 else { /* no more finalizers or emergency mode or no enough stack
1640 to run finalizers */
1640 g->gcstate = GCSpause; /* finish collection */ 1641 g->gcstate = GCSpause; /* finish collection */
1641 work = 0; 1642 work = 0;
1642 } 1643 }