From 516564e585f36fc3a1764c672615dc5f416832b8 Mon Sep 17 00:00:00 2001
From: davidnolen <david.nolen@gmail.com>
Date: Mon, 25 Sep 2023 14:57:24 -0400
Subject: [PATCH 01/10] * split number? into js-number? and bigint? checks *
 emit BigInt as JS * switch to js/Number.isNaN instead of js/isNaN

---
 src/main/cljs/cljs/core.cljs        | 13 +++++++------
 src/main/clojure/cljs/compiler.cljc |  3 ++-
 src/main/clojure/cljs/core.cljc     |  5 ++++-
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/src/main/cljs/cljs/core.cljs b/src/main/cljs/cljs/core.cljs
index 620bc8abc..29e793e9b 100644
--- a/src/main/cljs/cljs/core.cljs
+++ b/src/main/cljs/cljs/core.cljs
@@ -251,9 +251,10 @@
     (instance? js/Array x)))
 
 (defn ^boolean number?
-  "Returns true if x is a JavaScript number."
+  "Returns true if x is a JavaScript Number or BigInt"
   [x]
-  (cljs.core/number? x))
+  (or (cljs.core/js-number? x)
+      (cljs.core/bigint? x)))
 
 (defn not
   "Returns true if x is logical false, false otherwise."
@@ -2313,7 +2314,7 @@ reduces them without incurring seq initialization"
   "Returns true if n is a JavaScript number with no decimal part."
   [n]
   (and (number? n)
-       (not ^boolean (js/isNaN n))
+       (not ^boolean (js/Number.isNaN n))
        (not (identical? n js/Infinity))
        (== (js/parseFloat n) (js/parseInt n 10))))
 
@@ -10509,10 +10510,10 @@ reduces them without incurring seq initialization"
         (number? obj)
         (-write writer
           (cond
-            ^boolean (js/isNaN obj) "##NaN"
+            ^boolean (js/Number.isNaN obj) "##NaN"
             (identical? obj js/Number.POSITIVE_INFINITY) "##Inf"
             (identical? obj js/Number.NEGATIVE_INFINITY) "##-Inf"
-            :else (str obj)))
+            :else (str obj (when (bigint? obj) "N"))))
 
         (object? obj)
         (do
@@ -12211,7 +12212,7 @@ reduces them without incurring seq initialization"
 (defn ^boolean NaN?
   "Returns true if num is NaN, else false"
   [val]
-  (js/isNaN val))
+  (js/Number.isNaN val))
 
 (defn ^:private parsing-err
   "Construct message for parsing for non-string parsing error"
diff --git a/src/main/clojure/cljs/compiler.cljc b/src/main/clojure/cljs/compiler.cljc
index b96c09b36..2ef7c8c76 100644
--- a/src/main/clojure/cljs/compiler.cljc
+++ b/src/main/clojure/cljs/compiler.cljc
@@ -345,7 +345,8 @@
    (defmethod emit-constant* BigDecimal [x] (emits (.doubleValue ^BigDecimal x))))
 
 #?(:clj
-   (defmethod emit-constant* clojure.lang.BigInt [x] (emits (.doubleValue ^clojure.lang.BigInt x))))
+   (defmethod emit-constant* clojure.lang.BigInt [x]
+     (emits "(" (.toString ^clojure.lang.BigInt x) "n)")))
 
 (defmethod emit-constant* #?(:clj String :cljs js/String) [x]
   (emits (wrap-in-double-quotes (escape-string x))))
diff --git a/src/main/clojure/cljs/core.cljc b/src/main/clojure/cljs/core.cljc
index 72f465427..548cec089 100644
--- a/src/main/clojure/cljs/core.cljc
+++ b/src/main/clojure/cljs/core.cljc
@@ -1007,9 +1007,12 @@
                `(let [c# ~c x# ~x]
                   (~'js* "(~{} instanceof ~{})" x# c#)))))
 
-(core/defmacro number? [x]
+(core/defmacro js-number? [x]
   (bool-expr (core/list 'js* "typeof ~{} === 'number'" x)))
 
+(core/defmacro bigint? [x]
+  (bool-expr (core/list 'js* "typeof ~{} === 'bigint'" x)))
+
 (core/defmacro symbol? [x]
   (bool-expr `(instance? Symbol ~x)))
 

From 30d6254fd9a48f67d44419f250d00b3048df5b4c Mon Sep 17 00:00:00 2001
From: davidnolen <david.nolen@gmail.com>
Date: Mon, 25 Sep 2023 15:06:12 -0400
Subject: [PATCH 02/10] * bump :lang-in/out :ecmascript-2020 for BigInt support

---
 build.edn | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/build.edn b/build.edn
index c54f2ec13..a45ab4226 100644
--- a/build.edn
+++ b/build.edn
@@ -9,8 +9,8 @@
  :npm-deps {:lodash "4.17.4"}
  :closure-warnings {:non-standard-jsdoc :off :global-this :off}
  :install-deps true
- :language-in :es6
- :language-out :es5
+ :language-in :ecmascript-2020
+ :language-out :ecmascript-2020
  :foreign-libs [{:file "src/test/cljs/calculator_global.js"
                  :provides ["calculator"]
                  :global-exports {calculator Calculator}}
@@ -22,4 +22,4 @@
                  :provides ["calculator"]}
                 {:file "src/test/cljs/es6_default_hello.js"
                  :provides ["es6_default_hello"]
-                 :module-type :es6}]}
\ No newline at end of file
+                 :module-type :es6}]}

From 7e205323afbcc72fcd8ab63abc86349789bb1711 Mon Sep 17 00:00:00 2001
From: davidnolen <david.nolen@gmail.com>
Date: Mon, 25 Sep 2023 15:16:14 -0400
Subject: [PATCH 03/10] * need to bump resources.edn as well

---
 resources/test.edn | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/resources/test.edn b/resources/test.edn
index a8f258139..243058fac 100644
--- a/resources/test.edn
+++ b/resources/test.edn
@@ -9,7 +9,8 @@
  :npm-deps {:lodash "4.17.4"}
  :closure-warnings {:non-standard-jsdoc :off :global-this :off}
  :install-deps true
- :language-out :es5
+ :language-in :ecmascript-2020
+ :language-out :ecmascript-2020
  :foreign-libs
  [{:file "src/test/cljs/calculator_global.js"
    :provides ["calculator"]

From e6f5d04102d83b249ef2a99bc9c7223d532d3cc2 Mon Sep 17 00:00:00 2001
From: davidnolen <david.nolen@gmail.com>
Date: Mon, 25 Sep 2023 16:07:21 -0400
Subject: [PATCH 04/10] * comment out now bad assertion

---
 src/test/cljs/cljs/core_test.cljs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/test/cljs/cljs/core_test.cljs b/src/test/cljs/cljs/core_test.cljs
index 812d3a74a..95a894425 100644
--- a/src/test/cljs/cljs/core_test.cljs
+++ b/src/test/cljs/cljs/core_test.cljs
@@ -1040,7 +1040,7 @@
 
 (deftest test-807
   (testing "Testing CLJS-807, big int, float, big dec literals"
-    (is (= -1 -1N))
+    ;(is (= -1 -1N)) ;; invalid, -1N is now JS BigInt
     (is (= 9.007199254740996E15 9007199254740995N))
     (is (= 1.5 1.5M))
     (is (= 4.9E-324 5E-324M))))

From 782814938df7dc8be46bad422909be4425980390 Mon Sep 17 00:00:00 2001
From: davidnolen <david.nolen@gmail.com>
Date: Mon, 25 Sep 2023 17:16:37 -0400
Subject: [PATCH 05/10] * comment out other bad assertion

---
 src/test/cljs/cljs/core_test.cljs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/test/cljs/cljs/core_test.cljs b/src/test/cljs/cljs/core_test.cljs
index 95a894425..471a42943 100644
--- a/src/test/cljs/cljs/core_test.cljs
+++ b/src/test/cljs/cljs/core_test.cljs
@@ -1041,7 +1041,7 @@
 (deftest test-807
   (testing "Testing CLJS-807, big int, float, big dec literals"
     ;(is (= -1 -1N)) ;; invalid, -1N is now JS BigInt
-    (is (= 9.007199254740996E15 9007199254740995N))
+    ;(is (= 9.007199254740996E15 9007199254740995N)) ;; invalid, we emit JS BigInt now
     (is (= 1.5 1.5M))
     (is (= 4.9E-324 5E-324M))))
 

From 5477284edf6456e7254d139255d074bb2d087a75 Mon Sep 17 00:00:00 2001
From: davidnolen <david.nolen@gmail.com>
Date: Mon, 25 Sep 2023 20:39:50 -0400
Subject: [PATCH 06/10] * if Long beyond bounds of JS integral values, emit
 BigInt

---
 src/main/clojure/cljs/compiler.cljc | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/main/clojure/cljs/compiler.cljc b/src/main/clojure/cljs/compiler.cljc
index 2ef7c8c76..579fba962 100644
--- a/src/main/clojure/cljs/compiler.cljc
+++ b/src/main/clojure/cljs/compiler.cljc
@@ -313,7 +313,11 @@
 (defmethod emit-constant* nil [x] (emits "null"))
 
 #?(:clj
-   (defmethod emit-constant* Long [x] (emits "(" x ")")))
+   (defmethod emit-constant* Long [x]
+     (if (or (> x 9007199254740991)
+             (< x -9007199254740991))
+       (emits "(" x "n)")
+       (emits "(" x ")"))))
 
 #?(:clj
    (defmethod emit-constant* Integer [x] (emits x))) ; reader puts Integers in metadata

From 91e8ee4b7bfffe865c238c20ea62a846ba3a9396 Mon Sep 17 00:00:00 2001
From: davidnolen <david.nolen@gmail.com>
Date: Mon, 25 Sep 2023 21:43:47 -0400
Subject: [PATCH 07/10] * update hash to handle bigint * make number and bigint
 -equiv * handle bigint & number in PAM * minor refactor of private PAM lookup
 helper fn names

---
 src/main/cljs/cljs/core.cljs | 53 +++++++++++++++++++++++++++++-------
 1 file changed, 43 insertions(+), 10 deletions(-)

diff --git a/src/main/cljs/cljs/core.cljs b/src/main/cljs/cljs/core.cljs
index 29e793e9b..ce90467b1 100644
--- a/src/main/cljs/cljs/core.cljs
+++ b/src/main/cljs/cljs/core.cljs
@@ -1012,6 +1012,10 @@
         h
         (add-to-string-hash-cache k)))))
 
+(defn- safe-value? [n]
+  (and (<= n js/Number.MAX_SAFE_INTEGER)
+       (>= n js/Number.MIN_SAFE_INTEGER)))
+
 (defn hash
   "Returns the hash code of its argument. Note this is the hash code
    consistent with =."
@@ -1020,6 +1024,11 @@
     (implements? IHash o)
     (bit-xor (-hash o) 0)
 
+    (cljs.core/bigint? o)
+    (if (safe-value? o)
+      (hash (js/Number. o))
+      (hash-string (.toString o 32)))
+
     (number? o)
     (if ^boolean (js/isFinite o)
       (js-mod (Math/floor o) 2147483647)
@@ -1434,7 +1443,17 @@
 
 (extend-type number
   IEquiv
-  (-equiv [x o] (identical? x o)))
+  (-equiv [x o]
+    (if (cljs.core/bigint? o)
+      (cljs.core/coercive-= x o)
+      (identical? x o))))
+
+(extend-type bigint
+  IEquiv
+  (-equiv [x o]
+    (if (cljs.core/js-number? o)
+      (cljs.core/coercive-= x o)
+      (identical? x o))))
 
 (declare with-meta)
 
@@ -6687,7 +6706,7 @@ reduces them without incurring seq initialization"
 
 ;;; PersistentArrayMap
 
-(defn- array-index-of-nil? [arr]
+(defn- array-index-of-nil [arr]
   (let [len (alength arr)]
     (loop [i 0]
       (cond
@@ -6695,7 +6714,7 @@ reduces them without incurring seq initialization"
         (nil? (aget arr i)) i
         :else (recur (+ i 2))))))
 
-(defn- array-index-of-keyword? [arr k]
+(defn- array-index-of-keyword [arr k]
   (let [len  (alength arr)
         kstr (.-fqn k)]
     (loop [i 0]
@@ -6705,7 +6724,7 @@ reduces them without incurring seq initialization"
              (identical? kstr (.-fqn (aget arr i)))) i
         :else (recur (+ i 2))))))
 
-(defn- array-index-of-symbol? [arr k]
+(defn- array-index-of-symbol [arr k]
   (let [len  (alength arr)
         kstr (.-str k)]
     (loop [i 0]
@@ -6715,6 +6734,17 @@ reduces them without incurring seq initialization"
              (identical? kstr (.-str (aget arr i)))) i
         :else (recur (+ i 2))))))
 
+(defn- equal-number? [x y]
+  (and (number? x) (number? y) (cljs.core/coercive-= x y)))
+
+(defn- array-index-of-number [arr k]
+  (let [len (alength arr)]
+    (loop [i 0]
+      (cond
+        (<= len i) -1
+        (equal-number? k (aget arr i)) i
+        :else (recur (+ i 2))))))
+
 (defn- array-index-of-identical? [arr k]
   (let [len (alength arr)]
     (loop [i 0]
@@ -6723,7 +6753,7 @@ reduces them without incurring seq initialization"
         (identical? k (aget arr i)) i
         :else (recur (+ i 2))))))
 
-(defn- array-index-of-equiv? [arr k]
+(defn- array-index-of-equiv [arr k]
   (let [len (alength arr)]
     (loop [i 0]
       (cond
@@ -6733,17 +6763,20 @@ reduces them without incurring seq initialization"
 
 (defn array-index-of [arr k]
   (cond
-    (keyword? k) (array-index-of-keyword? arr k)
+    (keyword? k) (array-index-of-keyword arr k)
 
-    (or (string? k) (number? k))
+    (string? k)
     (array-index-of-identical? arr k)
 
-    (symbol? k) (array-index-of-symbol? arr k)
+    (number? k)
+    (array-index-of-number arr k)
+
+    (symbol? k) (array-index-of-symbol arr k)
 
     (nil? k)
-    (array-index-of-nil? arr)
+    (array-index-of-nil arr)
 
-    :else (array-index-of-equiv? arr k)))
+    :else (array-index-of-equiv arr k)))
 
 (defn- array-map-index-of [m k]
   (array-index-of (.-arr m) k))

From 6443339015fefb9597a36f5ac21566d659cafc6f Mon Sep 17 00:00:00 2001
From: davidnolen <david.nolen@gmail.com>
Date: Tue, 26 Sep 2023 09:56:42 -0400
Subject: [PATCH 08/10] * simple test cases and comments about state of things

---
 src/test/cljs/cljs/bigint_test.cljs | 40 +++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)
 create mode 100644 src/test/cljs/cljs/bigint_test.cljs

diff --git a/src/test/cljs/cljs/bigint_test.cljs b/src/test/cljs/cljs/bigint_test.cljs
new file mode 100644
index 000000000..dd5ad978f
--- /dev/null
+++ b/src/test/cljs/cljs/bigint_test.cljs
@@ -0,0 +1,40 @@
+;; Copyright (c) Rich Hickey. All rights reserved.
+;; The use and distribution terms for this software are covered by the
+;; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
+;; which can be found in the file epl-v10.html at the root of this distribution.
+;; By using this software in any fashion, you are agreeing to be bound by
+;; the terms of this license.
+;; You must not remove this notice, or any other, from this software.
+
+(ns cljs.bigint-test
+  (:require [cljs.test :refer-macros [deftest is testing]]))
+
+(deftest test-bigint
+  (testing "BigInt Basics"
+    (is (bigint? 1N))
+    (is (bigint? 9007199254740992))
+    (is (bigint? -9007199254740992)))
+  (testing "BigInt & Number equality"
+    ;; the below is a bit backwards from Clojure
+    ;; i.e. (= 0.5 1/2) ; false
+    ;; but  (== 0.5 1/2) ; true
+    (is (= 1 1N))
+    (is (= 1N 1))
+    (is (= 1 1N 1))
+    (is (not (== 1 1N)))
+    (is (not (== 1N 1)))
+    (is (not (== 1 1N 1))))
+  (testing "BigInt Hashing"
+    (is (= (hash 1N) (hash 1)))
+    (is (= (hash 9007199254740992) (hash 9007199254740992)))
+    (is (= (hash -9007199254740992) (hash -9007199254740992))))
+  (testing "BigInt as HashMap keys"
+    (let [m {1N 2}]
+      (is (= 2 (get m 1N)))
+      (is (= 2 (get m 1))))))
+
+(comment
+
+  (cljs.test/run-tests)
+
+  )

From d9c2b52985e459825f18e6ef72a88c208af4482f Mon Sep 17 00:00:00 2001
From: davidnolen <david.nolen@gmail.com>
Date: Tue, 26 Sep 2023 18:49:51 -0400
Subject: [PATCH 09/10] * create Integer type so the you can pass 1N into
 cljs.core fns w/o blowing up * Integer implements @@toPrimitive so that math
 operations work * more tests

---
 src/main/cljs/cljs/core.cljs        | 124 +++++++++++++++++++---------
 src/main/clojure/cljs/compiler.cljc |  10 ++-
 src/main/clojure/cljs/core.cljc     |   2 +-
 src/test/cljs/cljs/bigint_test.cljs |  19 +++--
 4 files changed, 106 insertions(+), 49 deletions(-)

diff --git a/src/main/cljs/cljs/core.cljs b/src/main/cljs/cljs/core.cljs
index ce90467b1..f5fb8aa93 100644
--- a/src/main/cljs/cljs/core.cljs
+++ b/src/main/cljs/cljs/core.cljs
@@ -250,11 +250,20 @@
     (.isArray js/Array x)
     (instance? js/Array x)))
 
+(declare Integer)
+
 (defn ^boolean number?
   "Returns true if x is a JavaScript Number or BigInt"
   [x]
   (or (cljs.core/js-number? x)
-      (cljs.core/bigint? x)))
+      (cljs.core/bigint? x)
+      (instance? Integer x)))
+
+(defn ^boolean bigint?
+  "Returns true if x is a JavaScript Number or BigInt"
+  [x]
+  (or (cljs.core/bigint? x)
+      (instance? Integer x)))
 
 (defn not
   "Returns true if x is logical false, false otherwise."
@@ -342,8 +351,12 @@
 
 (if (and (exists? js/Symbol)
          (identical? (goog/typeOf js/Symbol) "function"))
-  (def ITER_SYMBOL (.-iterator js/Symbol))
-  (def ITER_SYMBOL "@@iterator"))
+  (do
+    (def ITER_SYMBOL (.-iterator js/Symbol))
+    (def TO_PRIM_SYMBOL (.-toPrimitive js/Symbol)))
+  (do
+    (def ITER_SYMBOL "@@iterator")
+    (def TO_PRIM_SYMBOL "@@toPrimitive")))
 
 (def ^{:jsdoc ["@enum {string}"]}
   CHAR_MAP
@@ -1016,46 +1029,38 @@
   (and (<= n js/Number.MAX_SAFE_INTEGER)
        (>= n js/Number.MIN_SAFE_INTEGER)))
 
+(declare hash)
+
+(defn hash-bigint [n]
+  (if (safe-value? n)
+    (hash (js/Number. n))
+    (hash-string (.toString n 32))))
+
+(defn hash-number [n]
+  (if ^boolean (js/isFinite n)
+    (js-mod (Math/floor n) 2147483647)
+    (case n
+      ##Inf 2146435072
+      ##-Inf -1048576
+      2146959360)))
+
 (defn hash
   "Returns the hash code of its argument. Note this is the hash code
    consistent with =."
   [o]
   (cond
-    (implements? IHash o)
-    (bit-xor (-hash o) 0)
-
-    (cljs.core/bigint? o)
-    (if (safe-value? o)
-      (hash (js/Number. o))
-      (hash-string (.toString o 32)))
-
-    (number? o)
-    (if ^boolean (js/isFinite o)
-      (js-mod (Math/floor o) 2147483647)
-      (case o
-        ##Inf
-        2146435072
-        ##-Inf
-        -1048576
-        2146959360))
-
+    (implements? IHash o) (bit-xor (-hash o) 0)
+    (bigint? o) (hash-bigint o)
+    (number? o) (hash-number o)
     ;; note: mirrors Clojure's behavior on the JVM, where the hashCode is
     ;; 1231 for true and 1237 for false
     ;; http://docs.oracle.com/javase/7/docs/api/java/lang/Boolean.html#hashCode%28%29
     (true? o) 1231
-
     (false? o) 1237
-
-    (string? o)
-    (m3-hash-int (hash-string o))
-
-    (instance? js/Date o)
-    (bit-xor (.valueOf o) 0)
-
+    (string? o) (m3-hash-int (hash-string o))
+    (instance? js/Date o) (bit-xor (.valueOf o) 0)
     (nil? o) 0
-
-    :else
-    (bit-xor (-hash o) 0)))
+    :else (bit-xor (-hash o) 0)))
 
 (defn hash-combine [seed hash]
   ; a la boost
@@ -1094,6 +1099,45 @@
 
 (declare get)
 
+;; wrapper type to simplify bigint integration
+;; Integer has two fields, if number is null then beyond the range of
+;; JS safe integral values. bigint is set for comparisons.
+(deftype Integer [number bigint ^:mutable __hash]
+  Object
+  (toString [_]
+    (.toString bigint))
+  (equiv [this other] (-equiv this other))
+
+  IEquiv
+  (-equiv [_ other]
+    (cond
+      (instance? Integer other) (if (nil? number)
+                                  (== bigint (.-bigint other))
+                                  (== number (.-number other)))
+      (js-number? other) (== number other)
+      (bigint? other) (== bigint other)
+      :else false))
+
+  IHash
+  (-hash [_]
+    (if (nil? __hash)
+      (if (nil? bigint)
+        (set! __hash (hash-number number))
+        (set! __hash (hash-bigint bigint))))
+    __hash)
+
+  IPrintWithWriter
+  (-pr-writer [_ writer _]
+    (-write writer (or number bigint))
+    (-write writer "N")))
+
+(unchecked-set (.-prototype Integer) TO_PRIM_SYMBOL
+  (fn [hint]
+    (this-as this
+      (if (nil? (.-number this))
+        (.-bigint this)
+        (.-number this)))))
+
 (deftype Symbol [ns name str ^:mutable _hash _meta]
   Object
   (toString [_] str)
@@ -1444,16 +1488,18 @@
 (extend-type number
   IEquiv
   (-equiv [x o]
-    (if (cljs.core/bigint? o)
-      (cljs.core/coercive-= x o)
-      (identical? x o))))
+    (cond
+      (bigint? o) (coercive-= x o)
+      (instance? Integer o) (-equiv o x)
+      :else (identical? x o))))
 
 (extend-type bigint
   IEquiv
   (-equiv [x o]
-    (if (cljs.core/js-number? o)
-      (cljs.core/coercive-= x o)
-      (identical? x o))))
+    (cond
+      (js-number? o) (coercive-= x o)
+      (instance? Integer o) (-equiv o x)
+      :else (identical? x o))))
 
 (declare with-meta)
 
@@ -6735,7 +6781,7 @@ reduces them without incurring seq initialization"
         :else (recur (+ i 2))))))
 
 (defn- equal-number? [x y]
-  (and (number? x) (number? y) (cljs.core/coercive-= x y)))
+  (and (number? x) (number? y) (-equiv x y)))
 
 (defn- array-index-of-number [arr k]
   (let [len (alength arr)]
diff --git a/src/main/clojure/cljs/compiler.cljc b/src/main/clojure/cljs/compiler.cljc
index 579fba962..97e95c9a0 100644
--- a/src/main/clojure/cljs/compiler.cljc
+++ b/src/main/clojure/cljs/compiler.cljc
@@ -316,7 +316,7 @@
    (defmethod emit-constant* Long [x]
      (if (or (> x 9007199254740991)
              (< x -9007199254740991))
-       (emits "(" x "n)")
+       (emits "new cljs.core.Integer(null," x "n," (hash x) ")")
        (emits "(" x ")"))))
 
 #?(:clj
@@ -350,7 +350,13 @@
 
 #?(:clj
    (defmethod emit-constant* clojure.lang.BigInt [x]
-     (emits "(" (.toString ^clojure.lang.BigInt x) "n)")))
+     (if (or (> x 9007199254740991)
+             (< x -9007199254740991))
+       ;; not we don't set hash code at compile time because this is difficult to replicate
+       (emits "new cljs.core.Integer(null, " (.toString ^clojure.lang.BigInt x) "n, null)")
+       (emits "new cljs.core.Integer("
+         (.toString ^clojure.lang.BigInt x) ", " (.toString ^clojure.lang.BigInt x)
+         "n,  null)"))))
 
 (defmethod emit-constant* #?(:clj String :cljs js/String) [x]
   (emits (wrap-in-double-quotes (escape-string x))))
diff --git a/src/main/clojure/cljs/core.cljc b/src/main/clojure/cljs/core.cljc
index 548cec089..d7c3b07d2 100644
--- a/src/main/clojure/cljs/core.cljc
+++ b/src/main/clojure/cljs/core.cljc
@@ -1162,7 +1162,7 @@
 
 (core/defmacro ^::ana/numeric ==
   ([x] true)
-  ([x y] (bool-expr (core/list 'js* "(~{} === ~{})" x y)))
+  ([x y] (bool-expr (core/list 'js* "(~{} == ~{})" x y)))
   ([x y & more] `(and (== ~x ~y) (== ~y ~@more))))
 
 (core/defmacro ^::ana/numeric dec [x]
diff --git a/src/test/cljs/cljs/bigint_test.cljs b/src/test/cljs/cljs/bigint_test.cljs
index dd5ad978f..9522fa462 100644
--- a/src/test/cljs/cljs/bigint_test.cljs
+++ b/src/test/cljs/cljs/bigint_test.cljs
@@ -15,15 +15,12 @@
     (is (bigint? 9007199254740992))
     (is (bigint? -9007199254740992)))
   (testing "BigInt & Number equality"
-    ;; the below is a bit backwards from Clojure
-    ;; i.e. (= 0.5 1/2) ; false
-    ;; but  (== 0.5 1/2) ; true
     (is (= 1 1N))
     (is (= 1N 1))
     (is (= 1 1N 1))
-    (is (not (== 1 1N)))
-    (is (not (== 1N 1)))
-    (is (not (== 1 1N 1))))
+    (is (== 1 1N))
+    (is (== 1N 1))
+    (is (== 1 1N 1)))
   (testing "BigInt Hashing"
     (is (= (hash 1N) (hash 1)))
     (is (= (hash 9007199254740992) (hash 9007199254740992)))
@@ -31,7 +28,15 @@
   (testing "BigInt as HashMap keys"
     (let [m {1N 2}]
       (is (= 2 (get m 1N)))
-      (is (= 2 (get m 1))))))
+      (is (= 2 (get m 1)))))
+  (testing "Interop"
+    (is (= (js/BigInt 1) 1N))
+    (is (= 1N (js/BigInt 1)))
+    (is (= (js/BigInt 1) 1N))
+    (is (= (js/BigInt 1) 1))
+    (is (= 1 (js/BigInt 1))))
+  (testing "Interaction with core"
+    (is (= (range 1 5) (range 1 5N)))))
 
 (comment
 

From ec1e56f298f30f45947b928a21b80c6c93527b17 Mon Sep 17 00:00:00 2001
From: davidnolen <david.nolen@gmail.com>
Date: Tue, 26 Sep 2023 19:10:17 -0400
Subject: [PATCH 10/10] * some basic arithmetic cases

---
 src/test/cljs/cljs/bigint_test.cljs | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/test/cljs/cljs/bigint_test.cljs b/src/test/cljs/cljs/bigint_test.cljs
index 9522fa462..e273e5bdf 100644
--- a/src/test/cljs/cljs/bigint_test.cljs
+++ b/src/test/cljs/cljs/bigint_test.cljs
@@ -36,7 +36,11 @@
     (is (= (js/BigInt 1) 1))
     (is (= 1 (js/BigInt 1))))
   (testing "Interaction with core"
-    (is (= (range 1 5) (range 1 5N)))))
+    (is (= (range 1 5) (range 1 5N))))
+  (testing "Arithmetic"
+    (is (= 2 (+ 1 1N)))
+    (is (= 0.5 (/ 1N 2)))
+    (is (= 4N (* 2N 2)))))
 
 (comment