[armedbear-cvs] r13968 - trunk/abcl/src/org/armedbear/lisp
rschlatte at common-lisp.net
rschlatte at common-lisp.net
Sat Jun 16 10:45:29 UTC 2012
Author: rschlatte
Date: Sat Jun 16 03:45:26 2012
New Revision: 13968
Log:
Ensure add-method calls remove-method
- also move some error checks out of the fast path + into standard path
for non-standard metaclasses
Modified:
trunk/abcl/src/org/armedbear/lisp/clos.lisp
Modified: trunk/abcl/src/org/armedbear/lisp/clos.lisp
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/clos.lisp Fri Jun 15 13:41:56 2012 (r13967)
+++ trunk/abcl/src/org/armedbear/lisp/clos.lisp Sat Jun 16 03:45:26 2012 (r13968)
@@ -1922,16 +1922,15 @@
(remove method (class-direct-methods specializer)))))
(defun std-add-method (gf method)
- (when (and (method-generic-function method)
- (not (eql gf (method-generic-function method))))
- (error 'simple-error
- :format-control "~S is already a method of ~S, cannot add to ~S."
- :format-arguments (list method (method-generic-function method) gf)))
- ;; Remove existing method with same qualifiers and specializers (if any).
+ ;; calls sites need to make sure that method is either a method of the
+ ;; given gf or does not have a gf.
(let ((old-method (%find-method gf (std-method-qualifiers method)
(method-specializers method) nil)))
(when old-method
- (std-remove-method gf old-method)))
+ (if (and (eq (class-of gf) +the-standard-generic-function-class+)
+ (eq (class-of old-method) +the-standard-method-class+))
+ (std-remove-method gf old-method)
+ (remove-method gf old-method))))
(setf (std-slot-value method 'sys::%generic-function) gf)
(push method (generic-function-methods gf))
(dolist (specializer (method-specializers method))
@@ -3950,17 +3949,26 @@
(find-method (find-generic-function generic-function errorp)
qualifiers specializers errorp))
+;;; AMOP pg. 167
(defgeneric add-method (generic-function method))
+(defmethod add-method :before ((generic-function generic-function)
+ (method method))
+ (when (and (method-generic-function method)
+ (not (eql generic-function (method-generic-function method))))
+ (error 'simple-error
+ :format-control "~S is already a method of ~S, cannot add to ~S."
+ :format-arguments (list method (method-generic-function method)
+ generic-function)))
+ (check-method-lambda-list (generic-function-name generic-function)
+ (method-lambda-list method)
+ (generic-function-lambda-list generic-function)))
+
(defmethod add-method ((generic-function standard-generic-function)
- (method method))
- (let ((method-lambda-list (method-lambda-list method))
- (gf-lambda-list (generic-function-lambda-list generic-function)))
- (check-method-lambda-list (%generic-function-name generic-function)
- method-lambda-list gf-lambda-list))
+ (method standard-method))
(std-add-method generic-function method))
-(defmethod add-method :after ((generic-function standard-generic-function)
+(defmethod add-method :after ((generic-function generic-function)
(method method))
(map-dependents generic-function
#'(lambda (dep) (update-dependent generic-function dep
@@ -3969,10 +3977,10 @@
(defgeneric remove-method (generic-function method))
(defmethod remove-method ((generic-function standard-generic-function)
- (method method))
+ (method standard-method))
(std-remove-method generic-function method))
-(defmethod remove-method :after ((generic-function standard-generic-function)
+(defmethod remove-method :after ((generic-function generic-function)
(method method))
(map-dependents generic-function
#'(lambda (dep) (update-dependent generic-function dep
More information about the armedbear-cvs
mailing list