aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-06-01 13:51:34 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-06-01 13:51:34 -0300
commitfb8fa661366e15e98c60d8929feaab9e551a02f9 (patch)
treeb3eb16fcfe3eab8f4b07ccaa71c55011016ad005
parentb3970649550fe8471c55bfae57aa3752ddfa97a9 (diff)
downloadlua-fb8fa661366e15e98c60d8929feaab9e551a02f9.tar.gz
lua-fb8fa661366e15e98c60d8929feaab9e551a02f9.tar.bz2
lua-fb8fa661366e15e98c60d8929feaab9e551a02f9.zip
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)
-rw-r--r--lobject.h36
-rw-r--r--ltable.c19
-rw-r--r--ltable.h7
-rw-r--r--ltm.h4
-rw-r--r--lvm.c10
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 @@
1/* 1/*
2** $Id: lobject.h,v 2.141 2018/02/26 14:16:05 roberto Exp roberto $ 2** $Id: lobject.h,v 2.142 2018/04/04 14:23:41 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*/
@@ -137,7 +137,12 @@ typedef StackValue *StkId; /* index to stack elements */
137** =================================================================== 137** ===================================================================
138*/ 138*/
139 139
140#define ttisnil(o) checktag((o), LUA_TNIL) 140/* macro to test for (any kind of) nil */
141#define ttisnil(v) checktype((v), LUA_TNIL)
142
143/* macro to test for a "pure" nil */
144#define ttisstrictnil(o) checktag((o), LUA_TNIL)
145
141 146
142/* macro defining a nil value */ 147/* macro defining a nil value */
143#define NILCONSTANT {NULL}, LUA_TNIL 148#define NILCONSTANT {NULL}, LUA_TNIL
@@ -155,17 +160,32 @@ typedef StackValue *StkId; /* index to stack elements */
155*/ 160*/
156#define LUA_TEMPTY (LUA_TNIL | (1 << 4)) 161#define LUA_TEMPTY (LUA_TNIL | (1 << 4))
157 162
158#define ttisnilorempty(v) checktype((v), LUA_TNIL) 163/*
164** Variant used only in the value returned for a key not found in a
165** table (absent key).
166*/
167#define LUA_TABSTKEY (LUA_TNIL | (2 << 4))
168
159 169
160#define isreallyempty(v) checktag((v), LUA_TEMPTY) 170#define isabstkey(v) checktag((v), LUA_TABSTKEY)
161 171
162 172
163/* By default, entries with any kind of nil are considered empty */ 173/*
164#define isempty(v) ttisnilorempty(v) 174** macro to detect non-standard nils (used only in assertions)
175*/
176#define isreallyempty(v) (ttisnil(v) && !ttisstrictnil(v))
177
178
179/*
180** By default, entries with any kind of nil are considered empty.
181** (In any definition, values associated with absent keys must also
182** be accepted as empty.)
183*/
184#define isempty(v) ttisnil(v)
165 185
166 186
167/* macro defining an empty value */ 187/* macro defining a value corresponding to an absent key */
168#define EMPTYCONSTANT {NULL}, LUA_TEMPTY 188#define ABSTKEYCONSTANT {NULL}, LUA_TABSTKEY
169 189
170 190
171/* mark an entry as empty */ 191/* 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 @@
1/* 1/*
2** $Id: ltable.c,v 2.136 2018/05/29 18:01:50 roberto Exp roberto $ 2** $Id: ltable.c,v 2.137 2018/05/30 14:25:52 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*/
@@ -93,7 +93,8 @@ static const Node dummynode_ = {
93}; 93};
94 94
95 95
96LUAI_DDEF const TValue luaH_emptyobject_ = {EMPTYCONSTANT}; 96static const TValue absentkey = {ABSTKEYCONSTANT};
97
97 98
98 99
99/* 100/*
@@ -203,7 +204,7 @@ static const TValue *getgeneric (Table *t, const TValue *key) {
203 else { 204 else {
204 int nx = gnext(n); 205 int nx = gnext(n);
205 if (nx == 0) 206 if (nx == 0)
206 return luaH_emptyobject; /* not found */ 207 return &absentkey; /* not found */
207 n += nx; 208 n += nx;
208 } 209 }
209 } 210 }
@@ -235,7 +236,7 @@ static unsigned int findindex (lua_State *L, Table *t, TValue *key) {
235 return i; /* yes; that's the index */ 236 return i; /* yes; that's the index */
236 else { 237 else {
237 const TValue *n = getgeneric(t, key); 238 const TValue *n = getgeneric(t, key);
238 if (unlikely(n == luaH_emptyobject)) 239 if (unlikely(isabstkey(n)))
239 luaG_runerror(L, "invalid key to 'next'"); /* key not found */ 240 luaG_runerror(L, "invalid key to 'next'"); /* key not found */
240 i = cast_int(nodefromval(n) - gnode(t, 0)); /* key index in hash table */ 241 i = cast_int(nodefromval(n) - gnode(t, 0)); /* key index in hash table */
241 /* hash elements are numbered after array ones */ 242 /* hash elements are numbered after array ones */
@@ -629,7 +630,7 @@ const TValue *luaH_getint (Table *t, lua_Integer key) {
629 n += nx; 630 n += nx;
630 } 631 }
631 } 632 }
632 return luaH_emptyobject; 633 return &absentkey;
633 } 634 }
634} 635}
635 636
@@ -646,7 +647,7 @@ const TValue *luaH_getshortstr (Table *t, TString *key) {
646 else { 647 else {
647 int nx = gnext(n); 648 int nx = gnext(n);
648 if (nx == 0) 649 if (nx == 0)
649 return luaH_emptyobject; /* not found */ 650 return &absentkey; /* not found */
650 n += nx; 651 n += nx;
651 } 652 }
652 } 653 }
@@ -671,7 +672,7 @@ const TValue *luaH_get (Table *t, const TValue *key) {
671 switch (ttypetag(key)) { 672 switch (ttypetag(key)) {
672 case LUA_TSHRSTR: return luaH_getshortstr(t, tsvalue(key)); 673 case LUA_TSHRSTR: return luaH_getshortstr(t, tsvalue(key));
673 case LUA_TNUMINT: return luaH_getint(t, ivalue(key)); 674 case LUA_TNUMINT: return luaH_getint(t, ivalue(key));
674 case LUA_TNIL: return luaH_emptyobject; 675 case LUA_TNIL: return &absentkey;
675 case LUA_TNUMFLT: { 676 case LUA_TNUMFLT: {
676 lua_Integer k; 677 lua_Integer k;
677 if (luaV_flttointeger(fltvalue(key), &k, 0)) /* index is an integral? */ 678 if (luaV_flttointeger(fltvalue(key), &k, 0)) /* index is an integral? */
@@ -690,7 +691,7 @@ const TValue *luaH_get (Table *t, const TValue *key) {
690*/ 691*/
691TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { 692TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
692 const TValue *p = luaH_get(t, key); 693 const TValue *p = luaH_get(t, key);
693 if (p != luaH_emptyobject) 694 if (!isabstkey(p))
694 return cast(TValue *, p); 695 return cast(TValue *, p);
695 else return luaH_newkey(L, t, key); 696 else return luaH_newkey(L, t, key);
696} 697}
@@ -699,7 +700,7 @@ TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
699void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { 700void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
700 const TValue *p = luaH_getint(t, key); 701 const TValue *p = luaH_getint(t, key);
701 TValue *cell; 702 TValue *cell;
702 if (p != luaH_emptyobject) 703 if (!isabstkey(p))
703 cell = cast(TValue *, p); 704 cell = cast(TValue *, p);
704 else { 705 else {
705 TValue k; 706 TValue k;
diff --git a/ltable.h b/ltable.h
index bcf92984..9b1a3464 100644
--- a/ltable.h
+++ b/ltable.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.h,v 2.25 2017/06/09 16:48:44 roberto Exp roberto $ 2** $Id: ltable.h,v 2.26 2018/02/23 13:13:31 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*/
@@ -21,8 +21,6 @@
21/* true when 't' is using 'dummynode' as its hash part */ 21/* true when 't' is using 'dummynode' as its hash part */
22#define isdummy(t) ((t)->lastfree == NULL) 22#define isdummy(t) ((t)->lastfree == NULL)
23 23
24#define luaH_emptyobject (&luaH_emptyobject_)
25
26 24
27/* allocated size for hash nodes */ 25/* allocated size for hash nodes */
28#define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t)) 26#define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t))
@@ -32,9 +30,6 @@
32#define nodefromval(v) cast(Node *, (v)) 30#define nodefromval(v) cast(Node *, (v))
33 31
34 32
35LUAI_DDEC const TValue luaH_emptyobject_;
36
37
38LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); 33LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key);
39LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, 34LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,
40 TValue *value); 35 TValue *value);
diff --git a/ltm.h b/ltm.h
index 24b9a84e..38b6e1b2 100644
--- a/ltm.h
+++ b/ltm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltm.h,v 2.35 2018/04/04 14:23:41 roberto Exp roberto $ 2** $Id: ltm.h,v 2.36 2018/05/23 14:41:20 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*/
@@ -48,7 +48,7 @@ typedef enum {
48** Test whether there is no tagmethod. 48** Test whether there is no tagmethod.
49** (Because tagmethods use raw accesses, the result may be an "empty" nil.) 49** (Because tagmethods use raw accesses, the result may be an "empty" nil.)
50*/ 50*/
51#define notm(tm) ttisnilorempty(tm) 51#define notm(tm) ttisnil(tm)
52 52
53 53
54#define gfasttm(g,et,e) ((et) == NULL ? NULL : \ 54#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 @@
1/* 1/*
2** $Id: lvm.c,v 2.355 2018/05/22 12:02:36 roberto Exp roberto $ 2** $Id: lvm.c,v 2.356 2018/05/30 14:25:52 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -227,9 +227,9 @@ void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
227/* 227/*
228** Finish a table assignment 't[key] = val'. 228** Finish a table assignment 't[key] = val'.
229** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points 229** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points
230** to the entry 't[key]', or to 'luaH_emptyobject' if there is no such 230** to the entry 't[key]', or to a value with an absent key if there
231** entry. (The value at 'slot' must be empty, otherwise 'luaV_fastget' 231** is no such entry. (The value at 'slot' must be empty, otherwise
232** would have done the job.) 232** 'luaV_fastget' would have done the job.)
233*/ 233*/
234void luaV_finishset (lua_State *L, const TValue *t, TValue *key, 234void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
235 TValue *val, const TValue *slot) { 235 TValue *val, const TValue *slot) {
@@ -241,7 +241,7 @@ void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
241 lua_assert(isempty(slot)); /* slot must be empty */ 241 lua_assert(isempty(slot)); /* slot must be empty */
242 tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ 242 tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */
243 if (tm == NULL) { /* no metamethod? */ 243 if (tm == NULL) { /* no metamethod? */
244 if (slot == luaH_emptyobject) /* no previous entry? */ 244 if (isabstkey(slot)) /* no previous entry? */
245 slot = luaH_newkey(L, h, key); /* create one */ 245 slot = luaH_newkey(L, h, key); /* create one */
246 /* no metamethod and (now) there is an entry with given key */ 246 /* no metamethod and (now) there is an entry with given key */
247 setobj2t(L, cast(TValue *, slot), val); /* set its new value */ 247 setobj2t(L, cast(TValue *, slot), val); /* set its new value */