Optimize BIT-VECTOR-= on non-simple arrays.
[sbcl.git] / src / code / class.lisp
blobc2ceed6f7a2fe4d21aff55ce122cb86e817b4a0f
1 ;;;; This file contains structures and functions for the maintenance of
2 ;;;; basic information about defined types. Different object systems
3 ;;;; can be supported simultaneously.
5 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; more information.
7 ;;;;
8 ;;;; This software is derived from the CMU CL system, which was
9 ;;;; written at Carnegie Mellon University and released into the
10 ;;;; public domain. The software is in the public domain and is
11 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
12 ;;;; files for more information.
14 (in-package "SB!KERNEL")
16 (!begin-collecting-cold-init-forms)
18 ;;;; the CLASSOID structure
20 ;;; The CLASSOID structure is a supertype of all classoid types.
21 ;;; Its definition occurs in 'early-classoid.lisp'
23 (defun classoid-make-load-form-fun (self)
24 (let ((name (classoid-name self)))
25 (if (and name (eq (find-classoid name nil) self))
26 `(find-classoid ',name)
27 (error "can't use anonymous or undefined class as constant:~% ~S"
28 self))))
31 ;;;; basic LAYOUT stuff
33 ;;; a list of conses, initialized by genesis
34 ;;;
35 ;;; In each cons, the car is the symbol naming the layout, and the
36 ;;; cdr is the layout itself.
37 (defvar *!initial-layouts*)
39 ;;; a table mapping class names to layouts for classes we have
40 ;;; referenced but not yet loaded. This is initialized from an alist
41 ;;; created by genesis describing the layouts that genesis created at
42 ;;; cold-load time.
43 (defvar *forward-referenced-layouts*)
44 (!cold-init-forms
45 ;; Protected by *WORLD-LOCK*
46 (setq *forward-referenced-layouts* (make-hash-table :test 'equal))
47 #-sb-xc-host (progn
48 (/show0 "processing *!INITIAL-LAYOUTS*")
49 (dolist (x *!initial-layouts*)
50 (setf (layout-clos-hash (cdr x)) (random-layout-clos-hash))
51 (setf (gethash (car x) *forward-referenced-layouts*)
52 (cdr x)))
53 (/show0 "done processing *!INITIAL-LAYOUTS*")))
55 ;;; The LAYOUT structure itself is defined in 'early-classoid.lisp'
57 (declaim (inline layout-for-std-class-p))
58 (defun layout-for-std-class-p (x) (not (zerop (layout-%for-std-class-b x))))
60 (def!method print-object ((layout layout) stream)
61 (print-unreadable-object (layout stream :type t :identity t)
62 (format stream
63 "for ~S~@[, INVALID=~S~]"
64 (layout-proper-name layout)
65 (layout-invalid layout))))
67 (eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute)
68 (defun layout-proper-name (layout)
69 (classoid-proper-name (layout-classoid layout))))
71 ;;;; support for the hash values used by CLOS when working with LAYOUTs
73 ;;; a generator for random values suitable for the CLOS-HASH slots of
74 ;;; LAYOUTs. We use our own RANDOM-STATE here because we'd like
75 ;;; pseudo-random values to come the same way in the target even when
76 ;;; we make minor changes to the system, in order to reduce the
77 ;;; mysteriousness of possible CLOS bugs.
78 (defvar *layout-clos-hash-random-state*)
79 (defun random-layout-clos-hash ()
80 ;; FIXME: I'm not sure why this expression is (1+ (RANDOM FOO)),
81 ;; returning a strictly positive value. I copied it verbatim from
82 ;; CMU CL INITIALIZE-LAYOUT-HASH, so presumably it works, but I
83 ;; dunno whether the hash values are really supposed to be 1-based.
84 ;; They're declared as INDEX.. Or is this a hack to try to avoid
85 ;; having to use bignum arithmetic? Or what? An explanation would be
86 ;; nice.
88 ;; an explanation is provided in Kiczales and Rodriguez, "Efficient
89 ;; Method Dispatch in PCL", 1990. -- CSR, 2005-11-30
90 (1+ (random (1- layout-clos-hash-limit)
91 (if (boundp '*layout-clos-hash-random-state*)
92 *layout-clos-hash-random-state*
93 (setf *layout-clos-hash-random-state*
94 (make-random-state))))))
96 ;;; If we can't find any existing layout, then we create a new one
97 ;;; storing it in *FORWARD-REFERENCED-LAYOUTS*. In classic CMU CL, we
98 ;;; used to immediately check for compatibility, but for
99 ;;; cross-compilability reasons (i.e. convenience of using this
100 ;;; function in a MAKE-LOAD-FORM expression) that functionality has
101 ;;; been split off into INIT-OR-CHECK-LAYOUT.
102 (declaim (ftype (sfunction (symbol) layout) find-layout))
103 ;; The comment "This seems ..." is misleading but I don't have a better one.
104 ;; FIND-LAYOUT is used by FIND-AND-INIT-OR-CHECK-LAYOUT which is used
105 ;; by FOP-LAYOUT, so clearly it's used when reading fasl files.
106 (defun find-layout (name)
107 ;; This seems to be currently used only from the compiler, but make
108 ;; it thread-safe all the same. We need to lock *F-R-L* before doing
109 ;; FIND-CLASSOID in case (SETF FIND-CLASSOID) happens in parallel.
110 (let ((table *forward-referenced-layouts*))
111 (with-world-lock ()
112 (let ((classoid (find-classoid name nil)))
113 (or (and classoid (classoid-layout classoid))
114 (gethash name table)
115 (setf (gethash name table)
116 (make-layout :classoid (or classoid (make-undefined-classoid name)))))))))
118 ;;; If LAYOUT is uninitialized, initialize it with CLASSOID, LENGTH,
119 ;;; INHERITS, DEPTHOID, and RAW-SLOT-METADATA. Otherwise require
120 ;;; that it be consistent with the existing values.
122 ;;; UNDEFINED-CLASS values are interpreted specially as "we don't know
123 ;;; anything about the class", so if LAYOUT is initialized, any
124 ;;; preexisting class slot value is OK, and if it's not initialized,
125 ;;; its class slot value is set to an UNDEFINED-CLASS. -- FIXME: This
126 ;;; is no longer true, :UNINITIALIZED used instead.
127 (declaim (ftype (function (layout classoid index simple-vector layout-depthoid
128 layout-raw-slot-metadata-type)
129 layout)
130 %init-or-check-layout))
131 (defun %init-or-check-layout
132 (layout classoid length inherits depthoid raw-slot-metadata)
133 (cond ((eq (layout-invalid layout) :uninitialized)
134 ;; There was no layout before, we just created one which
135 ;; we'll now initialize with our information.
136 (setf (layout-length layout) length
137 (layout-inherits layout) inherits
138 (layout-depthoid layout) depthoid
139 (layout-raw-slot-metadata layout) raw-slot-metadata
140 (layout-classoid layout) classoid
141 (layout-invalid layout) nil))
142 ;; FIXME: Now that LAYOUTs are born :UNINITIALIZED, maybe this
143 ;; clause is not needed?
144 ((not *type-system-initialized*)
145 (setf (layout-classoid layout) classoid))
147 ;; There was an old layout already initialized with old
148 ;; information, and we'll now check that old information
149 ;; which was known with certainty is consistent with current
150 ;; information which is known with certainty.
151 (check-layout layout classoid length inherits depthoid
152 raw-slot-metadata)))
153 layout)
155 ;;; In code for the target Lisp, we don't dump LAYOUTs using the
156 ;;; standard load form mechanism, we use special fops instead, in
157 ;;; order to make cold load come out right. But when we're building
158 ;;; the cross-compiler, we can't do that because we don't have access
159 ;;; to special non-ANSI low-level things like special fops, and we
160 ;;; don't need to do that anyway because our code isn't going to be
161 ;;; cold loaded, so we use the ordinary load form system.
163 ;;; KLUDGE: A special hack causes this not to be called when we are
164 ;;; building code for the target Lisp. It would be tidier to just not
165 ;;; have it in place when we're building the target Lisp, but it
166 ;;; wasn't clear how to do that without rethinking DEF!STRUCT quite a
167 ;;; bit, so I punted. -- WHN 19990914
168 #+sb-xc-host
169 (defun make-load-form-for-layout (layout &optional env)
170 (declare (type layout layout))
171 (declare (ignore env))
172 (when (layout-invalid layout)
173 (sb!c::compiler-error "can't dump reference to obsolete class: ~S"
174 (layout-classoid layout)))
175 (let ((name (classoid-name (layout-classoid layout))))
176 (unless name
177 (sb!c::compiler-error "can't dump anonymous LAYOUT: ~S" layout))
178 ;; Since LAYOUT refers to a class which refers back to the LAYOUT,
179 ;; we have to do this in two stages, like the TREE-WITH-PARENT
180 ;; example in the MAKE-LOAD-FORM entry in the ANSI spec.
181 (values
182 ;; "creation" form (which actually doesn't create a new LAYOUT if
183 ;; there's a preexisting one with this name)
184 `(find-layout ',name)
185 ;; "initialization" form (which actually doesn't initialize
186 ;; preexisting LAYOUTs, just checks that they're consistent).
187 `(%init-or-check-layout ',layout
188 ',(layout-classoid layout)
189 ',(layout-length layout)
190 ',(layout-inherits layout)
191 ',(layout-depthoid layout)
192 ',(layout-raw-slot-metadata layout)))))
194 ;;; If LAYOUT's slot values differ from the specified slot values in
195 ;;; any interesting way, then give a warning and return T.
196 (declaim (ftype (function (simple-string
197 layout
198 simple-string
199 index
200 simple-vector
201 layout-depthoid
202 layout-raw-slot-metadata-type))
203 redefine-layout-warning))
204 (defun redefine-layout-warning (old-context old-layout
205 context length inherits depthoid
206 raw-slot-metadata)
207 (declare (type layout old-layout) (type simple-string old-context context))
208 (let ((name (layout-proper-name old-layout))
209 (old-inherits (layout-inherits old-layout)))
210 (or (when (mismatch old-inherits inherits :key #'layout-proper-name)
211 (warn "change in superclasses of class ~S:~% ~
212 ~A superclasses: ~S~% ~
213 ~A superclasses: ~S"
214 name
215 old-context
216 (map 'list #'layout-proper-name old-inherits)
217 context
218 (map 'list #'layout-proper-name inherits))
220 (let ((diff (mismatch old-inherits inherits)))
221 (when diff
222 (warn "in class ~S:~% ~
223 ~@(~A~) definition of superclass ~S is incompatible with~% ~
224 ~A definition."
225 name
226 old-context
227 (layout-proper-name (svref old-inherits diff))
228 context)
230 (let ((old-length (layout-length old-layout)))
231 (unless (= old-length length)
232 (warn "change in instance length of class ~S:~% ~
233 ~A length: ~W~% ~
234 ~A length: ~W"
235 name
236 old-context old-length
237 context length)
239 (let ((old-metadata (layout-raw-slot-metadata old-layout)))
240 (unless (= old-metadata raw-slot-metadata)
241 #!-interleaved-raw-slots
242 (warn "change in instance layout of class ~S:~% ~
243 ~A untagged slots: ~W~% ~
244 ~A untagged slots: ~W"
245 name
246 old-context old-metadata
247 context raw-slot-metadata)
248 #!+interleaved-raw-slots
249 (warn "change in placement of raw slots of class ~S ~
250 between the ~A definition and the ~A definition"
251 name old-context context)
253 (unless (= (layout-depthoid old-layout) depthoid)
254 (warn "change in the inheritance structure of class ~S~% ~
255 between the ~A definition and the ~A definition"
256 name old-context context)
257 t))))
259 ;;; Require that LAYOUT data be consistent with CLASSOID, LENGTH,
260 ;;; INHERITS, DEPTHOID, and RAW-SLOT-METADATA.
261 (declaim (ftype (function
262 (layout classoid index simple-vector layout-depthoid
263 layout-raw-slot-metadata-type))
264 check-layout))
265 (defun check-layout (layout classoid length inherits depthoid raw-slot-metadata)
266 (aver (eq (layout-classoid layout) classoid))
267 (when (redefine-layout-warning "current" layout
268 "compile time" length inherits depthoid
269 raw-slot-metadata)
270 ;; Classic CMU CL had more options here. There are several reasons
271 ;; why they might want more options which are less appropriate for
272 ;; us: (1) It's hard to fit the classic CMU CL flexible approach
273 ;; into the ANSI-style MAKE-LOAD-FORM system, and having a
274 ;; non-MAKE-LOAD-FORM-style system is painful when we're trying to
275 ;; make the cross-compiler run under vanilla ANSI Common Lisp. (2)
276 ;; We have CLOS now, and if you want to be able to flexibly
277 ;; redefine classes without restarting the system, it'd make sense
278 ;; to use that, so supporting complexity in order to allow
279 ;; modifying DEFSTRUCTs without restarting the system is a low
280 ;; priority. (3) We now have the ability to rebuild the SBCL
281 ;; system from scratch, so we no longer need this functionality in
282 ;; order to maintain the SBCL system by modifying running images.
283 (error "The loaded code expects an incompatible layout for class ~S."
284 (layout-proper-name layout)))
285 (values))
287 ;;; a common idiom (the same as CMU CL FIND-LAYOUT) rolled up into a
288 ;;; single function call
290 ;;; Used by the loader to forward-reference layouts for classes whose
291 ;;; definitions may not have been loaded yet. This allows type tests
292 ;;; to be loaded when the type definition hasn't been loaded yet.
293 (declaim (ftype (function (symbol index simple-vector layout-depthoid
294 layout-raw-slot-metadata-type)
295 layout)
296 find-and-init-or-check-layout))
297 (defun find-and-init-or-check-layout (name length inherits depthoid metadata)
298 (truly-the ; avoid an "assertion too complex to check" optimizer note
299 (values layout &optional)
300 (with-world-lock ()
301 (let ((layout (find-layout name)))
302 (%init-or-check-layout layout
303 (or (find-classoid name nil)
304 (layout-classoid layout))
305 length
306 inherits
307 depthoid
308 metadata)))))
310 ;;; Record LAYOUT as the layout for its class, adding it as a subtype
311 ;;; of all superclasses. This is the operation that "installs" a
312 ;;; layout for a class in the type system, clobbering any old layout.
313 ;;; However, this does not modify the class namespace; that is a
314 ;;; separate operation (think anonymous classes.)
315 ;;; -- If INVALIDATE, then all the layouts for any old definition
316 ;;; and subclasses are invalidated, and the SUBCLASSES slot is cleared.
317 ;;; -- If DESTRUCT-LAYOUT, then this is some old layout, and is to be
318 ;;; destructively modified to hold the same type information.
319 (eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute)
320 (defun register-layout (layout &key (invalidate t) destruct-layout)
321 (declare (type layout layout) (type (or layout null) destruct-layout))
322 (with-world-lock ()
323 (let* ((classoid (layout-classoid layout))
324 (classoid-layout (classoid-layout classoid))
325 (subclasses (classoid-subclasses classoid)))
327 ;; Attempting to register ourselves with a temporary undefined
328 ;; class placeholder is almost certainly a programmer error. (I
329 ;; should know, I did it.) -- WHN 19990927
330 (aver (not (undefined-classoid-p classoid)))
332 ;; This assertion dates from classic CMU CL. The rationale is
333 ;; probably that calling REGISTER-LAYOUT more than once for the
334 ;; same LAYOUT is almost certainly a programmer error.
335 (aver (not (eq classoid-layout layout)))
337 ;; Figure out what classes are affected by the change, and issue
338 ;; appropriate warnings and invalidations.
339 (when classoid-layout
340 (%modify-classoid classoid)
341 (when subclasses
342 (dohash ((subclass subclass-layout) subclasses :locked t)
343 (%modify-classoid subclass)
344 (when invalidate
345 (%invalidate-layout subclass-layout))))
346 (when invalidate
347 (%invalidate-layout classoid-layout)
348 (setf (classoid-subclasses classoid) nil)))
350 (if destruct-layout
351 (setf (layout-invalid destruct-layout) nil
352 (layout-inherits destruct-layout) (layout-inherits layout)
353 (layout-depthoid destruct-layout) (layout-depthoid layout)
354 (layout-length destruct-layout) (layout-length layout)
355 (layout-raw-slot-metadata destruct-layout)
356 (layout-raw-slot-metadata layout)
357 (layout-info destruct-layout) (layout-info layout)
358 (classoid-layout classoid) destruct-layout)
359 (setf (layout-invalid layout) nil
360 (classoid-layout classoid) layout))
362 (dovector (super-layout (layout-inherits layout))
363 (let* ((super (layout-classoid super-layout))
364 (subclasses (or (classoid-subclasses super)
365 (setf (classoid-subclasses super)
366 (make-hash-table :test 'eq
367 #-sb-xc-host #-sb-xc-host
368 :synchronized t)))))
369 (when (and (eq (classoid-state super) :sealed)
370 (not (gethash classoid subclasses)))
371 (warn "unsealing sealed class ~S in order to subclass it"
372 (classoid-name super))
373 (setf (classoid-state super) :read-only))
374 (setf (gethash classoid subclasses)
375 (or destruct-layout layout))))))
377 (values))
378 ); EVAL-WHEN
380 ;;; Arrange the inherited layouts to appear at their expected depth,
381 ;;; ensuring that hierarchical type tests succeed. Layouts with
382 ;;; DEPTHOID >= 0 (i.e. hierarchical classes) are placed first,
383 ;;; at exactly that index in the INHERITS vector. Then, non-hierarchical
384 ;;; layouts are placed in remaining elements. Then, any still-empty
385 ;;; elements are filled with their successors, ensuring that each
386 ;;; element contains a valid layout.
388 ;;; This reordering may destroy CPL ordering, so the inherits should
389 ;;; not be read as being in CPL order.
390 (defun order-layout-inherits (layouts)
391 (declare (simple-vector layouts))
392 (let ((length (length layouts))
393 (max-depth -1))
394 (dotimes (i length)
395 (let ((depth (layout-depthoid (svref layouts i))))
396 (when (> depth max-depth)
397 (setf max-depth depth))))
398 (let* ((new-length (max (1+ max-depth) length))
399 ;; KLUDGE: 0 here is the "uninitialized" element. We need
400 ;; to specify it explicitly for portability purposes, as
401 ;; elements can be read before being set [ see below, "(EQL
402 ;; OLD-LAYOUT 0)" ]. -- CSR, 2002-04-20
403 (inherits (make-array new-length :initial-element 0)))
404 (dotimes (i length)
405 (let* ((layout (svref layouts i))
406 (depth (layout-depthoid layout)))
407 (unless (eql depth -1)
408 (let ((old-layout (svref inherits depth)))
409 (unless (or (eql old-layout 0) (eq old-layout layout))
410 (error "layout depth conflict: ~S~%" layouts)))
411 (setf (svref inherits depth) layout))))
412 (do ((i 0 (1+ i))
413 (j 0))
414 ((>= i length))
415 (declare (type index i j))
416 (let* ((layout (svref layouts i))
417 (depth (layout-depthoid layout)))
418 (when (eql depth -1)
419 (loop (when (eql (svref inherits j) 0)
420 (return))
421 (incf j))
422 (setf (svref inherits j) layout))))
423 (do ((i (1- new-length) (1- i)))
424 ((< i 0))
425 (declare (type fixnum i))
426 (when (eql (svref inherits i) 0)
427 (setf (svref inherits i) (svref inherits (1+ i)))))
428 inherits)))
430 ;;;; class precedence lists
432 ;;; Topologically sort the list of objects to meet a set of ordering
433 ;;; constraints given by pairs (A . B) constraining A to precede B.
434 ;;; When there are multiple objects to choose, the tie-breaker
435 ;;; function is called with both the list of object to choose from and
436 ;;; the reverse ordering built so far.
437 (defun topological-sort (objects constraints tie-breaker)
438 (declare (list objects constraints)
439 (function tie-breaker))
440 (let ((obj-info (make-hash-table :size (length objects)))
441 (free-objs nil)
442 (result nil))
443 (dolist (constraint constraints)
444 (let ((obj1 (car constraint))
445 (obj2 (cdr constraint)))
446 (let ((info2 (gethash obj2 obj-info)))
447 (if info2
448 (incf (first info2))
449 (setf (gethash obj2 obj-info) (list 1))))
450 (let ((info1 (gethash obj1 obj-info)))
451 (if info1
452 (push obj2 (rest info1))
453 (setf (gethash obj1 obj-info) (list 0 obj2))))))
454 (dolist (obj objects)
455 (let ((info (gethash obj obj-info)))
456 (when (or (not info) (zerop (first info)))
457 (push obj free-objs))))
458 (loop
459 (flet ((next-result (obj)
460 (push obj result)
461 (dolist (successor (rest (gethash obj obj-info)))
462 (let* ((successor-info (gethash successor obj-info))
463 (count (1- (first successor-info))))
464 (setf (first successor-info) count)
465 (when (zerop count)
466 (push successor free-objs))))))
467 (cond ((endp free-objs)
468 (dohash ((obj info) obj-info)
469 (unless (zerop (first info))
470 (error "Topological sort failed due to constraint on ~S."
471 obj)))
472 (return (nreverse result)))
473 ((endp (rest free-objs))
474 (next-result (pop free-objs)))
476 (let ((obj (funcall tie-breaker free-objs result)))
477 (setf free-objs (remove obj free-objs))
478 (next-result obj))))))))
481 ;;; standard class precedence list computation
482 (defun std-compute-class-precedence-list (class)
483 (let ((classes nil)
484 (constraints nil))
485 (labels ((note-class (class)
486 (unless (member class classes)
487 (push class classes)
488 (let ((superclasses (classoid-direct-superclasses class)))
489 (do ((prev class)
490 (rest superclasses (rest rest)))
491 ((endp rest))
492 (let ((next (first rest)))
493 (push (cons prev next) constraints)
494 (setf prev next)))
495 (dolist (class superclasses)
496 (note-class class)))))
497 (std-cpl-tie-breaker (free-classes rev-cpl)
498 (dolist (class rev-cpl (first free-classes))
499 (let* ((superclasses (classoid-direct-superclasses class))
500 (intersection (intersection free-classes
501 superclasses)))
502 (when intersection
503 (return (first intersection)))))))
504 (note-class class)
505 (topological-sort classes constraints #'std-cpl-tie-breaker))))
507 ;;;; object types to represent classes
509 ;;; BUILT-IN-CLASS is used to represent the standard classes that
510 ;;; aren't defined with DEFSTRUCT and other specially implemented
511 ;;; primitive types whose only attribute is their name.
512 ;;; It is defined in 'early-classoid.lisp'
514 ;;; STRUCTURE-CLASS represents what we need to know about structure
515 ;;; classes. Non-structure "typed" defstructs are a special case, and
516 ;;; don't have a corresponding class.
517 (def!struct (structure-classoid (:include classoid)
518 (:constructor %make-structure-classoid)))
519 (defun make-structure-classoid (&key name)
520 (mark-ctype-interned (%make-structure-classoid :name name)))
522 ;;;; classoid namespace
524 (eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute)
525 (defun (setf find-classoid) (new-value name)
526 #-sb-xc (declare (type (or null classoid) new-value))
527 (aver new-value)
528 (let ((table *forward-referenced-layouts*))
529 (with-world-lock ()
530 (let ((cell (find-classoid-cell name :create t)))
531 (ecase (info :type :kind name)
532 ((nil))
533 (:forthcoming-defclass-type
534 ;; FIXME: Currently, nothing needs to be done in this case.
535 ;; Later, when PCL is integrated tighter into SBCL, this
536 ;; might need more work.
537 nil)
538 (:instance
539 (aver cell)
540 (let ((old-value (classoid-cell-classoid cell)))
541 (aver old-value)
542 ;; KLUDGE: The reason these clauses aren't directly
543 ;; parallel is that we need to use the internal
544 ;; CLASSOID structure ourselves, because we don't
545 ;; have CLASSes to work with until PCL is built. In
546 ;; the host, CLASSes have an approximately
547 ;; one-to-one correspondence with the target
548 ;; CLASSOIDs (as well as with the target CLASSes,
549 ;; modulo potential differences with respect to
550 ;; conditions).
551 #+sb-xc-host
552 (let ((old (class-of old-value))
553 (new (class-of new-value)))
554 (unless (eq old new)
555 (bug "Trying to change the metaclass of ~S from ~S to ~S in the ~
556 cross-compiler."
557 name (class-name old) (class-name new))))
558 #-sb-xc-host
559 (let ((old (classoid-of old-value))
560 (new (classoid-of new-value)))
561 (unless (eq old new)
562 (warn "Changing meta-class of ~S from ~S to ~S."
563 name (classoid-name old) (classoid-name new))))))
564 (:primitive
565 (error "Cannot redefine standard type ~S." name))
566 (:defined
567 (warn "redefining DEFTYPE type to be a class: ~
568 ~/sb-impl::print-symbol-with-prefix/" name)
569 (clear-info :type :expander name)
570 (clear-info :type :source-location name)))
572 (remhash name table)
573 (%note-type-defined name)
574 ;; FIXME: I'm unconvinced of the need to handle either of these.
575 ;; Package locks preclude the latter, and in the former case,
576 ;; once you've made some random thing into a :PRIMITIVE kind of type,
577 ;; you've painted yourself into a corner - those types
578 ;; elicit vociferous complaints if you try to redefine them.
580 ;; we need to handle things like
581 ;; (setf (find-class 'foo) (find-class 'integer))
582 ;; and
583 ;; (setf (find-class 'integer) (find-class 'integer))
584 (cond ((built-in-classoid-p new-value)
585 ;; But I can't figure out how to get assertions to pass
586 ;; without violation what would otherwise be invariants
587 ;; of the internal representation of types. This sucks.
588 (setf (info :type :kind name)
589 (or (info :type :kind name) :defined)))
591 (setf (info :type :kind name) :instance)))
592 (setf (classoid-cell-classoid cell) new-value)
593 (unless (eq (info :type :compiler-layout name)
594 (classoid-layout new-value))
595 (setf (info :type :compiler-layout name)
596 (classoid-layout new-value))))))
597 new-value)
599 (defun %clear-classoid (name cell)
600 (ecase (info :type :kind name)
601 ((nil))
602 (:defined)
603 (:primitive
604 (error "Attempt to remove :PRIMITIVE type: ~S" name))
605 ((:forthcoming-defclass-type :instance)
606 (when cell
607 ;; Note: We cannot remove the classoid cell from the table,
608 ;; since compiled code may refer directly to the cell, and
609 ;; getting a different cell for a classoid with the same name
610 ;; just would not do.
612 ;; Remove the proper name of the classoid, if this was it.
613 (let* ((classoid (classoid-cell-classoid cell))
614 (proper-name (classoid-name classoid)))
615 (when (eq proper-name name)
616 (setf (classoid-name classoid) nil)))
618 ;; Clear the cell.
619 (setf (classoid-cell-classoid cell) nil
620 (classoid-cell-pcl-class cell) nil))
621 (clear-info :type :kind name)
622 (clear-info :type :documentation name)
623 (clear-info :type :compiler-layout name)))))
625 ;;; Called when we are about to define NAME as a class meeting some
626 ;;; predicate (such as a meta-class type test.) The first result is
627 ;;; always of the desired class. The second result is any existing
628 ;;; LAYOUT for this name.
630 ;;; Again, this should be compiler-only, but easier to make this
631 ;;; thread-safe.
632 (defun insured-find-classoid (name predicate constructor)
633 (declare (type function predicate constructor))
634 (let ((table *forward-referenced-layouts*))
635 (with-locked-system-table (table)
636 (let* ((old (find-classoid name nil))
637 (res (if (and old (funcall predicate old))
639 (funcall constructor :name name)))
640 (found (or (gethash name table)
641 (when old (classoid-layout old)))))
642 (when found
643 (setf (layout-classoid found) res))
644 (values res found)))))
646 ;;; If the classoid has a proper name, return the name, otherwise return
647 ;;; the classoid.
648 (defun classoid-proper-name (classoid)
649 #-sb-xc (declare (type classoid classoid))
650 (let ((name (classoid-name classoid)))
651 (if (and name (eq (find-classoid name nil) classoid))
652 name
653 classoid)))
655 ;;;; CLASS type operations
657 ;; CLASSOID-ENUMERABLE-P is referenced during compile by !DEFINE-TYPE-CLASS.
658 ;; But don't redefine it when building the target since we've already
659 ;; got a perfectly good definition loaded for the host.
660 (eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute)
661 ;; Actually this definition makes very little sense because
662 ;; (TYPE-ENUMERABLE (FIND-CLASSOID 'CHARACTER)) => T
663 ;; but (TYPE-ENUMERABLE (SPECIFIER-TYPE 'CHARACTER)) => NIL.
664 ;; You should never see the CLASSOID used as a type though,
665 ;; at least not from parsing and set operations.
666 ;; On a related note, (TYPE-ENUMERABLE (FIND-CLASSOID 'NULL))
667 ;; should probably be T, but you'll never see that type either.
668 ;; Perhaps a better definition of this function would be
669 ;; (if (classoid-translation x) (bug "enumerable-p classoid?") nil)
670 (defun classoid-enumerable-p (x) (eq (classoid-name x) 'character)))
671 (!define-type-class classoid :enumerable #'classoid-enumerable-p
672 :might-contain-other-types nil)
674 ;;; We might be passed classoids with invalid layouts; in any pairwise
675 ;;; class comparison, we must ensure that both are valid before
676 ;;; proceeding.
677 (defun %ensure-classoid-valid (classoid layout error-context)
678 (declare (ignorable error-context)) ; not used on host
679 (aver (eq classoid (layout-classoid layout)))
680 (or (not (layout-invalid layout))
681 ;; Avoid accidentally reaching code that can't work.
682 #+sb-xc-host (bug "(TYPEP x 'STANDARD-CLASSOID) can't be tested")
683 #-sb-xc-host
684 (if (typep classoid 'standard-classoid)
685 (let ((class (classoid-pcl-class classoid)))
686 (cond
687 ((sb!pcl:class-finalized-p class)
688 (sb!pcl::%force-cache-flushes class)
690 ((sb!pcl::class-has-a-forward-referenced-superclass-p class)
691 (when error-context
692 (bug "~@<Invalid class ~S with forward-referenced superclass ~
693 ~S in ~A.~%~:@>"
694 class
695 (sb!pcl::class-has-a-forward-referenced-superclass-p class)
696 error-context))
697 nil)
699 (sb!pcl:finalize-inheritance class)
700 t)))
701 (bug "~@<Don't know how to ensure validity of ~S (not a STANDARD-CLASSOID) ~
702 for ~A.~%~:@>"
703 classoid (or error-context 'subtypep)))))
705 (defun %ensure-both-classoids-valid (class1 class2 &optional errorp)
706 (do ((layout1 (classoid-layout class1) (classoid-layout class1))
707 (layout2 (classoid-layout class2) (classoid-layout class2))
708 (i 0 (+ i 1)))
709 ((and (not (layout-invalid layout1)) (not (layout-invalid layout2)))
711 (aver (< i 2))
712 (unless (and (%ensure-classoid-valid class1 layout1 errorp)
713 (%ensure-classoid-valid class2 layout2 errorp))
714 (return-from %ensure-both-classoids-valid nil))))
716 #-sb-xc-host ; No such thing as LAYOUT-OF, never mind the rest
717 (defun update-object-layout-or-invalid (object layout)
718 ;; FIXME: explain why this isn't (LAYOUT-FOR-STD-CLASS-P LAYOUT).
719 (if (layout-for-std-class-p (layout-of object))
720 (sb!pcl::check-wrapper-validity object)
721 (sb!c::%layout-invalid-error object layout)))
723 ;;; Simple methods for TYPE= and SUBTYPEP should never be called when
724 ;;; the two classes are equal, since there are EQ checks in those
725 ;;; operations.
726 (!define-type-method (classoid :simple-=) (type1 type2)
727 (aver (not (eq type1 type2)))
728 (values nil t))
730 (!define-type-method (classoid :simple-subtypep) (class1 class2)
731 (aver (not (eq class1 class2)))
732 (with-world-lock ()
733 (if (%ensure-both-classoids-valid class1 class2)
734 (let ((subclasses2 (classoid-subclasses class2)))
735 (if (and subclasses2 (gethash class1 subclasses2))
736 (values t t)
737 (if (and (typep class1 'standard-classoid)
738 (typep class2 'standard-classoid)
739 (or (sb!pcl::class-has-a-forward-referenced-superclass-p
740 (classoid-pcl-class class1))
741 (sb!pcl::class-has-a-forward-referenced-superclass-p
742 (classoid-pcl-class class2))))
743 ;; If there's a forward-referenced class involved we don't know for sure.
744 ;; (There are cases which we /could/ figure out, but that doesn't seem
745 ;; to be required or important, really.)
746 (values nil nil)
747 (values nil t))))
748 (values nil nil))))
750 ;;; When finding the intersection of a sealed class and some other
751 ;;; class (not hierarchically related) the intersection is the union
752 ;;; of the currently shared subclasses.
753 (defun sealed-class-intersection2 (sealed other)
754 (declare (type classoid sealed other))
755 (let ((s-sub (classoid-subclasses sealed))
756 (o-sub (classoid-subclasses other)))
757 (if (and s-sub o-sub)
758 (collect ((res *empty-type* type-union))
759 (dohash ((subclass layout) s-sub :locked t)
760 (declare (ignore layout))
761 (when (gethash subclass o-sub)
762 (res (specifier-type subclass))))
763 (res))
764 *empty-type*)))
766 (!define-type-method (classoid :simple-intersection2) (class1 class2)
767 (declare (type classoid class1 class2))
768 (with-world-lock ()
769 (%ensure-both-classoids-valid class1 class2 "type intersection")
770 (cond ((eq class1 class2)
771 class1)
772 ;; If one is a subclass of the other, then that is the
773 ;; intersection.
774 ((let ((subclasses (classoid-subclasses class2)))
775 (and subclasses (gethash class1 subclasses)))
776 class1)
777 ((let ((subclasses (classoid-subclasses class1)))
778 (and subclasses (gethash class2 subclasses)))
779 class2)
780 ;; Otherwise, we can't in general be sure that the
781 ;; intersection is empty, since a subclass of both might be
782 ;; defined. But we can eliminate it for some special cases.
783 ((or (structure-classoid-p class1)
784 (structure-classoid-p class2))
785 ;; No subclass of both can be defined.
786 *empty-type*)
787 ((eq (classoid-state class1) :sealed)
788 ;; checking whether a subclass of both can be defined:
789 (sealed-class-intersection2 class1 class2))
790 ((eq (classoid-state class2) :sealed)
791 ;; checking whether a subclass of both can be defined:
792 (sealed-class-intersection2 class2 class1))
794 ;; uncertain, since a subclass of both might be defined
795 nil))))
797 ;;; KLUDGE: we need this to deal with the special-case INSTANCE and
798 ;;; FUNCALLABLE-INSTANCE types (which used to be CLASSOIDs until CSR
799 ;;; discovered that this was incompatible with the MOP class
800 ;;; hierarchy). See NAMED :COMPLEX-SUBTYPEP-ARG2
801 (defvar *non-instance-classoid-types*
802 '(symbol system-area-pointer weak-pointer code-component
803 lra fdefn random-class))
805 ;;; KLUDGE: we need this because of the need to represent
806 ;;; intersections of two classes, even when empty at a given time, as
807 ;;; uncanonicalized intersections because of the possibility of later
808 ;;; defining a subclass of both classes. The necessity for changing
809 ;;; the default return value from SUBTYPEP to NIL, T if no alternate
810 ;;; method is present comes about because, unlike the other places we
811 ;;; use INVOKE-COMPLEX-SUBTYPEP-ARG1-METHOD, in HAIRY methods and the
812 ;;; like, classes are in their own hierarchy with no possibility of
813 ;;; mixtures with other type classes.
814 (!define-type-method (classoid :complex-subtypep-arg2) (type1 class2)
815 (if (and (intersection-type-p type1)
816 (> (count-if #'classoid-p (intersection-type-types type1)) 1))
817 (values nil nil)
818 (invoke-complex-subtypep-arg1-method type1 class2 nil t)))
820 (!define-type-method (classoid :negate) (type) (make-negation-type type))
822 (!define-type-method (classoid :unparse) (type)
823 (classoid-proper-name type))
825 ;;;; built-in classes
827 ;;; The BUILT-IN-CLASSES list is a data structure which configures the
828 ;;; creation of all the built-in classes. It contains all the info
829 ;;; that we need to maintain the mapping between classes, compile-time
830 ;;; types and run-time type codes. These options are defined:
832 ;;; :TRANSLATION (default none)
833 ;;; When this class is "parsed" as a type specifier, it is
834 ;;; translated into the specified internal type representation,
835 ;;; rather than being left as a class. This is used for types
836 ;;; which we want to canonicalize to some other kind of type
837 ;;; object because in general we want to be able to include more
838 ;;; information than just the class (e.g. for numeric types.)
840 ;;; :STATE (default :SEALED)
841 ;;; The value of CLASS-STATE which we want on completion,
842 ;;; indicating whether subclasses can be created at run-time.
844 ;;; :HIERARCHICAL-P (default T unless any of the inherits are non-hierarchical)
845 ;;; True if we can assign this class a unique inheritance depth.
847 ;;; :CODES (default none)
848 ;;; Run-time type codes which should be translated back to this
849 ;;; class by CLASS-OF. Unspecified for abstract classes.
851 ;;; :INHERITS (default this class and T)
852 ;;; The class-precedence list for this class, with this class and
853 ;;; T implicit.
855 ;;; :DIRECT-SUPERCLASSES (default to head of CPL)
856 ;;; List of the direct superclasses of this class.
858 ;;; NB: not to be confused with SB-PCL::*BUILT-IN-CLASSES*
859 (!defvar *!built-in-classes*
860 ;; To me these data would look nicer with commas instead of "#."
861 '((t :state :read-only :translation t)
862 (character :codes (#.sb!vm:character-widetag)
863 :translation (character-set)
864 :prototype-form (code-char 42))
865 (symbol :codes (#.sb!vm:symbol-header-widetag)
866 :prototype-form '#:mu)
868 (system-area-pointer :codes (#.sb!vm:sap-widetag)
869 :prototype-form (int-sap 42))
870 (weak-pointer :codes (#.sb!vm:weak-pointer-widetag)
871 :prototype-form (make-weak-pointer (find-package "CL")))
872 (code-component :codes (#.sb!vm:code-header-widetag))
873 ;; should this be #!-(or x86 x86-64) ?
874 (lra :codes (#.sb!vm:return-pc-header-widetag))
875 (fdefn :codes (#.sb!vm:fdefn-widetag)
876 :prototype-form (make-fdefn "42"))
877 (random-class) ; used for unknown type codes
879 (function
880 :codes (#.sb!vm:closure-header-widetag
881 #.sb!vm:simple-fun-header-widetag)
882 :state :read-only
883 :prototype-form (function (lambda () 42)))
885 (number :translation number)
886 (complex
887 :translation complex
888 :inherits (number)
889 :codes (#.sb!vm:complex-widetag)
890 :prototype-form (complex 42 42))
891 (complex-single-float
892 :translation (complex single-float)
893 :inherits (complex number)
894 :codes (#.sb!vm:complex-single-float-widetag)
895 :prototype-form (complex 42f0 42f0))
896 (complex-double-float
897 :translation (complex double-float)
898 :inherits (complex number)
899 :codes (#.sb!vm:complex-double-float-widetag)
900 :prototype-form (complex 42d0 42d0))
901 #!+long-float
902 (complex-long-float
903 :translation (complex long-float)
904 :inherits (complex number)
905 :codes (#.sb!vm:complex-long-float-widetag)
906 :prototype-form (complex 42l0 42l0))
907 #!+sb-simd-pack
908 (simd-pack
909 :translation simd-pack
910 :codes (#.sb!vm:simd-pack-widetag)
911 :prototype-form (%make-simd-pack-ub64 42 42))
912 (real :translation real :inherits (number))
913 (float
914 :translation float
915 :inherits (real number))
916 (single-float
917 :translation single-float
918 :inherits (float real number)
919 :codes (#.sb!vm:single-float-widetag)
920 :prototype-form 42f0)
921 (double-float
922 :translation double-float
923 :inherits (float real number)
924 :codes (#.sb!vm:double-float-widetag)
925 :prototype-form 42d0)
926 #!+long-float
927 (long-float
928 :translation long-float
929 :inherits (float real number)
930 :codes (#.sb!vm:long-float-widetag)
931 :prototype-form 42l0)
932 (rational
933 :translation rational
934 :inherits (real number))
935 (ratio
936 :translation (and rational (not integer))
937 :inherits (rational real number)
938 :codes (#.sb!vm:ratio-widetag)
939 :prototype-form 1/42)
940 (integer
941 :translation integer
942 :inherits (rational real number))
943 (fixnum
944 :translation (integer #.sb!xc:most-negative-fixnum
945 #.sb!xc:most-positive-fixnum)
946 :inherits (integer rational real number)
947 :codes #.(mapcar #'symbol-value sb!vm::fixnum-lowtags)
948 :prototype-form 42)
949 (bignum
950 :translation (and integer (not fixnum))
951 :inherits (integer rational real number)
952 :codes (#.sb!vm:bignum-widetag)
953 :prototype-form (expt 2 #.(* sb!vm:n-word-bits (/ 3 2))))
955 (array :translation array :codes (#.sb!vm:complex-array-widetag)
956 :hierarchical-p nil
957 :prototype-form (make-array nil :adjustable t))
958 (simple-array
959 :translation simple-array :codes (#.sb!vm:simple-array-widetag)
960 :inherits (array)
961 :prototype-form (make-array nil))
962 (sequence
963 :translation (or cons (member nil) vector extended-sequence)
964 :state :read-only
965 :depth 2)
966 (vector
967 :translation vector :codes (#.sb!vm:complex-vector-widetag)
968 :direct-superclasses (array sequence)
969 :inherits (array sequence))
970 (simple-vector
971 :translation simple-vector :codes (#.sb!vm:simple-vector-widetag)
972 :direct-superclasses (vector simple-array)
973 :inherits (vector simple-array array sequence)
974 :prototype-form (make-array 0))
975 (bit-vector
976 :translation bit-vector :codes (#.sb!vm:complex-bit-vector-widetag)
977 :inherits (vector array sequence)
978 :prototype-form (make-array 0 :element-type 'bit :fill-pointer t))
979 (simple-bit-vector
980 :translation simple-bit-vector :codes (#.sb!vm:simple-bit-vector-widetag)
981 :direct-superclasses (bit-vector simple-array)
982 :inherits (bit-vector vector simple-array
983 array sequence)
984 :prototype-form (make-array 0 :element-type 'bit))
985 (simple-array-unsigned-byte-2
986 :translation (simple-array (unsigned-byte 2) (*))
987 :codes (#.sb!vm:simple-array-unsigned-byte-2-widetag)
988 :direct-superclasses (vector simple-array)
989 :inherits (vector simple-array array sequence)
990 :prototype-form (make-array 0 :element-type '(unsigned-byte 2)))
991 (simple-array-unsigned-byte-4
992 :translation (simple-array (unsigned-byte 4) (*))
993 :codes (#.sb!vm:simple-array-unsigned-byte-4-widetag)
994 :direct-superclasses (vector simple-array)
995 :inherits (vector simple-array array sequence)
996 :prototype-form (make-array 0 :element-type '(unsigned-byte 4)))
997 (simple-array-unsigned-byte-7
998 :translation (simple-array (unsigned-byte 7) (*))
999 :codes (#.sb!vm:simple-array-unsigned-byte-7-widetag)
1000 :direct-superclasses (vector simple-array)
1001 :inherits (vector simple-array array sequence)
1002 :prototype-form (make-array 0 :element-type '(unsigned-byte 7)))
1003 (simple-array-unsigned-byte-8
1004 :translation (simple-array (unsigned-byte 8) (*))
1005 :codes (#.sb!vm:simple-array-unsigned-byte-8-widetag)
1006 :direct-superclasses (vector simple-array)
1007 :inherits (vector simple-array array sequence)
1008 :prototype-form (make-array 0 :element-type '(unsigned-byte 8)))
1009 (simple-array-unsigned-byte-15
1010 :translation (simple-array (unsigned-byte 15) (*))
1011 :codes (#.sb!vm:simple-array-unsigned-byte-15-widetag)
1012 :direct-superclasses (vector simple-array)
1013 :inherits (vector simple-array array sequence)
1014 :prototype-form (make-array 0 :element-type '(unsigned-byte 15)))
1015 (simple-array-unsigned-byte-16
1016 :translation (simple-array (unsigned-byte 16) (*))
1017 :codes (#.sb!vm:simple-array-unsigned-byte-16-widetag)
1018 :direct-superclasses (vector simple-array)
1019 :inherits (vector simple-array array sequence)
1020 :prototype-form (make-array 0 :element-type '(unsigned-byte 16)))
1022 (simple-array-unsigned-fixnum
1023 :translation (simple-array (unsigned-byte #.sb!vm:n-positive-fixnum-bits) (*))
1024 :codes (#.sb!vm:simple-array-unsigned-fixnum-widetag)
1025 :direct-superclasses (vector simple-array)
1026 :inherits (vector simple-array array sequence)
1027 :prototype-form (make-array 0
1028 :element-type '(unsigned-byte #.sb!vm:n-positive-fixnum-bits)))
1030 (simple-array-unsigned-byte-31
1031 :translation (simple-array (unsigned-byte 31) (*))
1032 :codes (#.sb!vm:simple-array-unsigned-byte-31-widetag)
1033 :direct-superclasses (vector simple-array)
1034 :inherits (vector simple-array array sequence)
1035 :prototype-form (make-array 0 :element-type '(unsigned-byte 31)))
1036 (simple-array-unsigned-byte-32
1037 :translation (simple-array (unsigned-byte 32) (*))
1038 :codes (#.sb!vm:simple-array-unsigned-byte-32-widetag)
1039 :direct-superclasses (vector simple-array)
1040 :inherits (vector simple-array array sequence)
1041 :prototype-form (make-array 0 :element-type '(unsigned-byte 32)))
1042 #!+64-bit
1043 (simple-array-unsigned-byte-63
1044 :translation (simple-array (unsigned-byte 63) (*))
1045 :codes (#.sb!vm:simple-array-unsigned-byte-63-widetag)
1046 :direct-superclasses (vector simple-array)
1047 :inherits (vector simple-array array sequence)
1048 :prototype-form (make-array 0 :element-type '(unsigned-byte 63)))
1049 #!+64-bit
1050 (simple-array-unsigned-byte-64
1051 :translation (simple-array (unsigned-byte 64) (*))
1052 :codes (#.sb!vm:simple-array-unsigned-byte-64-widetag)
1053 :direct-superclasses (vector simple-array)
1054 :inherits (vector simple-array array sequence)
1055 :prototype-form (make-array 0 :element-type '(unsigned-byte 64)))
1056 (simple-array-signed-byte-8
1057 :translation (simple-array (signed-byte 8) (*))
1058 :codes (#.sb!vm:simple-array-signed-byte-8-widetag)
1059 :direct-superclasses (vector simple-array)
1060 :inherits (vector simple-array array sequence)
1061 :prototype-form (make-array 0 :element-type '(signed-byte 8)))
1062 (simple-array-signed-byte-16
1063 :translation (simple-array (signed-byte 16) (*))
1064 :codes (#.sb!vm:simple-array-signed-byte-16-widetag)
1065 :direct-superclasses (vector simple-array)
1066 :inherits (vector simple-array array sequence)
1067 :prototype-form (make-array 0 :element-type '(signed-byte 16)))
1069 (simple-array-fixnum
1070 :translation (simple-array (signed-byte #.sb!vm:n-fixnum-bits)
1071 (*))
1072 :codes (#.sb!vm:simple-array-fixnum-widetag)
1073 :direct-superclasses (vector simple-array)
1074 :inherits (vector simple-array array sequence)
1075 :prototype-form (make-array 0
1076 :element-type
1077 '(signed-byte #.sb!vm:n-fixnum-bits)))
1079 (simple-array-signed-byte-32
1080 :translation (simple-array (signed-byte 32) (*))
1081 :codes (#.sb!vm:simple-array-signed-byte-32-widetag)
1082 :direct-superclasses (vector simple-array)
1083 :inherits (vector simple-array array sequence)
1084 :prototype-form (make-array 0 :element-type '(signed-byte 32)))
1085 #!+64-bit
1086 (simple-array-signed-byte-64
1087 :translation (simple-array (signed-byte 64) (*))
1088 :codes (#.sb!vm:simple-array-signed-byte-64-widetag)
1089 :direct-superclasses (vector simple-array)
1090 :inherits (vector simple-array array sequence)
1091 :prototype-form (make-array 0 :element-type '(signed-byte 64)))
1092 (simple-array-single-float
1093 :translation (simple-array single-float (*))
1094 :codes (#.sb!vm:simple-array-single-float-widetag)
1095 :direct-superclasses (vector simple-array)
1096 :inherits (vector simple-array array sequence)
1097 :prototype-form (make-array 0 :element-type 'single-float))
1098 (simple-array-double-float
1099 :translation (simple-array double-float (*))
1100 :codes (#.sb!vm:simple-array-double-float-widetag)
1101 :direct-superclasses (vector simple-array)
1102 :inherits (vector simple-array array sequence)
1103 :prototype-form (make-array 0 :element-type 'double-float))
1104 #!+long-float
1105 (simple-array-long-float
1106 :translation (simple-array long-float (*))
1107 :codes (#.sb!vm:simple-array-long-float-widetag)
1108 :direct-superclasses (vector simple-array)
1109 :inherits (vector simple-array array sequence)
1110 :prototype-form (make-array 0 :element-type 'long-float))
1111 (simple-array-complex-single-float
1112 :translation (simple-array (complex single-float) (*))
1113 :codes (#.sb!vm:simple-array-complex-single-float-widetag)
1114 :direct-superclasses (vector simple-array)
1115 :inherits (vector simple-array array sequence)
1116 :prototype-form (make-array 0 :element-type '(complex single-float)))
1117 (simple-array-complex-double-float
1118 :translation (simple-array (complex double-float) (*))
1119 :codes (#.sb!vm:simple-array-complex-double-float-widetag)
1120 :direct-superclasses (vector simple-array)
1121 :inherits (vector simple-array array sequence)
1122 :prototype-form (make-array 0 :element-type '(complex double-float)))
1123 #!+long-float
1124 (simple-array-complex-long-float
1125 :translation (simple-array (complex long-float) (*))
1126 :codes (#.sb!vm:simple-array-complex-long-float-widetag)
1127 :direct-superclasses (vector simple-array)
1128 :inherits (vector simple-array array sequence)
1129 :prototype-form (make-array 0 :element-type '(complex long-float)))
1130 (string
1131 :translation string
1132 :direct-superclasses (vector)
1133 :inherits (vector array sequence))
1134 (simple-string
1135 :translation simple-string
1136 :direct-superclasses (string simple-array)
1137 :inherits (string vector simple-array array sequence))
1138 (vector-nil
1139 :translation (vector nil)
1140 :codes (#.sb!vm:complex-vector-nil-widetag)
1141 :direct-superclasses (string)
1142 :inherits (string vector array sequence)
1143 :prototype-form (make-array 0 :element-type 'nil :fill-pointer t))
1144 (simple-array-nil
1145 :translation (simple-array nil (*))
1146 :codes (#.sb!vm:simple-array-nil-widetag)
1147 :direct-superclasses (vector-nil simple-string)
1148 :inherits (vector-nil simple-string string vector simple-array
1149 array sequence)
1150 :prototype-form (make-array 0 :element-type 'nil))
1151 (base-string
1152 :translation base-string
1153 :codes (#.sb!vm:complex-base-string-widetag)
1154 :direct-superclasses (string)
1155 :inherits (string vector array sequence)
1156 :prototype-form (make-array 0 :element-type 'base-char :fill-pointer t))
1157 (simple-base-string
1158 :translation simple-base-string
1159 :codes (#.sb!vm:simple-base-string-widetag)
1160 :direct-superclasses (base-string simple-string)
1161 :inherits (base-string simple-string string vector simple-array
1162 array sequence)
1163 :prototype-form (make-array 0 :element-type 'base-char))
1164 #!+sb-unicode
1165 (character-string
1166 :translation (vector character)
1167 :codes (#.sb!vm:complex-character-string-widetag)
1168 :direct-superclasses (string)
1169 :inherits (string vector array sequence)
1170 :prototype-form (make-array 0 :element-type 'character :fill-pointer t))
1171 #!+sb-unicode
1172 (simple-character-string
1173 :translation (simple-array character (*))
1174 :codes (#.sb!vm:simple-character-string-widetag)
1175 :direct-superclasses (character-string simple-string)
1176 :inherits (character-string simple-string string vector simple-array
1177 array sequence)
1178 :prototype-form (make-array 0 :element-type 'character))
1179 (list
1180 :translation (or cons (member nil))
1181 :inherits (sequence))
1182 (cons
1183 :codes (#.sb!vm:list-pointer-lowtag)
1184 :translation cons
1185 :inherits (list sequence)
1186 :prototype-form (cons nil nil))
1187 (null
1188 :translation (member nil)
1189 :inherits (symbol list sequence)
1190 :direct-superclasses (symbol list)
1191 :prototype-form 'nil)
1192 (stream
1193 :state :read-only
1194 :depth 2)
1195 (file-stream
1196 :state :read-only
1197 :depth 4
1198 :inherits (stream))
1199 (string-stream
1200 :state :read-only
1201 :depth 4
1202 :inherits (stream))))
1204 ;;; See also src/code/class-init.lisp where we finish setting up the
1205 ;;; translations for built-in types.
1206 (!cold-init-forms
1207 (dolist (x *!built-in-classes*)
1208 #-sb-xc-host (/show0 "at head of loop over *!BUILT-IN-CLASSES*")
1209 (destructuring-bind
1210 (name &key
1211 (translation nil trans-p)
1212 inherits
1213 codes
1214 state
1215 depth
1216 prototype-form
1217 (hierarchical-p t) ; might be modified below
1218 (direct-superclasses (if inherits
1219 (list (car inherits))
1220 '(t))))
1222 (declare (ignore codes state translation prototype-form))
1223 (let ((inherits-list (if (eq name t)
1225 (cons t (reverse inherits))))
1226 (classoid
1227 (acond #+sb-xc ; genesis dumps some classoid literals
1228 ((find-classoid name nil)
1229 ;; Unseal it so that REGISTER-LAYOUT doesn't warn
1230 (setf (classoid-state it) nil)
1233 (setf (classoid-cell-classoid
1234 (find-classoid-cell name :create t))
1235 (mark-ctype-interned
1236 (make-built-in-classoid
1237 :name name
1238 :translation (if trans-p :initializing nil)
1239 :direct-superclasses
1240 (if (eq name t)
1242 (mapcar #'find-classoid
1243 direct-superclasses)))))))))
1244 (setf (info :type :kind name) :primitive)
1245 (unless trans-p
1246 (setf (info :type :builtin name) classoid))
1247 (let* ((inherits-vector
1248 (map 'simple-vector
1249 (lambda (x)
1250 (let ((super-layout
1251 (classoid-layout (find-classoid x))))
1252 (when (minusp (layout-depthoid super-layout))
1253 (setf hierarchical-p nil))
1254 super-layout))
1255 inherits-list))
1256 (depthoid (if hierarchical-p
1257 (or depth (length inherits-vector))
1258 -1)))
1259 (register-layout
1260 (find-and-init-or-check-layout name
1262 inherits-vector
1263 depthoid
1265 :invalidate nil)))))
1266 (/show0 "done with loop over *!BUILT-IN-CLASSES*"))
1268 ;;; Define temporary PCL STANDARD-CLASSes. These will be set up
1269 ;;; correctly and the Lisp layout replaced by a PCL wrapper after PCL
1270 ;;; is loaded and the class defined.
1271 (!cold-init-forms
1272 (/show0 "about to define temporary STANDARD-CLASSes")
1273 ;; You'd think with all the pedantic explanation in here it would at least
1274 ;; be right, but it isn't: layout-inherits for FUNDAMENTAL-STREAM
1275 ;; ends up as (T SLOT-OBJECT STREAM STANDARD-OBJECT)
1276 (dolist (x '(;; Why is STREAM duplicated in this list? Because, when
1277 ;; the inherits-vector of FUNDAMENTAL-STREAM is set up,
1278 ;; a vector containing the elements of the list below,
1279 ;; i.e. '(T STREAM STREAM), is created, and
1280 ;; this is what the function ORDER-LAYOUT-INHERITS
1281 ;; would do, too.
1283 ;; So, the purpose is to guarantee a valid layout for
1284 ;; the FUNDAMENTAL-STREAM class, matching what
1285 ;; ORDER-LAYOUT-INHERITS would do.
1286 ;; ORDER-LAYOUT-INHERITS would place STREAM at index 2
1287 ;; in the INHERITS(-VECTOR). Index 1 would not be
1288 ;; filled, so STREAM is duplicated there (as
1289 ;; ORDER-LAYOUTS-INHERITS would do). Maybe the
1290 ;; duplicate definition could be removed (removing a
1291 ;; STREAM element), because FUNDAMENTAL-STREAM is
1292 ;; redefined after PCL is set up, anyway. But to play
1293 ;; it safely, we define the class with a valid INHERITS
1294 ;; vector.
1295 (fundamental-stream (t stream stream))))
1296 (/show0 "defining temporary STANDARD-CLASS")
1297 (let* ((name (first x))
1298 (inherits-list (second x))
1299 (classoid (make-standard-classoid :name name))
1300 (classoid-cell (find-classoid-cell name :create t)))
1301 ;; Needed to open-code the MAP, below
1302 (declare (type list inherits-list))
1303 (setf (classoid-cell-classoid classoid-cell) classoid
1304 (info :type :kind name) :instance)
1305 (let ((inherits (map 'simple-vector
1306 (lambda (x)
1307 (classoid-layout (find-classoid x)))
1308 inherits-list)))
1309 #-sb-xc-host (/show0 "INHERITS=..") #-sb-xc-host (/hexstr inherits)
1310 (register-layout (find-and-init-or-check-layout name 0 inherits -1 0)
1311 :invalidate nil))))
1312 (/show0 "done defining temporary STANDARD-CLASSes"))
1314 ;;; Now that we have set up the class heterarchy, seal the sealed
1315 ;;; classes. This must be done after the subclasses have been set up.
1316 (!cold-init-forms
1317 (dolist (x *!built-in-classes*)
1318 (destructuring-bind (name &key (state :sealed) &allow-other-keys) x
1319 (setf (classoid-state (find-classoid name)) state))))
1321 ;;;; class definition/redefinition
1323 ;;; This is to be called whenever we are altering a class.
1324 #+sb-xc-host
1325 (defun %modify-classoid (classoid) (bug "MODIFY-CLASSOID ~S" classoid))
1326 #-sb-xc-host
1327 (defun %modify-classoid (classoid)
1328 (clear-type-caches)
1329 (awhen (classoid-state classoid)
1330 ;; FIXME: This should probably be CERROR.
1331 (warn "making ~(~A~) class ~S writable" it (classoid-name classoid))
1332 (setf (classoid-state classoid) nil)))
1334 ;;; Mark LAYOUT as invalid. Setting DEPTHOID -1 helps cause unsafe
1335 ;;; structure type tests to fail. Remove class from all superclasses
1336 ;;; too (might not be registered, so might not be in subclasses of the
1337 ;;; nominal superclasses.) We set the layout-clos-hash slots to 0 to
1338 ;;; invalidate the wrappers for specialized dispatch functions, which
1339 ;;; use those slots as indexes into tables.
1340 (defun %invalidate-layout (layout)
1341 (declare (type layout layout))
1342 (setf (layout-invalid layout) t
1343 (layout-depthoid layout) -1)
1344 (setf (layout-clos-hash layout) 0)
1345 (let ((inherits (layout-inherits layout))
1346 (classoid (layout-classoid layout)))
1347 (%modify-classoid classoid)
1348 (dovector (super inherits)
1349 (let ((subs (classoid-subclasses (layout-classoid super))))
1350 (when subs
1351 (remhash classoid subs)))))
1352 (values))
1354 ;;;; cold loading initializations
1356 ;;; FIXME: It would be good to arrange for this to be called when the
1357 ;;; cross-compiler is being built, not just when the target Lisp is
1358 ;;; being cold loaded. Perhaps this could be moved to its own file
1359 ;;; late in the build-order.lisp-expr sequence, and be put in
1360 ;;; !COLD-INIT-FORMS there?
1361 (defun !class-finalize ()
1362 (dohash ((name layout) *forward-referenced-layouts*)
1363 (let ((class (find-classoid name nil)))
1364 (cond ((not class)
1365 (setf (layout-classoid layout) (make-undefined-classoid name)))
1366 ((eq (classoid-layout class) layout)
1367 (remhash name *forward-referenced-layouts*))
1369 (error "Something strange with forward layout for ~S:~% ~S"
1370 name layout))))))
1372 (!cold-init-forms
1373 #-sb-xc-host (/show0 "about to set *BUILT-IN-CLASS-CODES*")
1374 (setq **built-in-class-codes**
1375 (let* ((initial-element (classoid-layout (find-classoid 'random-class)))
1376 (res (make-array 256 :initial-element initial-element)))
1377 (dolist (x *!built-in-classes* res)
1378 (destructuring-bind (name &key codes &allow-other-keys)
1380 (let ((layout (classoid-layout (find-classoid name))))
1381 (dolist (code codes)
1382 (setf (svref res code) layout)))))))
1383 #-sb-xc-host (/show0 "done setting *BUILT-IN-CLASS-CODES*"))
1385 (!defun-from-collected-cold-init-forms !classes-cold-init)