mirror of
https://github.com/lua/lua.git
synced 2025-01-28 06:03:00 +08:00
back to `__mode' metafield to specify weakness
This commit is contained in:
parent
43d1a6af12
commit
5c5d9b2703
27
lapi.c
27
lapi.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lapi.c,v 1.217 2002/11/07 15:37:10 roberto Exp roberto $
|
** $Id: lapi.c,v 1.218 2002/11/07 15:39:23 roberto Exp roberto $
|
||||||
** Lua API
|
** Lua API
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -505,20 +505,6 @@ LUA_API void lua_newtable (lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LUA_API const char *lua_getmode (lua_State *L, int index) {
|
|
||||||
static const char *const modes[] = {"", "k", "v", "kv"};
|
|
||||||
int mode = 0;
|
|
||||||
TObject *t;
|
|
||||||
lua_lock(L);
|
|
||||||
t = luaA_index(L, index);
|
|
||||||
api_check(L, ttistable(t));
|
|
||||||
if (hvalue(t)->mode & WEAKKEY) mode += 1;
|
|
||||||
if (hvalue(t)->mode & WEAKVALUE) mode += 2;
|
|
||||||
lua_unlock(L);
|
|
||||||
return modes[mode];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LUA_API int lua_getmetatable (lua_State *L, int objindex) {
|
LUA_API int lua_getmetatable (lua_State *L, int objindex) {
|
||||||
StkId obj;
|
StkId obj;
|
||||||
Table *mt;
|
Table *mt;
|
||||||
@ -597,17 +583,6 @@ LUA_API void lua_rawseti (lua_State *L, int index, int n) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LUA_API void lua_setmode (lua_State *L, int index, const char *mode) {
|
|
||||||
TObject *t;
|
|
||||||
lua_lock(L);
|
|
||||||
t = luaA_index(L, index);
|
|
||||||
api_check(L, ttistable(t));
|
|
||||||
hvalue(t)->mode &= ~(WEAKKEY | WEAKVALUE); /* clear bits */
|
|
||||||
if (strchr(mode, 'k')) hvalue(t)->mode |= WEAKKEY;
|
|
||||||
if (strchr(mode, 'v')) hvalue(t)->mode |= WEAKVALUE;
|
|
||||||
lua_unlock(L);
|
|
||||||
}
|
|
||||||
|
|
||||||
LUA_API int lua_setmetatable (lua_State *L, int objindex) {
|
LUA_API int lua_setmetatable (lua_State *L, int objindex) {
|
||||||
TObject *obj, *mt;
|
TObject *obj, *mt;
|
||||||
int res = 1;
|
int res = 1;
|
||||||
|
25
lbaselib.c
25
lbaselib.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lbaselib.c,v 1.104 2002/11/06 19:08:00 roberto Exp roberto $
|
** $Id: lbaselib.c,v 1.105 2002/11/07 15:39:23 roberto Exp roberto $
|
||||||
** Basic library
|
** Basic library
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -88,21 +88,6 @@ static int luaB_error (lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int luaB_getmode (lua_State *L) {
|
|
||||||
luaL_check_type(L, 1, LUA_TTABLE);
|
|
||||||
lua_pushstring(L, lua_getmode(L, 1));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int luaB_setmode (lua_State *L) {
|
|
||||||
luaL_check_type(L, 1, LUA_TTABLE);
|
|
||||||
lua_setmode(L, 1, luaL_check_string(L, 2));
|
|
||||||
lua_settop(L, 1);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int luaB_getmetatable (lua_State *L) {
|
static int luaB_getmetatable (lua_State *L) {
|
||||||
luaL_check_any(L, 1);
|
luaL_check_any(L, 1);
|
||||||
if (!lua_getmetatable(L, 1)) {
|
if (!lua_getmetatable(L, 1)) {
|
||||||
@ -524,8 +509,6 @@ static const luaL_reg base_funcs[] = {
|
|||||||
{"setmetatable", luaB_setmetatable},
|
{"setmetatable", luaB_setmetatable},
|
||||||
{"getglobals", luaB_getglobals},
|
{"getglobals", luaB_getglobals},
|
||||||
{"setglobals", luaB_setglobals},
|
{"setglobals", luaB_setglobals},
|
||||||
{"getmode", luaB_getmode},
|
|
||||||
{"setmode", luaB_setmode},
|
|
||||||
{"next", luaB_next},
|
{"next", luaB_next},
|
||||||
{"ipairs", luaB_ipairs},
|
{"ipairs", luaB_ipairs},
|
||||||
{"pairs", luaB_pairs},
|
{"pairs", luaB_pairs},
|
||||||
@ -646,7 +629,11 @@ static void base_open (lua_State *L) {
|
|||||||
/* `newproxy' needs a weaktable as upvalue */
|
/* `newproxy' needs a weaktable as upvalue */
|
||||||
lua_pushliteral(L, "newproxy");
|
lua_pushliteral(L, "newproxy");
|
||||||
lua_newtable(L); /* new table `w' */
|
lua_newtable(L); /* new table `w' */
|
||||||
lua_setmode(L, -1, "k");
|
lua_pushvalue(L, -1); /* `w' will be its own metatable */
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
lua_pushliteral(L, "__mode");
|
||||||
|
lua_pushliteral(L, "k");
|
||||||
|
lua_rawset(L, -3); /* metatable(w).__mode = "k" */
|
||||||
lua_pushcclosure(L, luaB_newproxy, 1);
|
lua_pushcclosure(L, luaB_newproxy, 1);
|
||||||
lua_rawset(L, -3); /* set global `newproxy' */
|
lua_rawset(L, -3); /* set global `newproxy' */
|
||||||
lua_rawset(L, -1); /* set global _G */
|
lua_rawset(L, -1); /* set global _G */
|
||||||
|
37
lgc.c
37
lgc.c
@ -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
|
** Garbage Collector
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -47,6 +47,13 @@ typedef struct GCState {
|
|||||||
#define markfinalized(u) resetbit((u)->uv.marked, 1)
|
#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); \
|
#define markobject(st,o) { checkconsistency(o); \
|
||||||
if (iscollectable(o) && !ismarked(gcvalue(o))) reallymarkobject(st,gcvalue(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 i;
|
||||||
int weakkey = 0;
|
int weakkey = 0;
|
||||||
int weakvalue = 0;
|
int weakvalue = 0;
|
||||||
|
const TObject *mode;
|
||||||
markvalue(st, h->metatable);
|
markvalue(st, h->metatable);
|
||||||
lua_assert(h->lsizenode || h->node == st->G->dummynode);
|
lua_assert(h->lsizenode || h->node == st->G->dummynode);
|
||||||
if (h->mode & (WEAKKEY | WEAKVALUE)) { /* weak table? */
|
mode = gfasttm(st->G, h->metatable, TM_MODE);
|
||||||
GCObject **weaklist;
|
if (mode && ttisstring(mode)) { /* is there a weak mode? */
|
||||||
weakkey = h->mode & WEAKKEY;
|
weakkey = (strchr(svalue(mode), 'k') != NULL);
|
||||||
weakvalue = h->mode & WEAKVALUE;
|
weakvalue = (strchr(svalue(mode), 'v') != NULL);
|
||||||
weaklist = (weakkey && weakvalue) ? &st->wkv :
|
if (weakkey || weakvalue) { /* is really weak? */
|
||||||
(weakkey) ? &st->wk :
|
GCObject **weaklist;
|
||||||
&st->wv;
|
h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
|
||||||
h->gclist = *weaklist; /* must be cleared after GC, ... */
|
h->marked |= (weakkey << KEYWEAKBIT) | (weakvalue << VALUEWEAKBIT);
|
||||||
*weaklist = valtogco(h); /* ... so put in the appropriate list */
|
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) {
|
if (!weakvalue) {
|
||||||
i = sizearray(h);
|
i = sizearray(h);
|
||||||
@ -280,7 +293,7 @@ static void cleartablekeys (GCObject *l) {
|
|||||||
while (l) {
|
while (l) {
|
||||||
Table *h = gcotoh(l);
|
Table *h = gcotoh(l);
|
||||||
int i = sizenode(h);
|
int i = sizenode(h);
|
||||||
lua_assert(h->mode & WEAKKEY);
|
lua_assert(h->marked & KEYWEAK);
|
||||||
while (i--) {
|
while (i--) {
|
||||||
Node *n = node(h, i);
|
Node *n = node(h, i);
|
||||||
if (!valismarked(key(n))) /* key was collected? */
|
if (!valismarked(key(n))) /* key was collected? */
|
||||||
@ -298,7 +311,7 @@ static void cleartablevalues (GCObject *l) {
|
|||||||
while (l) {
|
while (l) {
|
||||||
Table *h = gcotoh(l);
|
Table *h = gcotoh(l);
|
||||||
int i = sizearray(h);
|
int i = sizearray(h);
|
||||||
lua_assert(h->mode & WEAKVALUE);
|
lua_assert(h->marked & VALUEWEAK);
|
||||||
while (i--) {
|
while (i--) {
|
||||||
TObject *o = &h->array[i];
|
TObject *o = &h->array[i];
|
||||||
if (!valismarked(o)) /* value was collected? */
|
if (!valismarked(o)) /* value was collected? */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lobject.h,v 1.152 2002/11/07 15:37:10 roberto Exp roberto $
|
** $Id: lobject.h,v 1.153 2002/11/13 11:49:19 roberto Exp roberto $
|
||||||
** Type definitions for Lua objects
|
** Type definitions for Lua objects
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -292,7 +292,6 @@ typedef struct Node {
|
|||||||
typedef struct Table {
|
typedef struct Table {
|
||||||
CommonHeader;
|
CommonHeader;
|
||||||
lu_byte flags; /* 1<<p means tagmethod(p) is not present */
|
lu_byte flags; /* 1<<p means tagmethod(p) is not present */
|
||||||
lu_byte mode;
|
|
||||||
lu_byte lsizenode; /* log2 of size of `node' array */
|
lu_byte lsizenode; /* log2 of size of `node' array */
|
||||||
struct Table *metatable;
|
struct Table *metatable;
|
||||||
TObject *array; /* array part */
|
TObject *array; /* array part */
|
||||||
@ -302,9 +301,6 @@ typedef struct Table {
|
|||||||
int sizearray; /* size of `array' array */
|
int sizearray; /* size of `array' array */
|
||||||
} Table;
|
} Table;
|
||||||
|
|
||||||
/* bit masks for `mode' */
|
|
||||||
#define WEAKKEY 1
|
|
||||||
#define WEAKVALUE 2
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
3
ltable.c
3
ltable.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltable.c,v 1.120 2002/11/07 15:37:10 roberto Exp roberto $
|
** $Id: ltable.c,v 1.121 2002/11/13 11:31:39 roberto Exp roberto $
|
||||||
** Lua tables (hash)
|
** Lua tables (hash)
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -304,7 +304,6 @@ Table *luaH_new (lua_State *L, int narray, int lnhash) {
|
|||||||
luaC_link(L, valtogco(t), LUA_TTABLE);
|
luaC_link(L, valtogco(t), LUA_TTABLE);
|
||||||
t->metatable = hvalue(defaultmeta(L));
|
t->metatable = hvalue(defaultmeta(L));
|
||||||
t->flags = cast(lu_byte, ~0);
|
t->flags = cast(lu_byte, ~0);
|
||||||
t->mode = 0;
|
|
||||||
/* temporary values (kept only if some malloc fails) */
|
/* temporary values (kept only if some malloc fails) */
|
||||||
t->array = NULL;
|
t->array = NULL;
|
||||||
t->sizearray = 0;
|
t->sizearray = 0;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltablib.c,v 1.13 2002/10/04 14:30:31 roberto Exp roberto $
|
** $Id: ltablib.c,v 1.14 2002/10/23 19:08:23 roberto Exp roberto $
|
||||||
** Library for Table Manipulation
|
** Library for Table Manipulation
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -288,7 +288,11 @@ static const luaL_reg tab_funcs[] = {
|
|||||||
|
|
||||||
LUALIB_API int lua_tablibopen (lua_State *L) {
|
LUALIB_API int lua_tablibopen (lua_State *L) {
|
||||||
lua_newtable(L); /* create N (table to store num. elements in tables) */
|
lua_newtable(L); /* create N (table to store num. elements in tables) */
|
||||||
lua_setmode(L, -1, "k"); /* make it a weak table */
|
lua_pushvalue(L, -1); /* `N' will be its own metatable */
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
lua_pushliteral(L, "__mode");
|
||||||
|
lua_pushliteral(L, "k");
|
||||||
|
lua_rawset(L, -3); /* metatable(N).__mode = "k" */
|
||||||
luaL_opennamedlib(L, LUA_TABLIBNAME, tab_funcs, 1);
|
luaL_opennamedlib(L, LUA_TABLIBNAME, tab_funcs, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
4
ltm.c
4
ltm.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltm.c,v 1.102 2002/09/19 20:12:47 roberto Exp roberto $
|
** $Id: ltm.c,v 1.103 2002/10/25 20:05:28 roberto Exp roberto $
|
||||||
** Tag methods
|
** Tag methods
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -26,7 +26,7 @@ const char *const luaT_typenames[] = {
|
|||||||
void luaT_init (lua_State *L) {
|
void luaT_init (lua_State *L) {
|
||||||
static const char *const luaT_eventname[] = { /* ORDER TM */
|
static const char *const luaT_eventname[] = { /* ORDER TM */
|
||||||
"__index", "__newindex",
|
"__index", "__newindex",
|
||||||
"__gc", "__eq",
|
"__gc", "__mode", "__eq",
|
||||||
"__add", "__sub", "__mul", "__div",
|
"__add", "__sub", "__mul", "__div",
|
||||||
"__pow", "__unm", "__lt", "__le",
|
"__pow", "__unm", "__lt", "__le",
|
||||||
"__concat", "__call"
|
"__concat", "__call"
|
||||||
|
9
ltm.h
9
ltm.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: ltm.h,v 1.39 2002/08/06 17:06:56 roberto Exp roberto $
|
** $Id: ltm.h,v 1.40 2002/09/19 20:12:47 roberto Exp roberto $
|
||||||
** Tag methods
|
** Tag methods
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@ -19,6 +19,7 @@ typedef enum {
|
|||||||
TM_INDEX,
|
TM_INDEX,
|
||||||
TM_NEWINDEX,
|
TM_NEWINDEX,
|
||||||
TM_GC,
|
TM_GC,
|
||||||
|
TM_MODE,
|
||||||
TM_EQ, /* last tag method with `fast' access */
|
TM_EQ, /* last tag method with `fast' access */
|
||||||
TM_ADD,
|
TM_ADD,
|
||||||
TM_SUB,
|
TM_SUB,
|
||||||
@ -35,8 +36,10 @@ typedef enum {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define fasttm(l,et,e) \
|
#define gfasttm(g,et,e) \
|
||||||
(((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, G(l)->tmname[e]))
|
(((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
|
||||||
|
|
||||||
|
#define fasttm(l,et,e) gfasttm(G(l), et, e)
|
||||||
|
|
||||||
|
|
||||||
const TObject *luaT_gettm (Table *events, TMS event, TString *ename);
|
const TObject *luaT_gettm (Table *events, TMS event, TString *ename);
|
||||||
|
4
lua.h
4
lua.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lua.h,v 1.162 2002/11/06 19:08:00 roberto Exp roberto $
|
** $Id: lua.h,v 1.163 2002/11/07 15:39:23 roberto Exp roberto $
|
||||||
** Lua - An Extensible Extension Language
|
** Lua - An Extensible Extension Language
|
||||||
** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
|
** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
|
||||||
** http://www.lua.org mailto:info@lua.org
|
** http://www.lua.org mailto:info@lua.org
|
||||||
@ -174,7 +174,6 @@ LUA_API void lua_rawget (lua_State *L, int idx);
|
|||||||
LUA_API void lua_rawgeti (lua_State *L, int idx, int n);
|
LUA_API void lua_rawgeti (lua_State *L, int idx, int n);
|
||||||
LUA_API void lua_newtable (lua_State *L);
|
LUA_API void lua_newtable (lua_State *L);
|
||||||
LUA_API int lua_getmetatable (lua_State *L, int objindex);
|
LUA_API int lua_getmetatable (lua_State *L, int objindex);
|
||||||
LUA_API const char *lua_getmode (lua_State *L, int idx);
|
|
||||||
LUA_API void lua_getglobals (lua_State *L, int idx);
|
LUA_API void lua_getglobals (lua_State *L, int idx);
|
||||||
|
|
||||||
|
|
||||||
@ -184,7 +183,6 @@ LUA_API void lua_getglobals (lua_State *L, int idx);
|
|||||||
LUA_API void lua_settable (lua_State *L, int idx);
|
LUA_API void lua_settable (lua_State *L, int idx);
|
||||||
LUA_API void lua_rawset (lua_State *L, int idx);
|
LUA_API void lua_rawset (lua_State *L, int idx);
|
||||||
LUA_API void lua_rawseti (lua_State *L, int idx, int n);
|
LUA_API void lua_rawseti (lua_State *L, int idx, int n);
|
||||||
LUA_API void lua_setmode (lua_State *L, int idx, const char *md);
|
|
||||||
LUA_API int lua_setmetatable (lua_State *L, int objindex);
|
LUA_API int lua_setmetatable (lua_State *L, int objindex);
|
||||||
LUA_API int lua_setglobals (lua_State *L, int idx);
|
LUA_API int lua_setglobals (lua_State *L, int idx);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user