Skip to content

Commit 576fb6e

Browse files
author
dnolen
committed
CLJS-1188: multi-arity fns hinder cross-module code motion
This patch makes all top level function definitions completely static, we never issue an invoke to produce a top-level function value. This is accomplished by duplicating and further enhancing the fn emission logic in cljs.compiler at the macro level. The enhancements are entirely around eliminating invokes and any property aliasing. While useful in expression contexts, at the top level both of these approaches in cljs.compiler defeat cross module code motion. - test-simple should clean builds - cljs.analyzer * remove :method info, never used * read fn information from :top-fn meta if available - cljs.closure * enhance module build reporting - cljs.core * move clojure.core/defn macro + helpers directly into macro ns * handle top level multi-arity & variadic fns - cjls.compiler-tests * include some examples
1 parent 9bf486b commit 576fb6e

File tree

5 files changed

+298
-54
lines changed

5 files changed

+298
-54
lines changed

script/test-simple

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/bin/sh
22

33
# stop blowing compiled stuff
4-
#rm -rf builds/out-simp
4+
rm -rf builds/out-simp
55
mkdir -p builds/out-simp
66

77
possible=4

src/clj/cljs/analyzer.clj

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -864,22 +864,19 @@
864864
:impls #{}})
865865
(when fn-var?
866866
(let [params (map #(vec (map :name (:params %))) (:methods init-expr))]
867-
{:fn-var true
868-
;; protocol implementation context
869-
:protocol-impl (:protocol-impl init-expr)
870-
;; inline protocol implementation context
871-
:protocol-inline (:protocol-inline init-expr)
872-
:variadic (:variadic init-expr)
873-
:max-fixed-arity (:max-fixed-arity init-expr)
874-
:method-params params
875-
:arglists (:arglists sym-meta)
876-
:arglists-meta (doall (map meta (:arglists sym-meta)))
877-
:methods (map (fn [method]
878-
(let [tag (infer-tag env (assoc method :op :method))]
879-
(cond-> (select-keys method
880-
[:max-fixed-arity :variadic])
881-
tag (assoc :tag tag))))
882-
(:methods init-expr))}) )
867+
(merge
868+
{:fn-var true
869+
;; protocol implementation context
870+
:protocol-impl (:protocol-impl init-expr)
871+
;; inline protocol implementation context
872+
:protocol-inline (:protocol-inline init-expr)}
873+
(if-let [top-fn-meta (:top-fn sym-meta)]
874+
top-fn-meta
875+
{:variadic (:variadic init-expr)
876+
:max-fixed-arity (:max-fixed-arity init-expr)
877+
:method-params params
878+
:arglists (:arglists sym-meta)
879+
:arglists-meta (doall (map meta (:arglists sym-meta)))}))) )
883880
(when (and fn-var? tag)
884881
{:ret-tag tag})))
885882
(merge
@@ -978,8 +975,7 @@
978975
:fn-var true
979976
:variadic variadic
980977
:max-fixed-arity max-fixed-arity
981-
:method-params (map :params methods)
982-
:methods methods)
978+
:method-params (map :params methods))
983979
locals)
984980
methods (if name
985981
;; a second pass with knowledge of our function-ness/arity
@@ -1027,8 +1023,7 @@
10271023
:shadow (locals n)
10281024
:variadic (:variadic fexpr)
10291025
:max-fixed-arity (:max-fixed-arity fexpr)
1030-
:method-params (map :params (:methods fexpr))
1031-
:methods (:methods fexpr)}
1026+
:method-params (map :params (:methods fexpr))}
10321027
ret-tag (assoc :ret-tag ret-tag))]
10331028
[(assoc-in env [:locals n] be)
10341029
(conj bes be)]))
@@ -1043,8 +1038,7 @@
10431038
:init fexpr
10441039
:variadic (:variadic fexpr)
10451040
:max-fixed-arity (:max-fixed-arity fexpr)
1046-
:method-params (map :params (:methods fexpr))
1047-
:methods (:methods fexpr))]
1041+
:method-params (map :params (:methods fexpr)))]
10481042
[(assoc-in env [:locals name] be')
10491043
(conj bes be')]))
10501044
[meth-env []] bes)
@@ -1102,8 +1096,7 @@
11021096
{:fn-var true
11031097
:variadic (:variadic init-expr)
11041098
:max-fixed-arity (:max-fixed-arity init-expr)
1105-
:method-params (map :params (:methods init-expr))
1106-
:methods (:methods init-expr)})
1099+
:method-params (map :params (:methods init-expr))})
11071100
be)]
11081101
(recur (conj bes be)
11091102
(assoc-in env [:locals name] be)

src/clj/cljs/closure.clj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ should contain the source for the given namespace name."
701701
(fn [[sources ret] [name {:keys [entries output-to depends-on] :as module-desc}]]
702702
(assert (or (= name :cljs-base) (not (empty? entries)))
703703
(str "Module " name " does not define any :entries"))
704-
(when (and (:verbose opts) (not= name :cljs-base))
704+
(when (:verbose opts)
705705
(util/debug-prn "Building module" name))
706706
(let [js-module (JSModule. (clojure.core/name name))
707707
[sources' module-sources]
@@ -750,7 +750,7 @@ should contain the source for the given namespace name."
750750
cljs-base-closure-module (get-in (into {} modules) [:cljs-base :closure-module])
751751
foreign-deps (atom [])]
752752
(when (:verbose opts)
753-
(util/debug-prn "Building module" :cljs-base))
753+
(util/debug-prn "Adding remaining namespaces to" :cljs-base))
754754
;; add anything left to :cljs-base module
755755
(doseq [source sources']
756756
(when (:verbose opts)

0 commit comments

Comments
 (0)