aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-06-16 16:33:02 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-06-16 16:33:02 -0300
commit1b0f943da7dfb25987456a77259edbeea0b94edc (patch)
tree6d095ff675b6779078e4368db338ad57562d7651 /lgc.c
parent6e22fedb74cf0c9b6656e9fce8b7331db847c605 (diff)
downloadlua-1b0f943da7dfb25987456a77259edbeea0b94edc.tar.gz
lua-1b0f943da7dfb25987456a77259edbeea0b94edc.tar.bz2
lua-1b0f943da7dfb25987456a77259edbeea0b94edc.zip
Bug: new metatable in weak table can fool the GC
All-weak tables are not being revisited after being visited during propagation; if it gets a new metatable after that, the new metatable may not be marked.
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/lgc.c b/lgc.c
index 5817f9ee..c01660ab 100644
--- a/lgc.c
+++ b/lgc.c
@@ -553,8 +553,12 @@ static lu_mem traversetable (global_State *g, Table *h) {
553 traverseweakvalue(g, h); 553 traverseweakvalue(g, h);
554 else if (!weakvalue) /* strong values? */ 554 else if (!weakvalue) /* strong values? */
555 traverseephemeron(g, h, 0); 555 traverseephemeron(g, h, 0);
556 else /* all weak */ 556 else { /* all weak */
557 linkgclist(h, g->allweak); /* nothing to traverse now */ 557 if (g->gcstate == GCSpropagate)
558 linkgclist(h, g->grayagain); /* must visit again its metatable */
559 else
560 linkgclist(h, g->allweak); /* must clear collected entries */
561 }
558 } 562 }
559 else /* not weak */ 563 else /* not weak */
560 traversestrongtable(g, h); 564 traversestrongtable(g, h);