From 7b64da232519603ec07a28335e269386791df06f Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 10 Nov 2023 21:01:09 +0100 Subject: [PATCH] Improve BigInt hashing (#38) Fixes: https://github.com/quickjs-ng/quickjs/issues/35 --- quickjs.c | 7 ++++++- tests/test_bigint.js | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/quickjs.c b/quickjs.c index ad23f9c..85f2648 100644 --- a/quickjs.c +++ b/quickjs.c @@ -43301,6 +43301,7 @@ static uint32_t map_hash_key(JSContext *ctx, JSValueConst key) uint32_t h; double d; JSFloat64Union u; + bf_t *a; switch(tag) { case JS_TAG_BOOL: @@ -43316,6 +43317,10 @@ static uint32_t map_hash_key(JSContext *ctx, JSValueConst key) case JS_TAG_INT: d = JS_VALUE_GET_INT(key) * 3163; goto hash_float64; + case JS_TAG_BIG_INT: + a = JS_GetBigInt(key); + h = hash_string8((void *)a->tab, a->len * sizeof(*a->tab), 0); + break; case JS_TAG_FLOAT64: d = JS_VALUE_GET_FLOAT64(key); /* normalize the NaN */ @@ -43326,7 +43331,7 @@ static uint32_t map_hash_key(JSContext *ctx, JSValueConst key) h = (u.u32[0] ^ u.u32[1]) * 3163; break; default: - h = 0; /* XXX: bigint support */ + h = 0; break; } h ^= tag; diff --git a/tests/test_bigint.js b/tests/test_bigint.js index 4caa9a2..08858a3 100644 --- a/tests/test_bigint.js +++ b/tests/test_bigint.js @@ -110,5 +110,30 @@ function test_bigint2() assertThrows(SyntaxError, () => { BigInt(" 123 r") } ); } +function test_bigint_map() +{ + var m = new Map(); + assert(m.size, 0); + + for (let i = 0n; i < 1337n; i++) { + const r = m.set(i, i.toString()); + assert(r, m); + } + assert(m.size, 1337); + + for (let i = 0n; i < 1337n; i++) { + const r = m.get(i); + assert(r, i.toString()); + } + assert(m.get(1337n), undefined); + assert(m.size, 1337); + + for (let i = 0n; i < 1337n; i++) + assert(m.delete(i)); + assert(!m.delete(1337n)); + assert(m.size, 0); +} + test_bigint1(); test_bigint2(); +test_bigint_map();