Browse files

CLJS-401: gensym let names in statement context in the emitter

This fixes a bug where two subsequent lets could overwrite each other's names
  • Loading branch information...
1 parent 3acacf7 commit 234bd3a85213d98595090b3a6625f0aeae7ea6ed @bendlas bendlas committed with David Nolen Nov 2, 2012
Showing with 25 additions and 9 deletions.
  1. +18 −8 src/clj/cljs/compiler.clj
  2. +7 −1 test/cljs/cljs/core_test.cljs
View
26 src/clj/cljs/compiler.clj
@@ -34,6 +34,7 @@
(def ^:dynamic *position* nil)
(def ^:dynamic *emitted-provides* nil)
+(def ^:dynamic *lexical-renames* {})
(def cljs-reserved-file-names #{"deps.cljs"})
(defonce ns-first-segments (atom '#{"cljs" "clojure"}))
@@ -49,7 +50,11 @@
shadow (recur (inc d) shadow)
(@ns-first-segments (str name)) (inc d)
:else d))
- munged-name (munge (if field (str "self__." name) name) reserved)]
+ renamed (*lexical-renames* (System/identityHashCode s))
+ munged-name (munge (cond field (str "self__." name)
+ renamed renamed
+ :else name)
+ reserved)]
(if (or field (zero? depth))
munged-name
(symbol (str munged-name "__$" depth))))
@@ -547,13 +552,18 @@
[{:keys [bindings statements ret env loop]}]
(let [context (:context env)]
(when (= :expr context) (emits "(function (){"))
- (doseq [{:keys [init] :as binding} bindings]
- (emitln "var " (munge binding) " = " init ";"))
- (when loop (emitln "while(true){"))
- (emit-block (if (= :expr context) :return context) statements ret)
- (when loop
- (emitln "break;")
- (emitln "}"))
+ (binding [*lexical-renames* (into *lexical-renames*
+ (when (= :statement context)
+ (map #(vector (System/identityHashCode %)
+ (gensym (str (:name %) "-")))
+ bindings)))]
+ (doseq [{:keys [init] :as binding} bindings]
+ (emitln "var " (munge binding) " = " init ";"))
+ (when loop (emitln "while(true){"))
+ (emit-block (if (= :expr context) :return context) statements ret)
+ (when loop
+ (emitln "break;")
+ (emitln "}")))
;(emits "}")
(when (= :expr context) (emits "})()"))))
View
8 test/cljs/cljs/core_test.cljs
@@ -1699,7 +1699,13 @@
(assert (= 2 (-bar (baz inc) 1)))
- ;; CLJS-411
+ ;; CLJS-401 / CLJS-411
+
+ (let [x "original"]
+ (defn original-closure-stmt [] x))
+
+ (let [x "overwritten"]
+ (assert (= "original" (original-closure-stmt))))
(assert (= "original" (let [x "original"
oce (fn [] x)

0 comments on commit 234bd3a

Please sign in to comment.