diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-06-12 11:21:44 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-06-12 11:21:44 -0300 |
| commit | 73ec04fcf3e3f7017786fbaf0a83291b22bec5c4 (patch) | |
| tree | b2870a1e832fa3e013b67209592db32b611f8e5f /ltable.c | |
| parent | d13a3fb070fd0ec9ec3b85f88e0fcd914aa666d3 (diff) | |
| download | lua-73ec04fcf3e3f7017786fbaf0a83291b22bec5c4.tar.gz lua-73ec04fcf3e3f7017786fbaf0a83291b22bec5c4.tar.bz2 lua-73ec04fcf3e3f7017786fbaf0a83291b22bec5c4.zip | |
no more 'DEADKEY'. Table traversals do not need to consider dead keys;
if the key is dead, it cannot be given to 'next'. Instead, we now
use a 'table' tag without the collectable bit, which makes it
a unique tag good enough to reserve space.
Diffstat (limited to 'ltable.c')
| -rw-r--r-- | ltable.c | 64 |
1 files changed, 27 insertions, 37 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.c,v 2.122 2017/05/19 12:57:10 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 2.123 2017/06/09 16:48:44 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 | */ |
| @@ -176,6 +176,25 @@ static int equalkey (const TValue *k1, const Node *n2) { | |||
| 176 | 176 | ||
| 177 | 177 | ||
| 178 | /* | 178 | /* |
| 179 | ** "Generic" get version. (Not that generic: not valid for integers, | ||
| 180 | ** which may be in array part, nor for floats with integral values.) | ||
| 181 | */ | ||
| 182 | static const TValue *getgeneric (Table *t, const TValue *key) { | ||
| 183 | Node *n = mainpositionTV(t, key); | ||
| 184 | for (;;) { /* check whether 'key' is somewhere in the chain */ | ||
| 185 | if (equalkey(key, n)) | ||
| 186 | return gval(n); /* that's it */ | ||
| 187 | else { | ||
| 188 | int nx = gnext(n); | ||
| 189 | if (nx == 0) | ||
| 190 | return luaO_nilobject; /* not found */ | ||
| 191 | n += nx; | ||
| 192 | } | ||
| 193 | } | ||
| 194 | } | ||
| 195 | |||
| 196 | |||
| 197 | /* | ||
| 179 | ** returns the index for 'k' if 'k' is an appropriate key to live in | 198 | ** returns the index for 'k' if 'k' is an appropriate key to live in |
| 180 | ** the array part of a table, 0 otherwise. | 199 | ** the array part of a table, 0 otherwise. |
| 181 | */ | 200 | */ |
| @@ -199,22 +218,12 @@ static unsigned int findindex (lua_State *L, Table *t, StkId key) { | |||
| 199 | if (i != 0 && i <= t->sizearray) /* is 'key' inside array part? */ | 218 | if (i != 0 && i <= t->sizearray) /* is 'key' inside array part? */ |
| 200 | return i; /* yes; that's the index */ | 219 | return i; /* yes; that's the index */ |
| 201 | else { | 220 | else { |
| 202 | int nx; | 221 | const TValue *n = getgeneric(t, key); |
| 203 | Node *n = mainpositionTV(t, key); | 222 | if (n == luaO_nilobject) |
| 204 | for (;;) { /* check whether 'key' is somewhere in the chain */ | 223 | luaG_runerror(L, "invalid key to 'next'"); /* key not found */ |
| 205 | /* key may be dead already, but it is ok to use it in 'next' */ | 224 | i = cast_int(nodefromval(n) - gnode(t, 0)); /* key index in hash table */ |
| 206 | if (equalkey(key, n) || | 225 | /* hash elements are numbered after array ones */ |
| 207 | (keyisdead(n) && iscollectable(key) && | 226 | return (i + 1) + t->sizearray; |
| 208 | deadkey(n) == gcvalue(key))) { | ||
| 209 | i = cast_int(n - gnode(t, 0)); /* key index in hash table */ | ||
| 210 | /* hash elements are numbered after array ones */ | ||
| 211 | return (i + 1) + t->sizearray; | ||
| 212 | } | ||
| 213 | nx = gnext(n); | ||
| 214 | if (nx == 0) | ||
| 215 | luaG_runerror(L, "invalid key to 'next'"); /* key not found */ | ||
| 216 | else n += nx; | ||
| 217 | } | ||
| 218 | } | 227 | } |
| 219 | } | 228 | } |
| 220 | 229 | ||
| @@ -574,25 +583,6 @@ const TValue *luaH_getshortstr (Table *t, TString *key) { | |||
| 574 | } | 583 | } |
| 575 | 584 | ||
| 576 | 585 | ||
| 577 | /* | ||
| 578 | ** "Generic" get version. (Not that generic: not valid for integers, | ||
| 579 | ** which may be in array part, nor for floats with integral values.) | ||
| 580 | */ | ||
| 581 | static const TValue *getgeneric (Table *t, const TValue *key) { | ||
| 582 | Node *n = mainpositionTV(t, key); | ||
| 583 | for (;;) { /* check whether 'key' is somewhere in the chain */ | ||
| 584 | if (equalkey(key, n)) | ||
| 585 | return gval(n); /* that's it */ | ||
| 586 | else { | ||
| 587 | int nx = gnext(n); | ||
| 588 | if (nx == 0) | ||
| 589 | return luaO_nilobject; /* not found */ | ||
| 590 | n += nx; | ||
| 591 | } | ||
| 592 | } | ||
| 593 | } | ||
| 594 | |||
| 595 | |||
| 596 | const TValue *luaH_getstr (Table *t, TString *key) { | 586 | const TValue *luaH_getstr (Table *t, TString *key) { |
| 597 | if (key->tt == LUA_TSHRSTR) | 587 | if (key->tt == LUA_TSHRSTR) |
| 598 | return luaH_getshortstr(t, key); | 588 | return luaH_getshortstr(t, key); |
| @@ -662,7 +652,7 @@ void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { | |||
| 662 | ** absent while 'i' is present; so 'j > i'.) Otherwise, 'j' is a | 652 | ** absent while 'i' is present; so 'j > i'.) Otherwise, 'j' is a |
| 663 | ** boundary. ('j + 1' cannot be a present integer key because it is | 653 | ** boundary. ('j + 1' cannot be a present integer key because it is |
| 664 | ** not a valid integer in Lua.) | 654 | ** not a valid integer in Lua.) |
| 665 | */ | 655 | */ |
| 666 | static lua_Unsigned hash_search (Table *t, lua_Unsigned j) { | 656 | static lua_Unsigned hash_search (Table *t, lua_Unsigned j) { |
| 667 | lua_Unsigned i; | 657 | lua_Unsigned i; |
| 668 | if (j == 0) j++; /* the caller ensures 'j + 1' is present */ | 658 | if (j == 0) j++; /* the caller ensures 'j + 1' is present */ |
