1 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; This software is derived from software originally released by Xerox
5 ;;;; Corporation. Copyright and release statements follow. Later modifications
6 ;;;; to the software are in the public domain and are provided with
7 ;;;; absolutely no warranty. See the COPYING and CREDITS files for more
10 ;;;; copyright information from original PCL sources:
12 ;;;; Copyright (c) 1985, 1986, 1987, 1988, 1989, 1990 Xerox Corporation.
13 ;;;; All rights reserved.
15 ;;;; Use and copying of this software and preparation of derivative works based
16 ;;;; upon this software are permitted. Any distribution of this software or
17 ;;;; derivative works must comply with all applicable United States export
20 ;;;; This software is made available AS IS, and Xerox Corporation makes no
21 ;;;; warranty about the software, its performance or its conformity to any
26 ;;; (These are left over from the days when PCL was an add-on package
27 ;;; for a pre-CLOS Common Lisp. They shouldn't happen in a normal
28 ;;; build, of course, but they might happen if someone is experimenting
29 ;;; and debugging, and it's probably worth complaining if they do,
30 ;;; so we've left 'em in.)
31 (when (eq *boot-state* 'complete)
32 (error "Trying to load (or compile) PCL in an environment in which it~%~
33 has already been loaded. This doesn't work, you will have to~%~
34 get a fresh lisp (reboot) and then load PCL."))
36 (cerror "Try loading (or compiling) PCL anyways."
37 "Trying to load (or compile) PCL in an environment in which it~%~
38 has already been partially loaded. This may not work, you may~%~
39 need to get a fresh lisp (reboot) and then load PCL."))
41 ;;; comments from CMU CL version of PCL:
42 ;;; This is like fdefinition on the Lispm. If Common Lisp had
43 ;;; something like function specs I wouldn't need this. On the other
44 ;;; hand, I don't like the way this really works so maybe function
45 ;;; specs aren't really right either?
46 ;;; I also don't understand the real implications of a Lisp-1 on this
47 ;;; sort of thing. Certainly some of the lossage in all of this is
48 ;;; because these SPECs name global definitions.
49 ;;; Note that this implementation is set up so that an implementation
50 ;;; which has a 'real' function spec mechanism can use that instead
51 ;;; and in that way get rid of setf generic function names.
52 (defmacro parse-gspec (spec
53 (non-setf-var . non-setf-case))
54 `(let ((,non-setf-var ,spec)) ,@non-setf-case))
56 ;;; If symbol names a function which is traced, return the untraced
57 ;;; definition. This lets us get at the generic function object even
58 ;;; when it is traced.
59 (defun unencapsulated-fdefinition (symbol)
62 ;;; If symbol names a function which is traced, redefine the `real'
63 ;;; definition without affecting the trace.
64 (defun fdefine-carefully (name new-definition)
66 (sb-c::note-name-defined name :function)
68 (setf (fdefinition name) new-definition))
72 (name (fboundp name))))
74 (defun gmakunbound (spec)
76 (name (fmakunbound name))))
78 (defun gdefinition (spec)
80 (name (unencapsulated-fdefinition name))))
82 (defun (setf gdefinition) (new-value spec)
84 (name (fdefine-carefully name new-value))))
86 (declaim (special *the-class-t*
87 *the-class-vector* *the-class-symbol*
88 *the-class-string* *the-class-sequence*
89 *the-class-rational* *the-class-ratio*
90 *the-class-number* *the-class-null* *the-class-list*
91 *the-class-integer* *the-class-float* *the-class-cons*
92 *the-class-complex* *the-class-character*
93 *the-class-bit-vector* *the-class-array*
96 *the-class-slot-object*
97 *the-class-structure-object*
98 *the-class-std-object*
99 *the-class-standard-object*
100 *the-class-funcallable-standard-object*
102 *the-class-generic-function*
103 *the-class-built-in-class*
104 *the-class-slot-class*
105 *the-class-condition-class*
106 *the-class-structure-class*
107 *the-class-std-class*
108 *the-class-standard-class*
109 *the-class-funcallable-standard-class*
111 *the-class-standard-method*
112 *the-class-standard-reader-method*
113 *the-class-standard-writer-method*
114 *the-class-standard-boundp-method*
115 *the-class-standard-generic-function*
116 *the-class-standard-effective-slot-definition*
118 *the-eslotd-standard-class-slots*
119 *the-eslotd-funcallable-standard-class-slots*))
121 (declaim (special *the-wrapper-of-t*
122 *the-wrapper-of-vector* *the-wrapper-of-symbol*
123 *the-wrapper-of-string* *the-wrapper-of-sequence*
124 *the-wrapper-of-rational* *the-wrapper-of-ratio*
125 *the-wrapper-of-number* *the-wrapper-of-null*
126 *the-wrapper-of-list* *the-wrapper-of-integer*
127 *the-wrapper-of-float* *the-wrapper-of-cons*
128 *the-wrapper-of-complex* *the-wrapper-of-character*
129 *the-wrapper-of-bit-vector* *the-wrapper-of-array*))
131 ;;;; type specifier hackery
133 ;;; internal to this file
134 (defun coerce-to-class (class &optional make-forward-referenced-class-p)
136 (or (find-class class (not make-forward-referenced-class-p))
137 (ensure-class class))
141 (defun specializer-from-type (type &aux args)
143 (setq args (cdr type) type (car type)))
144 (cond ((symbolp type)
145 (or (and (null args) (find-class type))
147 (class (coerce-to-class (car args)))
148 (prototype (make-instance 'class-prototype-specializer
149 :object (coerce-to-class (car args))))
150 (class-eq (class-eq-specializer (coerce-to-class (car args))))
151 (eql (intern-eql-specializer (car args))))))
152 ;; FIXME: do we still need this?
153 ((and (null args) (typep type 'classoid))
154 (or (classoid-pcl-class type)
155 (ensure-non-standard-class (classoid-name type))))
156 ((specializerp type) type)))
159 (defun type-from-specializer (specl)
163 (unless (member (car specl) '(class prototype class-eq eql))
164 (error "~S is not a legal specializer type." specl))
167 (when (symbolp specl)
168 ;;maybe (or (find-class specl nil) (ensure-class specl)) instead?
169 (setq specl (find-class specl)))
170 (or (not (eq *boot-state* 'complete))
171 (specializerp specl)))
172 (specializer-type specl))
174 (error "~S is neither a type nor a specializer." specl))))
176 (defun type-class (type)
177 (declare (special *the-class-t*))
178 (setq type (type-from-specializer type))
182 (error "bad argument to TYPE-CLASS"))
184 (eql (class-of (cadr type)))
185 (prototype (class-of (cadr type))) ;?
186 (class-eq (cadr type))
187 (class (cadr type)))))
189 (defun class-eq-type (class)
190 (specializer-type (class-eq-specializer class)))
192 ;;; internal to this file..
194 ;;; These functions are a pale imitation of their namesake. They accept
195 ;;; class objects or types where they should.
196 (defun *normalize-type (type)
198 (if (member (car type) '(not and or))
199 `(,(car type) ,@(mapcar #'*normalize-type (cdr type)))
200 (if (null (cdr type))
201 (*normalize-type (car type))
204 (let ((class (find-class type nil)))
206 (let ((type (specializer-type class)))
207 (if (listp type) type `(,type)))
209 ((or (not (eq *boot-state* 'complete))
211 (specializer-type type))
213 (error "~S is not a type." type))))
215 ;;; internal to this file...
216 (defun convert-to-system-type (type)
218 ((not and or) `(,(car type) ,@(mapcar #'convert-to-system-type
220 ((class class-eq) ; class-eq is impossible to do right
221 (layout-classoid (class-wrapper (cadr type))))
223 (t (if (null (cdr type))
227 ;;; Writing the missing NOT and AND clauses will improve the quality
228 ;;; of code generated by GENERATE-DISCRIMINATION-NET, but calling
229 ;;; SUBTYPEP in place of just returning (VALUES NIL NIL) can be very
230 ;;; slow. *SUBTYPEP is used by PCL itself, and must be fast.
232 ;;; FIXME: SB-KERNEL has fast-and-not-quite-precise type code for use
233 ;;; in the compiler. Could we share some of it here?
234 (defun *subtypep (type1 type2)
235 (if (equal type1 type2)
237 (if (eq *boot-state* 'early)
238 (values (eq type1 type2) t)
239 (let ((*in-precompute-effective-methods-p* t))
240 (declare (special *in-precompute-effective-methods-p*))
241 ;; FIXME: *IN-PRECOMPUTE-EFFECTIVE-METHODS-P* is not a
242 ;; good name. It changes the way
243 ;; CLASS-APPLICABLE-USING-CLASS-P works.
244 (setq type1 (*normalize-type type1))
245 (setq type2 (*normalize-type type2))
248 (values nil nil)) ; XXX We should improve this.
250 (values nil nil)) ; XXX We should improve this.
251 ((eql wrapper-eq class-eq class)
252 (multiple-value-bind (app-p maybe-app-p)
253 (specializer-applicable-using-type-p type2 type1)
254 (values app-p (or app-p (not maybe-app-p)))))
256 (subtypep (convert-to-system-type type1)
257 (convert-to-system-type type2))))))))
259 (defvar *built-in-class-symbols* ())
260 (defvar *built-in-wrapper-symbols* ())
262 (defun get-built-in-class-symbol (class-name)
263 (or (cadr (assq class-name *built-in-class-symbols*))
264 (let ((symbol (intern (format nil
266 (symbol-name class-name))
268 (push (list class-name symbol) *built-in-class-symbols*)
271 (defun get-built-in-wrapper-symbol (class-name)
272 (or (cadr (assq class-name *built-in-wrapper-symbols*))
273 (let ((symbol (intern (format nil
274 "*THE-WRAPPER-OF-~A*"
275 (symbol-name class-name))
277 (push (list class-name symbol) *built-in-wrapper-symbols*)
280 (pushnew '%class *var-declarations*)
281 (pushnew '%variable-rebinding *var-declarations*)
283 (defun variable-class (var env)
284 (caddr (var-declaration 'class var env)))
286 (defvar *name->class->slotd-table* (make-hash-table))
288 (defvar *standard-method-combination*)
290 (defun make-class-predicate-name (name)
291 (list 'class-predicate name))
293 (defun plist-value (object name)
294 (getf (object-plist object) name))
296 (defun (setf plist-value) (new-value object name)
298 (setf (getf (object-plist object) name) new-value)
300 (remf (object-plist object) name)
303 ;;;; built-in classes
305 ;;; FIXME: This was the portable PCL way of setting up
306 ;;; *BUILT-IN-CLASSES*, but in SBCL (as in CMU CL) it's almost
307 ;;; entirely wasted motion, since it's immediately overwritten by a
308 ;;; result mostly derived from SB-KERNEL::*BUILT-IN-CLASSES*. However,
309 ;;; we can't just delete it, since the fifth element from each entry
310 ;;; (a prototype of the class) is still in the final result. It would
311 ;;; be nice to clean this up so that the other, never-used stuff is
312 ;;; gone, perhaps finding a tidier way to represent examples of each
315 ;;; FIXME: This can probably be blown away after bootstrapping.
316 ;;; And SB-KERNEL::*BUILT-IN-CLASSES*, too..
318 (defvar *built-in-classes*
319 ;; name supers subs cdr of cpl
321 '(;(t () (number sequence array character symbol) ())
322 (number (t) (complex float rational) (t))
323 (complex (number) () (number t)
325 (float (number) () (number t)
327 (rational (number) (integer ratio) (number t))
328 (integer (rational) () (rational number t)
330 (ratio (rational) () (rational number t)
333 (sequence (t) (list vector) (t))
334 (list (sequence) (cons null) (sequence t))
335 (cons (list) () (list sequence t)
338 (array (t) (vector) (t)
341 sequence) (string bit-vector) (array sequence t)
343 (string (vector) () (vector array sequence t)
345 (bit-vector (vector) () (vector array sequence t)
347 (character (t) () (t)
350 (symbol (t) (null) (t)
353 list) () (symbol list sequence t)
357 ;;; Grovel over SB-KERNEL::*BUILT-IN-CLASSES* in order to set
358 ;;; SB-PCL:*BUILT-IN-CLASSES*.
359 (/show "about to set up SB-PCL::*BUILT-IN-CLASSES*")
360 (defvar *built-in-classes*
361 (labels ((direct-supers (class)
362 (/noshow "entering DIRECT-SUPERS" (classoid-name class))
363 (if (typep class 'built-in-classoid)
364 (built-in-classoid-direct-superclasses class)
365 (let ((inherits (layout-inherits
366 (classoid-layout class))))
368 (list (svref inherits (1- (length inherits)))))))
370 (/noshow "entering DIRECT-SUBS" (classoid-name class))
372 (let ((subs (classoid-subclasses class)))
378 (when (member class (direct-supers sub))
381 (prototype (class-name)
382 (let ((assoc (assoc class-name
383 '((complex . #c(1 1))
399 ;; This is the default prototype value which was
400 ;; used, without explanation, by the CMU CL code
401 ;; we're derived from. Evidently it's safe in all
404 (mapcar (lambda (kernel-bic-entry)
405 (/noshow "setting up" kernel-bic-entry)
406 (let* ((name (car kernel-bic-entry))
407 (class (find-classoid name)))
410 ,(mapcar #'classoid-name (direct-supers class))
411 ,(mapcar #'classoid-name (direct-subs class))
415 (layout-classoid x)))
418 (classoid-layout class))))
420 (remove-if (lambda (kernel-bic-entry)
421 (member (first kernel-bic-entry)
422 ;; I'm not sure why these are removed from
423 ;; the list, but that's what the original
424 ;; CMU CL code did. -- WHN 20000715
428 sb-kernel::*built-in-classes*))))
429 (/noshow "done setting up SB-PCL::*BUILT-IN-CLASSES*")
431 ;;;; the classes that define the kernel of the metabraid
434 (:metaclass built-in-class))
436 (defclass instance (t) ()
437 (:metaclass built-in-class))
439 (defclass function (t) ()
440 (:metaclass built-in-class))
442 (defclass funcallable-instance (function) ()
443 (:metaclass built-in-class))
445 (defclass stream (instance) ()
446 (:metaclass built-in-class))
448 (defclass slot-object (t) ()
449 (:metaclass slot-class))
451 (defclass condition (slot-object instance) ()
452 (:metaclass condition-class))
454 (defclass structure-object (slot-object instance) ()
455 (:metaclass structure-class))
457 (defstruct (dead-beef-structure-object
458 (:constructor |STRUCTURE-OBJECT class constructor|)
461 (defclass std-object (slot-object) ()
462 (:metaclass std-class))
464 (defclass standard-object (std-object instance) ())
466 (defclass funcallable-standard-object (std-object funcallable-instance)
468 (:metaclass funcallable-standard-class))
470 (defclass specializer (standard-object)
473 :reader specializer-type)))
475 (defclass definition-source-mixin (std-object)
477 :initform *load-pathname*
478 :reader definition-source
479 :initarg :definition-source))
480 (:metaclass std-class))
482 (defclass plist-mixin (std-object)
485 :accessor object-plist))
486 (:metaclass std-class))
488 (defclass documentation-mixin (plist-mixin)
490 (:metaclass std-class))
492 (defclass dependent-update-mixin (plist-mixin)
494 (:metaclass std-class))
496 ;;; The class CLASS is a specified basic class. It is the common
497 ;;; superclass of any kind of class. That is, any class that can be a
498 ;;; metaclass must have the class CLASS in its class precedence list.
499 (defclass class (documentation-mixin
500 dependent-update-mixin
501 definition-source-mixin
506 :accessor class-name)
507 (class-eq-specializer
509 :reader class-eq-specializer)
512 :reader class-direct-superclasses)
513 ;; Note: The (CLASS-)DIRECT-SUBCLASSES for STRUCTURE-CLASSes and
514 ;; CONDITION-CLASSes are lazily computed whenever the subclass info
515 ;; becomes available, i.e. when the PCL class is created.
518 :reader class-direct-subclasses)
520 :initform (cons nil nil))
523 :reader class-predicate-name)
526 :reader class-finalized-p)))
528 (def!method make-load-form ((class class) &optional env)
529 ;; FIXME: should we not instead pass ENV to FIND-CLASS? Probably
530 ;; doesn't matter while all our environments are the same...
531 (declare (ignore env))
532 (let ((name (class-name class)))
533 (unless (and name (eq (find-class name nil) class))
534 (error "~@<Can't use anonymous or undefined class as constant: ~S~:@>"
536 `(find-class ',name)))
538 ;;; The class PCL-CLASS is an implementation-specific common
539 ;;; superclass of all specified subclasses of the class CLASS.
540 (defclass pcl-class (class)
541 ((class-precedence-list
542 :reader class-precedence-list)
545 :reader class-can-precede-list)
546 (incompatible-superclass-list
548 :accessor class-incompatible-superclass-list)
551 :reader class-wrapper)
554 :reader class-prototype)))
556 (defclass slot-class (pcl-class)
559 :accessor class-direct-slots)
562 :accessor class-slots)
565 :accessor class-initialize-info)))
567 ;;; The class STD-CLASS is an implementation-specific common
568 ;;; superclass of the classes STANDARD-CLASS and
569 ;;; FUNCALLABLE-STANDARD-CLASS.
570 (defclass std-class (slot-class)
573 (defclass standard-class (std-class)
576 (defclass funcallable-standard-class (std-class)
579 (defclass forward-referenced-class (pcl-class) ())
581 (defclass built-in-class (pcl-class) ())
583 (defclass condition-class (slot-class) ())
585 (defclass structure-class (slot-class)
588 :accessor class-defstruct-form)
589 (defstruct-constructor
591 :accessor class-defstruct-constructor)
594 :initarg :from-defclass-p)))
596 (defclass specializer-with-object (specializer) ())
598 (defclass exact-class-specializer (specializer) ())
600 (defclass class-eq-specializer (exact-class-specializer
601 specializer-with-object)
602 ((object :initarg :class
603 :reader specializer-class
604 :reader specializer-object)))
606 (defclass class-prototype-specializer (specializer-with-object)
607 ((object :initarg :class
608 :reader specializer-class
609 :reader specializer-object)))
611 (defclass eql-specializer (exact-class-specializer specializer-with-object)
612 ((object :initarg :object :reader specializer-object
613 :reader eql-specializer-object)))
615 (defvar *eql-specializer-table* (make-hash-table :test 'eql))
617 (defun intern-eql-specializer (object)
618 (or (gethash object *eql-specializer-table*)
619 (setf (gethash object *eql-specializer-table*)
620 (make-instance 'eql-specializer :object object))))
622 ;;;; slot definitions
624 (defclass slot-definition (standard-object)
628 :accessor slot-definition-name)
632 :accessor slot-definition-initform)
635 :initarg :initfunction
636 :accessor slot-definition-initfunction)
640 :accessor slot-definition-readers)
644 :accessor slot-definition-writers)
648 :accessor slot-definition-initargs)
652 :accessor slot-definition-type)
655 :initarg :documentation)
659 :accessor slot-definition-class)))
661 (defclass standard-slot-definition (slot-definition)
665 :accessor slot-definition-allocation)
668 :initarg :allocation-class
669 :accessor slot-definition-allocation-class)))
671 (defclass condition-slot-definition (slot-definition)
675 :accessor slot-definition-allocation)
678 :initarg :allocation-class
679 :accessor slot-definition-allocation-class)))
681 (defclass structure-slot-definition (slot-definition)
682 ((defstruct-accessor-symbol
684 :initarg :defstruct-accessor-symbol
685 :accessor slot-definition-defstruct-accessor-symbol)
686 (internal-reader-function
688 :initarg :internal-reader-function
689 :accessor slot-definition-internal-reader-function)
690 (internal-writer-function
692 :initarg :internal-writer-function
693 :accessor slot-definition-internal-writer-function)))
695 (defclass direct-slot-definition (slot-definition)
698 (defclass effective-slot-definition (slot-definition)
699 ((reader-function ; (lambda (object) ...)
700 :accessor slot-definition-reader-function)
701 (writer-function ; (lambda (new-value object) ...)
702 :accessor slot-definition-writer-function)
703 (boundp-function ; (lambda (object) ...)
704 :accessor slot-definition-boundp-function)
708 (defclass standard-direct-slot-definition (standard-slot-definition
709 direct-slot-definition)
712 (defclass standard-effective-slot-definition (standard-slot-definition
713 effective-slot-definition)
714 ((location ; nil, a fixnum, a cons: (slot-name . value)
716 :accessor slot-definition-location)))
718 (defclass condition-direct-slot-definition (condition-slot-definition
719 direct-slot-definition)
722 (defclass condition-effective-slot-definition (condition-slot-definition
723 effective-slot-definition)
726 (defclass structure-direct-slot-definition (structure-slot-definition
727 direct-slot-definition)
730 (defclass structure-effective-slot-definition (structure-slot-definition
731 effective-slot-definition)
734 (defclass method (standard-object) ())
736 (defclass standard-method (definition-source-mixin plist-mixin method)
739 :accessor method-generic-function)
742 ;;; :initarg :qualifiers
743 ;;; :reader method-qualifiers)
746 :initarg :specializers
747 :reader method-specializers)
750 :initarg :lambda-list
751 :reader method-lambda-list)
754 :initarg :function) ;no writer
757 :initarg :fast-function ;no writer
758 :reader method-fast-function)
761 ;;; :initarg :documentation
762 ;;; :reader method-documentation)
765 (defclass standard-accessor-method (standard-method)
766 ((slot-name :initform nil
768 :reader accessor-method-slot-name)
769 (slot-definition :initform nil
770 :initarg :slot-definition
771 :reader accessor-method-slot-definition)))
773 (defclass standard-reader-method (standard-accessor-method) ())
775 (defclass standard-writer-method (standard-accessor-method) ())
777 (defclass standard-boundp-method (standard-accessor-method) ())
779 (defclass generic-function (dependent-update-mixin
780 definition-source-mixin
782 funcallable-standard-object)
783 (;; We need to make a distinction between the methods initially set
784 ;; up by :METHOD options to DEFGENERIC and the ones set up later by
785 ;; DEFMETHOD, because ANSI's specifies that executing DEFGENERIC on
786 ;; an already-DEFGENERICed function clears the methods set by the
787 ;; previous DEFGENERIC, but not methods set by DEFMETHOD. (Making
788 ;; this distinction seems a little kludgy, but it has the positive
789 ;; effect of making it so that loading a file a.lisp containing
790 ;; DEFGENERIC, then loading a second file b.lisp containing
791 ;; DEFMETHOD, then modifying and reloading a.lisp and/or b.lisp
792 ;; tends to leave the generic function in a state consistent with
793 ;; the most-recently-loaded state of a.lisp and b.lisp.)
796 :accessor generic-function-initial-methods))
797 (:metaclass funcallable-standard-class))
799 (defclass standard-generic-function (generic-function)
803 :accessor generic-function-name)
806 :accessor generic-function-methods
809 :initarg :method-class
810 :accessor generic-function-method-class)
812 :initarg :method-combination
813 :accessor generic-function-method-combination)
815 :initarg :declarations
817 :accessor generic-function-declarations)
819 :initform (make-arg-info)
823 :accessor gf-dfun-state))
824 (:metaclass funcallable-standard-class)
825 (:default-initargs :method-class *the-class-standard-method*
826 :method-combination *standard-method-combination*))
828 (defclass method-combination (standard-object) ())
830 (defclass standard-method-combination (definition-source-mixin
833 :reader method-combination-type
836 :reader method-combination-documentation
837 :initarg :documentation)
839 :reader method-combination-options
842 (defclass long-method-combination (standard-method-combination)
845 :reader long-method-combination-function)
847 :initarg :args-lambda-list
848 :reader long-method-combination-args-lambda-list)))
850 (defparameter *early-class-predicates*
851 '((specializer specializerp)
852 (exact-class-specializer exact-class-specializer-p)
853 (class-eq-specializer class-eq-specializer-p)
854 (eql-specializer eql-specializer-p)
856 (slot-class slot-class-p)
857 (std-class std-class-p)
858 (standard-class standard-class-p)
859 (funcallable-standard-class funcallable-standard-class-p)
860 (condition-class condition-class-p)
861 (structure-class structure-class-p)
862 (forward-referenced-class forward-referenced-class-p)
864 (standard-method standard-method-p)
865 (standard-accessor-method standard-accessor-method-p)
866 (standard-reader-method standard-reader-method-p)
867 (standard-writer-method standard-writer-method-p)
868 (standard-boundp-method standard-boundp-method-p)
869 (generic-function generic-function-p)
870 (standard-generic-function standard-generic-function-p)
871 (method-combination method-combination-p)
872 (long-method-combination long-method-combination-p)))