X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fcondition.lisp;h=5b471c0e953fb1a7012db4149ba37d5337c76231;hb=61dc1d5c0b4988f7e957be876a9abf9f31d51e0a;hp=f8e70f3cb595a59e3b42dabb40ddea77e29c2d94;hpb=1a68f34a511841986710cc0012417a8633ab7241;p=sbcl.git diff --git a/src/code/condition.lisp b/src/code/condition.lisp index f8e70f3..5b471c0 100644 --- a/src/code/condition.lisp +++ b/src/code/condition.lisp @@ -266,7 +266,6 @@ (return nil))) (setf (getf (condition-assigned-slots res) (condition-slot-name hslot)) (find-slot-default class hslot)))) - res)) ;;;; DEFINE-CONDITION @@ -274,47 +273,49 @@ (eval-when (:compile-toplevel :load-toplevel :execute) (defun %compiler-define-condition (name direct-supers layout all-readers all-writers) - (sb!xc:proclaim `(ftype (function (t) t) ,@all-readers)) - (sb!xc:proclaim `(ftype (function (t t) t) ,@all-writers)) - (multiple-value-bind (class old-layout) - (insured-find-classoid name - #'condition-classoid-p - #'make-condition-classoid) - (setf (layout-classoid layout) class) - (setf (classoid-direct-superclasses class) - (mapcar #'find-classoid direct-supers)) - (cond ((not old-layout) - (register-layout layout)) - ((not *type-system-initialized*) - (setf (layout-classoid old-layout) class) - (setq layout old-layout) - (unless (eq (classoid-layout class) layout) + (with-single-package-locked-error + (:symbol name "defining ~A as a condition") + (sb!xc:proclaim `(ftype (function (t) t) ,@all-readers)) + (sb!xc:proclaim `(ftype (function (t t) t) ,@all-writers)) + (multiple-value-bind (class old-layout) + (insured-find-classoid name + #'condition-classoid-p + #'make-condition-classoid) + (setf (layout-classoid layout) class) + (setf (classoid-direct-superclasses class) + (mapcar #'find-classoid direct-supers)) + (cond ((not old-layout) + (register-layout layout)) + ((not *type-system-initialized*) + (setf (layout-classoid old-layout) class) + (setq layout old-layout) + (unless (eq (classoid-layout class) layout) + (register-layout layout))) + ((redefine-layout-warning "current" + old-layout + "new" + (layout-length layout) + (layout-inherits layout) + (layout-depthoid layout)) + (register-layout layout :invalidate t)) + ((not (classoid-layout class)) (register-layout layout))) - ((redefine-layout-warning "current" - old-layout - "new" - (layout-length layout) - (layout-inherits layout) - (layout-depthoid layout)) - (register-layout layout :invalidate t)) - ((not (classoid-layout class)) - (register-layout layout))) - - (setf (layout-info layout) - (locally - ;; KLUDGE: There's a FIND-CLASS DEFTRANSFORM for constant class - ;; names which creates fast but non-cold-loadable, non-compact - ;; code. In this context, we'd rather have compact, cold-loadable - ;; code. -- WHN 19990928 - (declare (notinline find-classoid)) - (layout-info (classoid-layout (find-classoid 'condition))))) - - (setf (find-classoid name) class) - - ;; Initialize CPL slot. - (setf (condition-classoid-cpl class) - (remove-if-not #'condition-classoid-p - (std-compute-class-precedence-list class)))) + + (setf (layout-info layout) + (locally + ;; KLUDGE: There's a FIND-CLASS DEFTRANSFORM for constant class + ;; names which creates fast but non-cold-loadable, non-compact + ;; code. In this context, we'd rather have compact, cold-loadable + ;; code. -- WHN 19990928 + (declare (notinline find-classoid)) + (layout-info (classoid-layout (find-classoid 'condition))))) + + (setf (find-classoid name) class) + + ;; Initialize CPL slot. + (setf (condition-classoid-cpl class) + (remove-if-not #'condition-classoid-p + (std-compute-class-precedence-list class))))) (values)) ) ; EVAL-WHEN @@ -369,49 +370,51 @@ (defun %define-condition (name parent-types layout slots documentation report default-initargs all-readers all-writers) - (%compiler-define-condition name parent-types layout all-readers all-writers) - (let ((class (find-classoid name))) - (setf (condition-classoid-slots class) slots) - (setf (condition-classoid-report class) report) - (setf (condition-classoid-default-initargs class) default-initargs) - (setf (fdocumentation name 'type) documentation) - - (dolist (slot slots) - - ;; Set up reader and writer functions. - (let ((slot-name (condition-slot-name slot))) - (dolist (reader (condition-slot-readers slot)) - (install-condition-slot-reader reader name slot-name)) - (dolist (writer (condition-slot-writers slot)) - (install-condition-slot-writer writer name slot-name)))) - - ;; Compute effective slots and set up the class and hairy slots - ;; (subsets of the effective slots.) - (let ((eslots (compute-effective-slots class)) - (e-def-initargs - (reduce #'append - (mapcar #'condition-classoid-default-initargs + (with-single-package-locked-error + (:symbol name "defining ~A as a condition") + (%compiler-define-condition name parent-types layout all-readers all-writers) + (let ((class (find-classoid name))) + (setf (condition-classoid-slots class) slots) + (setf (condition-classoid-report class) report) + (setf (condition-classoid-default-initargs class) default-initargs) + (setf (fdocumentation name 'type) documentation) + + (dolist (slot slots) + + ;; Set up reader and writer functions. + (let ((slot-name (condition-slot-name slot))) + (dolist (reader (condition-slot-readers slot)) + (install-condition-slot-reader reader name slot-name)) + (dolist (writer (condition-slot-writers slot)) + (install-condition-slot-writer writer name slot-name)))) + + ;; Compute effective slots and set up the class and hairy slots + ;; (subsets of the effective slots.) + (let ((eslots (compute-effective-slots class)) + (e-def-initargs + (reduce #'append + (mapcar #'condition-classoid-default-initargs (condition-classoid-cpl class))))) - (dolist (slot eslots) - (ecase (condition-slot-allocation slot) - (:class - (unless (condition-slot-cell slot) - (setf (condition-slot-cell slot) - (list (if (condition-slot-initform-p slot) - (let ((initform (condition-slot-initform slot))) - (if (functionp initform) - (funcall initform) - initform)) - *empty-condition-slot*)))) - (push slot (condition-classoid-class-slots class))) - ((:instance nil) - (setf (condition-slot-allocation slot) :instance) - (when (or (functionp (condition-slot-initform slot)) - (dolist (initarg (condition-slot-initargs slot) nil) - (when (functionp (getf e-def-initargs initarg)) - (return t)))) - (push slot (condition-classoid-hairy-slots class)))))))) - name) + (dolist (slot eslots) + (ecase (condition-slot-allocation slot) + (:class + (unless (condition-slot-cell slot) + (setf (condition-slot-cell slot) + (list (if (condition-slot-initform-p slot) + (let ((initform (condition-slot-initform slot))) + (if (functionp initform) + (funcall initform) + initform)) + *empty-condition-slot*)))) + (push slot (condition-classoid-class-slots class))) + ((:instance nil) + (setf (condition-slot-allocation slot) :instance) + (when (or (functionp (condition-slot-initform slot)) + (dolist (initarg (condition-slot-initargs slot) nil) + (when (functionp (getf e-def-initargs initarg)) + (return t)))) + (push slot (condition-classoid-hairy-slots class)))))))) + name)) (defmacro define-condition (name (&rest parent-types) (&rest slot-specs) &body options) @@ -583,6 +586,9 @@ (define-condition simple-error (simple-condition error) ()) +;;; not specified by ANSI, but too useful not to have around. +(define-condition simple-style-warning (simple-condition style-warning) ()) + (define-condition storage-condition (serious-condition) ()) (define-condition type-error (error) @@ -717,133 +723,6 @@ (reader-error-format-control condition) (reader-error-format-arguments condition))))))) -;;;; various other (not specified by ANSI) CONDITIONs -;;;; -;;;; These might logically belong in other files; they're here, after -;;;; setup of CONDITION machinery, only because that makes it easier to -;;;; get cold init to work. - -(define-condition simple-style-warning (simple-condition style-warning) ()) - -(define-condition values-type-error (type-error) - () - (:report - (lambda (condition stream) - (format stream - "~@" - (type-error-datum condition) - (type-error-expected-type condition))))) - -;;; KLUDGE: a condition for floating point errors when we can't or -;;; won't figure out what type they are. (In FreeBSD and OpenBSD we -;;; don't know how, at least as of sbcl-0.6.7; in Linux we probably -;;; know how but the old code was broken by the conversion to POSIX -;;; signal handling and hasn't been fixed as of sbcl-0.6.7.) -;;; -;;; FIXME: Perhaps this should also be a base class for all -;;; floating point exceptions? -(define-condition floating-point-exception (arithmetic-error) - ((flags :initarg :traps - :initform nil - :reader floating-point-exception-traps)) - (:report (lambda (condition stream) - (format stream - "An arithmetic error ~S was signalled.~%" - (type-of condition)) - (let ((traps (floating-point-exception-traps condition))) - (if traps - (format stream - "Trapping conditions are: ~%~{ ~S~^~}~%" - traps) - (write-line - "No traps are enabled? How can this be?" - stream)))))) - -(define-condition index-too-large-error (type-error) - () - (:report - (lambda (condition stream) - (format stream - "The index ~S is too large." - (type-error-datum condition))))) - -(define-condition bounding-indices-bad-error (type-error) - ((object :reader bounding-indices-bad-object :initarg :object)) - (:report - (lambda (condition stream) - (let* ((datum (type-error-datum condition)) - (start (car datum)) - (end (cdr datum)) - (object (bounding-indices-bad-object condition))) - (etypecase object - (sequence - (format stream - "The bounding indices ~S and ~S are bad for a sequence of length ~S." - start end (length object))) - (array - ;; from WITH-ARRAY-DATA - (format stream - "The START and END parameters ~S and ~S are bad for an array of total size ~S." - start end (array-total-size object)))))))) - -(define-condition nil-array-accessed-error (type-error) - () - (:report (lambda (condition stream) - (declare (ignore condition)) - (format stream - "An attempt to access an array of element-type ~ - NIL was made. Congratulations!")))) - -(define-condition io-timeout (stream-error) - ((direction :reader io-timeout-direction :initarg :direction)) - (:report - (lambda (condition stream) - (declare (type stream stream)) - (format stream - "I/O timeout ~(~A~)ing ~S" - (io-timeout-direction condition) - (stream-error-stream condition))))) - -(define-condition namestring-parse-error (parse-error) - ((complaint :reader namestring-parse-error-complaint :initarg :complaint) - (args :reader namestring-parse-error-args :initarg :args :initform nil) - (namestring :reader namestring-parse-error-namestring :initarg :namestring) - (offset :reader namestring-parse-error-offset :initarg :offset)) - (:report - (lambda (condition stream) - (format stream - "parse error in namestring: ~?~% ~A~% ~V@T^" - (namestring-parse-error-complaint condition) - (namestring-parse-error-args condition) - (namestring-parse-error-namestring condition) - (namestring-parse-error-offset condition))))) - -(define-condition simple-package-error (simple-condition package-error) ()) - -(define-condition reader-package-error (reader-error) ()) - -(define-condition reader-eof-error (end-of-file) - ((context :reader reader-eof-error-context :initarg :context)) - (:report - (lambda (condition stream) - (format stream - "unexpected end of file on ~S ~A" - (stream-error-stream condition) - (reader-eof-error-context condition))))) - -(define-condition reader-impossible-number-error (reader-error) - ((error :reader reader-impossible-number-error-error :initarg :error)) - (:report - (lambda (condition stream) - (let ((error-stream (stream-error-stream condition))) - (format stream "READER-ERROR ~@[at ~W ~]on ~S:~%~?~%Original error: ~A" - (file-position error-stream) error-stream - (reader-error-format-control condition) - (reader-error-format-arguments condition) - (reader-impossible-number-error-error condition)))))) - -(define-condition timeout (serious-condition) ()) - ;;;; special SBCL extension conditions ;;; an error apparently caused by a bug in SBCL itself @@ -913,6 +792,13 @@ ;;; FIXME: this is not the right place for this. (defun print-reference (reference stream) (ecase (car reference) + (:amop + (format stream "AMOP") + (format stream ", ") + (destructuring-bind (type data) (cdr reference) + (ecase type + (:generic-function (format stream "Generic Function ~S" data)) + (:section (format stream "Section ~{~D~^.~}" data))))) (:ansi-cl (format stream "The ANSI Standard") (format stream ", ") @@ -922,7 +808,8 @@ (:special-operator (format stream "Special Operator ~S" data)) (:macro (format stream "Macro ~S" data)) (:section (format stream "Section ~{~D~^.~}" data)) - (:glossary (format stream "Glossary Entry ~S" data))))) + (:glossary (format stream "Glossary entry for ~S" data)) + (:issue (format stream "writeup for Issue ~A" data))))) (:sbcl (format stream "The SBCL Manual") (format stream ", ") @@ -947,7 +834,7 @@ (print-reference r s) (unless (null (cdr rs)) (terpri s))))))) - + (define-condition duplicate-definition (reference-condition warning) ((name :initarg :name :reader duplicate-definition-name)) (:report (lambda (c s) @@ -978,8 +865,9 @@ (reference-condition simple-warning) () (:default-initargs - :references (list '(:ansi-cl :function make-array) - '(:ansi-cl :function upgraded-array-element-type)))) + :references (list + '(:ansi-cl :function make-array) + '(:ansi-cl :function sb!xc:upgraded-array-element-type)))) (define-condition displaced-to-array-too-small-error (reference-condition simple-error) @@ -1008,6 +896,194 @@ (define-condition extension-failure (reference-condition simple-error) ()) + +#!+sb-package-locks +(progn + +(define-condition package-lock-violation (reference-condition package-error) + ((format-control :initform nil :initarg :format-control + :reader package-error-format-control) + (format-arguments :initform nil :initarg :format-arguments + :reader package-error-format-arguments)) + (:report + (lambda (condition stream) + (let ((control (package-error-format-control condition))) + (if control + (apply #'format stream + (format nil "~~@" + (package-name (package-error-package condition)) + control) + (package-error-format-arguments condition)) + (format stream "~@" + (package-name (package-error-package condition))))))) + ;; no :default-initargs -- reference-stuff provided by the + ;; signalling form in target-package.lisp + #!+sb-doc + (:documentation + "Subtype of CL:PACKAGE-ERROR. A subtype of this error is signalled +when a package-lock is violated.")) + +(define-condition package-locked-error (package-lock-violation) () + #!+sb-doc + (:documentation + "Subtype of SB-EXT:PACKAGE-LOCK-VIOLATION. An error of this type is +signalled when an operation on a package violates a package lock.")) + +(define-condition symbol-package-locked-error (package-lock-violation) + ((symbol :initarg :symbol :reader package-locked-error-symbol)) + #!+sb-doc + (:documentation + "Subtype of SB-EXT:PACKAGE-LOCK-VIOLATION. An error of this type is +signalled when an operation on a symbol violates a package lock. The +symbol that caused the violation is accessed by the function +SB-EXT:PACKAGE-LOCKED-ERROR-SYMBOL.")) + +) ; progn + +;;;; various other (not specified by ANSI) CONDITIONs +;;;; +;;;; These might logically belong in other files; they're here, after +;;;; setup of CONDITION machinery, only because that makes it easier to +;;;; get cold init to work. + +(define-condition encapsulated-condition (condition) + ((condition :initarg :condition :reader encapsulated-condition))) + +;;; This comes to play if we have multiple levels of encapsulated +;;; errors and we need to dump them with MAKE-CONDITION-LOAD-FORM. +;;; Should not see much/any use, but better to have it. +(def!method make-load-form ((condition encapsulated-condition) &optional env) + `(make-condition 'encapsulated-condition + :condition ,(make-condition-load-form (encapsulated-condition condition) env))) + +(define-condition values-type-error (type-error) + () + (:report + (lambda (condition stream) + (format stream + "~@" + (type-error-datum condition) + (type-error-expected-type condition))))) + +;;; KLUDGE: a condition for floating point errors when we can't or +;;; won't figure out what type they are. (In FreeBSD and OpenBSD we +;;; don't know how, at least as of sbcl-0.6.7; in Linux we probably +;;; know how but the old code was broken by the conversion to POSIX +;;; signal handling and hasn't been fixed as of sbcl-0.6.7.) +;;; +;;; FIXME: Perhaps this should also be a base class for all +;;; floating point exceptions? +(define-condition floating-point-exception (arithmetic-error) + ((flags :initarg :traps + :initform nil + :reader floating-point-exception-traps)) + (:report (lambda (condition stream) + (format stream + "An arithmetic error ~S was signalled.~%" + (type-of condition)) + (let ((traps (floating-point-exception-traps condition))) + (if traps + (format stream + "Trapping conditions are: ~%~{ ~S~^~}~%" + traps) + (write-line + "No traps are enabled? How can this be?" + stream)))))) + +(define-condition index-too-large-error (type-error) + () + (:report + (lambda (condition stream) + (format stream + "The index ~S is too large." + (type-error-datum condition))))) + +(define-condition bounding-indices-bad-error (reference-condition type-error) + ((object :reader bounding-indices-bad-object :initarg :object)) + (:report + (lambda (condition stream) + (let* ((datum (type-error-datum condition)) + (start (car datum)) + (end (cdr datum)) + (object (bounding-indices-bad-object condition))) + (etypecase object + (sequence + (format stream + "The bounding indices ~S and ~S are bad ~ + for a sequence of length ~S." + start end (length object))) + (array + ;; from WITH-ARRAY-DATA + (format stream + "The START and END parameters ~S and ~S are ~ + bad for an array of total size ~S." + start end (array-total-size object))))))) + (:default-initargs + :references + (list '(:ansi-cl :glossary "bounding index designator") + '(:ansi-cl :issue "SUBSEQ-OUT-OF-BOUNDS:IS-AN-ERROR")))) + +(define-condition nil-array-accessed-error (reference-condition type-error) + () + (:report (lambda (condition stream) + (declare (ignore condition)) + (format stream + "An attempt to access an array of element-type ~ + NIL was made. Congratulations!"))) + (:default-initargs + :references (list '(:ansi-cl :function sb!xc:upgraded-array-element-type) + '(:ansi-cl :section (15 1 2 1)) + '(:ansi-cl :section (15 1 2 2))))) + +(define-condition io-timeout (stream-error) + ((direction :reader io-timeout-direction :initarg :direction)) + (:report + (lambda (condition stream) + (declare (type stream stream)) + (format stream + "I/O timeout ~(~A~)ing ~S" + (io-timeout-direction condition) + (stream-error-stream condition))))) + +(define-condition namestring-parse-error (parse-error) + ((complaint :reader namestring-parse-error-complaint :initarg :complaint) + (args :reader namestring-parse-error-args :initarg :args :initform nil) + (namestring :reader namestring-parse-error-namestring :initarg :namestring) + (offset :reader namestring-parse-error-offset :initarg :offset)) + (:report + (lambda (condition stream) + (format stream + "parse error in namestring: ~?~% ~A~% ~V@T^" + (namestring-parse-error-complaint condition) + (namestring-parse-error-args condition) + (namestring-parse-error-namestring condition) + (namestring-parse-error-offset condition))))) + +(define-condition simple-package-error (simple-condition package-error) ()) + +(define-condition reader-package-error (reader-error) ()) + +(define-condition reader-eof-error (end-of-file) + ((context :reader reader-eof-error-context :initarg :context)) + (:report + (lambda (condition stream) + (format stream + "unexpected end of file on ~S ~A" + (stream-error-stream condition) + (reader-eof-error-context condition))))) + +(define-condition reader-impossible-number-error (reader-error) + ((error :reader reader-impossible-number-error-error :initarg :error)) + (:report + (lambda (condition stream) + (let ((error-stream (stream-error-stream condition))) + (format stream "READER-ERROR ~@[at ~W ~]on ~S:~%~?~%Original error: ~A" + (file-position error-stream) error-stream + (reader-error-format-control condition) + (reader-error-format-arguments condition) + (reader-impossible-number-error-error condition)))))) + +(define-condition timeout (serious-condition) ()) ;;;; restart definitions