| 156 | |
| 157 | |
| 158 | static int traversetable (global_State *g, Table *h) { |
| 159 | int i; |
| 160 | int weakkey = 0; |
| 161 | int weakvalue = 0; |
| 162 | const TValue *mode; |
| 163 | if (h->metatable) |
| 164 | markobject(g, h->metatable); |
| 165 | mode = gfasttm(g, h->metatable, TM_MODE); |
| 166 | if (mode && ttisstring(mode)) { /* is there a weak mode? */ |
| 167 | weakkey = (strchr(svalue(mode), 'k') != NULL); |
| 168 | weakvalue = (strchr(svalue(mode), 'v') != NULL); |
| 169 | if (weakkey || weakvalue) { /* is really weak? */ |
| 170 | h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */ |
| 171 | h->marked |= cast_byte((weakkey << KEYWEAKBIT) | |
| 172 | (weakvalue << VALUEWEAKBIT)); |
| 173 | h->gclist = g->weak; /* must be cleared after GC, ... */ |
| 174 | g->weak = obj2gco(h); /* ... so put in the appropriate list */ |
| 175 | } |
| 176 | } |
| 177 | if (weakkey && weakvalue) return 1; |
| 178 | if (!weakvalue) { |
| 179 | i = h->sizearray; |
| 180 | while (i--) |
| 181 | markvalue(g, &h->array[i]); |
| 182 | } |
| 183 | i = sizenode(h); |
| 184 | while (i--) { |
| 185 | Node *n = gnode(h, i); |
| 186 | lua_assert(ttype(gkey(n)) != LUA_TDEADKEY || ttisnil(gval(n))); |
| 187 | if (ttisnil(gval(n))) |
| 188 | removeentry(n); /* remove empty entries */ |
| 189 | else { |
| 190 | lua_assert(!ttisnil(gkey(n))); |
| 191 | if (!weakkey) markvalue(g, gkey(n)); |
| 192 | if (!weakvalue) markvalue(g, gval(n)); |
| 193 | } |
| 194 | } |
| 195 | return weakkey || weakvalue; |
| 196 | } |
| 197 | |
| 198 | |
| 199 | /* |
no test coverage detected