;; invalidate wrappers.
(let ((wrappers (get-wrappers-from-classes
nkeys wrappers classes metatypes)))
- (setq cache (fill-cache cache wrappers value)))))))))
+ (when (if (atom wrappers)
+ (not (invalid-wrapper-p wrappers))
+ (every (complement #'invalid-wrapper-p)
+ wrappers))
+ (setq cache (fill-cache cache wrappers value))))))))))
(if classes-list
(mapc #'add-class-list classes-list)
(dolist (method (generic-function-methods generic-function))
wrapper nwrapper)
(do* ((slots (slot-value class 'slots) (cdr slots))
(dupes nil))
- ((null slots)
+ ((null slots)
(when dupes
(style-warn
"~@<slot names with the same SYMBOL-NAME but ~
class dupes)))
(let* ((slot (car slots))
(oslots (remove (slot-definition-name slot) (cdr slots)
- :test #'string/=
+ :test #'string/=
:key #'slot-definition-name)))
(when oslots
(pushnew (cons (slot-definition-name slot)
(defclass class-with-odd-class-name-method ()
((a :accessor class-name)))
\f
+;;; another case where precomputing (this time on PRINT-OBJET) and
+;;; lazily-finalized classes caused problems. (report from James Y
+;;; Knight sbcl-devel 20-07-2006)
+
+(defclass base-print-object () ())
+;;; this has the side-effect of finalizing BASE-PRINT-OBJECT, and
+;;; additionally the second specializer (STREAM) changes the cache
+;;; structure to require two keys, not just one.
+(defmethod print-object ((o base-print-object) (s stream))
+ nil)
+
+;;; unfinalized as yet
+(defclass sub-print-object (base-print-object) ())
+;;; the accessor causes an eager finalization
+(defclass subsub-print-object (sub-print-object)
+ ((a :accessor a)))
+
+;;; triggers a discriminating function (and so cache) recomputation.
+;;; The method on BASE-PRINT-OBJECT will cause the system to attempt
+;;; to fill the cache for all subclasses of BASE-PRINT-OBJECT which
+;;; have valid wrappers; however, in the course of doing so, the
+;;; SUB-PRINT-OBJECT class gets finalized, which invalidates the
+;;; SUBSUB-PRINT-OBJECT wrapper; if an invalid wrapper gets into a
+;;; cache with more than one key, then failure ensues.
+(reinitialize-instance #'print-object)
+\f
;;;; success
(when *in-reinitialize-instance*
(setf *finalized-class* class)))
-(defmethod reinitialize-instance :around
+(defmethod reinitialize-instance :around
((class test-standard-class) &key &allow-other-keys)
(let ((*in-reinitialize-instance* t))
(call-next-method)))
(defclass test-funcallable-standard-class (funcallable-standard-class) ())
(defmethod validate-superclass
- ((class test-funcallable-standard-class)
+ ((class test-funcallable-standard-class)
(superclass funcallable-standard-class))
t)
-(defmethod finalize-inheritance :before
+(defmethod finalize-inheritance :before
((class test-funcallable-standard-class))
(when *in-reinitialize-instance*
(setf *finalized-class* class)))
-(defmethod reinitialize-instance :around
+(defmethod reinitialize-instance :around
((class test-funcallable-standard-class) &key &allow-other-keys)
(let ((*in-reinitialize-instance* t))
(call-next-method)))
(assert (class-slots (find-class 'test-funcallable-standard-object)))
(assert (eq *finalized-class* (find-class 'test-standard-object)))
-(reinitialize-instance (find-class 'test-funcallable-standard-object)
+(reinitialize-instance (find-class 'test-funcallable-standard-object)
:direct-slots nil)
(assert (eq *finalized-class* (find-class 'test-funcallable-standard-object)))
-(assert (null (class-slots (find-class 'test-funcallable-standard-object))))
\ No newline at end of file
+(assert (null (class-slots (find-class 'test-funcallable-standard-object))))
;;; checkins which aren't released. (And occasionally for internal
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"0.9.14.31"
+"0.9.14.32"