count (zerop count))
(let ((n 0))
(declare (type index n))
- (dohash (k v x)
+ (dohash ((k v) x :locked t)
(unless (zerop n)
(write-char #\space s))
(incf n)
;; any nondefault options.
(format-universal-time nil (sb-c::debug-source-compiled source)
:style :abbreviated))
- (let ((name (sb-c::debug-source-name source)))
- (ecase (sb-c::debug-source-from source)
- (:file
- (format s "~&~A~@:_ Created: " (namestring name))
- (format-universal-time s (sb-c::debug-source-created source)))
- (:lisp (format s "~& ~S" (aref name 0))))))))))
+ (let ((name (sb-c::debug-source-namestring source)))
+ (cond (name
+ (format s "~&~A~@:_ Created: " name)
+ (format-universal-time s (sb-c::debug-source-created source)))
+ ((sb-di:debug-source-form source)
+ (format s "~& ~S" (sb-di:debug-source-form source)))
+ (t (bug "Don't know how to use a DEBUG-SOURCE without ~
+ a namestring or a form.")))))))))
;;; Describe a compiled function. The closure case calls us to print
;;; the guts.
(%describe-fun-name name s (%simple-fun-type x))))
(%describe-compiled-from (sb-kernel:fun-code-header x) s))
+(defun %describe-fun (x s &optional (kind :function) (name nil))
+ (etypecase x
+ #+sb-eval
+ (sb-eval:interpreted-function
+ (%describe-interpreted-fun x s kind name))
+ (function
+ (%describe-compiled-fun x s kind name))))
+
;;; Describe a function object. KIND and NAME provide some information
;;; about where the function came from.
-(defun %describe-fun (x s &optional (kind :function) (name nil))
+(defun %describe-compiled-fun (x s &optional (kind :function) (name nil))
(declare (type function x))
(declare (type stream s))
(declare (type (member :macro :function) kind))
(format s "~S is a function." x))))
(format s "~@:_~@<Its associated name (as in ~S) is ~2I~_~S.~:>"
'function-lambda-expression
- (%fun-name x))
- (case (widetag-of x)
- (#.sb-vm:closure-header-widetag
+ (nth-value 2 (function-lambda-expression x)))
+ (typecase x
+ (closure
(%describe-fun-compiled (%closure-fun x) s kind name)
(format s "~&Its closure environment is:")
- (loop for value in (%closure-values x)
- for i = 0 then (1+ i)
- do (format s "~& ~S: ~S" i value)))
- (#.sb-vm:simple-fun-header-widetag
+ (let ((i -1))
+ (do-closure-values (value x)
+ (format s "~& ~S: ~S" (incf i) value))))
+ (simple-fun
(%describe-fun-compiled x s kind name))
- (#.sb-vm:funcallable-instance-header-widetag
+ (funcallable-instance
;; Only STANDARD-GENERIC-FUNCTION would be handled here, but
;; since it has its own DESCRIBE-OBJECT method, it should've been
;; picked off before getting here. So hopefully we never get here.
(format s "~@:_It is an unknown type of function."))))
(terpri s))
+;; Describe an interpreted function.
+#+sb-eval
+(defun %describe-interpreted-fun (x s &optional (kind :function) (name nil))
+ (declare (type sb-eval:interpreted-function x))
+ (declare (type stream s))
+ (declare (type (member :macro :function) kind))
+ (fresh-line s)
+ (pprint-logical-block (s nil)
+ (ecase kind
+ (:macro (format s "Macro-function: ~S" x))
+ (:function (if name
+ (format s "Function: ~S" x)
+ (format s "~S is a function." x))))
+ (format s "~@:_~@<Its associated name (as in ~S) is ~2I~_~S.~:>"
+ 'function-lambda-expression
+ (nth-value 2 (function-lambda-expression x)))
+ (format s "~&It is an interpreted function.~%")
+ (let ((args (sb-eval:interpreted-function-debug-lambda-list x)))
+ (format s "Its lambda-list is: ")
+ (let ((*print-pretty* t)
+ (*print-escape* t)
+ (*print-base* 10)
+ (*print-radix* nil))
+ (pprint-logical-block (s nil)
+ (pprint-indent :current 2)
+ (format s "~A" args)))
+ (format s "~&It was defined as:~% ")
+ (let ((*print-pretty* t)
+ (*print-escape* t)
+ (*print-base* 10)
+ (*print-radix* nil))
+ (pprint-logical-block (s nil)
+ (pprint-indent :current 2)
+ (format s "~S" (function-lambda-expression x))))))
+ (terpri s))
+
(defmethod describe-object ((x function) s)
(%describe-fun x s :function))
(:special "special variable")
(:macro "symbol macro")
(:constant "constant")
- (:global "undefined variable")
+ (:global "global variable")
+ (:unknown "undefined variable")
(:alien nil))))
(pprint-logical-block (s nil)
(cond
((boundp x)
(format s "~&~@<It is a ~A; its ~_value is ~S.~:>"
wot (symbol-value x)))
- ((not (eq kind :global))
+ ((not (eq kind :unknown))
(format s "~&~@<It is a ~A; no current value.~:>" wot)))
(when (eq (info :variable :where-from x) :declared)
((fboundp x)
(describe-symbol-fdefinition (fdefinition x) s :name x)))
+ ;; Describe deftype lambda-list and doc
+ (when (info :type :expander x)
+ (format s "~&DEFTYPE lambda-list: ~A" (info :type :lambda-list x))
+ (%describe-doc x s 'type "Type"))
+
;; Print other documentation.
(%describe-doc x s 'structure "Structure")
- (%describe-doc x s 'type "Type")
(%describe-doc x s 'setf "Setf macro")
(dolist (assoc (info :random-documentation :stuff x))
- (format s
- "~&~@<Documentation on the ~(~A~):~@:_~A~:>"
- (car assoc)
- (cdr assoc)))
+ (let ((type (car assoc)))
+ (format s
+ "~&~@<Documentation on the ~(~A~):~@:_~A~:>"
+ (case type
+ ((optimize) "optimize quality")
+ (t (car assoc)))
+ (cdr assoc))))
;; Mention the associated type information, if any.
;;