mirror of https://github.com/rusefi/lua.git
new interface for weak modes
This commit is contained in:
parent
facfec0687
commit
b3bb0f132b
24
lapi.c
24
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
46
lgc.c
46
lgc.c
|
@ -4,6 +4,8 @@
|
|||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#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; o<L1->top; 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);
|
||||
|
|
|
@ -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<<p means tagmethod(p) is not present */
|
||||
Node *firstfree; /* this position is free; all positions after it are full */
|
||||
struct Table *next;
|
||||
|
|
1
ltable.c
1
ltable.c
|
@ -274,7 +274,6 @@ Table *luaH_new (lua_State *L, int narray, int lnhash) {
|
|||
t->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;
|
||||
|
|
2
ltm.c
2
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"
|
||||
|
|
Loading…
Reference in New Issue