aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-11-14 10:01:35 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-11-14 10:01:35 -0200
commit5c5d9b27031f0a7fcf61df86cd242105c38485d6 (patch)
tree534fb1ea4a4fc82253d5bc8b0af92b91a7ae9714
parent43d1a6af12fb9cf20e55cc6ba8a1b0231d6b7a3c (diff)
downloadlua-5c5d9b27031f0a7fcf61df86cd242105c38485d6.tar.gz
lua-5c5d9b27031f0a7fcf61df86cd242105c38485d6.tar.bz2
lua-5c5d9b27031f0a7fcf61df86cd242105c38485d6.zip
back to `__mode' metafield to specify weakness
-rw-r--r--lapi.c27
-rw-r--r--lbaselib.c25
-rw-r--r--lgc.c37
-rw-r--r--lobject.h6
-rw-r--r--ltable.c3
-rw-r--r--ltablib.c8
-rw-r--r--ltm.c4
-rw-r--r--ltm.h9
-rw-r--r--lua.h4
9 files changed, 49 insertions, 74 deletions
diff --git a/lapi.c b/lapi.c
index bcda55c3..c1880663 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 1.217 2002/11/07 15:37:10 roberto Exp roberto $ 2** $Id: lapi.c,v 1.218 2002/11/07 15:39:23 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -505,20 +505,6 @@ LUA_API void lua_newtable (lua_State *L) {
505} 505}
506 506
507 507
508LUA_API const char *lua_getmode (lua_State *L, int index) {
509 static const char *const modes[] = {"", "k", "v", "kv"};
510 int mode = 0;
511 TObject *t;
512 lua_lock(L);
513 t = luaA_index(L, index);
514 api_check(L, ttistable(t));
515 if (hvalue(t)->mode & WEAKKEY) mode += 1;
516 if (hvalue(t)->mode & WEAKVALUE) mode += 2;
517 lua_unlock(L);
518 return modes[mode];
519}
520
521
522LUA_API int lua_getmetatable (lua_State *L, int objindex) { 508LUA_API int lua_getmetatable (lua_State *L, int objindex) {
523 StkId obj; 509 StkId obj;
524 Table *mt; 510 Table *mt;
@@ -597,17 +583,6 @@ LUA_API void lua_rawseti (lua_State *L, int index, int n) {
597} 583}
598 584
599 585
600LUA_API void lua_setmode (lua_State *L, int index, const char *mode) {
601 TObject *t;
602 lua_lock(L);
603 t = luaA_index(L, index);
604 api_check(L, ttistable(t));
605 hvalue(t)->mode &= ~(WEAKKEY | WEAKVALUE); /* clear bits */
606 if (strchr(mode, 'k')) hvalue(t)->mode |= WEAKKEY;
607 if (strchr(mode, 'v')) hvalue(t)->mode |= WEAKVALUE;
608 lua_unlock(L);
609}
610
611LUA_API int lua_setmetatable (lua_State *L, int objindex) { 586LUA_API int lua_setmetatable (lua_State *L, int objindex) {
612 TObject *obj, *mt; 587 TObject *obj, *mt;
613 int res = 1; 588 int res = 1;
diff --git a/lbaselib.c b/lbaselib.c
index 8753273a..c55d3e98 100644
--- a/lbaselib.c
+++ b/lbaselib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lbaselib.c,v 1.104 2002/11/06 19:08:00 roberto Exp roberto $ 2** $Id: lbaselib.c,v 1.105 2002/11/07 15:39:23 roberto Exp roberto $
3** Basic library 3** Basic library
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -88,21 +88,6 @@ static int luaB_error (lua_State *L) {
88} 88}
89 89
90 90
91static int luaB_getmode (lua_State *L) {
92 luaL_check_type(L, 1, LUA_TTABLE);
93 lua_pushstring(L, lua_getmode(L, 1));
94 return 1;
95}
96
97
98static int luaB_setmode (lua_State *L) {
99 luaL_check_type(L, 1, LUA_TTABLE);
100 lua_setmode(L, 1, luaL_check_string(L, 2));
101 lua_settop(L, 1);
102 return 1;
103}
104
105
106static int luaB_getmetatable (lua_State *L) { 91static int luaB_getmetatable (lua_State *L) {
107 luaL_check_any(L, 1); 92 luaL_check_any(L, 1);
108 if (!lua_getmetatable(L, 1)) { 93 if (!lua_getmetatable(L, 1)) {
@@ -524,8 +509,6 @@ static const luaL_reg base_funcs[] = {
524 {"setmetatable", luaB_setmetatable}, 509 {"setmetatable", luaB_setmetatable},
525 {"getglobals", luaB_getglobals}, 510 {"getglobals", luaB_getglobals},
526 {"setglobals", luaB_setglobals}, 511 {"setglobals", luaB_setglobals},
527 {"getmode", luaB_getmode},
528 {"setmode", luaB_setmode},
529 {"next", luaB_next}, 512 {"next", luaB_next},
530 {"ipairs", luaB_ipairs}, 513 {"ipairs", luaB_ipairs},
531 {"pairs", luaB_pairs}, 514 {"pairs", luaB_pairs},
@@ -646,7 +629,11 @@ static void base_open (lua_State *L) {
646 /* `newproxy' needs a weaktable as upvalue */ 629 /* `newproxy' needs a weaktable as upvalue */
647 lua_pushliteral(L, "newproxy"); 630 lua_pushliteral(L, "newproxy");
648 lua_newtable(L); /* new table `w' */ 631 lua_newtable(L); /* new table `w' */
649 lua_setmode(L, -1, "k"); 632 lua_pushvalue(L, -1); /* `w' will be its own metatable */
633 lua_setmetatable(L, -2);
634 lua_pushliteral(L, "__mode");
635 lua_pushliteral(L, "k");
636 lua_rawset(L, -3); /* metatable(w).__mode = "k" */
650 lua_pushcclosure(L, luaB_newproxy, 1); 637 lua_pushcclosure(L, luaB_newproxy, 1);
651 lua_rawset(L, -3); /* set global `newproxy' */ 638 lua_rawset(L, -3); /* set global `newproxy' */
652 lua_rawset(L, -1); /* set global _G */ 639 lua_rawset(L, -1); /* set global _G */
diff --git a/lgc.c b/lgc.c
index 72984d2a..87ec40c9 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.156 2002/11/11 11:52:43 roberto Exp roberto $ 2** $Id: lgc.c,v 1.157 2002/11/13 11:49:19 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -47,6 +47,13 @@ typedef struct GCState {
47#define markfinalized(u) resetbit((u)->uv.marked, 1) 47#define markfinalized(u) resetbit((u)->uv.marked, 1)
48 48
49 49
50#define KEYWEAKBIT 1
51#define VALUEWEAKBIT 2
52#define KEYWEAK (1<<KEYWEAKBIT)
53#define VALUEWEAK (1<<VALUEWEAKBIT)
54
55
56
50#define markobject(st,o) { checkconsistency(o); \ 57#define markobject(st,o) { checkconsistency(o); \
51 if (iscollectable(o) && !ismarked(gcvalue(o))) reallymarkobject(st,gcvalue(o)); } 58 if (iscollectable(o) && !ismarked(gcvalue(o))) reallymarkobject(st,gcvalue(o)); }
52 59
@@ -140,17 +147,23 @@ static void traversetable (GCState *st, Table *h) {
140 int i; 147 int i;
141 int weakkey = 0; 148 int weakkey = 0;
142 int weakvalue = 0; 149 int weakvalue = 0;
150 const TObject *mode;
143 markvalue(st, h->metatable); 151 markvalue(st, h->metatable);
144 lua_assert(h->lsizenode || h->node == st->G->dummynode); 152 lua_assert(h->lsizenode || h->node == st->G->dummynode);
145 if (h->mode & (WEAKKEY | WEAKVALUE)) { /* weak table? */ 153 mode = gfasttm(st->G, h->metatable, TM_MODE);
146 GCObject **weaklist; 154 if (mode && ttisstring(mode)) { /* is there a weak mode? */
147 weakkey = h->mode & WEAKKEY; 155 weakkey = (strchr(svalue(mode), 'k') != NULL);
148 weakvalue = h->mode & WEAKVALUE; 156 weakvalue = (strchr(svalue(mode), 'v') != NULL);
149 weaklist = (weakkey && weakvalue) ? &st->wkv : 157 if (weakkey || weakvalue) { /* is really weak? */
150 (weakkey) ? &st->wk : 158 GCObject **weaklist;
151 &st->wv; 159 h->marked &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
152 h->gclist = *weaklist; /* must be cleared after GC, ... */ 160 h->marked |= (weakkey << KEYWEAKBIT) | (weakvalue << VALUEWEAKBIT);
153 *weaklist = valtogco(h); /* ... so put in the appropriate list */ 161 weaklist = (weakkey && weakvalue) ? &st->wkv :
162 (weakkey) ? &st->wk :
163 &st->wv;
164 h->gclist = *weaklist; /* must be cleared after GC, ... */
165 *weaklist = valtogco(h); /* ... so put in the appropriate list */
166 }
154 } 167 }
155 if (!weakvalue) { 168 if (!weakvalue) {
156 i = sizearray(h); 169 i = sizearray(h);
@@ -280,7 +293,7 @@ static void cleartablekeys (GCObject *l) {
280 while (l) { 293 while (l) {
281 Table *h = gcotoh(l); 294 Table *h = gcotoh(l);
282 int i = sizenode(h); 295 int i = sizenode(h);
283 lua_assert(h->mode & WEAKKEY); 296 lua_assert(h->marked & KEYWEAK);
284 while (i--) { 297 while (i--) {
285 Node *n = node(h, i); 298 Node *n = node(h, i);
286 if (!valismarked(key(n))) /* key was collected? */ 299 if (!valismarked(key(n))) /* key was collected? */
@@ -298,7 +311,7 @@ static void cleartablevalues (GCObject *l) {
298 while (l) { 311 while (l) {
299 Table *h = gcotoh(l); 312 Table *h = gcotoh(l);
300 int i = sizearray(h); 313 int i = sizearray(h);
301 lua_assert(h->mode & WEAKVALUE); 314 lua_assert(h->marked & VALUEWEAK);
302 while (i--) { 315 while (i--) {
303 TObject *o = &h->array[i]; 316 TObject *o = &h->array[i];
304 if (!valismarked(o)) /* value was collected? */ 317 if (!valismarked(o)) /* value was collected? */
diff --git a/lobject.h b/lobject.h
index d0352c10..d96229ac 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 1.152 2002/11/07 15:37:10 roberto Exp roberto $ 2** $Id: lobject.h,v 1.153 2002/11/13 11:49:19 roberto Exp roberto $
3** Type definitions for Lua objects 3** Type definitions for Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -292,7 +292,6 @@ typedef struct Node {
292typedef struct Table { 292typedef struct Table {
293 CommonHeader; 293 CommonHeader;
294 lu_byte flags; /* 1<<p means tagmethod(p) is not present */ 294 lu_byte flags; /* 1<<p means tagmethod(p) is not present */
295 lu_byte mode;
296 lu_byte lsizenode; /* log2 of size of `node' array */ 295 lu_byte lsizenode; /* log2 of size of `node' array */
297 struct Table *metatable; 296 struct Table *metatable;
298 TObject *array; /* array part */ 297 TObject *array; /* array part */
@@ -302,9 +301,6 @@ typedef struct Table {
302 int sizearray; /* size of `array' array */ 301 int sizearray; /* size of `array' array */
303} Table; 302} Table;
304 303
305/* bit masks for `mode' */
306#define WEAKKEY 1
307#define WEAKVALUE 2
308 304
309 305
310/* 306/*
diff --git a/ltable.c b/ltable.c
index f58d6dfb..04b3db35 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 1.120 2002/11/07 15:37:10 roberto Exp roberto $ 2** $Id: ltable.c,v 1.121 2002/11/13 11:31:39 roberto Exp roberto $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -304,7 +304,6 @@ Table *luaH_new (lua_State *L, int narray, int lnhash) {
304 luaC_link(L, valtogco(t), LUA_TTABLE); 304 luaC_link(L, valtogco(t), LUA_TTABLE);
305 t->metatable = hvalue(defaultmeta(L)); 305 t->metatable = hvalue(defaultmeta(L));
306 t->flags = cast(lu_byte, ~0); 306 t->flags = cast(lu_byte, ~0);
307 t->mode = 0;
308 /* temporary values (kept only if some malloc fails) */ 307 /* temporary values (kept only if some malloc fails) */
309 t->array = NULL; 308 t->array = NULL;
310 t->sizearray = 0; 309 t->sizearray = 0;
diff --git a/ltablib.c b/ltablib.c
index c95b621c..0893f055 100644
--- a/ltablib.c
+++ b/ltablib.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltablib.c,v 1.13 2002/10/04 14:30:31 roberto Exp roberto $ 2** $Id: ltablib.c,v 1.14 2002/10/23 19:08:23 roberto Exp roberto $
3** Library for Table Manipulation 3** Library for Table Manipulation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -288,7 +288,11 @@ static const luaL_reg tab_funcs[] = {
288 288
289LUALIB_API int lua_tablibopen (lua_State *L) { 289LUALIB_API int lua_tablibopen (lua_State *L) {
290 lua_newtable(L); /* create N (table to store num. elements in tables) */ 290 lua_newtable(L); /* create N (table to store num. elements in tables) */
291 lua_setmode(L, -1, "k"); /* make it a weak table */ 291 lua_pushvalue(L, -1); /* `N' will be its own metatable */
292 lua_setmetatable(L, -2);
293 lua_pushliteral(L, "__mode");
294 lua_pushliteral(L, "k");
295 lua_rawset(L, -3); /* metatable(N).__mode = "k" */
292 luaL_opennamedlib(L, LUA_TABLIBNAME, tab_funcs, 1); 296 luaL_opennamedlib(L, LUA_TABLIBNAME, tab_funcs, 1);
293 return 0; 297 return 0;
294} 298}
diff --git a/ltm.c b/ltm.c
index ff66afdd..60451581 100644
--- a/ltm.c
+++ b/ltm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.c,v 1.102 2002/09/19 20:12:47 roberto Exp roberto $ 2** $Id: ltm.c,v 1.103 2002/10/25 20:05:28 roberto Exp roberto $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -26,7 +26,7 @@ const char *const luaT_typenames[] = {
26void luaT_init (lua_State *L) { 26void luaT_init (lua_State *L) {
27 static const char *const luaT_eventname[] = { /* ORDER TM */ 27 static const char *const luaT_eventname[] = { /* ORDER TM */
28 "__index", "__newindex", 28 "__index", "__newindex",
29 "__gc", "__eq", 29 "__gc", "__mode", "__eq",
30 "__add", "__sub", "__mul", "__div", 30 "__add", "__sub", "__mul", "__div",
31 "__pow", "__unm", "__lt", "__le", 31 "__pow", "__unm", "__lt", "__le",
32 "__concat", "__call" 32 "__concat", "__call"
diff --git a/ltm.h b/ltm.h
index 09f34a25..4c56a093 100644
--- a/ltm.h
+++ b/ltm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.h,v 1.39 2002/08/06 17:06:56 roberto Exp roberto $ 2** $Id: ltm.h,v 1.40 2002/09/19 20:12:47 roberto Exp roberto $
3** Tag methods 3** Tag methods
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -19,6 +19,7 @@ typedef enum {
19 TM_INDEX, 19 TM_INDEX,
20 TM_NEWINDEX, 20 TM_NEWINDEX,
21 TM_GC, 21 TM_GC,
22 TM_MODE,
22 TM_EQ, /* last tag method with `fast' access */ 23 TM_EQ, /* last tag method with `fast' access */
23 TM_ADD, 24 TM_ADD,
24 TM_SUB, 25 TM_SUB,
@@ -35,8 +36,10 @@ typedef enum {
35 36
36 37
37 38
38#define fasttm(l,et,e) \ 39#define gfasttm(g,et,e) \
39 (((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, G(l)->tmname[e])) 40 (((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e]))
41
42#define fasttm(l,et,e) gfasttm(G(l), et, e)
40 43
41 44
42const TObject *luaT_gettm (Table *events, TMS event, TString *ename); 45const TObject *luaT_gettm (Table *events, TMS event, TString *ename);
diff --git a/lua.h b/lua.h
index 5b0270c8..b36f975c 100644
--- a/lua.h
+++ b/lua.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lua.h,v 1.162 2002/11/06 19:08:00 roberto Exp roberto $ 2** $Id: lua.h,v 1.163 2002/11/07 15:39:23 roberto Exp roberto $
3** Lua - An Extensible Extension Language 3** Lua - An Extensible Extension Language
4** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil 4** Tecgraf: Computer Graphics Technology Group, PUC-Rio, Brazil
5** http://www.lua.org mailto:info@lua.org 5** http://www.lua.org mailto:info@lua.org
@@ -174,7 +174,6 @@ LUA_API void lua_rawget (lua_State *L, int idx);
174LUA_API void lua_rawgeti (lua_State *L, int idx, int n); 174LUA_API void lua_rawgeti (lua_State *L, int idx, int n);
175LUA_API void lua_newtable (lua_State *L); 175LUA_API void lua_newtable (lua_State *L);
176LUA_API int lua_getmetatable (lua_State *L, int objindex); 176LUA_API int lua_getmetatable (lua_State *L, int objindex);
177LUA_API const char *lua_getmode (lua_State *L, int idx);
178LUA_API void lua_getglobals (lua_State *L, int idx); 177LUA_API void lua_getglobals (lua_State *L, int idx);
179 178
180 179
@@ -184,7 +183,6 @@ LUA_API void lua_getglobals (lua_State *L, int idx);
184LUA_API void lua_settable (lua_State *L, int idx); 183LUA_API void lua_settable (lua_State *L, int idx);
185LUA_API void lua_rawset (lua_State *L, int idx); 184LUA_API void lua_rawset (lua_State *L, int idx);
186LUA_API void lua_rawseti (lua_State *L, int idx, int n); 185LUA_API void lua_rawseti (lua_State *L, int idx, int n);
187LUA_API void lua_setmode (lua_State *L, int idx, const char *md);
188LUA_API int lua_setmetatable (lua_State *L, int objindex); 186LUA_API int lua_setmetatable (lua_State *L, int objindex);
189LUA_API int lua_setglobals (lua_State *L, int idx); 187LUA_API int lua_setglobals (lua_State *L, int idx);
190 188