]> git.kaiwu.me - quickjs.git/commitdiff
fixed BigInt hashing - removed -fno-bigint in qjsc and JS_AddIntrinsicBigInt() (BigIn...
authorFabrice Bellard <fabrice@bellard.org>
Wed, 19 Mar 2025 11:33:54 +0000 (12:33 +0100)
committerFabrice Bellard <fabrice@bellard.org>
Wed, 19 Mar 2025 11:33:54 +0000 (12:33 +0100)
Makefile
qjsc.c
quickjs.c
quickjs.h
tests/test_builtin.js

index 9c983db801bd2944809ca7ab6b620236e08c9e7d..be3f614f84686636235502164b4ea91f594c5a56 100644 (file)
--- 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 7a56a3b0c8432310519279c7ccb24a0166d0956c..de8ebd191b1101928d99e98502264eb7aa891fce 100644 (file)
--- 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)
index d664dedb3f828b8a640d46c98cf33bc803754316..161406e45801557df956c22ad935ac1c3b999d2e 100644 (file)
--- 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 */
index c59446d729cc9dd83347403f1fa2379157fa6498..2463364a26e71ee805c8ea7ca4c25d8976f781a9 100644 (file)
--- 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);
index 15cd18943b5437a2732451b24e59db577fd0b5df..1c47f8fbf8a877103fe10f564485e838633841ef 100644 (file)
@@ -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;