diff options
| author | Roberto I <roberto@inf.puc-rio.br> | 2026-07-22 14:42:55 -0300 |
|---|---|---|
| committer | Roberto I <roberto@inf.puc-rio.br> | 2026-07-22 14:42:55 -0300 |
| commit | 8511e90b7df5daf139aba290b9c9c1595927e7b3 (patch) | |
| tree | c785e4595f212d9972fe9f40d2bb58a980a9257b /lgc.c | |
| parent | 0f781f836ab348716eb9232d3831a871b9821a3c (diff) | |
| download | lua-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.c | 7 |
1 files changed, 4 insertions, 3 deletions
| @@ -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 | } |
