** mark an object. Userdata, strings, and closed upvalues are visited ** and turned black here. Other objects are marked gray and added ** to appropriate list to be visited (and turned black) later. (Open ** upvalues are already linked in 'headuv' list.) */
| 240 | ** upvalues are already linked in 'headuv' list.) |
| 241 | */ |
| 242 | static void reallymarkobject (global_State *g, GCObject *o) { |
| 243 | lu_mem size; |
| 244 | white2gray(o); |
| 245 | switch (gch(o)->tt) { |
| 246 | case LUA_TSHRSTR: |
| 247 | case LUA_TLNGSTR: { |
| 248 | size = sizestring(gco2ts(o)); |
| 249 | break; /* nothing else to mark; make it black */ |
| 250 | } |
| 251 | case LUA_TUSERDATA: { |
| 252 | Table *mt = gco2u(o)->metatable; |
| 253 | markobject(g, mt); |
| 254 | markobject(g, gco2u(o)->env); |
| 255 | size = sizeudata(gco2u(o)); |
| 256 | break; |
| 257 | } |
| 258 | case LUA_TUPVAL: { |
| 259 | UpVal *uv = gco2uv(o); |
| 260 | markvalue(g, uv->v); |
| 261 | if (uv->v != &uv->u.value) /* open? */ |
| 262 | return; /* open upvalues remain gray */ |
| 263 | size = sizeof(UpVal); |
| 264 | break; |
| 265 | } |
| 266 | case LUA_TLCL: { |
| 267 | gco2lcl(o)->gclist = g->gray; |
| 268 | g->gray = o; |
| 269 | return; |
| 270 | } |
| 271 | case LUA_TCCL: { |
| 272 | gco2ccl(o)->gclist = g->gray; |
| 273 | g->gray = o; |
| 274 | return; |
| 275 | } |
| 276 | case LUA_TTABLE: { |
| 277 | linktable(gco2t(o), &g->gray); |
| 278 | return; |
| 279 | } |
| 280 | case LUA_TTHREAD: { |
| 281 | gco2th(o)->gclist = g->gray; |
| 282 | g->gray = o; |
| 283 | return; |
| 284 | } |
| 285 | case LUA_TPROTO: { |
| 286 | gco2p(o)->gclist = g->gray; |
| 287 | g->gray = o; |
| 288 | return; |
| 289 | } |
| 290 | default: lua_assert(0); return; |
| 291 | } |
| 292 | gray2black(o); |
| 293 | g->GCmemtrav += size; |
| 294 | } |
| 295 | |
| 296 | |
| 297 | /* |
no outgoing calls
no test coverage detected