Permalink
Browse files

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
  • Loading branch information...
swannodette committed Apr 6, 2015
1 parent 9bf486b commit 576fb6e054dd50ec458a3c9e4172a5a0002c7aea
Showing with 298 additions and 54 deletions.
  1. +1 −1 script/test-simple
  2. +17 −24 src/clj/cljs/analyzer.clj
  3. +2 −2 src/clj/cljs/closure.clj
  4. +265 −27 src/clj/cljs/core.clj
  5. +13 −0 test/clj/cljs/compiler_tests.clj
View
@@ -1,7 +1,7 @@
#!/bin/sh
# stop blowing compiled stuff
-#rm -rf builds/out-simp
+rm -rf builds/out-simp
mkdir -p builds/out-simp
possible=4
View
@@ -864,22 +864,19 @@
:impls #{}})
(when fn-var?
(let [params (map #(vec (map :name (:params %))) (:methods init-expr))]
- {:fn-var true
- ;; protocol implementation context
- :protocol-impl (:protocol-impl init-expr)
- ;; inline protocol implementation context
- :protocol-inline (:protocol-inline init-expr)
- :variadic (:variadic init-expr)
- :max-fixed-arity (:max-fixed-arity init-expr)
- :method-params params
- :arglists (:arglists sym-meta)
- :arglists-meta (doall (map meta (:arglists sym-meta)))
- :methods (map (fn [method]
- (let [tag (infer-tag env (assoc method :op :method))]
- (cond-> (select-keys method
- [:max-fixed-arity :variadic])
- tag (assoc :tag tag))))
- (:methods init-expr))}) )
+ (merge
+ {:fn-var true
+ ;; protocol implementation context
+ :protocol-impl (:protocol-impl init-expr)
+ ;; inline protocol implementation context
+ :protocol-inline (:protocol-inline init-expr)}
+ (if-let [top-fn-meta (:top-fn sym-meta)]
+ top-fn-meta
+ {:variadic (:variadic init-expr)
+ :max-fixed-arity (:max-fixed-arity init-expr)
+ :method-params params
+ :arglists (:arglists sym-meta)
+ :arglists-meta (doall (map meta (:arglists sym-meta)))}))) )
(when (and fn-var? tag)
{:ret-tag tag})))
(merge
@@ -978,8 +975,7 @@
:fn-var true
:variadic variadic
:max-fixed-arity max-fixed-arity
- :method-params (map :params methods)
- :methods methods)
+ :method-params (map :params methods))
locals)
methods (if name
;; a second pass with knowledge of our function-ness/arity
@@ -1027,8 +1023,7 @@
:shadow (locals n)
:variadic (:variadic fexpr)
:max-fixed-arity (:max-fixed-arity fexpr)
- :method-params (map :params (:methods fexpr))
- :methods (:methods fexpr)}
+ :method-params (map :params (:methods fexpr))}
ret-tag (assoc :ret-tag ret-tag))]
[(assoc-in env [:locals n] be)
(conj bes be)]))
@@ -1043,8 +1038,7 @@
:init fexpr
:variadic (:variadic fexpr)
:max-fixed-arity (:max-fixed-arity fexpr)
- :method-params (map :params (:methods fexpr))
- :methods (:methods fexpr))]
+ :method-params (map :params (:methods fexpr)))]
[(assoc-in env [:locals name] be')
(conj bes be')]))
[meth-env []] bes)
@@ -1102,8 +1096,7 @@
{:fn-var true
:variadic (:variadic init-expr)
:max-fixed-arity (:max-fixed-arity init-expr)
- :method-params (map :params (:methods init-expr))
- :methods (:methods init-expr)})
+ :method-params (map :params (:methods init-expr))})
be)]
(recur (conj bes be)
(assoc-in env [:locals name] be)
View
@@ -701,7 +701,7 @@ should contain the source for the given namespace name."
(fn [[sources ret] [name {:keys [entries output-to depends-on] :as module-desc}]]
(assert (or (= name :cljs-base) (not (empty? entries)))
(str "Module " name " does not define any :entries"))
- (when (and (:verbose opts) (not= name :cljs-base))
+ (when (:verbose opts)
(util/debug-prn "Building module" name))
(let [js-module (JSModule. (clojure.core/name name))
[sources' module-sources]
@@ -750,7 +750,7 @@ should contain the source for the given namespace name."
cljs-base-closure-module (get-in (into {} modules) [:cljs-base :closure-module])
foreign-deps (atom [])]
(when (:verbose opts)
- (util/debug-prn "Building module" :cljs-base))
+ (util/debug-prn "Adding remaining namespaces to" :cljs-base))
;; add anything left to :cljs-base module
(doseq [source sources']
(when (:verbose opts)
Oops, something went wrong.

0 comments on commit 576fb6e

Please sign in to comment.