+(defun wrap-forms-in-debug-catch (forms)
+ #!+unwind-to-frame-and-call-vop
+ `((multiple-value-prog1
+ (progn
+ ,@forms)
+ ;; Just ensure that there won't be any tail-calls, IR2 magic will
+ ;; handle the rest.
+ (values)))
+ #!-unwind-to-frame-and-call-vop
+ `( ;; Normally, we'll return from this block with the below RETURN-FROM.
+ (block
+ return-value-tag
+ ;; If DEBUG-CATCH-TAG is thrown (with a thunk as the value) the
+ ;; RETURN-FROM is elided and we funcall the thunk instead. That
+ ;; thunk might either return a value (for a RETURN-FROM-FRAME)
+ ;; or call this same function again (for a RESTART-FRAME).
+ ;; -- JES, 2007-01-09
+ (funcall
+ (the function
+ ;; Use a constant catch tag instead of consing a new one for every
+ ;; entry to this block. The uniquencess of the catch tags is
+ ;; ensured when the tag is throw by the debugger. It'll allocate a
+ ;; new tag, and modify the reference this tag in the proper
+ ;; catch-block structure to refer to that new tag. This
+ ;; significantly decreases the runtime cost of high debug levels.
+ ;; -- JES, 2007-01-09
+ (catch 'debug-catch-tag
+ (return-from return-value-tag
+ (progn
+ ,@forms))))))))
+