void reallymarkobject (GCState *st, GCObject *o) { lua_assert(!ismarked(o)); setbit(o->gch.marked, 0); /* mark object */ switch (o->gch.tt) { case LUA_TUSERDATA: { markvalue(st, gcotou(o)->uv.metatable); break; } case LUA_TFUNCTION: { gcotocl(o)->c.gclist = st->tmark; st->tmark = o; break; } case LUA_TTABLE: { gcotoh(o)->gclist = st->tmark; st->tmark = o; break; } case LUA_TTHREAD: { #if LUA_REFCOUNT gcototh(o)->gclist_head.next = st->tmark; #else !LUA_REFCOUNT gcototh(o)->gclist = st->tmark; #endif LUA_REFCOUNT st->tmark = o; break; } case LUA_TPROTO: { gcotop(o)->gclist = st->tmark; st->tmark = o; break; } default: lua_assert(o->gch.tt == LUA_TSTRING || o->gch.tt == LUA_TWSTRING); } }
static void freeobj (lua_State *L, GCObject *o) { switch (o->gch.tt) { case LUA_TPROTO: luaF_freeproto(L, gcotop(o)); break; case LUA_TFUNCTION: luaF_freeclosure(L, gcotocl(o)); break; case LUA_TUPVAL: luaM_freelem(L, gcotouv(o)); break; case LUA_TTABLE: luaH_free(L, gcotoh(o)); break; case LUA_TTHREAD: { lua_assert(gcototh(o) != L && gcototh(o) != G(L)->mainthread); luaE_freethread(L, gcototh(o)); break; } case LUA_TSTRING: { luaM_free(L, o, sizestring(gcotots(o)->tsv.len)); break; } case LUA_TWSTRING: { luaM_free(L, o, sizewstring(gcototws(o)->tsv.len)); break; } case LUA_TUSERDATA: { luaM_free(L, o, sizeudata(gcotou(o)->uv.len)); break; } #if LUA_REFCOUNT case LUA_TNIL: { break; // Do nothing. } #endif LUA_REFCOUNT default: lua_assert(0); } }
static void propagatemarks (GCState *st) { while (st->tmark) { /* traverse marked objects */ switch (st->tmark->gch.tt) { case LUA_TTABLE: { Table *h = gcotoh(st->tmark); st->tmark = h->gclist; traversetable(st, h); break; } case LUA_TFUNCTION: { Closure *cl = gcotocl(st->tmark); st->tmark = cl->c.gclist; traverseclosure(st, cl); break; } case LUA_TTHREAD: { lua_State *th = gcototh(st->tmark); st->tmark = th->gclist; traversestack(st, th); break; } case LUA_TPROTO: { Proto *p = gcotop(st->tmark); st->tmark = p->gclist; traverseproto(st, p); break; } default: lua_assert(0); } } }
static void propagatemarks (GCState *st) { while (st->tmark) { /* traverse marked objects */ switch (st->tmark->gch.tt) { case LUA_TTABLE: { Table *h = gcotoh(st->tmark); st->tmark = h->gclist; traversetable(st, h); break; } case LUA_TFUNCTION: { Closure *cl = gcotocl(st->tmark); st->tmark = cl->c.gclist; traverseclosure(st, cl); break; } case LUA_TTHREAD: { lua_State *th = gcototh(st->tmark); #if LUA_REFCOUNT st->tmark = th->gclist_head.next; #else !LUA_REFCOUNT st->tmark = th->gclist; #endif LUA_REFCOUNT traversestack(st, th); if (G(th)->userGCFunction) { st->L = th; G(th)->userGCFunction(st); } break; } case LUA_TPROTO: { Proto *p = gcotop(st->tmark); st->tmark = p->gclist; traverseproto(st, p); break; } #if LUA_REFCOUNT case LUA_TNIL: { st->tmark = NULL; break; } #endif LUA_REFCOUNT default: lua_assert(0); } } }
static Proto *toproto(lua_State *L, int stackpos) { return gcotop(getobject(L, stackpos)->value.gc); }