From 49a9a0d37b9a1f0dc9ec5dcb52af7c09660878cf Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sat, 8 Nov 2025 10:39:12 -0500 Subject: [PATCH 1/4] CLJS-3461: don't hard-code destructuring to PAM - use empty map literal instead, use the constructor for createAsIfByAssoc - perf is not critical for `:lite-mode` opt for simplicity for now - add REPL aliases to deps.edn to make it easier to play around :lite-mode --- deps.edn | 6 +++++- src/main/cljs/cljs/core.cljs | 25 ++++++++++++++++++++----- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/deps.edn b/deps.edn index e3a236c2a..5233627bc 100644 --- a/deps.edn +++ b/deps.edn @@ -9,7 +9,11 @@ org.clojure/tools.reader {:mvn/version "1.3.6"} org.clojure/test.check {:mvn/version "1.1.1"}} :aliases - {:cli.test.run {:extra-paths ["src/test/cljs_cli"] + {:cljs-repl {:extra-paths ["src/test/cljs"] + :main-opts ["-m" "cljs.main" "-re" "node" "-d" ".cljs_repl" "-r"]} + :cljs-lite-repl {:extra-paths ["src/test/cljs"] + :main-opts ["-m" "cljs.main" "-co" "{:lite-mode true}" "-re" "node" "-d" ".cljs_lite_repl" "-r"]} + :cli.test.run {:extra-paths ["src/test/cljs_cli"] :main-opts ["-i" "src/test/cljs_cli/cljs_cli/test_runner.clj" "-e" "(cljs-cli.test-runner/-main)"]} :compiler.test {:extra-paths ["src/test/cljs" "src/test/cljs_build" "src/test/cljs_cp" diff --git a/src/main/cljs/cljs/core.cljs b/src/main/cljs/cljs/core.cljs index 82bd82c6b..9258db0c4 100644 --- a/src/main/cljs/cljs/core.cljs +++ b/src/main/cljs/cljs/core.cljs @@ -4129,10 +4129,10 @@ reduces them without incurring seq initialization" (defn --destructure-map [gmap] (if (implements? ISeq gmap) (if (next gmap) - (.createAsIfByAssoc PersistentArrayMap (to-array gmap)) + (.createAsIfByAssoc (. {} -constructor) (to-array gmap)) (if (seq gmap) (first gmap) - (.-EMPTY PersistentArrayMap))) + {})) gmap)) (defn vary-meta @@ -7126,7 +7126,7 @@ reduces them without incurring seq initialization" (fn [init] ;; check trailing element (let [len (alength init) - has-trailing? (== 1 (bit-and len 1))] + has-trailing? (== 1 (bit-and len 1))] (if-not (or has-trailing? (pam-dupes? init)) (PersistentArrayMap. nil (/ len 2) init nil) (.createAsIfByAssocComplexPath PersistentArrayMap init has-trailing?))))) @@ -9040,8 +9040,8 @@ reduces them without incurring seq initialization" https://clojure.org/reference/special_forms#keyword-arguments" [s] (if (next s) - (.createAsIfByAssoc PersistentArrayMap (to-array s)) - (if (seq s) (first s) (.-EMPTY PersistentArrayMap)))) + (.createAsIfByAssoc (. {} -constructor) (to-array s)) + (if (seq s) (first s) {}))) (defn sorted-map "keyval => key val @@ -12731,6 +12731,21 @@ reduces them without incurring seq initialization" (recur (nnext kvs))) (.fromObject ObjMap ks obj))))) +(set! (.-createAsIfByAssoc ObjMap) + (fn [init] + ;; check trailing element + (let [len (alength init) + has-trailing? (== 1 (bit-and len 1)) + init (if has-trailing? + (pam-grow-seed-array init + (into {} (aget init (dec len)))) + init) + len (alength init)] + (loop [i 0 ret {}] + (if (< i len) + (recur (+ i 2) (assoc ret (aget init i) (aget init (inc i)))) + ret))))) + (defn- scan-array-equiv [incr k array] (let [len (alength array)] (loop [i 0] From 797823b2d486def1457c56026da1a40b52fd311b Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sat, 8 Nov 2025 11:08:22 -0500 Subject: [PATCH 2/4] avoid accessing constructor --- src/main/cljs/cljs/core.cljs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/cljs/cljs/core.cljs b/src/main/cljs/cljs/core.cljs index 9258db0c4..41c924f15 100644 --- a/src/main/cljs/cljs/core.cljs +++ b/src/main/cljs/cljs/core.cljs @@ -4129,7 +4129,7 @@ reduces them without incurring seq initialization" (defn --destructure-map [gmap] (if (implements? ISeq gmap) (if (next gmap) - (.createAsIfByAssoc (. {} -constructor) (to-array gmap)) + (.createAsIfByAssoc (if ^boolean LITE_MODE ObjMap PersistentArrayMap) (to-array gmap)) (if (seq gmap) (first gmap) {})) @@ -9040,7 +9040,7 @@ reduces them without incurring seq initialization" https://clojure.org/reference/special_forms#keyword-arguments" [s] (if (next s) - (.createAsIfByAssoc (. {} -constructor) (to-array s)) + (.createAsIfByAssoc (if ^boolean LITE_MODE ObjMap PersistentArrayMap) (to-array s)) (if (seq s) (first s) {}))) (defn sorted-map From 7e11286fbfdcf05577e504a3ebf0c12614425a81 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sat, 8 Nov 2025 11:20:14 -0500 Subject: [PATCH 3/4] add missing declare --- src/main/cljs/cljs/core.cljs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/cljs/cljs/core.cljs b/src/main/cljs/cljs/core.cljs index 41c924f15..a973f1a82 100644 --- a/src/main/cljs/cljs/core.cljs +++ b/src/main/cljs/cljs/core.cljs @@ -4124,6 +4124,8 @@ reduces them without incurring seq initialization" (set! *unchecked-if* false) +(declare ObjMap) + ;; CLJS-3200: used by destructure macro for maps to reduce amount of repeated code ;; placed here because it needs apply and hash-map (only declared at this point) (defn --destructure-map [gmap] From c1356ce7d0b7ef999f48dffb27b3ecd716d66f3b Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sat, 8 Nov 2025 11:28:43 -0500 Subject: [PATCH 4/4] make the choice more static, not sure what's going on --- src/main/cljs/cljs/core.cljs | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/main/cljs/cljs/core.cljs b/src/main/cljs/cljs/core.cljs index a973f1a82..707a7f0cd 100644 --- a/src/main/cljs/cljs/core.cljs +++ b/src/main/cljs/cljs/core.cljs @@ -4129,13 +4129,21 @@ reduces them without incurring seq initialization" ;; CLJS-3200: used by destructure macro for maps to reduce amount of repeated code ;; placed here because it needs apply and hash-map (only declared at this point) (defn --destructure-map [gmap] - (if (implements? ISeq gmap) - (if (next gmap) - (.createAsIfByAssoc (if ^boolean LITE_MODE ObjMap PersistentArrayMap) (to-array gmap)) - (if (seq gmap) - (first gmap) - {})) - gmap)) + (if ^boolean LITE_MODE + (if (implements? ISeq gmap) + (if (next gmap) + (.createAsIfByAssoc ObjMap (to-array gmap)) + (if (seq gmap) + (first gmap) + (.-EMPTY ObjMap))) + gmap) + (if (implements? ISeq gmap) + (if (next gmap) + (.createAsIfByAssoc PersistentArrayMap (to-array gmap)) + (if (seq gmap) + (first gmap) + (.-EMPTY PersistentArrayMap))) + gmap))) (defn vary-meta "Returns an object of the same type and value as obj, with @@ -9041,9 +9049,13 @@ reduces them without incurring seq initialization" "Builds a map from a seq as described in https://clojure.org/reference/special_forms#keyword-arguments" [s] - (if (next s) - (.createAsIfByAssoc (if ^boolean LITE_MODE ObjMap PersistentArrayMap) (to-array s)) - (if (seq s) (first s) {}))) + (if ^boolean LITE_MODE + (if (next s) + (.createAsIfByAssoc ObjMap (to-array s)) + (if (seq s) (first s) (.-EMPTY ObjMap))) + (if (next s) + (.createAsIfByAssoc PersistentArrayMap (to-array s)) + (if (seq s) (first s) (.-EMPTY PersistentArrayMap))))) (defn sorted-map "keyval => key val @@ -12733,7 +12745,7 @@ reduces them without incurring seq initialization" (recur (nnext kvs))) (.fromObject ObjMap ks obj))))) -(set! (.-createAsIfByAssoc ObjMap) +(set! (. ObjMap -createAsIfByAssoc) (fn [init] ;; check trailing element (let [len (alength init)