X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fpcl%2Fdefs.lisp;h=cea2b0e514447e172a7e8f56cac0e2bd838a89d2;hb=4f7161165647d655392713a0d95c951e4e1749ea;hp=607f6c5960311b4bdc87a3430e34645baedfc5fe;hpb=4f8f4b25cb564509437d8fc26038143150077f14;p=sbcl.git diff --git a/src/pcl/defs.lisp b/src/pcl/defs.lisp index 607f6c5..cea2b0e 100644 --- a/src/pcl/defs.lisp +++ b/src/pcl/defs.lisp @@ -62,11 +62,12 @@ ;;; interface (defun specializer-from-type (type &aux args) + (when (symbolp type) + (return-from specializer-from-type (find-class type))) (when (consp type) (setq args (cdr type) type (car type))) (cond ((symbolp type) - (or (and (null args) (find-class type)) - (ecase type + (or (ecase type (class (coerce-to-class (car args))) (prototype (make-instance 'class-prototype-specializer :object (coerce-to-class (car args)))) @@ -75,7 +76,7 @@ ;; FIXME: do we still need this? ((and (null args) (typep type 'classoid)) (or (classoid-pcl-class type) - (ensure-non-standard-class (classoid-name type)))) + (ensure-non-standard-class (classoid-name type) type))) ((specializerp type) type))) ;;; interface @@ -194,12 +195,6 @@ (push (list class-name symbol) *built-in-wrapper-symbols*) symbol))) -(pushnew '%class *var-declarations*) -(pushnew '%variable-rebinding *var-declarations*) - -(defun variable-class (var env) - (caddr (var-declaration 'class var env))) - (defvar *standard-method-combination*) (defun plist-value (object name) @@ -232,7 +227,7 @@ (let ((subs (classoid-subclasses class))) (/noshow subs) (when subs - (dohash (sub v subs) + (dohash ((sub v) subs) (declare (ignore v)) (/noshow sub) (when (member class (direct-supers sub)) @@ -314,7 +309,9 @@ definition-source-mixin metaobject funcallable-standard-object) - ((%documentation :initform nil :initarg :documentation) + ((%documentation + :initform nil + :initarg :documentation) ;; We need to make a distinction between the methods initially set ;; up by :METHOD options to DEFGENERIC and the ones set up later by ;; DEFMETHOD, because ANSI specifies that executing DEFGENERIC on @@ -326,8 +323,9 @@ ;; DEFMETHOD, then modifying and reloading a.lisp and/or b.lisp ;; tends to leave the generic function in a state consistent with ;; the most-recently-loaded state of a.lisp and b.lisp.) - (initial-methods :initform () - :accessor generic-function-initial-methods)) + (initial-methods + :initform () + :accessor generic-function-initial-methods)) (:metaclass funcallable-standard-class)) (defclass standard-generic-function (generic-function) @@ -358,7 +356,11 @@ :reader gf-arg-info) (dfun-state :initform () - :accessor gf-dfun-state)) + :accessor gf-dfun-state) + ;; Used to make DFUN-STATE & FIN-FUNCTION updates atomic. + (%lock + :initform (sb-thread::make-spinlock :name "GF lock") + :reader gf-lock)) (:metaclass funcallable-standard-class) (:default-initargs :method-class *the-class-standard-method* :method-combination *standard-method-combination*)) @@ -366,21 +368,11 @@ (defclass method (metaobject) ()) (defclass standard-method (plist-mixin definition-source-mixin method) - ((%generic-function - :initform nil - :accessor method-generic-function) - (qualifiers - :initform () - :initarg :qualifiers - :reader method-qualifiers) - (specializers - :initform () - :initarg :specializers - :reader method-specializers) - (lambda-list - :initform () - :initarg :lambda-list - :reader method-lambda-list) + ((%generic-function :initform nil :accessor method-generic-function) + (qualifiers :initform () :initarg :qualifiers :reader method-qualifiers) + (specializers :initform () :initarg :specializers + :reader method-specializers) + (lambda-list :initform () :initarg :lambda-list :reader method-lambda-list) (%function :initform nil :initarg :function :reader method-function) (%documentation :initform nil :initarg :documentation))) @@ -552,35 +544,47 @@ ;; responses in comp.lang.lisp). -- CSR, 2006-02-27 ((%type :initform nil :reader specializer-type))) +;;; STANDARD in this name doesn't mean "blessed by a standard" but +;;; "comes as standard with PCL"; that is, it includes CLASS-EQ +;;; and vestiges of PROTOTYPE specializers +(defclass standard-specializer (specializer) ()) + (defclass specializer-with-object (specializer) ()) (defclass exact-class-specializer (specializer) ()) -(defclass class-eq-specializer (exact-class-specializer +(defclass class-eq-specializer (standard-specializer + exact-class-specializer specializer-with-object) ((object :initarg :class :reader specializer-class :reader specializer-object))) -(defclass class-prototype-specializer (specializer-with-object) +(defclass class-prototype-specializer (standard-specializer specializer-with-object) ((object :initarg :class :reader specializer-class :reader specializer-object))) -(defclass eql-specializer (exact-class-specializer specializer-with-object) +(defclass eql-specializer (standard-specializer exact-class-specializer specializer-with-object) ((object :initarg :object :reader specializer-object :reader eql-specializer-object))) (defvar *eql-specializer-table* (make-hash-table :test 'eql)) +(defvar *eql-specializer-table-lock* + (sb-thread::make-spinlock :name "EQL-specializer table lock")) + (defun intern-eql-specializer (object) - (or (gethash object *eql-specializer-table*) - (setf (gethash object *eql-specializer-table*) - (make-instance 'eql-specializer :object object)))) + ;; Need to lock, so that two threads don't get non-EQ specializers + ;; for an EQL object. + (sb-thread::with-spinlock (*eql-specializer-table-lock*) + (or (gethash object *eql-specializer-table*) + (setf (gethash object *eql-specializer-table*) + (make-instance 'eql-specializer :object object))))) (defclass class (dependent-update-mixin definition-source-mixin - specializer) + standard-specializer) ((name :initform nil :initarg :name @@ -647,10 +651,10 @@ (defclass slot-class (pcl-class) ((direct-slots :initform () - :accessor class-direct-slots) + :reader class-direct-slots) (slots :initform () - :accessor class-slots))) + :reader class-slots))) ;;; The class STD-CLASS is an implementation-specific common ;;; superclass of the classes STANDARD-CLASS and @@ -694,6 +698,7 @@ (defparameter *early-class-predicates* '((specializer specializerp) + (standard-specializer standard-specializer-p) (exact-class-specializer exact-class-specializer-p) (class-eq-specializer class-eq-specializer-p) (eql-specializer eql-specializer-p)