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