X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fcondition.lisp;h=a1d40d5f6d42e915814104b6a20da133f1d91ff7;hb=54da325f13fb41669869aea688ae195426c0e231;hp=c1dc599c132c9af0c97685fe2529098d71e042cf;hpb=9bdd2579f980573a74daabe03120ed64b1733b11;p=sbcl.git diff --git a/src/code/condition.lisp b/src/code/condition.lisp index c1dc599..a1d40d5 100644 --- a/src/code/condition.lisp +++ b/src/code/condition.lisp @@ -59,9 +59,6 @@ :metaclass-constructor make-condition-classoid :dd-type structure) -(defun make-condition-object (actual-initargs) - (%make-condition-object actual-initargs nil)) - (defstruct (condition-slot (:copier nil)) (name (missing-arg) :type symbol) ;; list of all applicable initargs @@ -71,12 +68,13 @@ (writers (missing-arg) :type list) ;; true if :INITFORM was specified (initform-p (missing-arg) :type (member t nil)) - ;; If this is a function, call it with no args. Otherwise, it's the - ;; actual value. - (initform (missing-arg) :type t) + ;; the initform if :INITFORM was specified, otherwise NIL + (initform nil :type t) + ;; if this is a function, call it with no args to get the initform value + (initfunction (missing-arg) :type t) ;; allocation of this slot, or NIL until defaulted (allocation nil :type (member :instance :class nil)) - ;; If ALLOCATION is :CLASS, this is a cons whose car holds the value. + ;; If ALLOCATION is :CLASS, this is a cons whose car holds the value (cell nil :type (or cons null)) ;; slot documentation (documentation nil :type (or string null))) @@ -190,10 +188,9 @@ ;; Otherwise use the initform of SLOT, if there is one. (if (condition-slot-initform-p slot) - (let ((initform (condition-slot-initform slot))) - (if (functionp initform) - (funcall initform) - initform)) + (let ((initfun (condition-slot-initfunction slot))) + (aver (functionp initfun)) + (funcall initfun)) (error "unbound condition slot: ~S" (condition-slot-name slot))))) (defun find-condition-class-slot (condition-class slot-name) @@ -239,19 +236,15 @@ ;;;; MAKE-CONDITION -(defun make-condition (type &rest args) - #!+sb-doc - "Make an instance of a condition object using the specified initargs." - ;; Note: ANSI specifies no exceptional situations in this function. - ;; signalling simple-type-error would not be wrong. - (let* ((type (or (and (symbolp type) (find-classoid type nil)) - type)) +(defun allocate-condition (type &rest initargs) + (let* ((type (if (symbolp type) + (find-classoid type nil) + type)) (class (typecase type (condition-classoid type) (class - ;; Punt to CLOS. - (return-from make-condition - (apply #'make-instance type args))) + (return-from allocate-condition + (apply #'allocate-condition (class-name type) initargs))) (classoid (error 'simple-type-error :datum type @@ -265,23 +258,37 @@ :format-control "~s does not designate a condition class." :format-arguments (list type))))) - (res (make-condition-object args))) - (setf (%instance-layout res) (classoid-layout class)) + (condition (%make-condition-object initargs '()))) + (setf (%instance-layout condition) (classoid-layout class)) + (values condition class))) + +(defun make-condition (type &rest initargs) + #!+sb-doc + "Make an instance of a condition object using the specified initargs." + ;; Note: ANSI specifies no exceptional situations in this function. + ;; signalling simple-type-error would not be wrong. + (multiple-value-bind (condition class) + (apply #'allocate-condition type initargs) + ;; Set any class slots with initargs present in this call. (dolist (cslot (condition-classoid-class-slots class)) (dolist (initarg (condition-slot-initargs cslot)) - (let ((val (getf args initarg *empty-condition-slot*))) + (let ((val (getf initargs initarg *empty-condition-slot*))) (unless (eq val *empty-condition-slot*) (setf (car (condition-slot-cell cslot)) val))))) + ;; Default any slots with non-constant defaults now. (dolist (hslot (condition-classoid-hairy-slots class)) (when (dolist (initarg (condition-slot-initargs hslot) t) - (unless (eq (getf args initarg *empty-condition-slot*) + (unless (eq (getf initargs initarg *empty-condition-slot*) *empty-condition-slot*) (return nil))) - (setf (getf (condition-assigned-slots res) (condition-slot-name hslot)) + (setf (getf (condition-assigned-slots condition) + (condition-slot-name hslot)) (find-slot-default class hslot)))) - res)) + + condition)) + ;;;; DEFINE-CONDITION @@ -357,7 +364,9 @@ (setf (condition-slot-initform-p found) (condition-slot-initform-p sslot)) (setf (condition-slot-initform found) - (condition-slot-initform sslot))) + (condition-slot-initform sslot)) + (setf (condition-slot-initfunction sslot) + (condition-slot-initfunction found))) (unless (condition-slot-allocation found) (setf (condition-slot-allocation found) (condition-slot-allocation sslot)))) @@ -415,6 +424,7 @@ ;; Compute effective slots and set up the class and hairy slots ;; (subsets of the effective slots.) + (setf (condition-classoid-hairy-slots class) '()) (let ((eslots (compute-effective-slots class)) (e-def-initargs (reduce #'append @@ -426,15 +436,15 @@ (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)) + (let ((initfun (condition-slot-initfunction slot))) + (aver (functionp initfun)) + (funcall initfun)) *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)) + ;; FIXME: isn't this "always hairy"? + (when (or (functionp (condition-slot-initfunction slot)) (dolist (initarg (condition-slot-initargs slot) nil) (when (functionp (third (assoc initarg e-def-initargs))) (return t)))) @@ -524,8 +534,10 @@ :writers ',(writers) :initform-p ',initform-p :documentation ',documentation - :initform ,(when initform-p - `#'(lambda () ,initform))))))) + :initform ,(when initform-p `',initform) + :initfunction ,(when initform-p + `#'(lambda () ,initform)) + :allocation ',allocation))))) (dolist (option options) (unless (consp option) @@ -614,7 +626,9 @@ (type-error-expected-type condition))))) (def!method print-object ((condition type-error) stream) - (if *print-escape* + (if (and *print-escape* + (slot-boundp condition 'expected-type) + (slot-boundp condition 'datum)) (flet ((maybe-string (thing) (ignore-errors (write-to-string thing :lines 1 :readably nil :array nil :pretty t)))) @@ -685,9 +699,10 @@ (define-condition undefined-function (cell-error) () (:report (lambda (condition stream) - (format stream - "The function ~/sb-impl::print-symbol-with-prefix/ is undefined." - (cell-error-name condition))))) + (let ((*package* (find-package :keyword))) + (format stream + "The function ~S is undefined." + (cell-error-name condition)))))) (define-condition special-form-function (undefined-function) () (:report @@ -966,9 +981,9 @@ ((name :initarg :name :reader implicit-generic-function-name)) (:report (lambda (condition stream) - (let ((*package* (find-package :keyword))) - (format stream "~@" - (implicit-generic-function-name condition)))))) + (format stream "~@" + (implicit-generic-function-name condition))))) (define-condition extension-failure (reference-condition simple-error) ()) @@ -1041,8 +1056,11 @@ SB-EXT:PACKAGE-LOCKED-ERROR-SYMBOL.")) (define-condition undefined-alien-function-error (undefined-alien-error) () (:report (lambda (condition stream) - (declare (ignore condition)) - (format stream "Attempt to call an undefined alien function.")))) + (if (and (slot-boundp condition 'name) + (cell-error-name condition)) + (format stream "The alien function ~s is undefined." + (cell-error-name condition)) + (format stream "Attempt to call an undefined alien function."))))) ;;;; various other (not specified by ANSI) CONDITIONs @@ -1382,13 +1400,14 @@ handled by any other handler, it will be muffled.") (let ((new (function-redefinition-warning-new-function warning)) (source-location (redefinition-warning-new-location warning))) (or - ;; Compiled->Interpreted is interesting. + ;; compiled->interpreted is interesting. (and (typep old 'compiled-function) (typep new '(not compiled-function))) - ;; FIN->Regular is interesting. - (and (typep old 'funcallable-instance) + ;; fin->regular is interesting except for interpreted->compiled. + (and (typep old '(and funcallable-instance + #!+sb-eval (not sb!eval:interpreted-function))) (typep new '(not funcallable-instance))) - ;; Different file or unknown location is interesting. + ;; different file or unknown location is interesting. (let* ((old-namestring (function-file-namestring old)) (new-namestring (or (function-file-namestring new)