Skip to content

Commit

Permalink
Support interrupting (recursive) function call
Browse files Browse the repository at this point in the history
  • Loading branch information
mk committed Oct 31, 2024
1 parent 6d9380f commit 7145c3a
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/sci/impl/fns.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
~@(when varargs
[`(aset ~'invoc-array ~'vararg-idx ~varargs-param)])
(loop []
#?(:clj (when (java.lang.Thread/.isInterrupted (Thread/currentThread))
(throw (java.lang.InterruptedException.))))
(let [ret# (types/eval ~'body ~'ctx ~'invoc-array)]
(if (kw-identical? :sci.impl.analyzer/recur ret#)
(recur)
Expand All @@ -44,6 +46,8 @@
~@(when varargs
[`(aset ~'invoc-array ~'vararg-idx ~varargs-param)])
(loop []
#?(:clj (when (java.lang.Thread/.isInterrupted (Thread/currentThread))
(throw (java.lang.InterruptedException.))))
(let [ret# (types/eval ~'body ~'ctx ~'invoc-array)]
(if (kw-identical? :sci.impl.analyzer/recur ret#)
(recur)
Expand Down
16 changes: 15 additions & 1 deletion test/sci/core_test.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -1703,15 +1703,29 @@
(is (true? (sci/eval-string "(exists? js/console.log)" {:classes {'js js/globalThis
:allow :all}})))
(is (false? (sci/eval-string "(exists? js/foo.bar)" {:classes {'js js/globalThis
:allow :all}})))
:allow :all}})))
(is (false? (sci/eval-string "(exists? js/console.log.foobar)" {:classes {'js js/globalThis
:allow :all}})))
(is (false? (sci/eval-string "(exists? console.log)" {:classes {'js js/globalThis
:allow :all}})))))

#?(:clj
(deftest interrupt-test
(testing "check that long-running recursive function can be interrupted")
(let [thread (Thread. (fn []
(sci/eval-form
(sci/init {})
'((fn a [n] (if (#{0 1} n) 1 (+ (a (- n 2)) (a (- n 1))))) 35))))]
(.start thread)
(is (= java.lang.Thread$State/RUNNABLE (.getState thread)))
(.interrupt thread)
(Thread/sleep 50)
(is (= java.lang.Thread$State/TERMINATED (.getState thread))))))

;;;; Scratch

(comment
(eval* 1 '(inc *in*))
(test-difference "foo" "[10 10]" 0 10)
(test-difference "rand" #(rand) 0 10))

0 comments on commit 7145c3a

Please sign in to comment.