In the table that hashes constants, use a light userdata as keys

to integer values to avoid collisions with floats with the same
numerical value
This commit is contained in:
Roberto Ierusalimschy 2013-06-20 14:37:31 -03:00
parent d6f5fb2d2c
commit f45177f2d3
1 changed files with 9 additions and 9 deletions

18
lcode.c
View File

@ -1,5 +1,5 @@
/* /*
** $Id: lcode.c,v 2.68 2013/05/02 12:37:24 roberto Exp roberto $ ** $Id: lcode.c,v 2.69 2013/05/06 17:22:16 roberto Exp roberto $
** Code generator for Lua ** Code generator for Lua
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -333,9 +333,12 @@ int luaK_stringK (FuncState *fs, TString *s) {
int luaK_intK (FuncState *fs, lua_Integer n) { int luaK_intK (FuncState *fs, lua_Integer n) {
TValue o; TValue k, o;
/* use userdata as key to avoid collision with float with same value;
conversion to 'void*' used only for hash, no "precision" problems */
setpvalue(&k, cast(void*, cast(size_t, n)));
setivalue(&o, n); setivalue(&o, n);
return addk(fs, &o, &o); return addk(fs, &k, &o);
} }
@ -344,17 +347,14 @@ static int luaK_numberK (FuncState *fs, lua_Number r) {
lua_State *L = fs->ls->L; lua_State *L = fs->ls->L;
TValue o; TValue o;
setnvalue(&o, r); setnvalue(&o, r);
if (r == 0 || luai_numisnan(NULL, r)) { /* handle -0 and NaN */ if (r != 0 && !luai_numisnan(NULL, r)) /* avoid -0 and NaN */
n = addk(fs, &o, &o); /* regular case */
else { /* handle -0 and NaN */
/* use raw representation as key to avoid numeric problems */ /* use raw representation as key to avoid numeric problems */
setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r))); setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r)));
n = addk(fs, L->top - 1, &o); n = addk(fs, L->top - 1, &o);
L->top--; L->top--;
} }
else {
TValue k;
setnvalue(&k, r + 0.5); /* ???? (avoid some collisions with ints) */
n = addk(fs, &k, &o); /* regular case */
}
return n; return n;
} }