eris: weak tables fixed (garbage collector updates sequence data)
This commit is contained in:
@@ -628,7 +628,7 @@ static void clearkeys (global_State *g, GCObject *l, GCObject *f) {
|
||||
Node *n, *limit = gnodelast(h);
|
||||
for (n = gnode(h, 0); n < limit; n++) {
|
||||
if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) {
|
||||
setnilvalue(gval(n)); /* remove value ... */
|
||||
luaH_setnil(h, ganode(n));
|
||||
removeentry(n); /* and remove entry from table */
|
||||
}
|
||||
}
|
||||
@@ -646,13 +646,14 @@ static void clearvalues (global_State *g, GCObject *l, GCObject *f) {
|
||||
Node *n, *limit = gnodelast(h);
|
||||
int i;
|
||||
for (i = 0; i < h->sizearray; i++) {
|
||||
ANode *anode = h->array + i;
|
||||
TValue *o = &h->array[i].i_val;
|
||||
if (iscleared(g, o)) /* value was collected? */
|
||||
setnilvalue(o); /* remove value */
|
||||
if (iscleared(g, &anode->i_val)) /* value was collected? */
|
||||
luaH_setnil(h, anode);
|
||||
}
|
||||
for (n = gnode(h, 0); n < limit; n++) {
|
||||
if (!ttisnil(gval(n)) && iscleared(g, gval(n))) {
|
||||
setnilvalue(gval(n)); /* remove value ... */
|
||||
luaH_setnil(h, ganode(n)); /* remove value ... */
|
||||
removeentry(n); /* and remove entry from table */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -656,7 +656,10 @@ const TValue *luaH_get (Table *t, const TValue *key) {
|
||||
}
|
||||
}
|
||||
|
||||
static void addsequence(Table *t, ANode *anode) {
|
||||
/* Change an entry to non-nil. */
|
||||
/* This means the entry must be added to the sequence */
|
||||
void luaH_setnonnil(Table *t, ANode *anode, const TValue *value) {
|
||||
assert(ttisnil(&anode->i_val));
|
||||
assert(anode->i_sequence == -1);
|
||||
int index = anodeindex(t, anode);
|
||||
int totalanodes = t->sizearray + truesizenode(t);
|
||||
@@ -664,9 +667,15 @@ static void addsequence(Table *t, ANode *anode) {
|
||||
anode->i_sequence = t->nnkeys++;
|
||||
assert((anode->i_sequence >= 0) && (anode->i_sequence < totalanodes));
|
||||
t->sequence[anode->i_sequence] = index;
|
||||
t->lastdeleted = NULL;
|
||||
t->lastdelseq = -1;
|
||||
setobj2t(L, &anode->i_val, value);
|
||||
}
|
||||
|
||||
static void delsequence(Table *t, ANode *anode) {
|
||||
/* Change an entry to nil. */
|
||||
/* This means the entry must be removed from the sequence */
|
||||
void luaH_setnil(Table *t, ANode *anode) {
|
||||
assert(!ttisnil(&anode->i_val));
|
||||
assert((anode->i_sequence >= 0) && (anode->i_sequence < t->nnkeys));
|
||||
/* remove the last item from the sequence, and get a pointer to its anode */
|
||||
int totalanodes = t->sizearray + truesizenode(t);
|
||||
@@ -679,11 +688,9 @@ static void delsequence(Table *t, ANode *anode) {
|
||||
t->sequence[freeslot] = lastanodeindex;
|
||||
t->nnkeys -= 1;
|
||||
lastanode->i_sequence = freeslot;
|
||||
/* set the last deleted variables */
|
||||
t->lastdeleted = anode;
|
||||
t->lastdelseq = anode->i_sequence;
|
||||
/* clear out the anode */
|
||||
anode->i_sequence = -1;
|
||||
setnilvalue(&anode->i_val);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -691,14 +698,13 @@ static void delsequence(Table *t, ANode *anode) {
|
||||
** barrier and invalidate the TM cache.
|
||||
*/
|
||||
void luaH_setupdate (lua_State *L, Table *t, const TValue *key, TValue *value, const TValue *getres) {
|
||||
t->lastdeleted = NULL;
|
||||
t->lastdelseq = -1;
|
||||
if (!ttisnil(getres)) {
|
||||
if (ttisnil(value)) {
|
||||
/* replacing a non-nil value with nil */
|
||||
TValue *cell = cast(TValue *, getres);
|
||||
delsequence(t, cast(ANode *, cell));
|
||||
setobj2t(L, cell, value);
|
||||
ANode *anode = cast(ANode *, getres);
|
||||
t->lastdeleted = anode;
|
||||
t->lastdelseq = anode->i_sequence;
|
||||
luaH_setnil(t, anode);
|
||||
checksequence(t);
|
||||
} else {
|
||||
/* replacing a non-nil value with a different non-nil value */
|
||||
@@ -709,16 +715,17 @@ void luaH_setupdate (lua_State *L, Table *t, const TValue *key, TValue *value, c
|
||||
} else if (getres == luaO_nilobject) {
|
||||
if (!ttisnil(value)) {
|
||||
/* creating a new key with a non-nil value */
|
||||
TValue *cell = luaH_newkey(L, t, key);
|
||||
addsequence(t, cast(ANode *, cell));
|
||||
setobj2t(L, cell, value);
|
||||
t->lastdeleted = NULL;
|
||||
t->lastdelseq = -1;
|
||||
ANode *anode = cast(ANode *, luaH_newkey(L, t, key));
|
||||
luaH_setnonnil(t, anode, value);
|
||||
checksequence(t);
|
||||
}
|
||||
} else if (!ttisnil(value)) {
|
||||
/* replacing a nil value with a non-nil value */
|
||||
TValue *cell = cast(TValue *, getres);
|
||||
addsequence(t, cast(ANode *, cell));
|
||||
setobj2t(L, cell, value);
|
||||
t->lastdeleted = NULL;
|
||||
t->lastdelseq = -1;
|
||||
luaH_setnonnil(t, cast(ANode *, getres), value);
|
||||
checksequence(t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
|
||||
LUAI_FUNC const TValue *luaH_getint (Table *t, int key);
|
||||
LUAI_FUNC void luaH_setnil (Table *t, ANode *anode);
|
||||
LUAI_FUNC void luaH_setnonnil (Table *t, ANode *anode, const TValue *value);
|
||||
LUAI_FUNC void luaH_setint (lua_State *L, Table *t, int key, TValue *value);
|
||||
LUAI_FUNC void luaH_setvalue (lua_State *L, Table *t, const TValue *key, TValue *value);
|
||||
LUAI_FUNC void luaH_setupdate (lua_State *L, Table *t, const TValue *key, TValue *value, const TValue *getres);
|
||||
|
||||
Reference in New Issue
Block a user