1 ;;;; compiler parts of the single stepper
3 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
14 ;;; Local stepping control: STEP binds this to T, and when forms are
15 ;;; being skipped this is bound to NIL down the stack to prevent
16 ;;; signalling of STEP-CONDITIONs.
19 ;;; Global stepping control: STEP binds this to T, and when the
20 ;;; restart to continue without stepping is selected this is set to
21 ;;; NIL to prevent the *STEPPER-HOOK* from being called.
22 (defvar *stepping
* nil
)
24 (defun step-form (form source-path pathname
)
27 (signal 'step-form-condition
29 :source-path source-path
32 (setf *stepping
* nil
))
38 (defun step-variable (symbol value
)
40 (signal 'step-variable-condition
:form symbol
:result value
)))
42 (defun step-values (form values
)
44 (signal 'step-values-condition
:form form
:result values
)))
46 (defun insert-step-conditions (form)
48 (optimize (insert-step-conditions
49 ,(policy *lexenv
* insert-step-conditions
))))
52 ;;; Flag to control instrumentation function call arguments.
53 (defvar *step-arguments-p
* nil
)
55 (defun known-single-value-fun-p (fun)
56 (and (legal-fun-name-p fun
)
57 (info :function
:info fun
)
58 (let ((type (info :function
:type fun
)))
59 (and (and (fun-type-p type
))
60 (type-single-value-p (fun-type-returns type
))))))
62 (defun ir1-convert-step (start next result form
)
63 (let ((form-string (let ((*print-pretty
* t
)
64 (*print-readably
* nil
))
65 (prin1-to-string form
))))
68 (let ((ctran (make-ctran))
69 (*allow-instrumenting
* nil
))
70 (ir1-convert start ctran nil
`(step-variable ,form-string
,form
))
71 (ir1-convert ctran next result form
)))
73 (let* ((*step-arguments-p
* (and *allow-instrumenting
*
74 (policy *lexenv
* (= insert-step-conditions
3))))
75 (step-form `(step-form ,form-string
76 ',(source-path-original-source *current-path
*)
77 *compile-file-pathname
*))
80 ,@(if *step-arguments-p
*
81 (mapcar #'insert-step-conditions
(cdr form
))
83 (ir1-convert start next result
84 `(locally (declare (optimize (insert-step-conditions 0)))
85 ,(if *step-arguments-p
*
86 `(let ((*step
* ,step-form
))
87 ,(if (known-single-value-fun-p fun
)
89 (step-values ,form-string
(list value
))
93 (lambda (&rest values
)
94 (step-values ,form-string values
)
97 `(progn ,step-form
,values-form
)))))))))
99 (defun step-form-p (form)
100 #+sb-xc-host
(declare (ignore form
))
102 (flet ((step-symbol-p (symbol)
103 (not (member (symbol-package symbol
)
105 ;; KLUDGE: packages we're not interested in stepping.
106 (mapcar #'find-package
'(sb!c sb
!int sb
!impl sb
!kernel sb
!pcl
)))))))
107 (let ((lexenv *lexenv
*))
108 (and *allow-instrumenting
*
109 (policy lexenv
(>= insert-step-conditions
2))
111 (let ((op (car form
)))
112 (or (and (consp op
) (eq 'lambda
(car op
)))
114 (not (special-operator-p op
))
115 (member (lexenv-find op funs
) '(nil functional global-var
))
116 (not (eq :macro
(info :function
:kind op
)))
117 (step-symbol-p op
)))))
119 (and *step-arguments-p
*
120 *allow-instrumenting
*
121 (policy lexenv
(= insert-step-conditions
3))
122 (not (consp (lexenv-find form vars
)))
123 (not (constantp form
))
124 (step-symbol-p form
))))))))