|
@@ -172,11 +172,17 @@ static Node *mainpositionTV (const Table *t, const TValue *key) {
|
|
|
** be equal to floats. It is assumed that 'eqshrstr' is simply
|
|
|
** pointer equality, so that short strings are handled in the
|
|
|
** default case.
|
|
|
-*/
|
|
|
-static int equalkey (const TValue *k1, const Node *n2) {
|
|
|
- if (rawtt(k1) != keytt(n2)) /* not the same variants? */
|
|
|
+** A true 'deadok' means to accept dead keys as equal to their original
|
|
|
+** values, which can only happen if the original key was collectable.
|
|
|
+** All dead values are compared in the default case, by pointer
|
|
|
+** identity. (Note that dead long strings are also compared by
|
|
|
+** identity).
|
|
|
+*/
|
|
|
+static int equalkey (const TValue *k1, const Node *n2, int deadok) {
|
|
|
+ if ((rawtt(k1) != keytt(n2)) && /* not the same variants? */
|
|
|
+ !(deadok && keyisdead(n2) && iscollectable(k1)))
|
|
|
return 0; /* cannot be same key */
|
|
|
- switch (ttypetag(k1)) {
|
|
|
+ switch (keytt(n2)) {
|
|
|
case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE:
|
|
|
return 1;
|
|
|
case LUA_VNUMINT:
|
|
@@ -187,7 +193,7 @@ static int equalkey (const TValue *k1, const Node *n2) {
|
|
|
return pvalue(k1) == pvalueraw(keyval(n2));
|
|
|
case LUA_VLCF:
|
|
|
return fvalue(k1) == fvalueraw(keyval(n2));
|
|
|
- case LUA_VLNGSTR:
|
|
|
+ case ctb(LUA_VLNGSTR):
|
|
|
return luaS_eqlngstr(tsvalue(k1), keystrval(n2));
|
|
|
default:
|
|
|
return gcvalue(k1) == gcvalueraw(keyval(n2));
|
|
@@ -251,11 +257,12 @@ static unsigned int setlimittosize (Table *t) {
|
|
|
/*
|
|
|
** "Generic" get version. (Not that generic: not valid for integers,
|
|
|
** which may be in array part, nor for floats with integral values.)
|
|
|
+** See explanation about 'deadok' in function 'equalkey'.
|
|
|
*/
|
|
|
-static const TValue *getgeneric (Table *t, const TValue *key) {
|
|
|
+static const TValue *getgeneric (Table *t, const TValue *key, int deadok) {
|
|
|
Node *n = mainpositionTV(t, key);
|
|
|
for (;;) { /* check whether 'key' is somewhere in the chain */
|
|
|
- if (equalkey(key, n))
|
|
|
+ if (equalkey(key, n, deadok))
|
|
|
return gval(n); /* that's it */
|
|
|
else {
|
|
|
int nx = gnext(n);
|
|
@@ -292,7 +299,7 @@ static unsigned int findindex (lua_State *L, Table *t, TValue *key,
|
|
|
if (i - 1u < asize) /* is 'key' inside array part? */
|
|
|
return i; /* yes; that's the index */
|
|
|
else {
|
|
|
- const TValue *n = getgeneric(t, key);
|
|
|
+ const TValue *n = getgeneric(t, key, 1);
|
|
|
if (unlikely(isabstkey(n)))
|
|
|
luaG_runerror(L, "invalid key to 'next'"); /* key not found */
|
|
|
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) {
|
|
|
else { /* for long strings, use generic case */
|
|
|
TValue ko;
|
|
|
setsvalue(cast(lua_State *, NULL), &ko, key);
|
|
|
- return getgeneric(t, &ko);
|
|
|
+ return getgeneric(t, &ko, 0);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -750,7 +757,7 @@ const TValue *luaH_get (Table *t, const TValue *key) {
|
|
|
/* else... */
|
|
|
} /* FALLTHROUGH */
|
|
|
default:
|
|
|
- return getgeneric(t, key);
|
|
|
+ return getgeneric(t, key, 0);
|
|
|
}
|
|
|
}
|
|
|
|