commit 3d44f4198322316716bd38aabc1268aa01ccb25c
parent 0e2ef9e944cf01ae7aaf2595bef468d7ac1bd994
Author: Charlie Gordon <github@chqrlie.org>
Date: Thu, 22 Feb 2024 19:31:57 +0100
Fix Map hash bug
- `map_hash_key` must generate the same key for JS_INT and JS_FLOAT64
with the same value
- add test cases in tests/test_builtin.js
Diffstat:
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/quickjs/quickjs.c b/quickjs/quickjs.c
@@ -47181,7 +47181,7 @@ static uint32_t map_hash_key(JSContext *ctx, JSValueConst key)
h = (uintptr_t)JS_VALUE_GET_PTR(key) * 3163;
break;
case JS_TAG_INT:
- d = JS_VALUE_GET_INT(key) * 3163;
+ d = JS_VALUE_GET_INT(key);
goto hash_float64;
case JS_TAG_FLOAT64:
d = JS_VALUE_GET_FLOAT64(key);
@@ -47191,7 +47191,7 @@ static uint32_t map_hash_key(JSContext *ctx, JSValueConst key)
hash_float64:
u.d = d;
h = (u.u32[0] ^ u.u32[1]) * 3163;
- break;
+ return h ^= JS_TAG_FLOAT64;
default:
h = 0; /* XXX: bignum support */
break;
diff --git a/quickjs/tests/test_builtin.js b/quickjs/tests/test_builtin.js
@@ -671,6 +671,20 @@ function test_map()
{
var a, i, n, tab, o, v;
n = 1000;
+
+ a = new Map();
+ for (var i = 0; i < n; i++) {
+ a.set(i, i);
+ }
+ a.set(-2147483648, 1);
+ assert(a.get(-2147483648), 1);
+ assert(a.get(-2147483647 - 1), 1);
+ assert(a.get(-2147483647.5 - 0.5), 1);
+
+ a.set(1n, 1n);
+ assert(a.get(1n), 1n);
+ assert(a.get(2n**1000n - (2n**1000n - 1n)), 1n);
+
a = new Map();
tab = [];
for(i = 0; i < n; i++) {