/* ** hash for lua_Numbers ** ** for non-complex modes, never called with 'lua_Integer' value range (s.a. 0) * * Note: Linux x86(_64) gcc 4.x, -O2/O3 and no '-fno-strict-aliasing' will * optimize out essential stuff from here, unless 'union' is used. * There is no automatic way to sniff whether compiler is having strict * aliasing optimizations on (use '-DNO_STRICT_ALIASING' to enable the * potentially faster code path that expects they are not on). */ static Node *hashnum (const Table *t, const lua_Number v) { unsigned int i,sum; #ifdef NO_STRICT_ALIASING /* For compilers not using "strict aliasing" optimizations (or when compiling * with '-fno-strict-aliasing'). */ const unsigned int *a= cast(const unsigned int*, &v); sum= a[0]; for (i = 1; i < NUM_INTS; i++) sum += a[i]; #else /* * This code is "strict aliasing" safe (to be used with gcc 4.x -O2 or above, * if no '-fno-strict-aliasing' is specified). Otherwise you'll be screwed. * Casting via 'char*' or 'void*' should do the same, but doesn't. * * Seems gcc enables strict aliasing even if '--std=c99' is not used. * There is no predefined macro to detect, whether the compiler is doing * strict aliasing optimizations or not. Bohoo... --AKa 7-Apr-2009 */ union { lua_Number v; unsigned int a[NUM_INTS]; } u; lua_assert( sizeof(u)==sizeof(v) ); u.v= v; sum= u.a[0]; for (i = 1; i < NUM_INTS; i++) sum += u.a[i]; #endif return hashmod(t, sum); }
/* ** returns the 'main' position of an element in a table (that is, ** the index of its hash value). The key comes broken (tag in 'ktt' ** and value in 'vkl') so that we can call it on keys inserted into ** nodes. */ static Node *mainposition (const Table *t, int ktt, const Value *kvl) { switch (withvariant(ktt)) { case LUA_TNUMINT: return hashint(t, ivalueraw(*kvl)); case LUA_TNUMFLT: return hashmod(t, l_hashfloat(fltvalueraw(*kvl))); case LUA_TSHRSTR: return hashstr(t, tsvalueraw(*kvl)); case LUA_TLNGSTR: return hashpow2(t, luaS_hashlongstr(tsvalueraw(*kvl))); case LUA_TBOOLEAN: return hashboolean(t, bvalueraw(*kvl)); case LUA_TLIGHTUSERDATA: return hashpointer(t, pvalueraw(*kvl)); case LUA_TLCF: return hashpointer(t, fvalueraw(*kvl)); default: { GCObject *o; lua_assert(!ttisdeadkey(kvl)); o = gcvalueraw(*kvl); if (o->gchash == 0) return hashpointer(t, o); return hashint(t, withvariant(ktt) * o->gchash); } } }
/* ** hash for lv_Numbers */ static Node *hashnum (const Table *t, lv_Number n) { unsigned int a[numints]; int i; if (lvi_numeq(n, 0)) /* avoid problems with -0 */ return gnode(t, 0); memcpy(a, &n, sizeof(a)); for (i = 1; i < numints; i++) a[0] += a[i]; return hashmod(t, a[0]); }
/* ** hash for lua_Numbers */ static Node *hashnum (const Table *t, lua_Number n) { unsigned int a[numints]; int i; n += 1; /* normalize number (avoid -0) */ lua_assert(sizeof(a) <= sizeof(n)); memcpy(a, &n, sizeof(a)); for (i = 1; i < numints; i++) a[0] += a[i]; return hashmod(t, a[0]); }
/* ** hash for lua_Numbers */ static Node *hashnum (const Table *t, lua_Number n) { int i; luai_hashnum(i, n); if (i < 0) { i = -i; /* must be a positive value */ if (i < 0) i = 0; /* handle INT_MIN */ } return hashmod(t, i); }