浏览代码

back to `__mode' metafield to specify weakness

Roberto Ierusalimschy 23 年之前
父节点
当前提交
5c5d9b2703
共有 9 个文件被更改,包括 49 次插入74 次删除
  1. 1 26
      lapi.c
  2. 6 19
      lbaselib.c
  3. 25 12
      lgc.c
  4. 1 5
      lobject.h
  5. 1 2
      ltable.c
  6. 6 2
      ltablib.c
  7. 2 2
      ltm.c
  8. 6 3
      ltm.h
  9. 1 3
      lua.h

+ 1 - 26
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;

+ 6 - 19
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 */

+ 25 - 12
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? */
-    GCObject **weaklist;
-    weakkey = h->mode & WEAKKEY;
-    weakvalue = h->mode & WEAKVALUE;
-    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 */
+  mode = gfasttm(st->G, h->metatable, TM_MODE);
+  if (mode && ttisstring(mode)) {  /* is there a weak mode? */
+    weakkey = (strchr(svalue(mode), 'k') != NULL);
+    weakvalue = (strchr(svalue(mode), 'v') != NULL);
+    if (weakkey || weakvalue) {  /* is really weak? */
+      GCObject **weaklist;
+      h->marked &= ~(KEYWEAK | VALUEWEAK);  /* clear bits */
+      h->marked |= (weakkey << KEYWEAKBIT) | (weakvalue << VALUEWEAKBIT);
+      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
lobject.h

@@ -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
 
 
 
 
 /*
 /*

+ 1 - 2
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;

+ 6 - 2
ltablib.c

@@ -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;
 }
 }

+ 2 - 2
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"

+ 6 - 3
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) \
-  (((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, G(l)->tmname[e]))
+#define gfasttm(g,et,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);

+ 1 - 3
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:[email protected]
 ** http://www.lua.org	mailto:[email protected]
@@ -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);