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