diff options
Diffstat (limited to 'src/lua/ltable.c')
-rw-r--r-- | src/lua/ltable.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/src/lua/ltable.c b/src/lua/ltable.c index 5a0d066..38bee1d 100644 --- a/src/lua/ltable.c +++ b/src/lua/ltable.c | |||
@@ -172,11 +172,17 @@ static Node *mainpositionTV (const Table *t, const TValue *key) { | |||
172 | ** be equal to floats. It is assumed that 'eqshrstr' is simply | 172 | ** be equal to floats. It is assumed that 'eqshrstr' is simply |
173 | ** pointer equality, so that short strings are handled in the | 173 | ** pointer equality, so that short strings are handled in the |
174 | ** default case. | 174 | ** default case. |
175 | */ | 175 | ** A true 'deadok' means to accept dead keys as equal to their original |
176 | static int equalkey (const TValue *k1, const Node *n2) { | 176 | ** values, which can only happen if the original key was collectable. |
177 | if (rawtt(k1) != keytt(n2)) /* not the same variants? */ | 177 | ** All dead values are compared in the default case, by pointer |
178 | ** identity. (Note that dead long strings are also compared by | ||
179 | ** identity). | ||
180 | */ | ||
181 | static int equalkey (const TValue *k1, const Node *n2, int deadok) { | ||
182 | if ((rawtt(k1) != keytt(n2)) && /* not the same variants? */ | ||
183 | !(deadok && keyisdead(n2) && iscollectable(k1))) | ||
178 | return 0; /* cannot be same key */ | 184 | return 0; /* cannot be same key */ |
179 | switch (ttypetag(k1)) { | 185 | switch (keytt(n2)) { |
180 | case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE: | 186 | case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE: |
181 | return 1; | 187 | return 1; |
182 | case LUA_VNUMINT: | 188 | case LUA_VNUMINT: |
@@ -187,7 +193,7 @@ static int equalkey (const TValue *k1, const Node *n2) { | |||
187 | return pvalue(k1) == pvalueraw(keyval(n2)); | 193 | return pvalue(k1) == pvalueraw(keyval(n2)); |
188 | case LUA_VLCF: | 194 | case LUA_VLCF: |
189 | return fvalue(k1) == fvalueraw(keyval(n2)); | 195 | return fvalue(k1) == fvalueraw(keyval(n2)); |
190 | case LUA_VLNGSTR: | 196 | case ctb(LUA_VLNGSTR): |
191 | return luaS_eqlngstr(tsvalue(k1), keystrval(n2)); | 197 | return luaS_eqlngstr(tsvalue(k1), keystrval(n2)); |
192 | default: | 198 | default: |
193 | return gcvalue(k1) == gcvalueraw(keyval(n2)); | 199 | return gcvalue(k1) == gcvalueraw(keyval(n2)); |
@@ -251,11 +257,12 @@ static unsigned int setlimittosize (Table *t) { | |||
251 | /* | 257 | /* |
252 | ** "Generic" get version. (Not that generic: not valid for integers, | 258 | ** "Generic" get version. (Not that generic: not valid for integers, |
253 | ** which may be in array part, nor for floats with integral values.) | 259 | ** which may be in array part, nor for floats with integral values.) |
260 | ** See explanation about 'deadok' in function 'equalkey'. | ||
254 | */ | 261 | */ |
255 | static const TValue *getgeneric (Table *t, const TValue *key) { | 262 | static const TValue *getgeneric (Table *t, const TValue *key, int deadok) { |
256 | Node *n = mainpositionTV(t, key); | 263 | Node *n = mainpositionTV(t, key); |
257 | for (;;) { /* check whether 'key' is somewhere in the chain */ | 264 | for (;;) { /* check whether 'key' is somewhere in the chain */ |
258 | if (equalkey(key, n)) | 265 | if (equalkey(key, n, deadok)) |
259 | return gval(n); /* that's it */ | 266 | return gval(n); /* that's it */ |
260 | else { | 267 | else { |
261 | int nx = gnext(n); | 268 | int nx = gnext(n); |
@@ -292,7 +299,7 @@ static unsigned int findindex (lua_State *L, Table *t, TValue *key, | |||
292 | if (i - 1u < asize) /* is 'key' inside array part? */ | 299 | if (i - 1u < asize) /* is 'key' inside array part? */ |
293 | return i; /* yes; that's the index */ | 300 | return i; /* yes; that's the index */ |
294 | else { | 301 | else { |
295 | const TValue *n = getgeneric(t, key); | 302 | const TValue *n = getgeneric(t, key, 1); |
296 | if (unlikely(isabstkey(n))) | 303 | if (unlikely(isabstkey(n))) |
297 | luaG_runerror(L, "invalid key to 'next'"); /* key not found */ | 304 | luaG_runerror(L, "invalid key to 'next'"); /* key not found */ |
298 | i = cast_int(nodefromval(n) - gnode(t, 0)); /* key index in hash table */ | 305 | i = cast_int(nodefromval(n) - gnode(t, 0)); /* key index in hash table */ |
@@ -730,7 +737,7 @@ const TValue *luaH_getstr (Table *t, TString *key) { | |||
730 | else { /* for long strings, use generic case */ | 737 | else { /* for long strings, use generic case */ |
731 | TValue ko; | 738 | TValue ko; |
732 | setsvalue(cast(lua_State *, NULL), &ko, key); | 739 | setsvalue(cast(lua_State *, NULL), &ko, key); |
733 | return getgeneric(t, &ko); | 740 | return getgeneric(t, &ko, 0); |
734 | } | 741 | } |
735 | } | 742 | } |
736 | 743 | ||
@@ -750,7 +757,7 @@ const TValue *luaH_get (Table *t, const TValue *key) { | |||
750 | /* else... */ | 757 | /* else... */ |
751 | } /* FALLTHROUGH */ | 758 | } /* FALLTHROUGH */ |
752 | default: | 759 | default: |
753 | return getgeneric(t, key); | 760 | return getgeneric(t, key, 0); |
754 | } | 761 | } |
755 | } | 762 | } |
756 | 763 | ||