summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabrice Bellard <fabrice@bellard.org>2025-03-19 12:33:54 +0100
committerFabrice Bellard <fabrice@bellard.org>2025-03-19 12:33:54 +0100
commit6d6893bfa3d383d4952b67954003800aba1f4be8 (patch)
treef1125ee057b2e61a0c530b7b0973cb602b7771f2
parent5a16c0c1eba084742ed328eff75b9e886e63d166 (diff)
downloadquickjs-6d6893bfa3d383d4952b67954003800aba1f4be8.tar.gz
quickjs-6d6893bfa3d383d4952b67954003800aba1f4be8.zip
fixed BigInt hashing - removed -fno-bigint in qjsc and JS_AddIntrinsicBigInt() (BigInt is now considered as a base object)
-rw-r--r--Makefile2
-rw-r--r--qjsc.c2
-rw-r--r--quickjs.c31
-rw-r--r--quickjs.h1
-rw-r--r--tests/test_builtin.js56
5 files changed, 63 insertions, 29 deletions
diff --git a/Makefile b/Makefile
index 9c983db..be3f614 100644
--- a/Makefile
+++ b/Makefile
@@ -371,7 +371,7 @@ endif
HELLO_SRCS=examples/hello.js
HELLO_OPTS=-fno-string-normalize -fno-map -fno-promise -fno-typedarray \
-fno-typedarray -fno-regexp -fno-json -fno-eval -fno-proxy \
- -fno-date -fno-module-loader -fno-bigint
+ -fno-date -fno-module-loader
hello.c: $(QJSC) $(HELLO_SRCS)
$(QJSC) -e $(HELLO_OPTS) -o $@ $(HELLO_SRCS)
diff --git a/qjsc.c b/qjsc.c
index 7a56a3b..de8ebd1 100644
--- a/qjsc.c
+++ b/qjsc.c
@@ -76,7 +76,6 @@ static const FeatureEntry feature_list[] = {
{ "promise", "Promise" },
#define FE_MODULE_LOADER 9
{ "module-loader", NULL },
- { "bigint", "BigInt" },
};
void namelist_add(namelist_t *lp, const char *name, const char *short_name,
@@ -359,7 +358,6 @@ void help(void)
{
int i;
printf("-flto use link time optimization\n");
- printf("-fbignum enable bignum extensions\n");
printf("-fno-[");
for(i = 0; i < countof(feature_list); i++) {
if (i != 0)
diff --git a/quickjs.c b/quickjs.c
index d664ded..161406e 100644
--- a/quickjs.c
+++ b/quickjs.c
@@ -2035,7 +2035,6 @@ JSContext *JS_NewContext(JSRuntime *rt)
JS_AddIntrinsicMapSet(ctx);
JS_AddIntrinsicTypedArrays(ctx);
JS_AddIntrinsicPromise(ctx);
- JS_AddIntrinsicBigInt(ctx);
return ctx;
}
@@ -3060,8 +3059,6 @@ static JSValue JS_AtomIsNumericIndex1(JSContext *ctx, JSAtom atom)
return JS_UNDEFINED;
}
}
- /* XXX: bignum: would be better to only accept integer to avoid
- relying on current floating point precision */
/* this is ECMA CanonicalNumericIndexString primitive */
num = JS_ToNumber(ctx, JS_MKPTR(JS_TAG_STRING, p));
if (JS_IsException(num))
@@ -46477,7 +46474,9 @@ static uint32_t map_hash_key(JSContext *ctx, JSValueConst key)
uint32_t h;
double d;
JSFloat64Union u;
-
+ JSBigInt *p;
+ JSBigIntBuf buf;
+
switch(tag) {
case JS_TAG_BOOL:
h = JS_VALUE_GET_INT(key);
@@ -46500,9 +46499,24 @@ static uint32_t map_hash_key(JSContext *ctx, JSValueConst key)
hash_float64:
u.d = d;
h = (u.u32[0] ^ u.u32[1]) * 3163;
- return h ^= JS_TAG_FLOAT64;
+ return h ^ JS_TAG_FLOAT64;
+ case JS_TAG_SHORT_BIG_INT:
+ p = js_bigint_set_short(&buf, key);
+ goto hash_bigint;
+ case JS_TAG_BIG_INT:
+ p = JS_VALUE_GET_PTR(key);
+ hash_bigint:
+ {
+ int i;
+ h = 1;
+ for(i = p->len - 1; i >= 0; i--) {
+ h = h * 263 + p->tab[i];
+ }
+ h *= 3163;
+ }
+ break;
default:
- h = 0; /* XXX: bignum support */
+ h = 0;
break;
}
h ^= tag;
@@ -50167,7 +50181,7 @@ static const JSCFunctionListEntry js_bigint_proto_funcs[] = {
JS_PROP_STRING_DEF("[Symbol.toStringTag]", "BigInt", JS_PROP_CONFIGURABLE ),
};
-void JS_AddIntrinsicBigInt(JSContext *ctx)
+static void JS_AddIntrinsicBigInt(JSContext *ctx)
{
JSValueConst obj1;
@@ -50454,6 +50468,9 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
JS_DefinePropertyValue(ctx, ctx->global_obj, JS_ATOM_globalThis,
JS_DupValue(ctx, ctx->global_obj),
JS_PROP_CONFIGURABLE | JS_PROP_WRITABLE);
+
+ /* BigInt */
+ JS_AddIntrinsicBigInt(ctx);
}
/* Typed Arrays */
diff --git a/quickjs.h b/quickjs.h
index c59446d..2463364 100644
--- a/quickjs.h
+++ b/quickjs.h
@@ -406,7 +406,6 @@ void JS_AddIntrinsicProxy(JSContext *ctx);
void JS_AddIntrinsicMapSet(JSContext *ctx);
void JS_AddIntrinsicTypedArrays(JSContext *ctx);
void JS_AddIntrinsicPromise(JSContext *ctx);
-void JS_AddIntrinsicBigInt(JSContext *ctx);
JSValue js_string_codePointRange(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv);
diff --git a/tests/test_builtin.js b/tests/test_builtin.js
index 15cd189..1c47f8f 100644
--- a/tests/test_builtin.js
+++ b/tests/test_builtin.js
@@ -714,29 +714,26 @@ function test_symbol()
assert(b.toString(), "Symbol(aaa)");
}
-function test_map()
+function test_map1(key_type, n)
{
- 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);
-
+ var a, i, tab, o, v;
a = new Map();
tab = [];
for(i = 0; i < n; i++) {
v = { };
- o = { id: i };
+ switch(key_type) {
+ case "small_bigint":
+ o = BigInt(i);
+ break;
+ case "bigint":
+ o = BigInt(i) + (1n << 128n);
+ break;
+ case "object":
+ o = { id: i };
+ break;
+ default:
+ assert(false);
+ }
tab[i] = [o, v];
a.set(o, v);
}
@@ -757,6 +754,29 @@ function test_map()
assert(a.size, 0);
}
+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);
+
+ test_map1("object", n);
+ test_map1("small_bigint", n);
+ test_map1("bigint", n);
+}
+
function test_weak_map()
{
var a, i, n, tab, o, v, n2;