"is not a non-null atom"))
(defmethod legal-slot-name-p ((object standard-method) x)
- (cond ((not (symbolp x)) "is not a symbol and so cannot be bound")
- ((keywordp x) "is a keyword and so cannot be bound")
- ((memq x '(t nil)) "cannot be bound")
- ((constantp x) "is a constant and so cannot be bound")
+ (cond ((not (symbolp x)) "is not a symbol")
(t t)))
(defmethod legal-specializers-p ((object standard-method) x)
(apply #'call-next-method generic-function initargs)))
||#
\f
-;;; These three are scheduled for demolition.
-
-(defmethod remove-named-method (generic-function-name argument-specifiers
- &optional extra)
- (let ((generic-function ())
- (method ()))
- (cond ((or (null (fboundp generic-function-name))
- (not (generic-function-p
- (setq generic-function
- (fdefinition generic-function-name)))))
- (error "~S does not name a generic function."
- generic-function-name))
- ((null (setq method (get-method generic-function
- extra
- (parse-specializers
- argument-specifiers)
- nil)))
- (error "There is no method for the generic function ~S~%~
- which matches the ARGUMENT-SPECIFIERS ~S."
- generic-function
- argument-specifiers))
- (t
- (remove-method generic-function method)))))
-
+;;; These two are scheduled for demolition.
(defun real-add-named-method (generic-function-name
qualifiers
specializers
&rest other-initargs)
(unless (and (fboundp generic-function-name)
(typep (fdefinition generic-function-name) 'generic-function))
- (sb-kernel::style-warn "implicitly creating new generic function ~S"
- generic-function-name))
+ (style-warn "implicitly creating new generic function ~S"
+ generic-function-name))
;; XXX What about changing the class of the generic function if
;; there is one? Whose job is that, anyway? Do we need something
;; kind of like CLASS-FOR-REDEFINITION?
:specializers specs
:lambda-list lambda-list
other-initargs)))
- (add-method generic-function new)))
+ (add-method generic-function new)
+ new))
(defun real-get-method (generic-function qualifiers specializers
&optional (errorp t))
- (let ((hit
+ (let* ((lspec (length specializers))
+ (hit
(dolist (method (generic-function-methods generic-function))
(let ((mspecializers (method-specializers method)))
+ (aver (= lspec (length mspecializers)))
(when (and (equal qualifiers (method-qualifiers method))
- (= (length specializers) (length mspecializers))
(every #'same-specializer-p specializers
(method-specializers method)))
(return method))))))
(cond (hit hit)
((null errorp) nil)
(t
- (error "no method on ~S with qualifiers ~:S and specializers ~:S"
+ (error "~@<There is no method on ~S with ~
+ ~:[no qualifiers~;~:*qualifiers ~S~] ~
+ and specializers ~S.~@:>"
generic-function qualifiers specializers)))))
-\f
+
(defmethod find-method ((generic-function standard-generic-function)
qualifiers specializers &optional (errorp t))
- (real-get-method generic-function qualifiers
- (parse-specializers specializers) errorp))
+ (let ((nreq (length (arg-info-metatypes (gf-arg-info generic-function)))))
+ ;; ANSI: "The specializers argument contains the parameter
+ ;; specializers for the method. It must correspond in length to
+ ;; the number of required arguments of the generic function, or an
+ ;; error is signaled."
+ (when (/= (length specializers) nreq)
+ (error "~@<The generic function ~S takes ~D required argument~:P; ~
+ was asked to find a method with specializers ~S~@:>"
+ generic-function nreq specializers))
+ (real-get-method generic-function qualifiers
+ (parse-specializers specializers) errorp)))
\f
;;; Compute various information about a generic-function's arglist by looking
;;; at the argument lists of the methods. The hair for trying not to use
(defun real-add-method (generic-function method &optional skip-dfun-update-p)
(when (method-generic-function method)
- (error "The method ~S is already part of the generic~@
- function ~S. It can't be added to another generic~@
- function until it is removed from the first one."
+ (error "~@<The method ~S is already part of the generic ~
+ function ~S; it can't be added to another generic ~
+ function until it is removed from the first one.~@:>"
method (method-generic-function method)))
(flet ((similar-lambda-lists-p (method-a method-b)
(multiple-value-bind (a-nreq a-nopt a-keyp a-restp)
:generic-function generic-function
:method method)
(update-dfun generic-function))
- method)))
+ generic-function)))
(defun real-remove-method (generic-function method)
- ;; Note: Error check prohibited by ANSI spec removed.
(when (eq generic-function (method-generic-function method))
- (let* ((name (generic-function-name generic-function))
+ (let* ((name (generic-function-name generic-function))
(specializers (method-specializers method))
- (methods (generic-function-methods generic-function))
- (new-methods (remove method methods)))
+ (methods (generic-function-methods generic-function))
+ (new-methods (remove method methods)))
(setf (method-generic-function method) nil)
(setf (generic-function-methods generic-function) new-methods)
(dolist (specializer (method-specializers method))
(update-ctors 'remove-method
:generic-function generic-function
:method method)
- (update-dfun generic-function)
- generic-function)))
+ (update-dfun generic-function)))
+ generic-function)
\f
(defun compute-applicable-methods-function (generic-function arguments)
(values (compute-applicable-methods-using-types
(pushnew other-class (class-incompatible-superclass-list class))))))
(defun superclasses-compatible-p (class1 class2)
- (let ((cpl1 (class-precedence-list class1))
- (cpl2 (class-precedence-list class2)))
+ (let ((cpl1 (cpl-or-nil class1))
+ (cpl2 (cpl-or-nil class2)))
(dolist (sc1 cpl1 t)
(dolist (ic (class-incompatible-superclass-list sc1))
(when (memq ic cpl2)
*standard-method-combination*))
type)))))
+
+;;; CMUCL (Gerd's PCL, 2002-04-25) comment:
+;;;
+;;; Return two values. First value is a function to be stored in
+;;; effective slot definition SLOTD for reading it with
+;;; SLOT-VALUE-USING-CLASS, setting it with (SETF
+;;; SLOT-VALUE-USING-CLASS) or testing it with
+;;; SLOT-BOUNDP-USING-CLASS. GF is one of these generic functions,
+;;; TYPE is one of the symbols READER, WRITER, BOUNDP. CLASS is
+;;; SLOTD's class.
+;;;
+;;; Second value is true if the function returned is one of the
+;;; optimized standard functions for the purpose, which are used
+;;; when only standard methods are applicable.
+;;;
+;;; FIXME: Change all these wacky function names to something sane.
(defun get-accessor-method-function (gf type class slotd)
(let* ((std-method (standard-svuc-method type))
(str-method (structure-svuc-method type))
(values
(if std-p
(get-optimized-std-accessor-method-function class slotd type)
- (get-accessor-from-svuc-method-function
- class slotd
- (get-secondary-dispatch-function
- gf methods types
- `((,(car (or (member std-method methods)
- (member str-method methods)
- (error "error in get-accessor-method-function")))
- ,(get-optimized-std-slot-value-using-class-method-function
- class slotd type)))
- (unless (and (eq type 'writer)
- (dolist (method methods t)
- (unless (eq (car (method-specializers method))
- *the-class-t*)
- (return nil))))
- (let ((wrappers (list (wrapper-of class)
- (class-wrapper class)
- (wrapper-of slotd))))
- (if (eq type 'writer)
- (cons (class-wrapper *the-class-t*) wrappers)
- wrappers))))
- type))
+ (let* ((optimized-std-fun
+ (get-optimized-std-slot-value-using-class-method-function
+ class slotd type))
+ (method-alist
+ `((,(car (or (member std-method methods)
+ (member str-method methods)
+ (bug "error in ~S"
+ 'get-accessor-method-function)))
+ ,optimized-std-fun)))
+ (wrappers
+ (let ((wrappers (list (wrapper-of class)
+ (class-wrapper class)
+ (wrapper-of slotd))))
+ (if (eq type 'writer)
+ (cons (class-wrapper *the-class-t*) wrappers)
+ wrappers)))
+ (sdfun (get-secondary-dispatch-function
+ gf methods types method-alist wrappers)))
+ (get-accessor-from-svuc-method-function class slotd sdfun type)))
std-p)))
;;; used by OPTIMIZE-SLOT-VALUE-BY-CLASS-P (vector.lisp)
(defvar *standard-slot-value-using-class-method* nil)
(defvar *standard-setf-slot-value-using-class-method* nil)
(defvar *standard-slot-boundp-using-class-method* nil)
+(defvar *condition-slot-value-using-class-method* nil)
+(defvar *condition-setf-slot-value-using-class-method* nil)
+(defvar *condition-slot-boundp-using-class-method* nil)
(defvar *structure-slot-value-using-class-method* nil)
(defvar *structure-setf-slot-value-using-class-method* nil)
(defvar *structure-slot-boundp-using-class-method* nil)
(writer (setq *standard-setf-slot-value-using-class-method* method))
(boundp (setq *standard-slot-boundp-using-class-method* method))))
+(defun condition-svuc-method (type)
+ (case type
+ (reader *condition-slot-value-using-class-method*)
+ (writer *condition-setf-slot-value-using-class-method*)
+ (boundp *condition-slot-boundp-using-class-method*)))
+
+(defun set-condition-svuc-method (type method)
+ (case type
+ (reader (setq *condition-slot-value-using-class-method* method))
+ (writer (setq *condition-setf-slot-value-using-class-method* method))
+ (boundp (setq *condition-slot-boundp-using-class-method* method))))
+
(defun structure-svuc-method (type)
(case type
(reader *structure-slot-value-using-class-method*)
(when (and (or (not (eq type 'writer))
(eq (pop specls) *the-class-t*))
(every #'classp specls))
- (cond ((and (eq (class-name (car specls))
- 'std-class)
- (eq (class-name (cadr specls))
- 'std-object)
+ (cond ((and (eq (class-name (car specls)) 'std-class)
+ (eq (class-name (cadr specls)) 'std-object)
(eq (class-name (caddr specls))
'standard-effective-slot-definition))
(set-standard-svuc-method type method))
- ((and (eq (class-name (car specls))
- 'structure-class)
- (eq (class-name (cadr specls))
- 'structure-object)
+ ((and (eq (class-name (car specls)) 'condition-class)
+ (eq (class-name (cadr specls)) 'condition)
+ (eq (class-name (caddr specls))
+ 'condition-effective-slot-definition))
+ (set-condition-svuc-method type method))
+ ((and (eq (class-name (car specls)) 'structure-class)
+ (eq (class-name (cadr specls)) 'structure-object)
(eq (class-name (caddr specls))
'structure-effective-slot-definition))
(set-structure-svuc-method type method)))))))
((eq valuep :constant-value)
(value-for-caching generic-function
classes)))))
- (setq cache (fill-cache cache wrappers value t))))))))
+ (setq cache (fill-cache cache wrappers value))))))))
(if classes-list
(mapc #'add-class-list classes-list)
(dolist (method (generic-function-methods generic-function))
(cond ((eq class *the-class-t*)
t)
((eq class *the-class-slot-object*)
- `(not (typep (sb-kernel:classoid-of ,arg)
- 'sb-kernel:built-in-classoid)))
+ `(not (typep (classoid-of ,arg)
+ 'built-in-classoid)))
((eq class *the-class-std-object*)
`(or (std-instance-p ,arg) (fsc-instance-p ,arg)))
((eq class *the-class-standard-object*)
(defmacro mlookup (key info default &optional eq-p type)
(unless (or (eq eq-p t) (null eq-p))
- (error "Invalid eq-p argument"))
+ (bug "Invalid eq-p argument: ~S" eq-p))
(ecase type
(:simple
- `(if (,(if eq-p 'eq 'eql) ,key (car ,info))
+ `(if (locally
+ (declare (optimize (inhibit-warnings 3)))
+ (,(if eq-p 'eq 'eql) ,key (car ,info)))
(cdr ,info)
,default))
(:assoc
`(dolist (e ,info ,default)
- (when (,(if eq-p 'eq 'eql) (car e) ,key)
+ (when (locally
+ (declare (optimize (inhibit-warnings 3)))
+ (,(if eq-p 'eq 'eql) (car e) ,key))
(return (cdr e)))))
(:hash-table
`(gethash ,key ,info ,default))))
(make-fast-method-call-lambda-list metatypes applyp))))
(multiple-value-bind (cfunction constants)
(get-fun1 `(,(if function-p
- 'sb-kernel:instance-lambda
+ 'instance-lambda
'lambda)
,arglist
,@(unless function-p
;;; the funcallable instance function of the generic function for which
;;; it was computed.
;;;
-;;; More precisely, if compute-discriminating-function is called with an
-;;; argument <gf1>, and returns a result <df1>, that result must not be
-;;; passed to apply or funcall directly. Rather, <df1> must be stored as
-;;; the funcallable instance function of the same generic function <gf1>
-;;; (using set-funcallable-instance-fun). Then the generic function
-;;; can be passed to funcall or apply.
+;;; More precisely, if compute-discriminating-function is called with
+;;; an argument <gf1>, and returns a result <df1>, that result must
+;;; not be passed to apply or funcall directly. Rather, <df1> must be
+;;; stored as the funcallable instance function of the same generic
+;;; function <gf1> (using SET-FUNCALLABLE-INSTANCE-FUNCTION). Then the
+;;; generic function can be passed to funcall or apply.
;;;
;;; An important exception is that methods on this generic function are
;;; permitted to return a function which itself ends up calling the value
;;; (lambda (arg)
;;; (cond (<some condition>
;;; <store some info in the generic function>
-;;; (set-funcallable-instance-fun
+;;; (set-funcallable-instance-function
;;; gf
;;; (compute-discriminating-function gf))
;;; (funcall gf arg))
;;; (defmethod compute-discriminating-function ((gf my-generic-function))
;;; (lambda (arg)
;;; (cond (<some condition>
-;;; (set-funcallable-instance-fun
+;;; (set-funcallable-instance-function
;;; gf
;;; (lambda (a) ..))
;;; (funcall gf arg))