Sfoglia il codice sorgente

no more 'luaH_emptyobject' and comparisons of addresses of global variables
(instead, use a different kind of nil to signal the fake entry returned
when a key is not found in a table)

Roberto Ierusalimschy 7 anni fa
parent
commit
fb8fa66136
5 ha cambiato i file con 46 aggiunte e 30 eliminazioni
  1. 28 8
      lobject.h
  2. 10 9
      ltable.c
  3. 1 6
      ltable.h
  4. 2 2
      ltm.h
  5. 5 5
      lvm.c

+ 28 - 8
lobject.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.h,v 2.141 2018/02/26 14:16:05 roberto Exp roberto $
+** $Id: lobject.h,v 2.142 2018/04/04 14:23:41 roberto Exp roberto $
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -137,7 +137,12 @@ typedef StackValue *StkId;  /* index to stack elements */
 ** ===================================================================
 */
 
-#define ttisnil(o)		checktag((o), LUA_TNIL)
+/* macro to test for (any kind of) nil */
+#define ttisnil(v)		checktype((v), LUA_TNIL)
+
+/* macro to test for a "pure" nil */
+#define ttisstrictnil(o)	checktag((o), LUA_TNIL)
+
 
 /* macro defining a nil value */
 #define NILCONSTANT	{NULL}, LUA_TNIL
@@ -155,17 +160,32 @@ typedef StackValue *StkId;  /* index to stack elements */
 */
 #define LUA_TEMPTY	(LUA_TNIL | (1 << 4))
 
-#define ttisnilorempty(v)	checktype((v), LUA_TNIL)
+/*
+** Variant used only in the value returned for a key not found in a
+** table (absent key).
+*/
+#define LUA_TABSTKEY	(LUA_TNIL | (2 << 4))
+
 
-#define isreallyempty(v)	checktag((v), LUA_TEMPTY)
+#define isabstkey(v)		checktag((v), LUA_TABSTKEY)
 
 
-/* By default, entries with any kind of nil are considered empty */
-#define isempty(v)		ttisnilorempty(v)
+/*
+** macro to detect non-standard nils (used only in assertions)
+*/
+#define isreallyempty(v)	(ttisnil(v) && !ttisstrictnil(v))
+
+
+/*
+** By default, entries with any kind of nil are considered empty.
+** (In any definition, values associated with absent keys must also
+** be accepted as empty.)
+*/
+#define isempty(v)		ttisnil(v)
 
 
-/* macro defining an empty value */
-#define EMPTYCONSTANT	{NULL}, LUA_TEMPTY
+/* macro defining a value corresponding to an absent key */
+#define ABSTKEYCONSTANT		{NULL}, LUA_TABSTKEY
 
 
 /* mark an entry as empty */

+ 10 - 9
ltable.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.c,v 2.136 2018/05/29 18:01:50 roberto Exp roberto $
+** $Id: ltable.c,v 2.137 2018/05/30 14:25:52 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -93,7 +93,8 @@ static const Node dummynode_ = {
 };
 
 
-LUAI_DDEF const TValue luaH_emptyobject_ = {EMPTYCONSTANT};
+static const TValue absentkey = {ABSTKEYCONSTANT};
+
 
 
 /*
@@ -203,7 +204,7 @@ static const TValue *getgeneric (Table *t, const TValue *key) {
     else {
       int nx = gnext(n);
       if (nx == 0)
-        return luaH_emptyobject;  /* not found */
+        return &absentkey;  /* not found */
       n += nx;
     }
   }
@@ -235,7 +236,7 @@ static unsigned int findindex (lua_State *L, Table *t, TValue *key) {
     return i;  /* yes; that's the index */
   else {
     const TValue *n = getgeneric(t, key);
-    if (unlikely(n == luaH_emptyobject))
+    if (unlikely(isabstkey(n)))
       luaG_runerror(L, "invalid key to 'next'");  /* key not found */
     i = cast_int(nodefromval(n) - gnode(t, 0));  /* key index in hash table */
     /* hash elements are numbered after array ones */
@@ -629,7 +630,7 @@ const TValue *luaH_getint (Table *t, lua_Integer key) {
         n += nx;
       }
     }
-    return luaH_emptyobject;
+    return &absentkey;
   }
 }
 
@@ -646,7 +647,7 @@ const TValue *luaH_getshortstr (Table *t, TString *key) {
     else {
       int nx = gnext(n);
       if (nx == 0)
-        return luaH_emptyobject;  /* not found */
+        return &absentkey;  /* not found */
       n += nx;
     }
   }
@@ -671,7 +672,7 @@ const TValue *luaH_get (Table *t, const TValue *key) {
   switch (ttypetag(key)) {
     case LUA_TSHRSTR: return luaH_getshortstr(t, tsvalue(key));
     case LUA_TNUMINT: return luaH_getint(t, ivalue(key));
-    case LUA_TNIL: return luaH_emptyobject;
+    case LUA_TNIL: return &absentkey;
     case LUA_TNUMFLT: {
       lua_Integer k;
       if (luaV_flttointeger(fltvalue(key), &k, 0)) /* index is an integral? */
@@ -690,7 +691,7 @@ const TValue *luaH_get (Table *t, const TValue *key) {
 */
 TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
   const TValue *p = luaH_get(t, key);
-  if (p != luaH_emptyobject)
+  if (!isabstkey(p))
     return cast(TValue *, p);
   else return luaH_newkey(L, t, key);
 }
@@ -699,7 +700,7 @@ TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
 void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
   const TValue *p = luaH_getint(t, key);
   TValue *cell;
-  if (p != luaH_emptyobject)
+  if (!isabstkey(p))
     cell = cast(TValue *, p);
   else {
     TValue k;

+ 1 - 6
ltable.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.h,v 2.25 2017/06/09 16:48:44 roberto Exp roberto $
+** $Id: ltable.h,v 2.26 2018/02/23 13:13:31 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -21,8 +21,6 @@
 /* true when 't' is using 'dummynode' as its hash part */
 #define isdummy(t)		((t)->lastfree == NULL)
 
-#define luaH_emptyobject	(&luaH_emptyobject_)
-
 
 /* allocated size for hash nodes */
 #define allocsizenode(t)	(isdummy(t) ? 0 : sizenode(t))
@@ -32,9 +30,6 @@
 #define nodefromval(v) 	cast(Node *, (v))
 
 
-LUAI_DDEC const TValue luaH_emptyobject_;
-
-
 LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key);
 LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,
                                                     TValue *value);

+ 2 - 2
ltm.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ltm.h,v 2.35 2018/04/04 14:23:41 roberto Exp roberto $
+** $Id: ltm.h,v 2.36 2018/05/23 14:41:20 roberto Exp roberto $
 ** Tag methods
 ** See Copyright Notice in lua.h
 */
@@ -48,7 +48,7 @@ typedef enum {
 ** Test whether there is no tagmethod.
 ** (Because tagmethods use raw accesses, the result may be an "empty" nil.)
 */
-#define notm(tm)	ttisnilorempty(tm)
+#define notm(tm)	ttisnil(tm)
 
 
 #define gfasttm(g,et,e) ((et) == NULL ? NULL : \

+ 5 - 5
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 2.355 2018/05/22 12:02:36 roberto Exp roberto $
+** $Id: lvm.c,v 2.356 2018/05/30 14:25:52 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -227,9 +227,9 @@ void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
 /*
 ** Finish a table assignment 't[key] = val'.
 ** If 'slot' is NULL, 't' is not a table.  Otherwise, 'slot' points
-** to the entry 't[key]', or to 'luaH_emptyobject' if there is no such
-** entry.  (The value at 'slot' must be empty, otherwise 'luaV_fastget'
-** would have done the job.)
+** to the entry 't[key]', or to a value with an absent key if there
+** is no such entry.  (The value at 'slot' must be empty, otherwise
+** 'luaV_fastget' would have done the job.)
 */
 void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
                      TValue *val, const TValue *slot) {
@@ -241,7 +241,7 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
       lua_assert(isempty(slot));  /* slot must be empty */
       tm = fasttm(L, h->metatable, TM_NEWINDEX);  /* get metamethod */
       if (tm == NULL) {  /* no metamethod? */
-        if (slot == luaH_emptyobject)  /* no previous entry? */
+        if (isabstkey(slot))  /* no previous entry? */
           slot = luaH_newkey(L, h, key);  /* create one */
         /* no metamethod and (now) there is an entry with given key */
         setobj2t(L, cast(TValue *, slot), val);  /* set its new value */