aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-06-16 16:29:32 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-06-16 16:29:32 -0300
commit9386e49a3173b68e8b5a7ba882c4c2faf557b61e (patch)
tree01de173acfac35de39aec9d4398dc0395a080ce5 /lgc.c
parent8cd7ae7da06f54b97f95d6994d6bf47086e4e7eb (diff)
downloadlua-9386e49a3173b68e8b5a7ba882c4c2faf557b61e.tar.gz
lua-9386e49a3173b68e8b5a7ba882c4c2faf557b61e.tar.bz2
lua-9386e49a3173b68e8b5a7ba882c4c2faf557b61e.zip
New metatable in an all-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.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/lgc.c b/lgc.c
index e4cbcf0c..bbaa5ff7 100644
--- a/lgc.c
+++ b/lgc.c
@@ -617,8 +617,11 @@ static l_mem traversetable (global_State *g, Table *h) {
617 case 2: /* weak keys */ 617 case 2: /* weak keys */
618 traverseephemeron(g, h, 0); 618 traverseephemeron(g, h, 0);
619 break; 619 break;
620 case 3: /* all weak */ 620 case 3: /* all weak; nothing to traverse */
621 linkgclist(h, g->allweak); /* nothing to traverse now */ 621 if (g->gcstate == GCSpropagate)
622 linkgclist(h, g->grayagain); /* must visit again its metatable */
623 else
624 linkgclist(h, g->allweak); /* must clear collected entries */
622 break; 625 break;
623 } 626 }
624 return 1 + 2*sizenode(h) + h->asize; 627 return 1 + 2*sizenode(h) + h->asize;