X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fpcl%2Fboot.lisp;h=aee604a3d7d28e501de0a195e4a5d5ae4c6882e5;hb=b319107330cea71911b346974508c699f8b7fe6c;hp=411411091af84d974c20e71edd3d3f92a1c9553f;hpb=3a5eefac8a65dfd36729031f0a9b9dd8c022b7f2;p=sbcl.git diff --git a/src/pcl/boot.lisp b/src/pcl/boot.lisp index 4114110..aee604a 100644 --- a/src/pcl/boot.lisp +++ b/src/pcl/boot.lisp @@ -818,6 +818,10 @@ bootstrapping. (,',next-methods (cdr ,',next-methods))) .next-method. ,',next-methods ,@body)) + (check-cnm-args-body (&environment env method-name-declaration cnm-args) + (if (safe-code-p env) + `(%check-cnm-args ,cnm-args ,',method-args ',method-name-declaration) + nil)) (call-next-method-body (method-name-declaration cnm-args) `(if .next-method. (funcall (if (std-instance-p .next-method.) @@ -1062,7 +1066,8 @@ bootstrapping. (apply emf args)))) (defmacro bind-fast-lexical-method-macros ((args rest-arg next-method-call) - &body body) + &body body + &environment env) (let* ((all-params (append args (when rest-arg (list rest-arg)))) (rebindings (mapcar (lambda (x) (list x x)) all-params))) `(macrolet ((narrowed-emf (emf) @@ -1093,6 +1098,11 @@ bootstrapping. ,emf)) (call-next-method-bind (&body body) `(let () ,@body)) + (check-cnm-args-body (&environment env method-name-declaration cnm-args) + (if (safe-code-p env) + `(%check-cnm-args ,cnm-args (list ,@',args) + ',method-name-declaration) + nil)) (call-next-method-body (method-name-declaration cnm-args) `(if ,',next-method-call ,(locally @@ -1155,15 +1165,42 @@ bootstrapping. `(call-next-method-bind (flet (,@(and call-next-method-p `((call-next-method (&rest cnm-args) - (call-next-method-body - ,method-name-declaration - cnm-args)))) + (check-cnm-args-body ,method-name-declaration cnm-args) + (call-next-method-body ,method-name-declaration cnm-args)))) ,@(and next-method-p-p '((next-method-p () (next-method-p-body))))) (with-rebound-original-args (,call-next-method-p ,setq-p) ,@body)))))) +;;; CMUCL comment (Gerd Moellmann): +;;; +;;; The standard says it's an error if CALL-NEXT-METHOD is called with +;;; arguments, and the set of methods applicable to those arguments is +;;; different from the set of methods applicable to the original +;;; method arguments. (According to Barry Margolin, this rule was +;;; probably added to ensure that before and around methods are always +;;; run before primary methods.) +;;; +;;; This could be optimized for the case that the generic function +;;; doesn't have hairy methods, does have standard method combination, +;;; is a standard generic function, there are no methods defined on it +;;; for COMPUTE-APPLICABLE-METHODS and probably a lot more of such +;;; preconditions. That looks hairy and is probably not worth it, +;;; because this check will never be fast. +(defun %check-cnm-args (cnm-args orig-args method-name-declaration) + (when cnm-args + (let* ((gf (fdefinition (caar method-name-declaration))) + (omethods (compute-applicable-methods gf orig-args)) + (nmethods (compute-applicable-methods gf cnm-args))) + (unless (equal omethods nmethods) + (error "~@" + nmethods (length cnm-args) cnm-args omethods + (length orig-args) orig-args))))) + (defmacro bind-args ((lambda-list args) &body body) (let ((args-tail '.args-tail.) (key '.key.) @@ -1852,10 +1889,10 @@ bootstrapping. fin (or function (if (eq spec 'print-object) - #'(instance-lambda (instance stream) + #'(lambda (instance stream) (print-unreadable-object (instance stream :identity t) (format stream "std-instance"))) - #'(instance-lambda (&rest args) + #'(lambda (&rest args) (declare (ignore args)) (error "The function of the funcallable-instance ~S~ has not been set." fin))))) @@ -1950,7 +1987,9 @@ bootstrapping. (let ((method-class (getf ,all-keys :method-class '.shes-not-there.))) (unless (eq method-class '.shes-not-there.) (setf (getf ,all-keys :method-class) - (find-class method-class t ,env)))))) + (cond ((classp method-class) + method-class) + (t (find-class method-class t ,env)))))))) (defun real-ensure-gf-using-class--generic-function (existing