[armedbear-cvs] r13877 - trunk/abcl/src/org/armedbear/lisp
rschlatte at common-lisp.net
rschlatte at common-lisp.net
Fri Feb 24 04:20:53 UTC 2012
Author: rschlatte
Date: Thu Feb 23 20:20:52 2012
New Revision: 13877
Log:
Implement the dependent maintenance protocol (AMOP Sec. 5.5.6)
Modified:
trunk/abcl/src/org/armedbear/lisp/clos.lisp
trunk/abcl/src/org/armedbear/lisp/mop.lisp
Modified: trunk/abcl/src/org/armedbear/lisp/clos.lisp
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/clos.lisp Thu Feb 23 02:33:06 2012 (r13876)
+++ trunk/abcl/src/org/armedbear/lisp/clos.lisp Thu Feb 23 20:20:52 2012 (r13877)
@@ -210,7 +210,11 @@
(defun function-keywords (method)
(std-function-keywords method))
-
+(declaim (notinline map-dependents))
+(defun map-dependents (metaobject function)
+ ;; stub, will be redefined later
+ (declare (ignore metaobject function))
+ nil)
(defmacro push-on-end (value location)
`(setf ,location (nconc ,location (list ,value))))
@@ -1423,7 +1427,12 @@
;; specified by CLHS, 7.7 (Macro DEFGENERIC).
(dolist (method (generic-function-initial-methods gf))
(if (typep gf 'standard-generic-function)
- (std-remove-method gf method)
+ (progn
+ (std-remove-method gf method)
+ (map-dependents gf
+ #'(lambda (dep)
+ (update-dependent gf dep
+ 'remove-method method))))
(remove-method gf method)))
(setf (generic-function-initial-methods gf) '()))))
(apply 'ensure-generic-function function-name all-keys))
@@ -1791,7 +1800,11 @@
(apply #'make-instance-standard-method gf all-keys)
(apply #'make-instance (generic-function-method-class gf) all-keys))))
(if (eq (generic-function-method-class gf) +the-standard-method-class+)
- (std-add-method gf method)
+ (progn
+ (std-add-method gf method)
+ (map-dependents gf
+ #'(lambda (dep)
+ (update-dependent gf dep 'add-method method))))
(add-method gf method))
method)))
@@ -2546,7 +2559,11 @@
:generic-function nil ; handled by add-method
initargs))))
(if (eq (class-of gf) +the-standard-generic-function-class+)
- (std-add-method gf method)
+ (progn
+ (std-add-method gf method)
+ (map-dependents gf
+ #'(lambda (dep)
+ (update-dependent gf dep 'add-method method))))
(add-method gf method))
method)))
@@ -2591,7 +2608,11 @@
:generic-function nil ; handled by add-method
initargs))))
(if (eq (class-of gf) +the-standard-generic-function-class+)
- (std-add-method gf method)
+ (progn
+ (std-add-method gf method)
+ (map-dependents gf
+ #'(lambda (dep)
+ (update-dependent gf dep 'add-method method))))
(add-method gf method))
method)))
@@ -3390,7 +3411,26 @@
(list* class all-keys)
class t all-keys
nil 'reinitialize-instance)
- (apply #'std-after-initialization-for-classes class all-keys))
+ (apply #'std-after-initialization-for-classes class all-keys)
+ (map-dependents class #'(lambda (dep) (update-dependent class dep all-keys))))
+
+(defmethod reinitialize-instance :after ((class funcallable-standard-class)
+ &rest all-keys)
+ (remhash class *make-instance-initargs-cache*)
+ (remhash class *reinitialize-instance-initargs-cache*)
+ (%make-instances-obsolete class)
+ (setf (class-finalized-p class) nil)
+ (check-initargs (list #'allocate-instance
+ #'initialize-instance)
+ (list* class all-keys)
+ class t all-keys
+ nil 'reinitialize-instance)
+ (apply #'std-after-initialization-for-classes class all-keys)
+ (map-dependents class #'(lambda (dep) (update-dependent class dep all-keys))))
+
+(defmethod reinitialize-instance :after ((gf standard-generic-function)
+ &rest all-keys)
+ (map-dependents gf #'(lambda (dep) (update-dependent gf dep all-keys))))
;;; Finalize inheritance
@@ -3686,11 +3726,24 @@
method-lambda-list gf-lambda-list))
(std-add-method generic-function method))
+(defmethod add-method :after ((generic-function standard-generic-function)
+ (method method))
+ (map-dependents generic-function
+ #'(lambda (dep) (update-dependent generic-function dep
+ 'add-method method))))
+
(defgeneric remove-method (generic-function method))
-(defmethod remove-method ((generic-function standard-generic-function) method)
+(defmethod remove-method ((generic-function standard-generic-function)
+ (method method))
(std-remove-method generic-function method))
+(defmethod remove-method :after ((generic-function standard-generic-function)
+ (method method))
+ (map-dependents generic-function
+ #'(lambda (dep) (update-dependent generic-function dep
+ 'remove-method method))))
+
;; See describe.lisp.
(defgeneric describe-object (object stream))
@@ -3819,6 +3872,47 @@
(setf (slot-value specializer 'direct-methods)
(remove method (slot-value specializer 'direct-methods)))))
+;;; The Dependent Maintenance Protocol (AMOP pg. 160ff.)
+
+(defvar *dependents* (make-hash-table :test 'eq :weakness :key))
+
+;;; AMOP pg. 164
+(defgeneric add-dependent (metaobject dependent))
+(defmethod add-dependent ((metaobject standard-class) dependent)
+ (pushnew dependent (gethash metaobject *dependents* nil)))
+(defmethod add-dependent ((metaobject funcallable-standard-class) dependent)
+ (pushnew dependent (gethash metaobject *dependents* nil)))
+(defmethod add-dependent ((metaobject standard-generic-function) dependent)
+ (pushnew dependent (gethash metaobject *dependents* nil)))
+
+;;; AMOP pg. 225
+(defgeneric remove-dependent (metaobject dependent))
+(defmethod remove-dependent ((metaobject standard-class) dependent)
+ (setf (gethash metaobject *dependents*)
+ (delete dependent (gethash metaobject *dependents* nil) :test #'eq)))
+(defmethod remove-dependent ((metaobject funcallable-standard-class) dependent)
+ (setf (gethash metaobject *dependents*)
+ (delete dependent (gethash metaobject *dependents* nil) :test #'eq)))
+(defmethod remove-dependent ((metaobject standard-generic-function) dependent)
+ (setf (gethash metaobject *dependents*)
+ (delete dependent (gethash metaobject *dependents* nil) :test #'eq)))
+
+;;; AMOP pg. 210
+(atomic-defgeneric map-dependents (metaobject function)
+ (:method ((metaobject standard-class) function)
+ (dolist (dependent (gethash metaobject *dependents* nil))
+ (funcall function dependent)))
+ (:method ((metaobject funcallable-standard-class) function)
+ (dolist (dependent (gethash metaobject *dependents* nil))
+ (funcall function dependent)))
+ (:method ((metaobject standard-generic-function) function)
+ (dolist (dependent (gethash metaobject *dependents* nil))
+ (funcall function dependent))))
+
+;;; AMOP pg. 239
+(defgeneric update-dependent (metaobject dependent &rest initargs))
+
+
;;; SLIME compatibility functions.
(defun %method-generic-function (method)
Modified: trunk/abcl/src/org/armedbear/lisp/mop.lisp
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/mop.lisp Thu Feb 23 02:33:06 2012 (r13876)
+++ trunk/abcl/src/org/armedbear/lisp/mop.lisp Thu Feb 23 20:20:52 2012 (r13877)
@@ -82,7 +82,11 @@
extract-lambda-list
extract-specializer-names
- ))
+
+ add-dependent
+ remove-dependent
+ map-dependents
+ update-dependent))
(provide 'mop)
More information about the armedbear-cvs
mailing list