clojurescript icon indicating copy to clipboard operation
clojurescript copied to clipboard

catch js/Object e causes `Can't qualify symbol in catch` error

Open wbrown opened this issue 11 years ago • 5 comments

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.

wbrown avatar Apr 23 '14 21:04 wbrown

As referenced in the now closed pull request, this doesn't produce correct compiled output.

}catch (js.Object){var statearr_4209_4222 = state_4190;

wbrown avatar Apr 23 '14 23:04 wbrown

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.

wbrown avatar Apr 24 '14 00:04 wbrown

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).

kanaka avatar Apr 24 '14 04:04 kanaka

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.

wbrown avatar Apr 24 '14 05:04 wbrown

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

wbrown avatar Apr 24 '14 18:04 wbrown