** 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; otherwise, call 'genlink' ** to check table age in generational mode. */
| 485 | ** to check table age in generational mode. |
| 486 | */ |
| 487 | static void traverseweakvalue (global_State *g, Table *h) { |
| 488 | Node *n, *limit = gnodelast(h); |
| 489 | /* if there is array part, assume it may have white values (it is not |
| 490 | worth traversing it now just to check) */ |
| 491 | int hasclears = (h->asize > 0); |
| 492 | for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ |
| 493 | if (isempty(gval(n))) /* entry is empty? */ |
| 494 | clearkey(n); /* clear its key */ |
| 495 | else { |
| 496 | lua_assert(!keyisnil(n)); |
| 497 | markkey(g, n); |
| 498 | if (!hasclears && iscleared(g, gcvalueN(gval(n)))) /* a white value? */ |
| 499 | hasclears = 1; /* table will have to be cleared */ |
| 500 | } |
| 501 | } |
| 502 | if (g->gcstate == GCSpropagate) |
| 503 | linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ |
| 504 | else if (hasclears) |
| 505 | linkgclist(h, g->weak); /* has to be cleared later */ |
| 506 | else |
| 507 | genlink(g, obj2gco(h)); |
| 508 | } |
| 509 | |
| 510 | |
| 511 | /* |
no test coverage detected