diff options
-rw-r--r-- | lobject.h | 36 | ||||
-rw-r--r-- | ltable.c | 19 | ||||
-rw-r--r-- | ltable.h | 7 | ||||
-rw-r--r-- | ltm.h | 4 | ||||
-rw-r--r-- | lvm.c | 10 |
5 files changed, 46 insertions, 30 deletions
@@ -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 */ |
@@ -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 | ||
96 | LUAI_DDEF const TValue luaH_emptyobject_ = {EMPTYCONSTANT}; | 96 | static 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 | */ |
691 | TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { | 692 | TValue *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) { | |||
699 | void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { | 700 | void 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; |
@@ -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 | ||
35 | LUAI_DDEC const TValue luaH_emptyobject_; | ||
36 | |||
37 | |||
38 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); | 33 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); |
39 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, | 34 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, |
40 | TValue *value); | 35 | TValue *value); |
@@ -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 : \ |
@@ -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 | */ |
234 | void luaV_finishset (lua_State *L, const TValue *t, TValue *key, | 234 | void 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 */ |