(defn
process-exception
[state]
(let
[exception-frame
(aget-object state EXCEPTION-FRAMES)
catch-block
(:catch-block exception-frame)
catch-exception
(:catch-exception exception-frame)
exception
(aget-object state CURRENT-EXCEPTION)]
(cond
(and exception (not exception-frame))
(throw exception)
(and
exception
catch-block
(or
(= :default catch-exception)
(instance? catch-exception exception)))
(ioc/aset-all!
state
STATE-IDX
catch-block
VALUE-IDX
exception
CURRENT-EXCEPTION
nil
EXCEPTION-FRAMES
(assoc exception-frame :catch-block nil :catch-exception nil))
(and
exception
(not catch-block)
(not (:finally-block exception-frame)))
(do
(ioc/aset-all! state EXCEPTION-FRAMES (:prev exception-frame))
(recur state))
(and exception (not catch-block) (:finally-block exception-frame))
(ioc/aset-all!
state
STATE-IDX
(:finally-block exception-frame)
EXCEPTION-FRAMES
(assoc exception-frame :finally-block nil))
(and (not exception) (:finally-block exception-frame))
(do
(ioc/aset-all!
state
STATE-IDX
(:finally-block exception-frame)
EXCEPTION-FRAMES
(assoc exception-frame :finally-block nil)))
(and (not exception) (not (:finally-block exception-frame)))
(do
(ioc/aset-all!
state
STATE-IDX
(:continue-block exception-frame)
EXCEPTION-FRAMES
(:prev exception-frame)))
:else
(throw (js/Error. "No matching clause")))))