<< Back to previous view

[CLJS-1386] Symbols should be added to the constants table Created: 01/Aug/15  Updated: 01/Aug/15  Resolved: 01/Aug/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.28
Fix Version/s: Next

Type: Enhancement Priority: Major
Reporter: David Nolen Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: None


 Description   

Now that optional bootstrap is a thing, this is a significant optimization.



 Comments   
Comment by David Nolen [ 01/Aug/15 6:11 AM ]

fixed https://github.com/clojure/clojurescript/commit/d92b3004046d1f83ab76a2b94f4129cb16e47848





[CLJS-1385] cljs.js/compile-str does not correctly track the current ns Created: 31/Jul/15  Updated: 31/Jul/15  Resolved: 31/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: 1.7.28

Type: Defect Priority: Major
Reporter: David Nolen Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: None


 Description   

Macros are not correctly expanded. Instead macro calls resolve to cljs.user.



 Comments   
Comment by David Nolen [ 31/Jul/15 10:22 AM ]

fixed https://github.com/clojure/clojurescript/commit/f3cf45d745af5e63500375d084dd0d7b19c40dac





[CLJS-1384] cljs.js/eval-str doc that :ns returned upon success Created: 31/Jul/15  Updated: 31/Jul/15  Resolved: 31/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: None


 Description   

If eval-str is called and it succeeds with a `:value`, the resulting `:ns` is also passed back, but the doctoring hasn't been updated to reflect this fact.



 Comments   
Comment by David Nolen [ 31/Jul/15 8:38 AM ]

fixed https://github.com/clojure/clojurescript/commit/86f8255d4536e4e2022adb467db46293c7616f74





[CLJS-1383] cljs.js/eval in a specific ns does not work Created: 30/Jul/15  Updated: 30/Jul/15  Resolved: 30/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: 1.7.28

Type: Defect Priority: Major
Reporter: David Nolen Assignee: David Nolen
Resolution: Not Reproducible Votes: 0
Labels: None


 Description   
(cljs/eval (cljs/empty-state)
           '(def x 1)
           {:eval cljs/js-eval
            :context :expr
            :def-emits-var true
            :ns cells.core
            }
           #(pprint %))


 Comments   
Comment by David Nolen [ 30/Jul/15 3:05 PM ]

Cannot repro on master





[CLJS-1382] Macros time and case use unqualified core/str in syntax quote (breaks bootstrap) Created: 30/Jul/15  Updated: 30/Jul/15  Resolved: 30/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Joel Martin Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: bootstrap
Environment:

cljs-bootstrap


Attachments: Text File time-case-fix.patch    
Patch: Code

 Description   

The following are broken in bootstrapped clojurescript because they call unqualified versions of core/str within syntax quote:

(time (reduce #(+ %1 %2) 0 (range 1000000)))

(case :constant false "nope")


 Comments   
Comment by David Nolen [ 30/Jul/15 11:36 AM ]

fixed https://github.com/clojure/clojurescript/commit/cf0374cfe9e85ae77f26c062190241f09caa5544





[CLJS-1381] cljs.js: Memory perf on JSC for first defn evaluation Created: 30/Jul/15  Updated: 30/Jul/15  Resolved: 30/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None

Attachments: PNG File memory.png    

 Description   

If you evaluate something like (defn f []) via cljs.js/eval-str with JavaScriptCore, a spike in memory will occur and it will take several seconds to complete the evaluation. After this, subsequent evaluations don't exhibit this behavior. Also, this doesn't occur for Firefox or Chrome.

Additionally, it did not occur previously with bootstrapped ClojureScript when we were building things outside of `cljs.js` (it doesn't occur in Replete, for example, nor the earlier versions of Planck: https://youtu.be/AMT63rxK4E8).

You can see it for yourself at http://ClojureScript.net (you can see the slowness in desktop Safari, and on an iPhone it exhausts memory).



 Comments   
Comment by Mike Fikes [ 30/Jul/15 10:58 AM ]

Attached memory.png, which shows what happens in Planck when you do (defn f [])

Comment by Mike Fikes [ 30/Jul/15 5:06 PM ]

This is the same as CLJS-910. An easy workaround is :static-fns true.





[CLJS-1380] Hashing is broken when using iphone 4 Created: 30/Jul/15  Updated: 31/Jul/15  Resolved: 31/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Jean-Louis Giordano Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: bug
Environment:

iphone 4 running iOS 7.1.2



 Description   

On a physical iPhone 4 running iOS 7.1.2, when running the `hash` function too many times at the top level, the result becomes inconsistent.

This only happens when not using the safari webinspector.

I have setup a minimal failing spec here: https://github.com/Jell/iphone-bug

Instructions to reproduce in the README.

I must confess, this took me a very long time to debug! I hope someone can take it from here.



 Comments   
Comment by Jean-Louis Giordano [ 30/Jul/15 7:23 AM ]

With the help of my colleague, we narrowed it down further to this:

(ns iphone-bug.core)

(def yyyy (hash "yyyy"))

(dotimes [i 1000] (hash "yyyy"))

(js/alert (str "Before: " yyyy " After: " (hash "yyyy")))
Comment by Jean-Louis Giordano [ 30/Jul/15 7:36 AM ]

Note: the bug only appears on iPhone 4, not iPhone 4S!

Comment by David Nolen [ 30/Jul/15 10:58 AM ]

I believe this is something to do with 32bit vs. 64bit JavaScriptCore. Super low priority but happy to take a patch if someone can devise one.

Comment by Thomas Heller [ 30/Jul/15 11:34 AM ]

Sounds like something which was fixed a long time ago and I haven't personally seen since. Maybe a recent change reverted the Math.imul fix?

http://dev.clojure.org/jira/browse/CLJS-839
http://dev.clojure.org/jira/browse/CLJS-830

Comment by David Nolen [ 30/Jul/15 11:53 AM ]

Thomas I'm not sure we solved this for older phones only relatively newer ones with specific versions of Safari. iPhone 4 was ARM Cortex A8, and the 4S was an ARM Cortex A9. Turns out both are 32bit, but I still suspect this is a JITing issue if it disappears with a debugger attached.

Comment by Thomas Heller [ 31/Jul/15 3:33 AM ]

Just saying that the description exactly matched what I saw when investigating the keyword hashing issue. The problem never appeared with the devtools running and sometimes produced the correct hash without. After adding the imul.js the issue disappeared and clients stopped sending invalid maps. See CLJS-830 for a list of user agents [1] that were problematic before, the issue was with a specific webkit version and seemingly not hardware related (iOS 7.1.2 was the version at the time, user agents don't identify the device though).

Not claiming that this is the same issue, just saying that it sounds very very similar.

[1] https://gist.github.com/thheller/8cae79cabd9ac74958ca

Comment by Jean-Louis Giordano [ 31/Jul/15 9:32 AM ]

We found a fix that works for us!

We redefine the imul polyfill (cljs/imul.js) with the following:

if(typeof Math.imul == "undefined" || (Math.imul(0xffffffff,5) == 0)) {
    Math.imul = function (a, b) {
      try {
        var ah  = (a >>> 16) & 0xffff;
        var al = a & 0xffff;
        var bh  = (b >>> 16) & 0xffff;
        var bl = b & 0xffff;
        // the shift by 0 fixes the sign on the high part
        // the final |0 converts the unsigned value into a signed value
        return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0)|0);
      } catch(err) { throw err; }
    }
}

The error is not really coming from inside this function, but adding the try/catch disables JIT optimisation for callers of imul as far as we understand, which solves the hashing issues we saw on Iphone 4.

The errors seems to come from bit operations, in particular the `x|0` operations (corresponding to (int x) calls or bit-or in CLJS).

Infuriating to pin the bug down, because observing intermediate variables will prevent the bug from happening!

Comment by Francis Avila [ 31/Jul/15 9:59 AM ]

This is going to cause an enormous performance regression.

Comment by Jean-Louis Giordano [ 31/Jul/15 10:05 AM ]

Well a perf regression for the browsers that do not have a built-in or broken Math/imul, which might not be that big of a deal?

This is good enough for us at least, so we will probably not be investigating this further.

Comment by David Nolen [ 31/Jul/15 10:20 AM ]

Thanks for the bug report good to have monkey-path solution for those that need it. Closing this one.





[CLJS-1379] cljs.js: Macroexpansion defeated when calling helper Created: 29/Jul/15  Updated: 30/Jul/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Mike Fikes
Resolution: Unresolved Votes: 0
Labels: None
Environment:

1.7.10



 Description   

If you have a namespace:

(ns foo.macros
  (:require foo.helper))

(defmacro my-inc [n]
  `(foo.helper/my-inc ~n))

That makes use of a helper namespace:

(ns foo.helper)

(defn my-inc [x]
  (inc x))

Then things will work properly for non-bootstrapped ClojureScript. Here is an example use in Ambly:

cljs.user=> (require 'foo.helper)
nil
cljs.user=> (require-macros 'foo.macros)
nil
cljs.user=> (defn f [] (foo.macros/my-inc 3))
#'cljs.user/f
cljs.user=> f
#<function cljs$user$f() {
return foo.helper.my_inc.call(null,(3));
}>
cljs.user=> (f)
4

But, the same sequence in bootstrapped ClojureScript fails:

cljs.user=> (require 'foo.helper)
nil
cljs.user=> (require-macros 'foo.macros)
nil
cljs.user=> (defn f [] (foo.macros/my-inc 3))
#'cljs.user/f
cljs.user=> f
#<function cljs$user$f() {
return foo.macros.my_inc.call(null,3);
}>
cljs.user=> (f)
Error occurred
cljs$user$f

Note that the emitted JavaScript in this second case treats the macro as a function.

Also, I've seen that if you eliminate the call to a helper, but instead, say make direct use of say, inc, then macro expansion works properly in bootstrapped ClojureScript (and for the example above you end up with JavaScript code that adds 1 and 3.)

Of course, these are with downstream REPLs. Let me know if a minimal repro without any downstream stuff is desired and I'm sure I can scratch one together involving the same calls Planck is making to cljs.js.



 Comments   
Comment by David Nolen [ 30/Jul/15 3:18 PM ]

The second case is only possible if for some reason the macros could not get loaded.

Comment by Mike Fikes [ 30/Jul/15 5:12 PM ]

As discussed in IRC, Mike to add minimal repro to this ticket.





[CLJS-1378] JARs that end in .exe are problematic Created: 29/Jul/15  Updated: 30/Jul/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: None

Type: Defect Priority: Trivial
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

compile-from-jar cannot handle the later form

{{jar:file:/Users/candera/cognitect/walmart/walsim/deploy/walsim-v0.3.5.jar!/cljs/com/walmart/test/app.cljs}}
{{jar:file:/Users/candera/cognitect/walmart/walsim/deploy/walsim-v0.3.5.exe!/cljs/com/walmart/test/app.cljs}}






[CLJS-1377] om-tools.core fails to compile Created: 29/Jul/15  Updated: 30/Jul/15  Resolved: 30/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Sean Grove Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: None


 Description   

Any file with a ns declaration that requires om-tools.core will throw an exception:

(ns example.core (:require [om-tools.core]))

=>

clojure.lang.ExceptionInfo: failed compiling file:src/cljs/example/core.cljs {:file #object[java.io.File 0x37f37699 "src/cljs/example/core.cljs"]}
at clojure.core$ex_info.invoke(core.clj:4593)
at cljs.compiler$compile_file$fn__2999.invoke(compiler.cljc:1249)
at cljs.compiler$compile_file.invoke(compiler.cljc:1211)
at cljs.compiler$compile_root.invoke(compiler.cljc:1286)
at cljs.closure$compile_dir.invoke(closure.clj:430)
at cljs.closure$eval3382$fn__3383.invoke(closure.clj:470)
at cljs.closure$eval3334$fn_3335$G3325_3342.invoke(closure.clj:375)
at cljs.closure$eval3395$fn__3396.invoke(closure.clj:484)
at cljs.closure$eval3334$fn_3335$G3325_3342.invoke(closure.clj:375)
at cljsbuild.compiler.SourcePaths$fn__3862.invoke(compiler.clj:67)
at clojure.core$map$fn__4553.invoke(core.clj:2622)
at clojure.lang.LazySeq.sval(LazySeq.java:40)
at clojure.lang.LazySeq.seq(LazySeq.java:49)
at clojure.lang.RT.seq(RT.java:507)
at clojure.core$seq__4128.invoke(core.clj:137)
at clojure.core$apply.invoke(core.clj:630)
at clojure.core$mapcat.doInvoke(core.clj:2660)
at clojure.lang.RestFn.invoke(RestFn.java:423)
at cljsbuild.compiler.SourcePaths._compile(compiler.clj:67)
at cljs.closure$build.invoke(closure.clj:1634)
at cljs.closure$build.invoke(closure.clj:1590)
at cljsbuild.compiler$compile_cljs$fn__3873.invoke(compiler.clj:81)
at cljsbuild.compiler$compile_cljs.invoke(compiler.clj:80)
at cljsbuild.compiler$run_compiler.invoke(compiler.clj:187)
at user$eval4007$iter_40434047$fn4048$fn_4066.invoke(form-init7604443915532456796.clj:1)
at user$eval4007$iter_40434047$fn_4048.invoke(form-init7604443915532456796.clj:1)
at clojure.lang.LazySeq.sval(LazySeq.java:40)
at clojure.lang.LazySeq.seq(LazySeq.java:49)
at clojure.lang.RT.seq(RT.java:507)
at clojure.core$seq__4128.invoke(core.clj:137)
at clojure.core$dorun.invoke(core.clj:3009)
at clojure.core$doall.invoke(core.clj:3025)
at user$eval4007.invoke(form-init7604443915532456796.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:6782)
at clojure.lang.Compiler.eval(Compiler.java:6772)
at clojure.lang.Compiler.load(Compiler.java:7227)
at clojure.lang.Compiler.loadFile(Compiler.java:7165)
at clojure.main$load_script.invoke(main.clj:275)
at clojure.main$init_opt.invoke(main.clj:280)
at clojure.main$initialize.invoke(main.clj:308)
at clojure.main$null_opt.invoke(main.clj:343)
at clojure.main$main.doInvoke(main.clj:421)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:383)
at clojure.lang.AFn.applyToHelper(AFn.java:156)
at clojure.lang.Var.applyTo(Var.java:700)
at clojure.main.main(main.java:37)
Caused by: clojure.lang.ExceptionInfo: Don't know how to create ISeq from: clojure.lang.Symbol {:tag :cljs/analysis-error}
at clojure.core$ex_info.invoke(core.clj:4593)
at cljs.analyzer$error.invoke(analyzer.cljc:525)
at cljs.analyzer$analyze_seq_STAR__wrap.invoke(analyzer.cljc:2363)
at cljs.analyzer$analyze_seq.invoke(analyzer.cljc:2381)
at cljs.analyzer$analyze_form.invoke(analyzer.cljc:2490)
at cljs.analyzer$analyze_STAR_.invoke(analyzer.cljc:2536)
at cljs.analyzer$analyze.invoke(analyzer.cljc:2552)
at cljs.analyzer$analyze.invoke(analyzer.cljc:2547)
at cljs.analyzer$analyze.invoke(analyzer.cljc:2546)
at cljs.analyzer$analyze_do_statements_STAR_$fn__1522.invoke(analyzer.cljc:1370)
at clojure.core$map$fn__4553.invoke(core.clj:2622)
at clojure.lang.LazySeq.sval(LazySeq.java:40)
at clojure.lang.LazySeq.seq(LazySeq.java:49)
at clojure.lang.RT.seq(RT.java:507)
at clojure.core$seq__4128.invoke(core.clj:137)
at cljs.analyzer$analyze_do_statements_STAR_.invoke(analyzer.cljc:1370)
at cljs.analyzer$analyze_do_statements.invoke(analyzer.cljc:1373)
at cljs.analyzer$eval1526$fn__1528.invoke(analyzer.cljc:1377)
at clojure.lang.MultiFn.invoke(MultiFn.java:251)
at cljs.analyzer$analyze_seq_STAR_.invoke(analyzer.cljc:2359)
at cljs.analyzer$analyze_seq_STAR__wrap.invoke(analyzer.cljc:2364)
at cljs.analyzer$analyze_seq.invoke(analyzer.cljc:2381)
at cljs.analyzer$analyze_form.invoke(analyzer.cljc:2490)
at cljs.analyzer$analyze_STAR_.invoke(analyzer.cljc:2536)
at cljs.analyzer$analyze.invoke(analyzer.cljc:2552)
at cljs.analyzer$analyze.invoke(analyzer.cljc:2547)
at cljs.analyzer$analyze.invoke(analyzer.cljc:2546)
at cljs.analyzer$analyze_let_body_STAR_.invoke(analyzer.cljc:1456)
at cljs.analyzer$analyze_let_body.invoke(analyzer.cljc:1461)
at cljs.analyzer$analyze_let.invoke(analyzer.cljc:1477)
at cljs.analyzer$eval1545$fn__1546.invoke(analyzer.cljc:1489)
at clojure.lang.MultiFn.invoke(MultiFn.java:251)
at cljs.analyzer$analyze_seq_STAR_.invoke(analyzer.cljc:2359)
at cljs.analyzer$analyze_seq_STAR__wrap.invoke(analyzer.cljc:2364)
at cljs.analyzer$analyze_seq.invoke(analyzer.cljc:2381)
at cljs.analyzer$analyze_form.invoke(analyzer.cljc:2490)
at cljs.analyzer$analyze_STAR_.invoke(analyzer.cljc:2536)
at cljs.analyzer$analyze.invoke(analyzer.cljc:2552)
at cljs.analyzer$analyze_seq.invoke(analyzer.cljc:2382)
at cljs.analyzer$analyze_form.invoke(analyzer.cljc:2490)
at cljs.analyzer$analyze_STAR_.invoke(analyzer.cljc:2536)
at cljs.analyzer$analyze.invoke(analyzer.cljc:2552)
at cljs.analyzer$analyze_seq.invoke(analyzer.cljc:2382)
at cljs.analyzer$analyze_form.invoke(analyzer.cljc:2490)
at cljs.analyzer$analyze_STAR_.invoke(analyzer.cljc:2536)
at cljs.analyzer$analyze.invoke(analyzer.cljc:2552)
at cljs.analyzer$analyze_file$fn__2031.invoke(analyzer.cljc:2796)
at cljs.analyzer$analyze_file.invoke(analyzer.cljc:2791)
at cljs.analyzer$analyze_deps.invoke(analyzer.cljc:1625)
at cljs.analyzer$ns_side_effects.invoke(analyzer.cljc:2457)
at cljs.analyzer$analyze_STAR_$fn__1980.invoke(analyzer.cljc:2537)
at clojure.lang.PersistentVector.reduce(PersistentVector.java:333)
at clojure.core$reduce.invoke(core.clj:6518)
at cljs.analyzer$analyze_STAR_.invoke(analyzer.cljc:2537)
at cljs.analyzer$analyze.invoke(analyzer.cljc:2552)
at cljs.analyzer$analyze_file$fn__2031.invoke(analyzer.cljc:2796)
at cljs.analyzer$analyze_file.invoke(analyzer.cljc:2791)
at cljs.analyzer$analyze_deps.invoke(analyzer.cljc:1625)
at cljs.analyzer$ns_side_effects.invoke(analyzer.cljc:2457)
at cljs.analyzer$analyze_STAR_$fn__1980.invoke(analyzer.cljc:2537)
at clojure.lang.PersistentVector.reduce(PersistentVector.java:333)
at clojure.core$reduce.invoke(core.clj:6518)
at cljs.analyzer$analyze_STAR_.invoke(analyzer.cljc:2537)
at cljs.analyzer$analyze.invoke(analyzer.cljc:2552)
at cljs.analyzer$analyze_file$fn__2031.invoke(analyzer.cljc:2796)
at cljs.analyzer$analyze_file.invoke(analyzer.cljc:2791)
at cljs.analyzer$analyze_deps.invoke(analyzer.cljc:1625)
at cljs.analyzer$ns_side_effects.invoke(analyzer.cljc:2457)
at cljs.analyzer$analyze_STAR_$fn__1980.invoke(analyzer.cljc:2537)
at clojure.lang.PersistentVector.reduce(PersistentVector.java:333)
at clojure.core$reduce.invoke(core.clj:6518)
at cljs.analyzer$analyze_STAR_.invoke(analyzer.cljc:2537)
at cljs.analyzer$analyze.invoke(analyzer.cljc:2552)
at cljs.analyzer$analyze_file$fn__2031.invoke(analyzer.cljc:2796)
at cljs.analyzer$analyze_file.invoke(analyzer.cljc:2791)
at cljs.analyzer$analyze_deps.invoke(analyzer.cljc:1625)
at cljs.analyzer$ns_side_effects.invoke(analyzer.cljc:2457)
at cljs.analyzer$analyze_STAR_$fn__1980.invoke(analyzer.cljc:2537)
at clojure.lang.PersistentVector.reduce(PersistentVector.java:333)
at clojure.core$reduce.invoke(core.clj:6518)
at cljs.analyzer$analyze_STAR_.invoke(analyzer.cljc:2537)
at cljs.analyzer$analyze.invoke(analyzer.cljc:2552)
at cljs.compiler$compile_file_STAR_$fn__2958.invoke(compiler.cljc:1120)
at cljs.compiler$with_core_cljs.invoke(compiler.cljc:1048)
at cljs.compiler$compile_file_STAR_.invoke(compiler.cljc:1071)
at cljs.compiler$compile_file$fn__2999.invoke(compiler.cljc:1232)
... 45 more
Caused by: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol
at clojure.lang.RT.seqFrom(RT.java:528)
at clojure.lang.RT.seq(RT.java:509)
at clojure.core$seq__4128.invoke(core.clj:137)
at clojure.core.protocols$seq_reduce.invoke(protocols.clj:30)
at clojure.core.protocols$fn__6500.invoke(protocols.clj:84)
at clojure.core.protocols$fn_6452$G6447_6465.invoke(protocols.clj:13)
at clojure.core$reduce.invoke(core.clj:6519)
at cljs.analyzer$parse_type.invoke(analyzer.cljc:1943)
at cljs.analyzer$eval1766$fn__1767.invoke(analyzer.cljc:1972)
at clojure.lang.MultiFn.invoke(MultiFn.java:251)
at cljs.analyzer$analyze_seq_STAR_.invoke(analyzer.cljc:2359)
at cljs.analyzer$analyze_seq_STAR__wrap.invoke(analyzer.cljc:2364)
... 128 more
Subprocess failed



 Comments   
Comment by David Nolen [ 30/Jul/15 7:33 AM ]

already fixed in master.





[CLJS-1376] Printing in a tagged literal data form Created: 28/Jul/15  Updated: 30/Jul/15  Resolved: 30/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: None

Type: Task Priority: Major
Reporter: Ewen Grosjean Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File CLJS-1376.patch    

 Description   

Since Clojure 1.7, objects, functions, atoms and volatiles print in a tagged literal data form.

(atom {})
#object[clojure.lang.Atom 0x349c1daf {:status :ready, :val {}}]

Clojurescript format is different

(atom {})
#<Atom: {}>


 Comments   
Comment by Ewen Grosjean [ 30/Jul/15 3:52 PM ]

patch attached.

(fn [] nil)
#object ["function" "function (){\nreturn null;\n}"]
(js/AnimationEvent. 1)
#object ["object" "[object AnimationEvent]"]
(atom {})
#object [cljs.core.Atom {:status :ready, :val {}}]
(volatile! 1)
#object [cljs.core.Volatile 1]

I have also made undefined printing to nil.

I hope that helps.

Comment by David Nolen [ 30/Jul/15 4:01 PM ]

fixed https://github.com/clojure/clojurescript/commit/34c3b8985ed8197d90f441c46d168c4024a20eb8

Comment by David Nolen [ 30/Jul/15 4:03 PM ]

Ewen you need to submit a CA if you want to submit patches. Once you've done that you should assign tickets to yourself if you decide to work on them so people are aware of progress.

Comment by Ewen Grosjean [ 30/Jul/15 4:26 PM ]

Thanks for the fix.

I think there are still a few things missing.
Atom and volatile are still printed the old way: https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/core.cljs#L9053
As is "undefined", even though undefined is printed as nil because it is catched by the nil? clause:
https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/core.cljs#L8776





[CLJS-1375] cljs.js/require does not conj to *loaded* Created: 28/Jul/15  Updated: 28/Jul/15  Resolved: 28/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: None
Environment:

Master "0.0-3664"


Attachments: Text File CLJS-1375.patch    
Patch: Code

 Description   

While :reload and :reload-all remove from *loaded*, nothing adds to it.

Steps to reproduce.

(do (set! js/window js/global) nil)

(require 'cljs.js)

(defn load [spec cb]
  (prn spec)
  (cb {:lang   :clj
       :source (case (:path spec)
                 "test/alpha" "(ns test.alpha)")}))

(defn eval [{:keys [source]}]
  (js/eval source))

(cljs.js/require 
  'test.alpha
  {:load load
   :eval eval} 
  (fn [res] (prn res)))
; {:name test.alpha, :macros nil, :path "test/alpha"}
; {:value true}

@cljs.js/*loaded*
; #{}

(cljs.js/require 
  'test.alpha
  {:load load
   :eval eval} 
  (fn [res] (prn res)))
; {:name test.alpha, :macros nil, :path "test/alpha"}
; {:value true}


 Comments   
Comment by David Nolen [ 28/Jul/15 4:30 PM ]

fixed https://github.com/clojure/clojurescript/commit/a1dca29d3ba248062de055a7c951512949515b9b





[CLJS-1374] cljs.js/require doesn't supply good defaults Created: 28/Jul/15  Updated: 28/Jul/15  Resolved: 28/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: 1.7.28

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: None
Environment:

Master 0.0-3664



 Description   

Here is a case where cljs.js/require works properly with respect to loading transitive namespaces:

(ns test.alpha
  (:require test.beta))

(defn f [] 
  test.beta/x)
(ns test.beta)

(def x 3)

For the above, a require for test.alpha causes *load-fn* to be called with this sequence:

{:name test.alpha, :macros nil, :path "test/alpha"}
{:name test.beta, :macros nil, :path "test/beta"}

calling back with this result:

{:value true}

On the other hand, here is an example where an ns form works but require fails:

(ns foo.core
  (#?(:clj  :require 
      :cljs :require-macros)
    [foo.macros]))

(defn str->int [s]
  #?(:clj  (Integer/parseInt s)
     :cljs (js/parseInt s)))

(defn add-five [s]
  (+ (str->int s) 
     (foo.macros/str->int "5")))
(ns foo.macros)

(defmacro str->int [s]
  #?(:clj  (Integer/parseInt s)
     :cljs (js/parseInt s)))

In this case, require results in this sequence:

{:name foo.core, :macros nil, :path "foo/core"}

calling back with this result:

{:value true}

Starting with a fresh REPL, here is what (ns cljs.user (:require foo.core)) results in:

{:name foo.core, :macros nil, :path "foo/core"}
{:name foo.macros, :macros true, :path "foo/macros"}


 Comments   
Comment by Mike Fikes [ 28/Jul/15 12:13 PM ]

Minimal repro:

Set up a ClojureScript REPL with access to

[org.clojure/tools.reader "0.10.0-SNAPSHOT" :exclusions [org.clojure/clojure]]

Then run the following forms in the REPL (I did this in Ambly Demo, but apart from the need to do the js/window bit, it probably reproduces in any ClojureScript REPL):

(do (set! js/window js/global) nil)

(require 'cljs.js)
(require 'cljs.tagged-literals)

(def st (cljs.js/empty-state))

(defn load [spec cb]
  (prn spec)
  (cb {:lang   :clj
       :source (case (:path spec)
                 "test/alpha" "(ns test.alpha (:require test.beta))"
                 "test/beta" "(ns test.beta)"
                 "foo/core" "(ns foo.core (:require-macros foo.macros))"
                 "foo/macros" "(ns foo.macros)")}))

(defn eval [{:keys [source]}]
  (js/eval source))

(defn test-require [sym]
  (cljs.js/require
    {:*compiler*     st
     :*data-readers* cljs.tagged-literals/*cljs-data-readers*
     :*load-fn*      load
     :*eval-fn*      eval}
    sym
    nil
    (fn [res]
      (prn res))))

(test-require 'test.alpha)
; {:name test.alpha, :macros nil, :path "test/alpha"}
; {:name test.beta, :macros nil, :path "test/beta"}
; {:value true}

(test-require 'foo.core)
; {:name foo.core, :macros nil, :path "foo/core"}
; {:value true}
Comment by Mike Fikes [ 28/Jul/15 5:16 PM ]

With {:verbose true}

cljs.user=> *clojurescript-version*
"0.0-3670"
cljs.user=> (test-require 'test.alpha)
Loading test.alpha namespace
{:name test.alpha, :macros nil, :path "test/alpha"}
Evaluating test.alpha
Namespace side effects for test.alpha
Loading dependencies for test.alpha
Loading test.beta namespace
{:name test.beta, :macros nil, :path "test/beta"}
Evaluating test.beta
Namespace side effects for test.beta
goog.provide("test.beta");

Loading dependencies for test.alpha
goog.provide("test.alpha");

{:value true}
nil
cljs.user=> (test-require 'foo.core)
Loading foo.core namespace
{:name foo.core, :macros nil, :path "foo/core"}
Evaluating foo.core
Namespace side effects for foo.core
goog.provide("foo.core");

{:value true}
nil
Comment by David Nolen [ 28/Jul/15 5:40 PM ]

fixed https://github.com/clojure/clojurescript/commit/078f207884304dd39c61775345505d4da7ca9b64

Comment by Mike Fikes [ 28/Jul/15 5:53 PM ]

Confirmed fixed using the minimal repro. I now see:

cljs.user=> (test-require 'foo.core)
{:name foo.core, :macros nil, :path "foo/core"}
{:name foo.macros, :macros true, :path "foo/macros"}
{:value true}
nil




[CLJS-1373] Generalize CLJS-1324, check invokes of all IFn implementors Created: 28/Jul/15  Updated: 31/Jul/15

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: 1.7.28
Fix Version/s: Next

Type: Enhancement Priority: Major
Reporter: David Nolen Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None


 Description   

We currently track all IFn implementors but in order to do arity checking of statically analyzeable invokes of keywords, vector, etc. we need to do a bit more. extend-type should update the type in the compiler state with :method-params :max-fixed-arity and :variadic. Then we can just reuse the existing checks in cljs.analyzer/parse-invoke.






[CLJS-1372] cljs.stacktrace: Unconditional File reference in :nashorn section Created: 27/Jul/15  Updated: 27/Jul/15  Resolved: 27/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Mike Fikes
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File CLJS-1372.patch    

 Description   

In the :nashorn impl there is a platform-dependent line referring to Java File/separator

https://github.com/clojure/clojurescript/blob/fa0da846e6f30eec330fac9e2ac8aced2660d20f/src/main/cljs/cljs/stacktrace.cljc#L414

Perhaps the entire (defmethod parse-stacktrace :nashorn should be conditional on :clj?



 Comments   
Comment by Mike Fikes [ 27/Jul/15 11:33 AM ]

Attached patch copies approach taken for :rhino.

Passes unit tests and this smoke test:

orion:clojurescript mfikes$ script/nashornrepljs 
To quit, type: :cljs/quit
cljs.user=> (ffirst 1)
Error: 1 is not ISeqable
	 cljs$core$seq (.cljs_nashorn_repl/cljs/core.cljs:1067:36)
	 cljs.core/first (.cljs_nashorn_repl/cljs/core.cljs:1076:13)
	 cljs$core$ffirst (.cljs_nashorn_repl/cljs/core.cljs:1514:4)
	 (NO_SOURCE_FILE <eval>:1:0)
	 (NO_SOURCE_FILE <eval>:1:0)
	 (NO_SOURCE_FILE <eval>:1:0)
Comment by David Nolen [ 27/Jul/15 2:00 PM ]

fixed https://github.com/clojure/clojurescript/commit/d7db622e4eecf305bbf24c107e3b05d926fd916a





[CLJS-1371] cljs.js: Core functions in required namespaces Created: 27/Jul/15  Updated: 27/Jul/15  Resolved: 27/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: None


 Description   

Like CLJS-1362, but for required namespaces.

I have a namespace that uses map:

(ns foo.bar)

(defn test-me []
  (map inc [1 2 3]))

(defn test-me-2 []
  (cljs.core/map inc [1 2 3]))

Here is a transcript from Planck illustrating an issue with map being used in test-me:

cljs.user=> *clojurescript-version*
"0.0-3654"
cljs.user=> (map inc [1 2 3])
(2 3 4)
cljs.user=> (require 'foo.bar)
cljs.user=> (foo.bar/test-me-2)
(2 3 4)
cljs.user=> (foo.bar/test-me)
undefined is not an object (evaluating 'foo.bar.map.call') 
 foo$bar$test_me
cljs.user=>


 Comments   
Comment by Mike Fikes [ 27/Jul/15 9:52 AM ]

Defect in Planck not cljs.js: I was passing an empty compiler environment into cljs.js/require instead of my atom.





[CLJS-1370] cljs.js: Path for goog off Created: 27/Jul/15  Updated: 30/Jul/15  Resolved: 30/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Mike Fikes Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: bootstrap


 Description   

I have a namespace that indirectly uses goog.

(ns foo.bar
  (:require clojure.string))

(def a 4)

When I use cljs.js to require this source, ultimately the path "goog/string" is passed to *load-fn*. The transcript here shows the argument sequence passed to *load-fn*.

cljs.user=> (require 'foo.bar)
{:name foo.bar, :macros nil, :path "foo/bar"}
{:name clojure.string, :macros nil, :path "clojure/string"}
{:name goog.string, :macros nil, :path "goog/string"}

My *load-fn* implementation successfully loads clojure/string.cljs which contains

(:require [goog.string :as gstring])

as one of its namespace specs, which triggers the last path "goog/string".

On disk, there is actually "goog/string/string.js" that could be loaded, but before trying any hacking surrounding that, figured I'd submit a ticket regarding this case.



 Comments   
Comment by David Nolen [ 30/Jul/15 3:24 PM ]

We're not going to address this one at all. REPLs will have to provide their own Google Closure Library index to make this work.





[CLJS-1369] eval-str should support compilation output caching Created: 27/Jul/15  Updated: 27/Jul/15  Resolved: 27/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: None

Type: Defect Priority: Major
Reporter: David Nolen Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: bootstrap


 Description   

This is the only place for people to run side effects (like writing compilation output to disk).



 Comments   
Comment by David Nolen [ 27/Jul/15 9:12 AM ]

fixed https://github.com/clojure/clojurescript/commit/de8bc1c4cce44e9c6de07bbf79411463138939ee





[CLJS-1368] cljs.analyzer tests broken, undeclared-var warning doesn't work Created: 26/Jul/15  Updated: 27/Jul/15  Resolved: 27/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: 1.7.28

Type: Defect Priority: Major
Reporter: Juho Teperi Assignee: David Nolen
Resolution: Completed Votes: 0
Labels: None


 Description   

A test in `cljs.analyzer-tests` is failing because undeclared-var test doesn't produce warning: https://github.com/clojure/clojurescript/blob/bf643dbbb06eb7ae5ec27cb9feaa9aa41960862f/src/test/clojure/cljs/analyzer_tests.clj#L31

I bisected the problem to this commit: https://github.com/clojure/clojurescript/commit/f46db8f693b7337cdc095819e412ee3e154d9e83



 Comments   
Comment by David Nolen [ 27/Jul/15 7:40 AM ]

fixed https://github.com/clojure/clojurescript/commit/8b70d7541ffd61789c6e95b1d58e471e12d310e0





[CLJS-1367] cljs.analyzer.api warning handler utilities Created: 26/Jul/15  Updated: 28/Jul/15  Resolved: 28/Jul/15

Status: Closed
Project: ClojureScript
Component/s: None
Affects Version/s: 0.0-3308
Fix Version/s: 1.7.28

Type: Enhancement Priority: Major
Reporter: Juho Teperi Assignee: Juho Teperi
Resolution: Completed Votes: 0
Labels: None

Attachments: Text File cljs-1367-1.patch     Text File cljs-1367-2.patch     Text File cljs-1367-3.patch    

 Description   

To see if warnings happened during the compilation process build tooling has to currently use cljs.analyzer ns directly.

In boot-cljs we currently use cljs.analyzer/with-warning-handlers to append our own warning-handler to default handlers to count number of warnings.

I propose adding with-warning-handlers to cljs.analyzer.api. Also there should be a way to modify existing warning-handlers binding without overwriting the default handlers, my idea is to provide vary-warning-handlers macro which would use given function to create new handlers collection.

The default warning handler uses cljs.analyzer/*cljs-warnings* to check if warning was enabled, this should be exposed also.

I have implemented the changes already, but I have some problems testing them as I can't get {[analyze}} to generate any warnings.



 Comments   
Comment by Juho Teperi [ 26/Jul/15 12:58 PM ]

I noticed it's undeclared-var warning which is not working, so I used another warning to test these utilities.

Comment by Juho Teperi [ 26/Jul/15 3:58 PM ]

Here is the code in boot-cljs which uses warning handlers: https://github.com/adzerk-oss/boot-cljs/blob/31732b3d723c6f0a0f9d60384fb27d893976c5c5/src/adzerk/boot_cljs/impl.clj#L36-L52

The number of warnings in interesting because Boot can for example play notification sound if warning count in non-zero.

If others think number of warnings is common use case, perhaps that should be directly exposed in the api? Though I'm not sure how that would look like.

Comment by David Nolen [ 27/Jul/15 4:43 AM ]

There's no need to expose the dynamic binding aspect of the underlying implementation. Instead this should be configurable via opts.

Comment by Juho Teperi [ 27/Jul/15 10:53 AM ]

This version adds code to any api function which takes opts argument and uses `:warning-handlers` key to set the dynamic binding.

Not sure if using with-bindings is the best approach, but this version should show where the opts need to be handled.

Comment by David Nolen [ 27/Jul/15 2:03 PM ]

Have you confirmed this approach works under AOT? I'm always very wary of var-centric code like this.

Comment by Juho Teperi [ 28/Jul/15 12:54 PM ]

New version with bindings inline. Also adds state as first argument to any api call which uses compiler-env.

env/with-compiler-env throws error if compiler-env is nil which changes functionality in some cases which previously could work without compiler-env (analyze).

I can think of two fixes for this:

  • Setting compiler-env directly using binding
  • Instead of calling state-version of function from other arities, call the implementation directly thus working exactly like before
Comment by David Nolen [ 28/Jul/15 4:39 PM ]

fixed https://github.com/clojure/clojurescript/commit/9e662c3ea5b9f536f303e9084415e988bf5d0878





Generated at Sat Aug 01 06:56:06 CDT 2015 using JIRA 4.4#649-r158309.