The first is CLHS 9.1.4.1: a clause that signalled the condition it handles used to re-enter itself until the stack ran out. The stale list now names a lifted clause by the function it is written in, and BUILT.md's cost line is measured against master.
47 lines
1.4 KiB
Plaintext
47 lines
1.4 KiB
Plaintext
;;;; A handler-bind clause that signals the condition it is handling.
|
|
;;;;
|
|
;;;; While a clause runs, the handlers in force are the ones that were in force
|
|
;;;; when its handler-bind was established (CLHS 9.1.4.1). So the inner clause's
|
|
;;;; own bad index reaches the *outer* clause, once, and not the inner one
|
|
;;;; again — which used to recurse until the stack ran out.
|
|
;;;;
|
|
;;;; The second half is the other order: after the inner clause has run and
|
|
;;;; declined, the handler it belongs to is in force again for the next signal.
|
|
|
|
(defonce hits i64)
|
|
(def grid [4 i32] [1 2 3 4])
|
|
|
|
(defn bad [i i32] i32 (at grid i))
|
|
|
|
(defn nested [] i64
|
|
(restart-case
|
|
(handler-bind [(BoundsError [c] (set hits (+ hits 100)) (invoke-restart 'outer))]
|
|
(restart-case
|
|
(handler-bind [(BoundsError [c]
|
|
(set hits (+ hits 1))
|
|
(bad 9)
|
|
(invoke-restart 'inner))]
|
|
(bad 7))
|
|
(inner [] 0)))
|
|
(outer [] 0))
|
|
hits)
|
|
|
|
(defn again [] i64
|
|
(set hits 0)
|
|
(restart-case
|
|
(handler-bind [(BoundsError [c] (set hits (+ hits 1)) (invoke-restart 'out))]
|
|
(handler-bind [(BoundsError [c] (set hits (+ hits 10)))]
|
|
(bad 5)
|
|
0))
|
|
(out [] 0))
|
|
(restart-case
|
|
(handler-bind [(BoundsError [c] (set hits (+ hits 1000)) (invoke-restart 'out))]
|
|
(bad 6))
|
|
(out [] 0))
|
|
hits)
|
|
|
|
(defn main [] i32
|
|
(println (nested))
|
|
(println (again))
|
|
0)
|