least permitted and maybe required by AMOP). As a consolation,
however, the SBCL implementation of these functions now calls
REINITIALIZE-INSTANCE as specified by AMOP.
+ * bug fix: REINITIALIZE-INSTANCE on generic functions calls
+ COMPUTE-DISCRIMINATING-FUNCTION (almost) unconditionally, as
+ specified by AMOP.
* bug fix: it is now possible to have more than one subclass of
STANDARD-GENERIC-FUNCTION without causing stack overflow.
(reported by Bruno Haible, Pascal Costanza and others)
(defun accessor-miss (gf new object dfun-info)
(let ((wrapper (wrapper-of object))
- (previous-miss (assq gf *accessor-miss-history*)))
+ (previous-miss (assq gf *accessor-miss-history*)))
(when (eq wrapper (cdr previous-miss))
(error "~@<Vicious metacircle: The computation of a ~
dfun of ~s for argument ~s uses the dfun being ~
computed.~@:>"
- gf object))
+ gf object))
(let* ((*accessor-miss-history* (acons gf wrapper *accessor-miss-history*))
- (ostate (type-of dfun-info))
- (otype (dfun-info-accessor-type dfun-info))
- oindex ow0 ow1 cache
- (args (ecase otype
- ((reader boundp) (list object))
- (writer (list new object)))))
+ (ostate (type-of dfun-info))
+ (otype (dfun-info-accessor-type dfun-info))
+ oindex ow0 ow1 cache
+ (args (ecase otype
+ ((reader boundp) (list object))
+ (writer (list new object)))))
(dfun-miss (gf args wrappers invalidp nemf ntype nindex)
- ;; The following lexical functions change the state of the
- ;; dfun to that which is their name. They accept arguments
- ;; which are the parameters of the new state, and get other
- ;; information from the lexical variables bound above.
- (flet ((two-class (index w0 w1)
+ ;; The following lexical functions change the state of the
+ ;; dfun to that which is their name. They accept arguments
+ ;; which are the parameters of the new state, and get other
+ ;; information from the lexical variables bound above.
+ (flet ((two-class (index w0 w1)
(when (zerop (random 2)) (psetf w0 w1 w1 w0))
(dfun-update gf
#'make-two-class-accessor-dfun
:argument-precedence-order argument-precedence-order))
(lambda-list-p (set-arg-info gf :lambda-list lambda-list))
(t (set-arg-info gf)))
- (when (and (arg-info-valid-p (gf-arg-info gf))
- (not (null args))
- (or lambda-list-p (cddr args)))
+ (when (arg-info-valid-p (gf-arg-info gf))
(update-dfun gf))
(map-dependents gf (lambda (dependent)
(apply #'update-dependent gf dependent args))))))
--- /dev/null
+;;;; miscellaneous side-effectful tests of the MOP
+
+;;;; This software is part of the SBCL system. See the README file for
+;;;; more information.
+;;;;
+;;;; While most of SBCL is derived from the CMU CL system, the test
+;;;; files (like this one) were written from scratch after the fork
+;;;; from CMU CL.
+;;;;
+;;;; This software is in the public domain and is provided with
+;;;; absolutely no warranty. See the COPYING and CREDITS files for
+;;;; more information.
+
+;;; this file contains tests of REINITIALIZE-INSTANCE on generic
+;;; functions.
+
+(defpackage "MOP-10"
+ (:use "CL" "SB-MOP" "TEST-UTIL"))
+
+(in-package "MOP-10")
+
+(defclass my-generic-function (standard-generic-function)
+ ()
+ (:metaclass funcallable-standard-class))
+
+(defgeneric foo (x)
+ (:method-combination list)
+ (:method list ((x float)) (* x x))
+ (:method list ((x integer)) (1+ x))
+ (:method list ((x number)) (expt x 2))
+ (:generic-function-class my-generic-function))
+
+(assert (equal (foo 3) '(4 9)))
+(defmethod compute-discriminating-function ((gf my-generic-function))
+ (let ((orig (call-next-method)))
+ (lambda (&rest args)
+ (let ((orig-result (apply orig args)))
+ (cons gf (reverse orig-result))))))
+(assert (equal (foo 3) '(4 9)))
+(reinitialize-instance #'foo)
+(assert (equal (foo 3) (cons #'foo '(9 4))))
;;; 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.6.14"
+"0.9.6.15"