From fb8fa661366e15e98c60d8929feaab9e551a02f9 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 1 Jun 2018 13:51:34 -0300 Subject: 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) --- lobject.h | 36 ++++++++++++++++++++++++++++-------- ltable.c | 19 ++++++++++--------- ltable.h | 7 +------ ltm.h | 4 ++-- lvm.c | 10 +++++----- 5 files changed, 46 insertions(+), 30 deletions(-) diff --git a/lobject.h b/lobject.h index dc5f32a1..a7b4318f 100644 --- a/lobject.h +++ b/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 */ diff --git a/ltable.c b/ltable.c index 56fe64fd..cc98f456 100644 --- a/ltable.c +++ b/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; diff --git a/ltable.h b/ltable.h index bcf92984..9b1a3464 100644 --- a/ltable.h +++ b/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); diff --git a/ltm.h b/ltm.h index 24b9a84e..38b6e1b2 100644 --- a/ltm.h +++ b/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 : \ diff --git a/lvm.c b/lvm.c index 36c7699f..3fed2a27 100644 --- a/lvm.c +++ b/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 */ -- cgit v1.2.3-55-g6feb