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 | ||
