| 1280 | } |
| 1281 | |
| 1282 | txU4 fxSumEntry(txMachine* the, txSlot* slot) |
| 1283 | { |
| 1284 | txU1 kind = slot->kind; |
| 1285 | txU8 sum; |
| 1286 | |
| 1287 | if ((XS_STRING_KIND == kind) || (XS_STRING_X_KIND == kind)) { |
| 1288 | // Dan Bernstein: http://www.cse.yorku.ca/~oz/hash.html |
| 1289 | txU1 *string = (txU1*)slot->value.string; |
| 1290 | sum = 5381; |
| 1291 | while ((kind = c_read8(string++))) { |
| 1292 | sum = ((sum << 5) + sum) + kind; |
| 1293 | } |
| 1294 | } |
| 1295 | else { |
| 1296 | if (XS_REFERENCE_KIND == kind) { |
| 1297 | sum = (txU8)(((uintptr_t)slot->value.reference) / sizeof(txSlot)); |
| 1298 | } |
| 1299 | else if (XS_INTEGER_KIND == kind) { |
| 1300 | fxToNumber(the, slot); |
| 1301 | sum = *((txU8*)&slot->value.number); |
| 1302 | } |
| 1303 | else if (XS_NUMBER_KIND == kind) { |
| 1304 | if (slot->value.number == 0) { |
| 1305 | sum = slot->value.number = 0; |
| 1306 | } |
| 1307 | else { |
| 1308 | if (c_isnan(slot->value.number)) { |
| 1309 | #if mxCanonicalNaN |
| 1310 | slot->value.number = *gxCanonicalNaN64; |
| 1311 | #else |
| 1312 | slot->value.number = C_NAN; |
| 1313 | #endif |
| 1314 | } |
| 1315 | sum = *((txU8*)&slot->value.number); |
| 1316 | } |
| 1317 | } |
| 1318 | else if ((XS_BIGINT_KIND == kind) || (XS_BIGINT_X_KIND == kind)) { |
| 1319 | sum = gxTypeBigInt.toBigUint64(the, slot); |
| 1320 | } |
| 1321 | else if (XS_SYMBOL_KIND == kind) { |
| 1322 | sum = slot->value.symbol; |
| 1323 | } |
| 1324 | else if (XS_BOOLEAN_KIND == kind) { |
| 1325 | sum = slot->value.boolean; |
| 1326 | } |
| 1327 | else { |
| 1328 | sum = 0; |
| 1329 | } |
| 1330 | // Thomas Wang: http://web.archive.org/web/20071223173210/http://www.concentric.net/~Ttwang/tech/inthash.htm |
| 1331 | sum = (~sum) + (sum << 18); // sum = (sum << 18) - sum - 1; |
| 1332 | sum = sum ^ (sum >> 31); |
| 1333 | sum = sum * 21; // sum = (sum + (sum << 2)) + (sum << 4); |
| 1334 | sum = sum ^ (sum >> 11); |
| 1335 | sum = sum + (sum << 6); |
| 1336 | sum = sum ^ (sum >> 22); |
| 1337 | } |
| 1338 | sum &= 0xFFFFFFFF; |
| 1339 | return (txU4)sum; |
no test coverage detected