** Traverse a table with weak values and link it to proper list. During ** propagate phase, keep it in 'grayagain' list, to be revisited in the ** atomic phase. In the atomic phase, if table has any white value, ** put it in 'weak' list, to be cleared. */
| 359 | ** put it in 'weak' list, to be cleared. |
| 360 | */ |
| 361 | static void traverseweakvalue (global_State *g, Table *h) { |
| 362 | Node *n, *limit = gnodelast(h); |
| 363 | /* if there is array part, assume it may have white values (it is not |
| 364 | worth traversing it now just to check) */ |
| 365 | int hasclears = (h->sizearray > 0); |
| 366 | for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ |
| 367 | checkdeadkey(n); |
| 368 | if (ttisnil(gval(n))) /* entry is empty? */ |
| 369 | removeentry(n); /* remove it */ |
| 370 | else { |
| 371 | lua_assert(!ttisnil(gkey(n))); |
| 372 | markvalue(g, gkey(n)); /* mark key */ |
| 373 | if (!hasclears && iscleared(g, gval(n))) /* is there a white value? */ |
| 374 | hasclears = 1; /* table will have to be cleared */ |
| 375 | } |
| 376 | } |
| 377 | if (g->gcstate == GCSpropagate) |
| 378 | linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ |
| 379 | else if (hasclears) |
| 380 | linkgclist(h, g->weak); /* has to be cleared later */ |
| 381 | } |
| 382 | |
| 383 | |
| 384 | /* |
no test coverage detected