From 311575eb308143e910d2f71862e454ec88239898 Mon Sep 17 00:00:00 2001 From: Josh Yelon Date: Fri, 9 Jul 2021 15:03:06 -0400 Subject: [PATCH] eris: weak tables fixed (garbage collector updates sequence data) --- luprex/eris-master/src/lgc.c | 9 ++++---- luprex/eris-master/src/ltable.c | 39 +++++++++++++++++++-------------- luprex/eris-master/src/ltable.h | 2 ++ 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/luprex/eris-master/src/lgc.c b/luprex/eris-master/src/lgc.c index f4335db7..e1f58441 100644 --- a/luprex/eris-master/src/lgc.c +++ b/luprex/eris-master/src/lgc.c @@ -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 */ } } diff --git a/luprex/eris-master/src/ltable.c b/luprex/eris-master/src/ltable.c index a2032cb6..5b1243a6 100644 --- a/luprex/eris-master/src/ltable.c +++ b/luprex/eris-master/src/ltable.c @@ -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); } } diff --git a/luprex/eris-master/src/ltable.h b/luprex/eris-master/src/ltable.h index 0341b841..b09353b3 100644 --- a/luprex/eris-master/src/ltable.h +++ b/luprex/eris-master/src/ltable.h @@ -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);