diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-11-14 10:01:35 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-11-14 10:01:35 -0200 |
commit | 5c5d9b27031f0a7fcf61df86cd242105c38485d6 (patch) | |
tree | 534fb1ea4a4fc82253d5bc8b0af92b91a7ae9714 | |
parent | 43d1a6af12fb9cf20e55cc6ba8a1b0231d6b7a3c (diff) | |
download | lua-5c5d9b27031f0a7fcf61df86cd242105c38485d6.tar.gz lua-5c5d9b27031f0a7fcf61df86cd242105c38485d6.tar.bz2 lua-5c5d9b27031f0a7fcf61df86cd242105c38485d6.zip |
back to `__mode' metafield to specify weakness
-rw-r--r-- | lapi.c | 27 | ||||
-rw-r--r-- | lbaselib.c | 25 | ||||
-rw-r--r-- | lgc.c | 37 | ||||
-rw-r--r-- | lobject.h | 6 | ||||
-rw-r--r-- | ltable.c | 3 | ||||
-rw-r--r-- | ltablib.c | 8 | ||||
-rw-r--r-- | ltm.c | 4 | ||||
-rw-r--r-- | ltm.h | 9 | ||||
-rw-r--r-- | lua.h | 4 |
9 files changed, 49 insertions, 74 deletions
@@ -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 | ||
508 | LUA_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 | |||
522 | LUA_API int lua_getmetatable (lua_State *L, int objindex) { | 508 | LUA_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 | ||
600 | LUA_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 | |||
611 | LUA_API int lua_setmetatable (lua_State *L, int objindex) { | 586 | LUA_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; |
@@ -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 | ||
91 | static 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 | |||
98 | static 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 | |||
106 | static int luaB_getmetatable (lua_State *L) { | 91 | static 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 */ |
@@ -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? */ |
@@ -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 { | |||
292 | typedef struct Table { | 292 | typedef 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 | /* |
@@ -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; |
@@ -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 | ||
289 | LUALIB_API int lua_tablibopen (lua_State *L) { | 289 | LUALIB_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 | } |
@@ -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[] = { | |||
26 | void luaT_init (lua_State *L) { | 26 | void 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" |
@@ -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 | ||
42 | const TObject *luaT_gettm (Table *events, TMS event, TString *ename); | 45 | const TObject *luaT_gettm (Table *events, TMS event, TString *ename); |
@@ -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); | |||
174 | LUA_API void lua_rawgeti (lua_State *L, int idx, int n); | 174 | LUA_API void lua_rawgeti (lua_State *L, int idx, int n); |
175 | LUA_API void lua_newtable (lua_State *L); | 175 | LUA_API void lua_newtable (lua_State *L); |
176 | LUA_API int lua_getmetatable (lua_State *L, int objindex); | 176 | LUA_API int lua_getmetatable (lua_State *L, int objindex); |
177 | LUA_API const char *lua_getmode (lua_State *L, int idx); | ||
178 | LUA_API void lua_getglobals (lua_State *L, int idx); | 177 | LUA_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); | |||
184 | LUA_API void lua_settable (lua_State *L, int idx); | 183 | LUA_API void lua_settable (lua_State *L, int idx); |
185 | LUA_API void lua_rawset (lua_State *L, int idx); | 184 | LUA_API void lua_rawset (lua_State *L, int idx); |
186 | LUA_API void lua_rawseti (lua_State *L, int idx, int n); | 185 | LUA_API void lua_rawseti (lua_State *L, int idx, int n); |
187 | LUA_API void lua_setmode (lua_State *L, int idx, const char *md); | ||
188 | LUA_API int lua_setmetatable (lua_State *L, int objindex); | 186 | LUA_API int lua_setmetatable (lua_State *L, int objindex); |
189 | LUA_API int lua_setglobals (lua_State *L, int idx); | 187 | LUA_API int lua_setglobals (lua_State *L, int idx); |
190 | 188 | ||