back to `__mode' metafield to specify weakness
This commit is contained in:
37
lgc.c
37
lgc.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lgc.c,v 1.156 2002/11/11 11:52:43 roberto Exp roberto $
|
||||
** $Id: lgc.c,v 1.157 2002/11/13 11:49:19 roberto Exp roberto $
|
||||
** Garbage Collector
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -47,6 +47,13 @@ typedef struct GCState {
|
||||
#define markfinalized(u) resetbit((u)->uv.marked, 1)
|
||||
|
||||
|
||||
#define KEYWEAKBIT 1
|
||||
#define VALUEWEAKBIT 2
|
||||
#define KEYWEAK (1<<KEYWEAKBIT)
|
||||
#define VALUEWEAK (1<<VALUEWEAKBIT)
|
||||
|
||||
|
||||
|
||||
#define markobject(st,o) { checkconsistency(o); \
|
||||
if (iscollectable(o) && !ismarked(gcvalue(o))) reallymarkobject(st,gcvalue(o)); }
|
||||
|
||||
@@ -140,17 +147,23 @@ static void traversetable (GCState *st, Table *h) {
|
||||
int i;
|
||||
int weakkey = 0;
|
||||
int weakvalue = 0;
|
||||
const TObject *mode;
|
||||
markvalue(st, h->metatable);
|
||||
lua_assert(h->lsizenode || h->node == st->G->dummynode);
|
||||
if (h->mode & (WEAKKEY | WEAKVALUE)) { /* weak table? */
|
||||
GCObject **weaklist;
|
||||
weakkey = h->mode & WEAKKEY;
|
||||
weakvalue = h->mode & WEAKVALUE;
|
||||
weaklist = (weakkey && weakvalue) ? &st->wkv :
|
||||
(weakkey) ? &st->wk :
|
||||
&st->wv;
|
||||
h->gclist = *weaklist; /* must be cleared after GC, ... */
|
||||
*weaklist = valtogco(h); /* ... so put in the appropriate list */
|
||||
mode = gfasttm(st->G, h->metatable, TM_MODE);
|
||||
if (mode && ttisstring(mode)) { /* is there a weak mode? */
|
||||
weakkey = (strchr(svalue(mode), 'k') != NULL);
|
||||
weakvalue = (strchr(svalue(mode), 'v') != NULL);
|
||||
if (weakkey || weakvalue) { /* is really weak? */
|
||||
GCObject **weaklist;
|
||||
h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
|
||||
h->marked |= (weakkey << KEYWEAKBIT) | (weakvalue << VALUEWEAKBIT);
|
||||
weaklist = (weakkey && weakvalue) ? &st->wkv :
|
||||
(weakkey) ? &st->wk :
|
||||
&st->wv;
|
||||
h->gclist = *weaklist; /* must be cleared after GC, ... */
|
||||
*weaklist = valtogco(h); /* ... so put in the appropriate list */
|
||||
}
|
||||
}
|
||||
if (!weakvalue) {
|
||||
i = sizearray(h);
|
||||
@@ -280,7 +293,7 @@ static void cleartablekeys (GCObject *l) {
|
||||
while (l) {
|
||||
Table *h = gcotoh(l);
|
||||
int i = sizenode(h);
|
||||
lua_assert(h->mode & WEAKKEY);
|
||||
lua_assert(h->marked & KEYWEAK);
|
||||
while (i--) {
|
||||
Node *n = node(h, i);
|
||||
if (!valismarked(key(n))) /* key was collected? */
|
||||
@@ -298,7 +311,7 @@ static void cleartablevalues (GCObject *l) {
|
||||
while (l) {
|
||||
Table *h = gcotoh(l);
|
||||
int i = sizearray(h);
|
||||
lua_assert(h->mode & WEAKVALUE);
|
||||
lua_assert(h->marked & VALUEWEAK);
|
||||
while (i--) {
|
||||
TObject *o = &h->array[i];
|
||||
if (!valismarked(o)) /* value was collected? */
|
||||
|
||||
Reference in New Issue
Block a user