X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fpcl%2Fstd-class.lisp;h=3a7da7bc392983b83669af81ccb9cb5460b36932;hb=56f96e77ade913d6363a3068c94e60f44ae9b3e7;hp=969791562bc8d0c8f4fad79a6c571313ef45e093;hpb=683874b497a99cd2c11b6c5d9b47e2785b1ede5f;p=sbcl.git diff --git a/src/pcl/std-class.lisp b/src/pcl/std-class.lisp index 9697915..3a7da7b 100644 --- a/src/pcl/std-class.lisp +++ b/src/pcl/std-class.lisp @@ -282,27 +282,27 @@ (nreverse collect))))))) (defun map-specializers (function) - (map-all-classes #'(lambda (class) - (funcall function (class-eq-specializer class)) - (funcall function class))) - (maphash #'(lambda (object methods) - (declare (ignore methods)) - (intern-eql-specializer object)) + (map-all-classes (lambda (class) + (funcall function (class-eq-specializer class)) + (funcall function class))) + (maphash (lambda (object methods) + (declare (ignore methods)) + (intern-eql-specializer object)) *eql-specializer-methods*) - (maphash #'(lambda (object specl) - (declare (ignore object)) - (funcall function specl)) + (maphash (lambda (object specl) + (declare (ignore object)) + (funcall function specl)) *eql-specializer-table*) nil) (defun map-all-generic-functions (function) (let ((all-generic-functions (make-hash-table :test 'eq))) - (map-specializers #'(lambda (specl) - (dolist (gf (specializer-direct-generic-functions - specl)) - (unless (gethash gf all-generic-functions) - (setf (gethash gf all-generic-functions) t) - (funcall function gf)))))) + (map-specializers (lambda (specl) + (dolist (gf (specializer-direct-generic-functions + specl)) + (unless (gethash gf all-generic-functions) + (setf (gethash gf all-generic-functions) t) + (funcall function gf)))))) nil) (defmethod shared-initialize :after ((specl class-eq-specializer) @@ -338,7 +338,6 @@ (ensure-class-values class args) (setf class (apply #'make-instance meta :name name initargs) (find-class name) class) - (inform-type-system-about-class class name) class)) (defmethod ensure-class-using-class (name (class pcl-class) &rest args &key) @@ -347,7 +346,6 @@ (unless (eq (class-of class) meta) (change-class class meta)) (apply #'reinitialize-instance class initargs) (setf (find-class name) class) - (inform-type-system-about-class class name) class)) (defmethod class-predicate-name ((class t)) @@ -464,8 +462,8 @@ &rest initargs &key) (map-dependents class - #'(lambda (dependent) - (apply #'update-dependent class dependent initargs)))) + (lambda (dependent) + (apply #'update-dependent class dependent initargs)))) (defmethod shared-initialize :after ((slotd standard-slot-definition) slot-names &key) @@ -483,11 +481,10 @@ (defun make-structure-class-defstruct-form (name direct-slots include) (let* ((conc-name (intern (format nil "~S structure class " name))) - (constructor (intern (format nil "~A constructor" conc-name))) + (constructor (intern (format nil "~Aconstructor" conc-name))) (defstruct `(defstruct (,name ,@(when include `((:include ,(class-name include)))) - (:print-function print-std-instance) (:predicate nil) (:conc-name ,conc-name) (:constructor ,constructor ()) @@ -556,17 +553,17 @@ (if direct-slots-p (setf (slot-value class 'direct-slots) (setq direct-slots - (mapcar #'(lambda (pl) - (when defstruct-p - (let* ((slot-name (getf pl :name)) - (acc-name - (format nil - "~S structure class ~A" - name slot-name)) - (accessor (intern acc-name))) - (setq pl (list* :defstruct-accessor-symbol - accessor pl)))) - (make-direct-slotd class pl)) + (mapcar (lambda (pl) + (when defstruct-p + (let* ((slot-name (getf pl :name)) + (acc-name + (format nil + "~S structure class ~A" + name slot-name)) + (accessor (intern acc-name))) + (setq pl (list* :defstruct-accessor-symbol + accessor pl)))) + (make-direct-slotd class pl)) direct-slots))) (setq direct-slots (slot-value class 'direct-slots))) (when defstruct-p @@ -574,14 +571,14 @@ (multiple-value-bind (defstruct-form constructor reader-names writer-names) (make-structure-class-defstruct-form name direct-slots include) (unless (structure-type-p name) (eval defstruct-form)) - (mapc #'(lambda (dslotd reader-name writer-name) - (let* ((reader (gdefinition reader-name)) - (writer (when (gboundp writer-name) - (gdefinition writer-name)))) - (setf (slot-value dslotd 'internal-reader-function) - reader) - (setf (slot-value dslotd 'internal-writer-function) - writer))) + (mapc (lambda (dslotd reader-name writer-name) + (let* ((reader (gdefinition reader-name)) + (writer (when (gboundp writer-name) + (gdefinition writer-name)))) + (setf (slot-value dslotd 'internal-reader-function) + reader) + (setf (slot-value dslotd 'internal-writer-function) + writer))) direct-slots reader-names writer-names) (setf (slot-value class 'defstruct-form) defstruct-form) (setf (slot-value class 'defstruct-constructor) constructor)))) @@ -631,14 +628,14 @@ (dolist (r (slot-definition-readers dslotd)) (fix r slot-name 'r)) (dolist (w (slot-definition-writers dslotd)) (fix w slot-name 'w)))))) -(defun add-direct-subclasses (class new) - (dolist (n new) +(defun add-direct-subclasses (class supers) + (dolist (super supers) (unless (memq class (class-direct-subclasses class)) - (add-direct-subclass n class)))) + (add-direct-subclass super class)))) -(defun remove-direct-subclasses (class new) +(defun remove-direct-subclasses (class supers) (let ((old (class-direct-superclasses class))) - (dolist (o (set-difference old new)) + (dolist (o (set-difference old supers)) (remove-direct-subclass o class)))) (defmethod finalize-inheritance ((class std-class)) @@ -771,9 +768,9 @@ (setf (gethash gf gf-table) t)) (mapc #'collect-gfs (class-direct-superclasses class)))) (collect-gfs class) - (maphash #'(lambda (gf ignore) - (declare (ignore ignore)) - (update-gf-dfun class gf)) + (maphash (lambda (gf ignore) + (declare (ignore ignore)) + (update-gf-dfun class gf)) gf-table))))) (defun update-inits (class inits) @@ -819,9 +816,9 @@ (if entry (push d (cdr entry)) (push (list name d) name-dslotds-alist)))))) - (mapcar #'(lambda (direct) - (compute-effective-slot-definition class - (nreverse (cdr direct)))) + (mapcar (lambda (direct) + (compute-effective-slot-definition class + (nreverse (cdr direct)))) name-dslotds-alist))) (defmethod compute-slots :around ((class std-class)) @@ -845,11 +842,11 @@ eslotds)) (defmethod compute-slots ((class structure-class)) - (mapcan #'(lambda (superclass) - (mapcar #'(lambda (dslotd) - (compute-effective-slot-definition class - (list dslotd))) - (class-direct-slots superclass))) + (mapcan (lambda (superclass) + (mapcar (lambda (dslotd) + (compute-effective-slot-definition class + (list dslotd))) + (class-direct-slots superclass))) (reverse (slot-value class 'class-precedence-list)))) (defmethod compute-slots :around ((class structure-class)) @@ -973,18 +970,17 @@ (let ((method (get-method generic-function () (list class) nil))) (when method (remove-method generic-function method)))) -;;; make-reader-method-function and make-write-method function are NOT part of -;;; the standard protocol. They are however useful, PCL makes uses makes use -;;; of them internally and documents them for PCL users. +;;; MAKE-READER-METHOD-FUNCTION and MAKE-WRITE-METHOD function are NOT +;;; part of the standard protocol. They are however useful, PCL makes +;;; use of them internally and documents them for PCL users. ;;; ;;; *** This needs work to make type testing by the writer functions which ;;; *** do type testing faster. The idea would be to have one constructor -;;; *** for each possible type test. In order to do this it would be nice -;;; *** to have help from inform-type-system-about-class and friends. +;;; *** for each possible type test. ;;; ;;; *** There is a subtle bug here which is going to have to be fixed. ;;; *** Namely, the simplistic use of the template has to be fixed. We -;;; *** have to give the optimize-slot-value method the user might have +;;; *** have to give the OPTIMIZE-SLOT-VALUE method the user might have ;;; *** defined for this metaclass a chance to run. (defmethod make-reader-method-function ((class slot-class) slot-name) @@ -996,20 +992,6 @@ (defmethod make-boundp-method-function ((class slot-class) slot-name) (make-std-boundp-method-function (class-name class) slot-name)) -;;;; inform-type-system-about-class -;;; -;;; These are NOT part of the standard protocol. They are internal -;;; mechanism which PCL uses to *try* and tell the type system about -;;; class definitions. In a more fully integrated implementation of -;;; CLOS, the type system would know about class objects and class -;;; names in a more fundamental way and the mechanism used to inform -;;; the type system about new classes would be different. -(defmethod inform-type-system-about-class ((class std-class) name) - (inform-type-system-about-std-class name)) - -(defmethod inform-type-system-about-class ((class structure-class) (name t)) - nil) - (defmethod compatible-meta-class-change-p (class proto-new-class) (eq (class-of class) (class-of proto-new-class))) @@ -1023,14 +1005,13 @@ (eq (class-of class) new-super-meta-class)))) (defun force-cache-flushes (class) - (let* ((owrapper (class-wrapper class)) - (state (wrapper-state owrapper))) + (let* ((owrapper (class-wrapper class))) ;; We only need to do something if the state is still T. If the ;; state isn't T, it will be FLUSH or OBSOLETE, and both of those ;; will already be doing what we want. In particular, we must be ;; sure we never change an OBSOLETE into a FLUSH since OBSOLETE ;; means do what FLUSH does and then some. - (when (eq state t) ; FIXME: should be done through INVALID-WRAPPER-P + (unless (invalid-wrapper-p owrapper) (let ((nwrapper (make-wrapper (wrapper-no-of-instance-slots owrapper) class))) (setf (wrapper-instance-slots-layout nwrapper) @@ -1040,15 +1021,15 @@ (sb-sys:without-interrupts (update-lisp-class-layout class nwrapper) (setf (slot-value class 'wrapper) nwrapper) - (invalidate-wrapper owrapper ':flush nwrapper)))))) + (invalidate-wrapper owrapper :flush nwrapper)))))) (defun flush-cache-trap (owrapper nwrapper instance) (declare (ignore owrapper)) (set-wrapper instance nwrapper)) -;;; make-instances-obsolete can be called by user code. It will cause the -;;; next access to the instance (as defined in 88-002R) to trap through the -;;; update-instance-for-redefined-class mechanism. +;;; MAKE-INSTANCES-OBSOLETE can be called by user code. It will cause +;;; the next access to the instance (as defined in 88-002R) to trap +;;; through the UPDATE-INSTANCE-FOR-REDEFINED-CLASS mechanism. (defmethod make-instances-obsolete ((class std-class)) (let* ((owrapper (class-wrapper class)) (nwrapper (make-wrapper (wrapper-no-of-instance-slots owrapper) @@ -1060,14 +1041,14 @@ (sb-sys:without-interrupts (update-lisp-class-layout class nwrapper) (setf (slot-value class 'wrapper) nwrapper) - (invalidate-wrapper owrapper ':obsolete nwrapper) + (invalidate-wrapper owrapper :obsolete nwrapper) class))) (defmethod make-instances-obsolete ((class symbol)) (make-instances-obsolete (find-class class))) -;;; obsolete-instance-trap is the internal trap that is called when we see -;;; an obsolete instance. The times when it is called are: +;;; OBSOLETE-INSTANCE-TRAP is the internal trap that is called when we +;;; see an obsolete instance. The times when it is called are: ;;; - when the instance is involved in method lookup ;;; - when attempting to access a slot of an instance ;;; @@ -1085,12 +1066,13 @@ ;;; sure that the traps are only happening when they should, and that ;;; the trap methods are computing appropriate new wrappers. -;;; obsolete-instance-trap might be called on structure instances -;;; after a structure is redefined. In most cases, obsolete-instance-trap -;;; will not be able to fix the old instance, so it must signal an -;;; error. The hard part of this is that the error system and debugger -;;; might cause obsolete-instance-trap to be called again, so in that -;;; case, we have to return some reasonable wrapper, instead. +;;; OBSOLETE-INSTANCE-TRAP might be called on structure instances +;;; after a structure is redefined. In most cases, +;;; OBSOLETE-INSTANCE-TRAP will not be able to fix the old instance, +;;; so it must signal an error. The hard part of this is that the +;;; error system and debugger might cause OBSOLETE-INSTANCE-TRAP to be +;;; called again, so in that case, we have to return some reasonable +;;; wrapper, instead. (defvar *in-obsolete-instance-trap* nil) (defvar *the-wrapper-of-structure-object* @@ -1168,18 +1150,7 @@ plist) nwrapper))) -(defmacro copy-instance-internal (instance) - `(progn - (let* ((class (class-of instance)) - (copy (allocate-instance class))) - (if (std-instance-p ,instance) - (setf (std-instance-slots ,instance) - (std-instance-slots ,instance)) - (setf (fsc-instance-slots ,instance) - (fsc-instance-slots ,instance))) - copy))) - -(defun change-class-internal (instance new-class) +(defun change-class-internal (instance new-class initargs) (let* ((old-class (class-of instance)) (copy (allocate-instance new-class)) (new-wrapper (get-wrapper copy)) @@ -1198,7 +1169,8 @@ (let ((old-position (posq new-slot old-layout))) (when old-position (setf (clos-slots-ref new-slots new-position) - (clos-slots-ref old-slots old-position)))))) + (clos-slots-ref old-slots old-position)))) + (incf new-position))) ;; "The values of slots specified as shared in the class CFROM and ;; as local in the class CTO are retained." @@ -1211,31 +1183,37 @@ ;; old instance point to the new storage. (swap-wrappers-and-slots instance copy) - (update-instance-for-different-class copy instance) + (apply #'update-instance-for-different-class copy instance initargs) instance)) (defmethod change-class ((instance standard-object) - (new-class standard-class)) - (change-class-internal instance new-class)) + (new-class standard-class) + &rest initargs) + (change-class-internal instance new-class initargs)) (defmethod change-class ((instance funcallable-standard-object) - (new-class funcallable-standard-class)) - (change-class-internal instance new-class)) + (new-class funcallable-standard-class) + &rest initargs) + (change-class-internal instance new-class initargs)) (defmethod change-class ((instance standard-object) - (new-class funcallable-standard-class)) + (new-class funcallable-standard-class) + &rest initargs) + (declare (ignore initargs)) (error "You can't change the class of ~S to ~S~@ because it isn't already an instance with metaclass ~S." instance new-class 'standard-class)) (defmethod change-class ((instance funcallable-standard-object) - (new-class standard-class)) + (new-class standard-class) + &rest initargs) + (declare (ignore initargs)) (error "You can't change the class of ~S to ~S~@ because it isn't already an instance with metaclass ~S." instance new-class 'funcallable-standard-class)) -(defmethod change-class ((instance t) (new-class-name symbol)) - (change-class instance (find-class new-class-name))) +(defmethod change-class ((instance t) (new-class-name symbol) &rest initargs) + (apply #'change-class instance (find-class new-class-name) initargs)) ;;;; The metaclass BUILT-IN-CLASS ;;;;