better SIGNAL
authorNikodemus Siivola <nikodemus@random-state.net>
Mon, 21 May 2012 20:27:53 +0000 (23:27 +0300)
committerNikodemus Siivola <nikodemus@random-state.net>
Tue, 22 May 2012 18:53:04 +0000 (21:53 +0300)
  Add *STACK-TOP-HINT*.

  Move out the *BREAK-ON-SIGNALS* stuff to a separate function for
  clarity. Conditionalize the call there, meaning those restarts don't need to
  be allocated unless we actually need them -- making SIGNAL faster and a lot
  less consy. (TYPEP calls still cons, though. Can't have everything...)

src/code/cold-error.lisp

index 966d189..fb4926c 100644 (file)
   "When (TYPEP condition *BREAK-ON-SIGNALS*) is true, then calls to SIGNAL will
    enter the debugger prior to signalling that condition.")
 
-(defun signal (datum &rest arguments)
-  #!+sb-doc
-  "Invokes the signal facility on a condition formed from DATUM and
-   ARGUMENTS. If the condition is not handled, NIL is returned. If
-   (TYPEP condition *BREAK-ON-SIGNALS*) is true, the debugger is invoked
-   before any signalling is done."
-  (let ((condition (coerce-to-condition datum
-                                        arguments
-                                        'simple-condition
-                                        'signal))
-        (*handler-clusters* *handler-clusters*)
-        (old-bos *break-on-signals*)
+(defun maybe-break-on-signal (condition)
+  (let ((old-bos *break-on-signals*)
         (bos-actually-breaking nil))
     (restart-case
         (let ((break-on-signals *break-on-signals*)
         (lambda (stream)
           (format stream
                   (if bos-actually-breaking
-                    "Return from BREAK and assign a new value to ~
-                     *BREAK-ON-SIGNALS*."
-                    "Assign a new value to *BREAK-ON-SIGNALS* and ~
-                     continue with signal handling.")))
+                      "Return from BREAK and assign a new value to ~
+                       *BREAK-ON-SIGNALS*."
+                      "Assign a new value to *BREAK-ON-SIGNALS* and ~
+                       continue with signal handling.")))
         :interactive
         (lambda ()
           (let (new-value)
             (loop
-             (format *query-io*
-                     "Enter new value for *BREAK-ON-SIGNALS*. ~
-                      Current value is ~S.~%~
-                      > "
-                     old-bos)
-             (force-output *query-io*)
-             (let ((*break-on-signals* nil))
-               (setf new-value (eval (read *query-io*)))
-               (if (typep new-value 'type-specifier)
-                   (return)
-                   (format *query-io*
-                           "~S is not a valid value for *BREAK-ON-SIGNALS* ~
-                            (must be a type-specifier).~%"
-                           new-value))))
+              (format *query-io*
+                      "Enter new value for *BREAK-ON-SIGNALS*. ~
+                       Current value is ~S.~%~
+                       > "
+                      old-bos)
+              (force-output *query-io*)
+              (let ((*break-on-signals* nil))
+                (setf new-value (eval (read *query-io*)))
+                (if (typep new-value 'type-specifier)
+                    (return)
+                    (format *query-io*
+                            "~S is not a valid value for *BREAK-ON-SIGNALS* ~
+                             (must be a type-specifier).~%"
+                            new-value))))
             (list new-value)))
-        (setf *break-on-signals* new-value)))
+        (setf *break-on-signals* new-value)))))
+
+(defun signal (datum &rest arguments)
+  #!+sb-doc
+  "Invokes the signal facility on a condition formed from DATUM and
+   ARGUMENTS. If the condition is not handled, NIL is returned. If
+   (TYPEP condition *BREAK-ON-SIGNALS*) is true, the debugger is invoked
+   before any signalling is done."
+  (let ((condition (coerce-to-condition datum
+                                        arguments
+                                        'simple-condition
+                                        'signal))
+        (*handler-clusters* *handler-clusters*)
+        (sb!debug:*stack-top-hint* (or sb!debug:*stack-top-hint* 'signal)))
+    (when *break-on-signals*
+      (maybe-break-on-signal condition))
     (loop
       (unless *handler-clusters*
         (return))