catch js/Object e causes `Can't qualify symbol in catch` error
I am trying to get core.async built with the compiler in the cljsc-in-cljsc tree. It looks like it takes exception to the js namespace for catch.
https://github.com/clojure/core.async/blob/master/src/main/clojure/cljs/core/async.cljs#L700
(catch js/Object e
(swap! dctr dec))))
The output given is:
Exception in thread "main" java.lang.AssertionError: Assert failed: Can't qualify symbol in catch
(not (namespace name))
at cljs.analyzer$eval124$fn__126.invoke(analyzer.clj:284)
at clojure.lang.MultiFn.invoke(MultiFn.java:241)
at cljs.analyzer$analyze_seq.invoke(analyzer.clj:898)
at cljs.analyzer$analyze.invoke(analyzer.clj:953)
at cljs.analyzer$analyze_seq.invoke(analyzer.clj:900)
Looking at the analyzer.js code, it looks like we have a few special exceptions for namespace references to js -- I will see if I can get this to understand that it can ignore a namespace of 'js', but hints would be appreciated.
As referenced in the now closed pull request, this doesn't produce correct compiled output.
}catch (js.Object){var statearr_4209_4222 = state_4190;
After some digging and some test compilation, it turns out that it works just fine with js/Object in most cases.. However, the wrench in the works is the cljs.core.async.impl.ioc-macros namespace having a state machine generator.
https://github.com/clojure/core.async/blob/master/src/main/clojure/cljs/core/async/impl/ioc_macros.clj#L851
(fn state-machine#
([] (aset-all! (make-array ~state-arr-size)
~FN-IDX state-machine#
~STATE-IDX ~(:start-block machine)))
([~state-sym]
(let [ret-value# (try (loop []
(let [result# (switch# ~state-sym)]
(if (cljs.core/keyword-identical? result# :recur)
(recur)
result#)))
(catch js/Object ex#
(aset-all! ~state-sym ~CURRENT-EXCEPTION ex#)
(cljs.core.async.impl.ioc-helpers/process-exception ~state-sym)
:recur))]
(if (cljs.core/keyword-identical? ret-value# :recur)
(recur ~state-sym)
ret-value#)))))))
It looks like something in the compiler is not quite working right with the emitter from the state machine generator.
Please note that the code base is over 1 year out of date. If you are feeling (very) ambitious, you could merge it forward. You would learn a LOT about the compiler :-)
Regarding the problem, it might be interesting to try and macroexpand the macro. The error may become obvious (or not).
I've already partially started that process by going ahead and backporting some changes in against analyzer and compiler related to try/catch that are six months newer, but not quite so earth shattering as the current bleeding edge ClojureScript. Basically, at around six months ago, they went ahead and unified the try/catch forms with that of the Java version. The current one has changed drastically relative to one year ago.
The partial backport seems to have done the trick. I'll put up a pull request once I'm confident that the non-trivial changes to the analyzer and compiler don't break other stuff. My interest mainly is in getting this to a workable state for my contract project, so my changes immediately are going to be on an 'as needed' basis.
I'm no stranger to compilers and interpreters: https://github.com/ephsec/svforth :)
-Wes
On Apr 24, 2014, at 12:25 AM, Joel Martin [email protected] wrote:
Please note that the code base is over 1 year out of date. If you are feeling (very) ambitious, you could merge it forward. You would learn a LOT about the compiler :-)
Regarding the problem, it might be interesting to try and macroexpand the macro. The error may become obvious (or not).
— Reply to this email directly or view it on GitHub.
Finally resolve this issue by going back in time and finding the least intrusive change to the try/catch form, which was when they applied CLJS613. I've opened a pull request at #43