From b3bb0f132b2a3dba88385f8d71ba3f34252d94e4 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 9 Jan 2002 19:50:35 -0200 Subject: new interface for weak modes --- lapi.c | 24 ++---------------------- lgc.c | 46 ++++++++++++++++++++++++++++------------------ lobject.h | 3 +-- ltable.c | 1 - ltm.c | 2 +- ltm.h | 1 + 6 files changed, 33 insertions(+), 44 deletions(-) diff --git a/lapi.c b/lapi.c index 30e4d268..1331d4c4 100644 --- a/lapi.c +++ b/lapi.c @@ -695,28 +695,7 @@ LUA_API void lua_newuserdatabox (lua_State *L, void *p) { } -LUA_API int lua_getweakmode (lua_State *L, int index) { - StkId t; - int mode; - lua_lock(L); - t = luaA_index(L, index); - api_check(L, ttype(t) == LUA_TTABLE); - mode = hvalue(t)->weakmode; - lua_unlock(L); - return mode; -} - - -LUA_API void lua_setweakmode (lua_State *L, int mode) { - lua_lock(L); - api_check(L, ttype(L->top-1) == LUA_TTABLE); - hvalue(L->top-1)->weakmode = cast(lu_byte, mode); - lua_unlock(L); -} - - - -LUA_API void lua_pushupvalues (lua_State *L) { +LUA_API int lua_pushupvalues (lua_State *L) { TObject *func; int n, i; lua_lock(L); @@ -730,6 +709,7 @@ LUA_API void lua_pushupvalues (lua_State *L) { L->top++; } lua_unlock(L); + return n; } diff --git a/lgc.c b/lgc.c index d7971346..64eee046 100644 --- a/lgc.c +++ b/lgc.c @@ -4,6 +4,8 @@ ** See Copyright Notice in lua.h */ +#include + #include "lua.h" #include "ldebug.h" @@ -22,6 +24,7 @@ typedef struct GCState { Table *tmark; /* list of marked tables to be visited */ Table *toclear; /* list of visited weak tables (to be cleared after GC) */ + lua_State *L; } GCState; @@ -119,8 +122,8 @@ static void markobject (GCState *st, TObject *o) { } -static void markstacks (lua_State *L, GCState *st) { - lua_State *L1 = L; +static void markstacks (GCState *st) { + lua_State *L1 = st->L; do { /* for each thread */ StkId o, lim; for (o=L1->stack; otop; o++) @@ -130,15 +133,15 @@ static void markstacks (lua_State *L, GCState *st) { for (; o<=lim; o++) setnilvalue(o); lua_assert(L1->previous->next == L1 && L1->next->previous == L1); L1 = L1->next; - } while (L1 != L); + } while (L1 != st->L); } -static void markudet (lua_State *L, GCState *st) { +static void markudet (GCState *st) { Udata *u; - for (u = G(L)->rootudata; u; u = u->uv.next) + for (u = G(st->L)->rootudata; u; u = u->uv.next) marktable(st, u->uv.eventtable); - for (u = G(L)->tmudata; u; u = u->uv.next) + for (u = G(st->L)->tmudata; u; u = u->uv.next) marktable(st, u->uv.eventtable); } @@ -152,13 +155,20 @@ static void removekey (Node *n) { static void traversetable (GCState *st, Table *h) { int i; - int mode = h->weakmode; + const TObject *mode; + int weakkey = 0; + int weakvalue = 0; + marktable(st, h->eventtable); + mode = fasttm(st->L, h->eventtable, TM_WEAKMODE); if (mode) { /* weak table? must be cleared after GC... */ h->mark = st->toclear; /* put in the appropriate list */ st->toclear = h; + if (ttype(mode) == LUA_TSTRING) { + weakkey = (strchr(svalue(mode), 'k') != NULL); + weakvalue = (strchr(svalue(mode), 'v') != NULL); + } } - marktable(st, h->eventtable); - if (!(mode & LUA_WEAK_VALUE)) { + if (!weakvalue) { i = sizearray(h); while (i--) markobject(st, &h->array[i]); @@ -168,18 +178,18 @@ static void traversetable (GCState *st, Table *h) { Node *n = node(h, i); if (ttype(val(n)) != LUA_TNIL) { lua_assert(ttype(key(n)) != LUA_TNIL); - if (!(mode & LUA_WEAK_KEY)) - markobject(st, key(n)); - if (!(mode & LUA_WEAK_VALUE)) - markobject(st, val(n)); + if (!weakkey) markobject(st, key(n)); + if (!weakvalue) markobject(st, val(n)); } } } -static void markall (lua_State *L, GCState *st) { - markstacks(L, st); /* mark all stacks */ - markudet(L, st); /* mark userdata's event tables */ +static void markall (GCState *st) { + lua_assert(hvalue(defaultet(st->L))->flags == cast(unsigned short, ~0)); + /* table is unchanged */ + markstacks(st); /* mark all stacks */ + markudet(st); /* mark userdata's event tables */ while (st->tmark) { /* traverse marked tables */ Table *h = st->tmark; /* get first table from list */ st->tmark = h->mark; /* remove it from list */ @@ -210,7 +220,6 @@ static int hasmark (const TObject *o) { static void cleartables (Table *h) { for (; h; h = h->mark) { int i; - lua_assert(h->weakmode); i = sizearray(h); while (i--) { TObject *o = &h->array[i]; @@ -421,9 +430,10 @@ void luaC_collect (lua_State *L, int all) { void luaC_collectgarbage (lua_State *L) { GCState st; + st.L = L; st.tmark = NULL; st.toclear = NULL; - markall(L, &st); + markall(&st); cleartables(st.toclear); luaC_collect(L, 0); checkMbuffer(L); diff --git a/lobject.h b/lobject.h index a8dcf35e..37bb16e8 100644 --- a/lobject.h +++ b/lobject.h @@ -214,9 +214,9 @@ typedef union Closure { */ typedef struct Node { - struct Node *next; /* for chaining */ TObject _key; TObject _val; + struct Node *next; /* for chaining */ } Node; @@ -226,7 +226,6 @@ typedef struct Table { Node *node; int sizearray; /* size of `array' array */ lu_byte lsizenode; /* log2 of size of `node' array */ - lu_byte weakmode; unsigned short flags; /* 1<

next = G(L)->roottable; G(L)->roottable = t; t->mark = t; - t->weakmode = 0; t->flags = cast(unsigned short, ~0); /* temporary values (kept only if some malloc fails) */ t->array = NULL; diff --git a/ltm.c b/ltm.c index 62c3b38a..f69c6f9f 100644 --- a/ltm.c +++ b/ltm.c @@ -26,7 +26,7 @@ const char *const luaT_typenames[] = { void luaT_init (lua_State *L) { static const char *const luaT_eventname[] = { /* ORDER TM */ "gettable", "settable", "index", - "gc", + "gc", "weakmode", "add", "sub", "mul", "div", "pow", "unm", "lt", "concat", "call" diff --git a/ltm.h b/ltm.h index 053b6f90..eedcc32d 100644 --- a/ltm.h +++ b/ltm.h @@ -19,6 +19,7 @@ typedef enum { TM_SETTABLE, TM_INDEX, TM_GC, + TM_WEAKMODE, TM_ADD, TM_SUB, TM_MUL, -- cgit v1.2.3-55-g6feb