diff --git a/lgc.c b/lgc.c index 0c84da8f..189adc6a 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 1.78 2001/01/22 18:01:38 roberto Exp roberto $ +** $Id: lgc.c,v 1.79 2001/01/25 16:45:36 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -121,6 +121,29 @@ static void marktagmethods (global_State *G, GCState *st) { } +static void traverseclosure (GCState *st, Closure *f) { + int i; + for (i=0; inupvalues; i++) /* mark its upvalues */ + markobject(st, &f->upvalue[i]); +} + + +static void traversetable (GCState *st, Hash *h) { + int i; + for (i=0; isize; i++) { + Node *n = node(h, i); + if (ttype(val(n)) == LUA_TNIL) { + if (ttype(key(n)) != LUA_TNIL) + sethvalue(key(n), NULL); /* dead key; remove it */ + } + else { + markobject(st, &n->key); + markobject(st, &n->val); + } + } +} + + static void markall (lua_State *L) { GCState st; st.cmark = NULL; @@ -131,25 +154,14 @@ static void markall (lua_State *L) { marktable(&st, G(L)->type2tag); for (;;) { /* mark tables and closures */ if (st.cmark) { - int i; Closure *f = st.cmark; /* get first closure from list */ st.cmark = f->mark; /* remove it from list */ - for (i=0; inupvalues; i++) /* mark its upvalues */ - markobject(&st, &f->upvalue[i]); + traverseclosure(&st, f); } else if (st.tmark) { - int i; Hash *h = st.tmark; /* get first table from list */ st.tmark = h->mark; /* remove it from list */ - for (i=0; isize; i++) { - Node *n = node(h, i); - if (ttype(key(n)) != LUA_TNIL) { - if (ttype(val(n)) == LUA_TNIL) - luaH_remove(h, key(n)); /* dead element; try to remove it */ - markobject(&st, &n->key); - markobject(&st, &n->val); - } - } + traversetable(&st, h); } else break; /* nothing else to mark */ } diff --git a/ltable.c b/ltable.c index 926fb49e..a13e8c24 100644 --- a/ltable.c +++ b/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 1.66 2001/01/24 15:45:33 roberto Exp roberto $ +** $Id: ltable.c,v 1.67 2001/01/25 16:45:36 roberto Exp roberto $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -126,30 +126,6 @@ Node *luaH_next (lua_State *L, const Hash *t, const TObject *key) { } -/* -** try to remove a key without value from a table. To avoid problems with -** hash, change `key' for a number with the same hash. -*/ -void luaH_remove (Hash *t, TObject *key) { - if (ttype(key) == LUA_TNUMBER || - (ttype(key) == LUA_TSTRING && tsvalue(key)->len <= 30)) - return; /* do not remove numbers nor small strings */ - else { - /* try to find a number `n' with the same hash as `key' */ - Node *mp = luaH_mainposition(t, key); - int n = mp - &t->node[0]; - /* make sure `n' is not in `t' */ - while (luaH_getnum(t, n) != &luaO_nilobject) { - if (n >= MAX_INT - t->size) - return; /* give up; (to avoid overflow) */ - n += t->size; - } - setnvalue(key, n); - lua_assert(luaH_mainposition(t, key) == mp); - } -} - - static void setnodevector (lua_State *L, Hash *t, luint32 size) { int i; if (size > MAX_INT) @@ -227,7 +203,7 @@ static void rehash (lua_State *L, Hash *t) { ** position), new key goes to an empty position. */ static TObject *newkey (lua_State *L, Hash *t, Node *mp, const TObject *key) { - if (ttype(&mp->key) != LUA_TNIL) { /* main position is not free? */ + if (ttype(&mp->val) != LUA_TNIL) { /* main position is not free? */ Node *othern = luaH_mainposition(t, &mp->key); /* `mp' of colliding node */ Node *n = t->firstfree; /* get a free place */ if (othern != mp) { /* is colliding node out of its main position? */ diff --git a/ltable.h b/ltable.h index 6283a2d5..565a8606 100644 --- a/ltable.h +++ b/ltable.h @@ -1,5 +1,5 @@ /* -** $Id: ltable.h,v 1.26 2000/12/04 18:33:40 roberto Exp roberto $ +** $Id: ltable.h,v 1.27 2001/01/10 18:56:11 roberto Exp roberto $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -19,7 +19,6 @@ void luaH_free (lua_State *L, Hash *t); const TObject *luaH_get (const Hash *t, const TObject *key); const TObject *luaH_getnum (const Hash *t, lua_Number key); const TObject *luaH_getstr (const Hash *t, TString *key); -void luaH_remove (Hash *t, TObject *key); TObject *luaH_set (lua_State *L, Hash *t, const TObject *key); Node * luaH_next (lua_State *L, const Hash *t, const TObject *r); TObject *luaH_setnum (lua_State *L, Hash *t, lua_Number key);