x86-64: Treat more symbols as having immediate storage class
[sbcl.git] / src / code / class.lisp
blobc06c0c547588756a65906f2b167d80ffdd9d8afe
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 vector 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 (dovector (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 (:copier nil)
497 (:constructor %make-structure-classoid)))
498 (defun make-structure-classoid (&key name)
499 (mark-ctype-interned (%make-structure-classoid :name name)))
501 ;;;; classoid namespace
503 (eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute)
504 (defun (setf find-classoid) (new-value name)
505 #-sb-xc (declare (type (or null classoid) new-value))
506 (aver new-value)
507 (let ((table *forward-referenced-layouts*))
508 (with-world-lock ()
509 (let ((cell (find-classoid-cell name :create t)))
510 (ecase (info :type :kind name)
511 ((nil))
512 (:forthcoming-defclass-type
513 ;; FIXME: Currently, nothing needs to be done in this case.
514 ;; Later, when PCL is integrated tighter into SBCL, this
515 ;; might need more work.
516 nil)
517 (:instance
518 (aver cell)
519 (let ((old-value (classoid-cell-classoid cell)))
520 (aver old-value)
521 ;; KLUDGE: The reason these clauses aren't directly
522 ;; parallel is that we need to use the internal
523 ;; CLASSOID structure ourselves, because we don't
524 ;; have CLASSes to work with until PCL is built. In
525 ;; the host, CLASSes have an approximately
526 ;; one-to-one correspondence with the target
527 ;; CLASSOIDs (as well as with the target CLASSes,
528 ;; modulo potential differences with respect to
529 ;; conditions).
530 #+sb-xc-host
531 (let ((old (class-of old-value))
532 (new (class-of new-value)))
533 (unless (eq old new)
534 (bug "Trying to change the metaclass of ~S from ~S to ~S in the ~
535 cross-compiler."
536 name (class-name old) (class-name new))))
537 #-sb-xc-host
538 (let ((old (classoid-of old-value))
539 (new (classoid-of new-value)))
540 (unless (eq old new)
541 (warn "Changing meta-class of ~S from ~S to ~S."
542 name (classoid-name old) (classoid-name new))))))
543 (:primitive
544 (error "Cannot redefine standard type ~
545 ~/sb!impl:print-type-specifier/." name))
546 (:defined
547 (warn "redefining DEFTYPE type to be a class: ~
548 ~/sb!impl::print-symbol-with-prefix/" name)
549 (clear-info :type :expander name)
550 (clear-info :type :source-location name)))
552 (remhash name table)
553 (%note-type-defined name)
554 ;; FIXME: I'm unconvinced of the need to handle either of these.
555 ;; Package locks preclude the latter, and in the former case,
556 ;; once you've made some random thing into a :PRIMITIVE kind of type,
557 ;; you've painted yourself into a corner - those types
558 ;; elicit vociferous complaints if you try to redefine them.
560 ;; we need to handle things like
561 ;; (setf (find-class 'foo) (find-class 'integer))
562 ;; and
563 ;; (setf (find-class 'integer) (find-class 'integer))
564 (cond ((built-in-classoid-p new-value)
565 ;; But I can't figure out how to get assertions to pass
566 ;; without violation what would otherwise be invariants
567 ;; of the internal representation of types. This sucks.
568 (setf (info :type :kind name)
569 (or (info :type :kind name) :defined)))
571 (setf (info :type :kind name) :instance)))
572 (setf (classoid-cell-classoid cell) new-value)
573 (unless (eq (info :type :compiler-layout name)
574 (classoid-layout new-value))
575 (setf (info :type :compiler-layout name)
576 (classoid-layout new-value))))))
577 new-value)
579 (defun %clear-classoid (name cell)
580 (ecase (info :type :kind name)
581 ((nil))
582 (:defined)
583 (:primitive
584 (error "Attempt to remove :PRIMITIVE type: ~
585 ~/sb!impl:print-type-specifier/" name))
586 ((:forthcoming-defclass-type :instance)
587 (when cell
588 ;; Note: We cannot remove the classoid cell from the table,
589 ;; since compiled code may refer directly to the cell, and
590 ;; getting a different cell for a classoid with the same name
591 ;; just would not do.
593 ;; Remove the proper name of the classoid, if this was it.
594 (let* ((classoid (classoid-cell-classoid cell))
595 (proper-name (classoid-name classoid)))
596 (when (eq proper-name name)
597 (setf (classoid-name classoid) nil)))
599 ;; Clear the cell.
600 (setf (classoid-cell-classoid cell) nil
601 (classoid-cell-pcl-class cell) nil))
602 (clear-info :type :kind name)
603 (clear-info :type :documentation name)
604 (clear-info :type :compiler-layout name)
605 (values-specifier-type-cache-clear)))))
607 ;;; Called when we are about to define NAME as a class meeting some
608 ;;; predicate (such as a meta-class type test.) The first result is
609 ;;; always of the desired class. The second result is any existing
610 ;;; LAYOUT for this name.
612 ;;; Again, this should be compiler-only, but easier to make this
613 ;;; thread-safe.
614 (defun insured-find-classoid (name predicate constructor)
615 (declare (type function predicate constructor))
616 (let ((table *forward-referenced-layouts*))
617 (with-locked-system-table (table)
618 (let* ((old (find-classoid name nil))
619 (res (if (and old (funcall predicate old))
621 (funcall constructor :name name)))
622 (found (or (gethash name table)
623 (when old (classoid-layout old)))))
624 (when found
625 (setf (layout-classoid found) res))
626 (values res found)))))
628 ;;; If the classoid has a proper name, return the name, otherwise return
629 ;;; the classoid.
630 (defun classoid-proper-name (classoid)
631 #-sb-xc (declare (type classoid classoid))
632 (let ((name (classoid-name classoid)))
633 (if (and name (eq (find-classoid name nil) classoid))
634 name
635 classoid)))
637 ;;;; CLASS type operations
639 ;; CLASSOID-ENUMERABLE-P is referenced during compile by !DEFINE-TYPE-CLASS.
640 ;; But don't redefine it when building the target since we've already
641 ;; got a perfectly good definition loaded for the host.
642 (eval-when (#-sb-xc :compile-toplevel :load-toplevel :execute)
643 ;; Actually this definition makes very little sense because
644 ;; (TYPE-ENUMERABLE (FIND-CLASSOID 'CHARACTER)) => T
645 ;; but (TYPE-ENUMERABLE (SPECIFIER-TYPE 'CHARACTER)) => NIL.
646 ;; You should never see the CLASSOID used as a type though,
647 ;; at least not from parsing and set operations.
648 ;; On a related note, (TYPE-ENUMERABLE (FIND-CLASSOID 'NULL))
649 ;; should probably be T, but you'll never see that type either.
650 ;; Perhaps a better definition of this function would be
651 ;; (if (classoid-translation x) (bug "enumerable-p classoid?") nil)
652 (defun classoid-enumerable-p (x) (eq (classoid-name x) 'character)))
653 (!define-type-class classoid :enumerable #'classoid-enumerable-p
654 :might-contain-other-types nil)
656 (defun classoid-inherits-from (sub super-or-name)
657 (declare (type classoid sub)
658 (type (or symbol classoid) super-or-name))
659 (let ((super (if (symbolp super-or-name)
660 (find-classoid super-or-name)
661 super-or-name)))
662 (find (classoid-layout super)
663 (layout-inherits (classoid-layout sub)))))
665 ;;; We might be passed classoids with invalid layouts; in any pairwise
666 ;;; class comparison, we must ensure that both are valid before
667 ;;; proceeding.
668 (defun %ensure-classoid-valid (classoid layout error-context)
669 (declare (ignorable error-context)) ; not used on host
670 (aver (eq classoid (layout-classoid layout)))
671 (or (not (layout-invalid layout))
672 ;; Avoid accidentally reaching code that can't work.
673 #+sb-xc-host (bug "(TYPEP x 'STANDARD-CLASSOID) can't be tested")
674 #-sb-xc-host
675 (if (typep classoid 'standard-classoid)
676 (let ((class (classoid-pcl-class classoid)))
677 (cond
678 ((sb!pcl:class-finalized-p class)
679 (sb!pcl::%force-cache-flushes class)
681 ((sb!pcl::class-has-a-forward-referenced-superclass-p class)
682 (when error-context
683 (bug "~@<Invalid class ~S with forward-referenced superclass ~
684 ~S in ~A.~%~:@>"
685 class
686 (sb!pcl::class-has-a-forward-referenced-superclass-p class)
687 error-context))
688 nil)
690 (sb!pcl:finalize-inheritance class)
691 t)))
692 (bug "~@<Don't know how to ensure validity of ~S (not a STANDARD-CLASSOID) ~
693 for ~A.~%~:@>"
694 classoid (or error-context 'subtypep)))))
696 (defun %ensure-both-classoids-valid (class1 class2 &optional errorp)
697 (do ((layout1 (classoid-layout class1) (classoid-layout class1))
698 (layout2 (classoid-layout class2) (classoid-layout class2))
699 (i 0 (+ i 1)))
700 ((and (not (layout-invalid layout1)) (not (layout-invalid layout2)))
702 (aver (< i 2))
703 (unless (and (%ensure-classoid-valid class1 layout1 errorp)
704 (%ensure-classoid-valid class2 layout2 errorp))
705 (return-from %ensure-both-classoids-valid nil))))
707 #-sb-xc-host ; No such thing as LAYOUT-OF, never mind the rest
708 (defun update-object-layout-or-invalid (object layout)
709 ;; FIXME: explain why this isn't (LAYOUT-FOR-STD-CLASS-P LAYOUT).
710 (if (layout-for-std-class-p (layout-of object))
711 (sb!pcl::check-wrapper-validity object)
712 (sb!c::%layout-invalid-error object layout)))
714 ;;; Simple methods for TYPE= and SUBTYPEP should never be called when
715 ;;; the two classes are equal, since there are EQ checks in those
716 ;;; operations.
717 (!define-type-method (classoid :simple-=) (type1 type2)
718 (aver (not (eq type1 type2)))
719 (values nil t))
721 (!define-type-method (classoid :simple-subtypep) (class1 class2)
722 (aver (not (eq class1 class2)))
723 (with-world-lock ()
724 (if (%ensure-both-classoids-valid class1 class2)
725 (let ((subclasses2 (classoid-subclasses class2)))
726 (if (and subclasses2 (gethash class1 subclasses2))
727 (values t t)
728 (if (and (typep class1 'standard-classoid)
729 (typep class2 'standard-classoid)
730 (or (sb!pcl::class-has-a-forward-referenced-superclass-p
731 (classoid-pcl-class class1))
732 (sb!pcl::class-has-a-forward-referenced-superclass-p
733 (classoid-pcl-class class2))))
734 ;; If there's a forward-referenced class involved we don't know for sure.
735 ;; (There are cases which we /could/ figure out, but that doesn't seem
736 ;; to be required or important, really.)
737 (values nil nil)
738 (values nil t))))
739 (values nil nil))))
741 ;;; When finding the intersection of a sealed class and some other
742 ;;; class (not hierarchically related) the intersection is the union
743 ;;; of the currently shared subclasses.
744 (defun sealed-class-intersection2 (sealed other)
745 (declare (type classoid sealed other))
746 (let ((s-sub (classoid-subclasses sealed))
747 (o-sub (classoid-subclasses other)))
748 (if (and s-sub o-sub)
749 (collect ((res *empty-type* type-union))
750 (dohash ((subclass layout) s-sub :locked t)
751 (declare (ignore layout))
752 (when (gethash subclass o-sub)
753 (res (specifier-type subclass))))
754 (res))
755 *empty-type*)))
757 (!define-type-method (classoid :simple-intersection2) (class1 class2)
758 (declare (type classoid class1 class2))
759 (with-world-lock ()
760 (%ensure-both-classoids-valid class1 class2 "type intersection")
761 (cond ((eq class1 class2)
762 class1)
763 ;; If one is a subclass of the other, then that is the
764 ;; intersection.
765 ((let ((subclasses (classoid-subclasses class2)))
766 (and subclasses (gethash class1 subclasses)))
767 class1)
768 ((let ((subclasses (classoid-subclasses class1)))
769 (and subclasses (gethash class2 subclasses)))
770 class2)
771 ;; Otherwise, we can't in general be sure that the
772 ;; intersection is empty, since a subclass of both might be
773 ;; defined. But we can eliminate it for some special cases.
774 ((or (structure-classoid-p class1)
775 (structure-classoid-p class2))
776 ;; No subclass of both can be defined.
777 *empty-type*)
778 ((eq (classoid-state class1) :sealed)
779 ;; checking whether a subclass of both can be defined:
780 (sealed-class-intersection2 class1 class2))
781 ((eq (classoid-state class2) :sealed)
782 ;; checking whether a subclass of both can be defined:
783 (sealed-class-intersection2 class2 class1))
784 ;; If exactly one of CLASS{1,2} is a CONDITION-CLASSOID,
785 ;; there can be no intersection: sub-/superclass relations
786 ;; between CONDITION-CLASSOIDs and other CLASSOIDs are not
787 ;; possible and a CONDITION-CLASSOIDs cannot be changed into
788 ;; different CLASSOIDs.
789 ((let ((c1 (condition-classoid-p class1))
790 (c2 (condition-classoid-p class2)))
791 (or (and c1 (not c2)) (and (not c1) c2)))
792 *empty-type*)
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 (declaim (type cons **non-instance-classoid-types**))
802 (defglobal **non-instance-classoid-types**
803 '(symbol system-area-pointer weak-pointer code-component
804 #!-(or x86 x86-64) lra
805 fdefn random-class))
807 (defun classoid-non-instance-p (classoid)
808 (declare (type classoid classoid))
809 (member classoid **non-instance-classoid-types**
810 :key #'find-classoid))
812 ;;; KLUDGE: we need this because of the need to represent
813 ;;; intersections of two classes, even when empty at a given time, as
814 ;;; uncanonicalized intersections because of the possibility of later
815 ;;; defining a subclass of both classes. The necessity for changing
816 ;;; the default return value from SUBTYPEP to NIL, T if no alternate
817 ;;; method is present comes about because, unlike the other places we
818 ;;; use INVOKE-COMPLEX-SUBTYPEP-ARG1-METHOD, in HAIRY methods and the
819 ;;; like, classes are in their own hierarchy with no possibility of
820 ;;; mixtures with other type classes.
821 (!define-type-method (classoid :complex-subtypep-arg2) (type1 class2)
822 (if (and (intersection-type-p type1)
823 (> (count-if #'classoid-p (intersection-type-types type1)) 1))
824 (values nil nil)
825 (invoke-complex-subtypep-arg1-method type1 class2 nil t)))
827 (!define-type-method (classoid :negate) (type) (make-negation-type type))
829 (!define-type-method (classoid :unparse) (type)
830 (classoid-proper-name type))
832 ;;;; built-in classes
834 ;;; The BUILT-IN-CLASSES list is a data structure which configures the
835 ;;; creation of all the built-in classes. It contains all the info
836 ;;; that we need to maintain the mapping between classes, compile-time
837 ;;; types and run-time type codes. These options are defined:
839 ;;; :TRANSLATION (default none)
840 ;;; When this class is "parsed" as a type specifier, it is
841 ;;; translated into the specified internal type representation,
842 ;;; rather than being left as a class. This is used for types
843 ;;; which we want to canonicalize to some other kind of type
844 ;;; object because in general we want to be able to include more
845 ;;; information than just the class (e.g. for numeric types.)
847 ;;; :STATE (default :SEALED)
848 ;;; The value of CLASS-STATE which we want on completion,
849 ;;; indicating whether subclasses can be created at run-time.
851 ;;; :HIERARCHICAL-P (default T unless any of the inherits are non-hierarchical)
852 ;;; True if we can assign this class a unique inheritance depth.
854 ;;; :CODES (default none)
855 ;;; Run-time type codes which should be translated back to this
856 ;;; class by CLASS-OF. Unspecified for abstract classes.
858 ;;; :INHERITS (default this class and T)
859 ;;; The class-precedence list for this class, with this class and
860 ;;; T implicit.
862 ;;; :DIRECT-SUPERCLASSES (default to head of CPL)
863 ;;; List of the direct superclasses of this class.
865 ;;; NB: not to be confused with SB-PCL::*BUILT-IN-CLASSES*
866 (!defvar *!built-in-classes*
867 ;; To me these data would look nicer with commas instead of "#."
868 '((t :state :read-only :translation t)
869 (character :codes (#.sb!vm:character-widetag)
870 :translation (character-set)
871 :prototype-form (code-char 42))
872 (symbol :codes (#.sb!vm:symbol-widetag)
873 :prototype-form '#:mu)
875 (system-area-pointer :codes (#.sb!vm:sap-widetag)
876 :prototype-form (int-sap 42))
877 (weak-pointer :codes (#.sb!vm:weak-pointer-widetag)
878 :prototype-form (make-weak-pointer (find-package "CL")))
879 (code-component :codes (#.sb!vm:code-header-widetag))
880 #!-(or x86 x86-64) (lra :codes (#.sb!vm:return-pc-widetag))
881 (fdefn :codes (#.sb!vm:fdefn-widetag)
882 :prototype-form (make-fdefn "42"))
883 (random-class) ; used for unknown type codes
885 (function
886 :codes (#.sb!vm:closure-widetag
887 #.sb!vm:simple-fun-widetag)
888 :state :read-only
889 :prototype-form (function (lambda () 42)))
891 (number :translation number)
892 (complex
893 :translation complex
894 :inherits (number)
895 :codes (#.sb!vm:complex-widetag)
896 :prototype-form (complex 42 42))
897 (complex-single-float
898 :translation (complex single-float)
899 :inherits (complex number)
900 :codes (#.sb!vm:complex-single-float-widetag)
901 :prototype-form (complex 42f0 42f0))
902 (complex-double-float
903 :translation (complex double-float)
904 :inherits (complex number)
905 :codes (#.sb!vm:complex-double-float-widetag)
906 :prototype-form (complex 42d0 42d0))
907 #!+long-float
908 (complex-long-float
909 :translation (complex long-float)
910 :inherits (complex number)
911 :codes (#.sb!vm:complex-long-float-widetag)
912 :prototype-form (complex 42l0 42l0))
913 #!+sb-simd-pack
914 (simd-pack
915 :translation simd-pack
916 :codes (#.sb!vm:simd-pack-widetag)
917 :prototype-form (%make-simd-pack-ub64 42 42))
918 (real :translation real :inherits (number))
919 (float
920 :translation float
921 :inherits (real number))
922 (single-float
923 :translation single-float
924 :inherits (float real number)
925 :codes (#.sb!vm:single-float-widetag)
926 :prototype-form 42f0)
927 (double-float
928 :translation double-float
929 :inherits (float real number)
930 :codes (#.sb!vm:double-float-widetag)
931 :prototype-form 42d0)
932 #!+long-float
933 (long-float
934 :translation long-float
935 :inherits (float real number)
936 :codes (#.sb!vm:long-float-widetag)
937 :prototype-form 42l0)
938 (rational
939 :translation rational
940 :inherits (real number))
941 (ratio
942 :translation (and rational (not integer))
943 :inherits (rational real number)
944 :codes (#.sb!vm:ratio-widetag)
945 :prototype-form 1/42)
946 (integer
947 :translation integer
948 :inherits (rational real number))
949 (fixnum
950 :translation (integer #.sb!xc:most-negative-fixnum
951 #.sb!xc:most-positive-fixnum)
952 :inherits (integer rational real number)
953 :codes #.(mapcar #'symbol-value sb!vm::fixnum-lowtags)
954 :prototype-form 42)
955 (bignum
956 :translation (and integer (not fixnum))
957 :inherits (integer rational real number)
958 :codes (#.sb!vm:bignum-widetag)
959 :prototype-form (expt 2 #.(* sb!vm:n-word-bits (/ 3 2))))
961 (array :translation array :codes (#.sb!vm:complex-array-widetag)
962 :hierarchical-p nil
963 :prototype-form (make-array nil :adjustable t))
964 (simple-array
965 :translation simple-array :codes (#.sb!vm:simple-array-widetag)
966 :inherits (array)
967 :prototype-form (make-array nil))
968 (sequence
969 :translation (or cons (member nil) vector extended-sequence)
970 :state :read-only
971 :depth 1)
972 (vector
973 :translation vector :codes (#.sb!vm:complex-vector-widetag)
974 :direct-superclasses (array sequence)
975 :inherits (array sequence))
976 (simple-vector
977 :translation simple-vector :codes (#.sb!vm:simple-vector-widetag)
978 :direct-superclasses (vector simple-array)
979 :inherits (vector simple-array array sequence)
980 :prototype-form (make-array 0))
981 (bit-vector
982 :translation bit-vector :codes (#.sb!vm:complex-bit-vector-widetag)
983 :inherits (vector array sequence)
984 :prototype-form (make-array 0 :element-type 'bit :fill-pointer t))
985 (simple-bit-vector
986 :translation simple-bit-vector :codes (#.sb!vm:simple-bit-vector-widetag)
987 :direct-superclasses (bit-vector simple-array)
988 :inherits (bit-vector vector simple-array
989 array sequence)
990 :prototype-form (make-array 0 :element-type 'bit))
991 (string
992 :translation string
993 :direct-superclasses (vector)
994 :inherits (vector array sequence))
995 (simple-string
996 :translation simple-string
997 :direct-superclasses (string simple-array)
998 :inherits (string vector simple-array array sequence))
999 (vector-nil
1000 :translation (vector nil)
1001 :codes (#.sb!vm:complex-vector-nil-widetag)
1002 :direct-superclasses (string)
1003 :inherits (string vector array sequence)
1004 :prototype-form (make-array 0 :element-type 'nil :fill-pointer t))
1005 (simple-array-nil
1006 :translation (simple-array nil (*))
1007 :codes (#.sb!vm:simple-array-nil-widetag)
1008 :direct-superclasses (vector-nil simple-string)
1009 :inherits (vector-nil simple-string string vector simple-array
1010 array sequence)
1011 :prototype-form (make-array 0 :element-type 'nil))
1012 (base-string
1013 :translation base-string
1014 :codes (#.sb!vm:complex-base-string-widetag)
1015 :direct-superclasses (string)
1016 :inherits (string vector array sequence)
1017 :prototype-form (make-array 0 :element-type 'base-char :fill-pointer t))
1018 (simple-base-string
1019 :translation simple-base-string
1020 :codes (#.sb!vm:simple-base-string-widetag)
1021 :direct-superclasses (base-string simple-string)
1022 :inherits (base-string simple-string string vector simple-array
1023 array sequence)
1024 :prototype-form (make-array 0 :element-type 'base-char))
1025 #!+sb-unicode
1026 (character-string
1027 :translation (vector character)
1028 :codes (#.sb!vm:complex-character-string-widetag)
1029 :direct-superclasses (string)
1030 :inherits (string vector array sequence)
1031 :prototype-form (make-array 0 :element-type 'character :fill-pointer t))
1032 #!+sb-unicode
1033 (simple-character-string
1034 :translation (simple-array character (*))
1035 :codes (#.sb!vm:simple-character-string-widetag)
1036 :direct-superclasses (character-string simple-string)
1037 :inherits (character-string simple-string string vector simple-array
1038 array sequence)
1039 :prototype-form (make-array 0 :element-type 'character))
1040 (list
1041 :translation (or cons (member nil))
1042 :inherits (sequence))
1043 (cons
1044 :codes (#.sb!vm:list-pointer-lowtag)
1045 :translation cons
1046 :inherits (list sequence)
1047 :prototype-form (cons nil nil))
1048 (null
1049 :translation (member nil)
1050 :inherits (symbol list sequence)
1051 :direct-superclasses (symbol list)
1052 :prototype-form 'nil)
1053 ;; These last few are strange. STREAM has only T as an ancestor,
1054 ;; so you'd think it would be at depth 1. FILE- and STRING-STREAM
1055 ;; each have STREAM and T as ancestors, so you'd think they'd be at depth
1056 ;; 1 greater than STREAM, instead of 2 greater. But changing any of
1057 ;; these to the "obvious" value makes various type checks go wrong.
1058 (stream
1059 :state :read-only
1060 :depth 2)
1061 (file-stream
1062 :state :read-only
1063 :depth 4
1064 :inherits (stream))
1065 (string-stream
1066 :state :read-only
1067 :depth 4
1068 :inherits (stream))
1070 #.(loop for x across sb!vm:*specialized-array-element-type-properties*
1071 unless (member (sb!vm::saetp-specifier x) '(t character base-char nil bit))
1072 collect
1073 ;; I'm not sure if it's an accident that there are distinct SB!KERNEL
1074 ;; versus SB!VM symbols for the specialized arrays. The former are types
1075 ;; in the language, and the latter are primitive object types,
1076 ;; but istm they should be designated by the same symbols.
1077 `(,(intern (string (sb!vm::saetp-primitive-type-name x)) *package*)
1078 :translation (simple-array ,(sb!vm::saetp-specifier x) (*))
1079 :codes (,(sb!vm::saetp-typecode x))
1080 :direct-superclasses (vector simple-array)
1081 :inherits (vector simple-array array sequence)
1082 :prototype-form (make-array 0 :element-type ',(sb!vm::saetp-specifier x))))))
1084 ;;; See also src/code/class-init.lisp where we finish setting up the
1085 ;;; translations for built-in types.
1086 (!cold-init-forms
1087 (dolist (x *!built-in-classes*)
1088 #-sb-xc-host (/show0 "at head of loop over *!BUILT-IN-CLASSES*")
1089 (destructuring-bind
1090 (name &key
1091 (translation nil trans-p)
1092 inherits
1093 codes
1094 state
1095 depth
1096 prototype-form
1097 (hierarchical-p t) ; might be modified below
1098 (direct-superclasses (if inherits
1099 (list (car inherits))
1100 '(t))))
1102 (declare (ignore codes state translation prototype-form))
1103 (let ((inherits-list (if (eq name t)
1105 (cons t (reverse inherits))))
1106 (classoid
1107 (acond #+sb-xc ; genesis dumps some classoid literals
1108 ((find-classoid name nil)
1109 ;; Unseal it so that REGISTER-LAYOUT doesn't warn
1110 (setf (classoid-state it) nil)
1113 (setf (classoid-cell-classoid
1114 (find-classoid-cell name :create t))
1115 (mark-ctype-interned
1116 (make-built-in-classoid
1117 :name name
1118 :translation (if trans-p :initializing nil)
1119 :direct-superclasses
1120 (if (eq name t)
1122 (mapcar #'find-classoid
1123 direct-superclasses)))))))))
1124 (setf (info :type :kind name) :primitive)
1125 (unless trans-p
1126 (setf (info :type :builtin name) classoid))
1127 (let* ((inherits-vector
1128 (map 'simple-vector
1129 (lambda (x)
1130 (let ((super-layout
1131 (classoid-layout (find-classoid x))))
1132 (when (minusp (layout-depthoid super-layout))
1133 (setf hierarchical-p nil))
1134 super-layout))
1135 inherits-list))
1136 (depthoid (if hierarchical-p
1137 (or depth (length inherits-vector))
1138 -1)))
1139 (register-layout
1140 (find-and-init-or-check-layout name
1142 inherits-vector
1143 depthoid
1144 +layout-all-tagged+)
1145 :invalidate nil)))))
1146 (/show0 "done with loop over *!BUILT-IN-CLASSES*"))
1148 ;;; Now that we have set up the class heterarchy, seal the sealed
1149 ;;; classes. This must be done after the subclasses have been set up.
1150 (!cold-init-forms
1151 (dolist (x *!built-in-classes*)
1152 (destructuring-bind (name &key (state :sealed) &allow-other-keys) x
1153 (setf (classoid-state (find-classoid name)) state))))
1155 ;;;; class definition/redefinition
1157 ;;; This is to be called whenever we are altering a class.
1158 #+sb-xc-host
1159 (defun %modify-classoid (classoid) (bug "MODIFY-CLASSOID ~S" classoid))
1160 #-sb-xc-host
1161 (defun %modify-classoid (classoid)
1162 (clear-type-caches)
1163 (awhen (classoid-state classoid)
1164 ;; FIXME: This should probably be CERROR.
1165 (warn "making ~(~A~) class ~S writable" it (classoid-name classoid))
1166 (setf (classoid-state classoid) nil)))
1168 ;;; Mark LAYOUT as invalid. Setting DEPTHOID -1 helps cause unsafe
1169 ;;; structure type tests to fail. Remove class from all superclasses
1170 ;;; too (might not be registered, so might not be in subclasses of the
1171 ;;; nominal superclasses.) We set the layout-clos-hash slots to 0 to
1172 ;;; invalidate the wrappers for specialized dispatch functions, which
1173 ;;; use those slots as indexes into tables.
1174 (defun %invalidate-layout (layout)
1175 (declare (type layout layout))
1176 (setf (layout-invalid layout) t
1177 (layout-depthoid layout) -1)
1178 (setf (layout-clos-hash layout) 0)
1179 (let ((inherits (layout-inherits layout))
1180 (classoid (layout-classoid layout)))
1181 (%modify-classoid classoid)
1182 (dovector (super inherits)
1183 (let ((subs (classoid-subclasses (layout-classoid super))))
1184 (when subs
1185 (remhash classoid subs)))))
1186 (values))
1188 ;;;; cold loading initializations
1190 ;;; FIXME: It would be good to arrange for this to be called when the
1191 ;;; cross-compiler is being built, not just when the target Lisp is
1192 ;;; being cold loaded. Perhaps this could be moved to its own file
1193 ;;; late in the build-order.lisp-expr sequence, and be put in
1194 ;;; !COLD-INIT-FORMS there?
1195 (defun !class-finalize ()
1196 (dohash ((name layout) *forward-referenced-layouts*)
1197 (let ((class (find-classoid name nil)))
1198 (cond ((not class)
1199 (setf (layout-classoid layout) (make-undefined-classoid name)))
1200 ((eq (classoid-layout class) layout)
1201 (remhash name *forward-referenced-layouts*))
1203 (error "Something strange with forward layout for ~S:~% ~S"
1204 name layout))))))
1206 (!cold-init-forms
1207 #-sb-xc-host (/show0 "about to set *BUILT-IN-CLASS-CODES*")
1208 (setq **built-in-class-codes**
1209 (let* ((initial-element (classoid-layout (find-classoid 'random-class)))
1210 (res (make-array 256 :initial-element initial-element)))
1211 (dolist (x *!built-in-classes* res)
1212 (destructuring-bind (name &key codes &allow-other-keys)
1214 (let ((layout (classoid-layout (find-classoid name))))
1215 (dolist (code codes)
1216 (setf (svref res code) layout)))))))
1217 #!+immobile-space
1218 (let ((table **built-in-class-codes**))
1219 (loop with layout = (aref table sb!vm:list-pointer-lowtag)
1220 for i from sb!vm:list-pointer-lowtag by 16 below 256
1221 do (setf (aref table i) layout))
1222 (loop with layout = (aref table sb!vm:even-fixnum-lowtag)
1223 for i from sb!vm:even-fixnum-lowtag by (ash 1 sb!vm:n-fixnum-tag-bits) below 256
1224 do (setf (aref table i) layout)))
1225 #-sb-xc-host (/show0 "done setting *BUILT-IN-CLASS-CODES*"))
1227 (!defun-from-collected-cold-init-forms !classes-cold-init)