back to `__mode' metafield to specify weakness

This commit is contained in:
Roberto Ierusalimschy
2002-11-14 10:01:35 -02:00
parent 43d1a6af12
commit 5c5d9b2703
9 changed files with 49 additions and 74 deletions

37
lgc.c
View File

@@ -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? */