Record XREFs for symbols that name functions.
[sbcl.git] / src / code / defstruct.lisp
blob7721b717cc6fe83c2b283b08a9c0529484c12849
1 ;;;; that part of DEFSTRUCT implementation which is needed not just
2 ;;;; in the target Lisp but also in the cross-compilation host
4 ;;;; This software is part of the SBCL system. See the README file for
5 ;;;; more information.
6 ;;;;
7 ;;;; This software is derived from the CMU CL system, which was
8 ;;;; written at Carnegie Mellon University and released into the
9 ;;;; public domain. The software is in the public domain and is
10 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
11 ;;;; files for more information.
13 (in-package "SB-KERNEL")
15 (/show0 "code/defstruct.lisp 15")
17 ;;;; getting LAYOUTs
19 ;;; Return the compiler layout for NAME. (The class referred to by
20 ;;; NAME must be a structure-like class.)
21 (defun compiler-layout-or-lose (name)
22 (let ((res (info :type :compiler-layout name)))
23 (cond ((not res)
24 (error "Class is not yet defined or was undefined: ~S" name))
25 ((not (typep (layout-%info res) 'defstruct-description))
26 (error "Class is not a structure class: ~S" name))
28 (check-deprecated-type name)
29 res))))
31 (defun compiler-layout-ready-p (name)
32 (let ((layout (info :type :compiler-layout name)))
33 (and layout (typep (layout-%info layout) 'defstruct-description))))
35 (sb-xc:defmacro %make-structure-instance-macro (dd slot-specs &rest slot-vars)
36 (if (compiler-layout-ready-p (dd-name dd))
37 `(truly-the ,(dd-name dd)
38 (%make-structure-instance ,dd ,slot-specs ,@slot-vars))
39 ;; Non-toplevel defstructs don't have a layout at compile time,
40 ;; so we need to construct the actual function at runtime -- but
41 ;; we cache it at the call site, so that we don't perform quite
42 ;; so horribly.
43 `(let* ((cell (load-time-value (list nil)))
44 (fun (car cell)))
45 (if (functionp fun)
46 (funcall fun ,@slot-vars)
47 (funcall (setf (car cell)
48 (%make-structure-instance-allocator ,dd ,slot-specs
49 ',slot-vars))
50 ,@slot-vars)))))
52 (sb-xc:defmacro %new-instance (layout size)
53 `(let* ((l ,layout)
54 (i (truly-the ,(if (constantp layout) (layout-classoid layout) 'instance)
55 (%make-instance ,size))))
56 (%set-instance-layout i l)
57 i))
58 (sb-xc:defmacro %new-instance* (layout len)
59 `(let ((i (truly-the
60 ,(if (constantp layout) (layout-classoid layout) 'instance)
61 (if (logtest (layout-flags ,layout) sb-vm::+strictly-boxed-flag+)
62 (%make-instance ,len)
63 (%make-instance/mixed ,len)))))
64 (%set-instance-layout i ,layout)
65 i))
67 (declaim (ftype (sfunction (defstruct-description list list) function)
68 %make-structure-instance-allocator))
69 (defun %make-structure-instance-allocator (dd slot-specs slot-vars)
70 (values (compile nil
71 `(lambda ,(loop for var in slot-vars
72 collect (if (consp var)
73 (third var)
74 var))
75 (declare (optimize (sb-c:store-source-form 0)))
76 (%make-structure-instance-macro ,dd ',slot-specs ,@slot-vars)))))
78 (defun %make-funcallable-structure-instance-allocator (dd slot-specs)
79 (when slot-specs
80 (bug "funcallable-structure-instance allocation with slots unimplemented"))
81 (values
82 (compile nil `(lambda ()
83 (declare (optimize (sb-c:store-source-form 0)))
84 (let ((object (%make-funcallable-instance ,(dd-length dd))))
85 (setf (%fun-layout object) ,(find-layout (dd-name dd)))
86 object)))))
88 ;;;; DEFSTRUCT-DESCRIPTION
90 ;;; The DEFSTRUCT-DESCRIPTION structure holds compile-time information
91 ;;; about a structure type.
92 ;;; Its definition occurs in 'early-classoid.lisp'
93 (defmethod print-object ((x defstruct-description) stream)
94 (print-unreadable-object (x stream :type t :identity t)
95 (prin1 (dd-name x) stream)))
97 ;;; Does DD describe a structure with a class?
98 (defun dd-class-p (dd)
99 (if (member (dd-type dd) '(structure funcallable-structure)) t nil))
100 (defmacro dd-named (dd) `(logtest (dd-flags ,dd) +dd-named+))
101 (defmacro dd-pure (dd) `(logtest (dd-flags ,dd) +dd-pure+))
102 (defmacro dd-null-lexenv-p (dd) `(logtest (dd-flags ,dd) +dd-nullenv+))
103 (defun dd-print-option (dd)
104 (cond ((logtest (dd-flags dd) +dd-printfun+) :print-function)
105 ((logtest (dd-flags dd) +dd-printobj+) :print-object)))
107 (defun dd-layout-or-lose (dd)
108 (compiler-layout-or-lose (dd-name dd)))
110 ;;;; DEFSTRUCT-SLOT-DESCRIPTION
112 ;;; A DEFSTRUCT-SLOT-DESCRIPTION holds compile-time information about
113 ;;; a structure slot. These objects are immutable.
114 (def!struct (defstruct-slot-description
115 (:constructor make-dsd (name type accessor-name bits default))
116 (:conc-name dsd-)
117 (:copier nil)
118 (:pure t))
119 (name nil :read-only t) ; name of slot
120 (type t :read-only t) ; declared type specifier
121 (accessor-name nil :type symbol :read-only t) ; name of the accessor function
122 ;; Packed integer with 4 subfields.
123 ;; FIXNUM is ok for the host - it's guaranteed to be at least 16 signed bits
124 ;; and we don't have structures whose slot indices run into the thousands.
125 (bits 0 :type fixnum)
126 (default nil :read-only t)) ; default value expression
127 (declaim (freeze-type defstruct-slot-description))
129 (eval-when (:compile-toplevel)
130 ;; Ensure that rsd-index is representable in 3 bits. (Can easily be changed)
131 (assert (<= (1+ (length *raw-slot-data*)) 8)))
133 (defconstant sb-vm:dsd-index-shift 8)
134 (defconstant sb-vm:dsd-raw-type-mask #b111)
135 (defconstant dsd-default-error (ash 1 7))
137 (defun pack-dsd-bits (index read-only safe-p always-boundp gc-ignorable rsd-index)
138 (logior (ash index sb-vm:dsd-index-shift)
139 ;; (ash 1 7) meaning DEFAULT doesn't match TYPE is set during compilation of the constructor.
140 (if read-only (ash 1 6) 0)
141 (if safe-p (ash 1 5) 0)
142 (if always-boundp (ash 1 4) 0)
143 (if gc-ignorable (ash 1 3) 0)
144 (the (unsigned-byte 3) (if rsd-index (1+ rsd-index) 0))))
146 (declaim (inline dsd-always-boundp
147 dsd-safe-p
148 dsd-gc-ignorable
149 ; dsd-read-only ; compilation order problem
152 ;;; In general we type-check a slot when it is written, not when read.
153 ;;; There are cases where we must check each read though:
155 ;;; (1) a structure subtype can constrain a slot type more highly than the
156 ;;; parent type constrains it. This requires that each read via the subtype's
157 ;;; accessor be type-checked, because a write via the parent writer may
158 ;;; store a value that does not satisfy the more restrictive constraint.
159 ;;; These slots have SAFE-P = 0 in the dsd.
160 ;;; (2) If a BOA constructor leaves an ordinary (non-raw) slot uninitialized,
161 ;;; then the slot contains the unbound-marker which can be tested with just
162 ;;; an EQ comparison. Such slots have ALWAYS-BOUNDP = 0 in the dsd.
163 ;;; This does not apply to raw slots, which can not hold an unbound marker.
165 ;;; Note that inheritance in the presence of a BOA constructor can cause
166 ;;; the parent structure's notion of ALWAYS-BOUNDP to be wrong.
167 ;;; We don't try to deal with that.
168 ;;; FIXME: We could emit a style-warning if this happens, and/or if any code
169 ;;; was compiled under the assumption that the slot was safe.
171 ;;; Further note that MAKE-LOAD-FORM methods can do damage to type invariants
172 ;;; without any efficient means of detection, if MAKE-LOAD-FORM-SAVING-SLOTS
173 ;;; is used without specifying all slots.
175 ;; Index into *RAW-SLOT-DATA* vector of the RAW-SLOT-DATA for this slot.
176 ;; The index is NIL if this slot is not raw.
177 (defun dsd-rsd-index (dsd)
178 (let ((val (logand (dsd-bits dsd) sb-vm:dsd-raw-type-mask)))
179 (if (plusp val) (the (mod #.(length *raw-slot-data*)) (1- val)))))
180 ;;; GC-ignorable slots are a superset of raw slots.
181 (defun dsd-gc-ignorable (dsd) (logbitp 3 (dsd-bits dsd)))
183 ;; Whether the slot is always bound. Slots are almost always bound,
184 ;; the exception being those which appear as an &AUX var with no value
185 ;; in a BOA constructor.
186 (defun dsd-always-boundp (dsd) (logbitp 4 (dsd-bits dsd)))
187 ;; Whether the slot is known to be always of the specified type
188 ;; A slot may be SAFE-P even if not always-boundp.
189 (defun dsd-safe-p (dsd) (logbitp 5 (dsd-bits dsd)))
190 (defun dsd-read-only (dsd) (logbitp 6 (dsd-bits dsd)))
191 ;; its position in the implementation sequence
192 (defun dsd-index (dsd)
193 (the index (ash (dsd-bits dsd) (- sb-vm:dsd-index-shift))))
194 (sb-c:define-source-transform dsd-index (dsd)
195 `(truly-the index (ash (dsd-bits ,dsd) ,(- sb-vm:dsd-index-shift))))
197 (!set-load-form-method defstruct-slot-description (:host :xc :target))
198 (defmethod print-object ((x defstruct-slot-description) stream)
199 (print-unreadable-object (x stream :type t)
200 (prin1 (dsd-name x) stream)))
202 (defun dsd-raw-slot-data (dsd)
203 (let ((rsd-index (dsd-rsd-index dsd)))
204 (and rsd-index
205 (svref *raw-slot-data* rsd-index))))
207 (defun dsd-raw-type (dsd)
208 (acond ((dsd-raw-slot-data dsd) (raw-slot-data-raw-type it))
209 (t)))
211 (defun dsd-reader (dsd funinstancep)
212 (acond ((dsd-raw-slot-data dsd)
213 (values (raw-slot-data-reader-name it) (raw-slot-data-writer-name it)))
214 (funinstancep
215 (values '%funcallable-instance-info '%set-funcallable-instance-info))
217 (values '%instance-ref '%instance-set))))
219 ;;;; typed (non-class) structures
221 ;;; Return a type specifier we can use for testing :TYPE'd structures.
222 (defun dd-lisp-type (defstruct)
223 (ecase (dd-type defstruct)
224 (list 'list)
225 (vector `(simple-array ,(dd-%element-type defstruct) (*)))))
227 ;;;; shared machinery for inline and out-of-line slot accessor functions
229 ;;; Classic comment preserved for entertainment value:
231 ;;; "A lie can travel halfway round the world while the truth is
232 ;;; putting on its shoes." -- Mark Twain
234 ;;;; the legendary DEFSTRUCT macro itself (both CL:DEFSTRUCT and its
235 ;;;; close personal friend SB-XC:DEFSTRUCT)
237 (defun %defstruct-package-locks (dd)
238 (declare (ignorable dd))
239 #-sb-xc-host
240 (let ((name (dd-name dd)))
241 (with-single-package-locked-error
242 (:symbol name "defining ~S as a structure"))
243 (awhen (dd-predicate-name dd)
244 (with-single-package-locked-error
245 (:symbol it "defining ~s as a predicate for ~s structure" name)))
246 (awhen (dd-copier-name dd)
247 (with-single-package-locked-error
248 (:symbol it "defining ~s as a copier for ~s structure" name)))
249 (dolist (ctor (dd-constructors dd))
250 (with-single-package-locked-error
251 (:symbol (car ctor) "defining ~s as a constructor for ~s structure" name)))
252 (dolist (dsd (dd-slots dd))
253 (awhen (dsd-accessor-name dsd)
254 (with-single-package-locked-error
255 (:symbol it "defining ~s as an accessor for ~s structure" name))))))
257 ;;; Since DSDs live a long time for inheritance purposes don't attach
258 ;;; the source form to them directly.
259 (defvar *dsd-source-form*)
261 (defun accessor-definitions (dd defuns)
262 (if defuns
263 ;; Return the ordinary toplevel (usually, anyway) defuns
264 (loop for dsd in (dd-slots dd)
265 for accessor-name = (dsd-accessor-name dsd)
266 unless (accessor-inherited-data accessor-name dd)
267 nconc (dx-let ((key (cons dd dsd)))
268 (let ((source-form (and (boundp '*dsd-source-form*)
269 (cdr (assq dsd *dsd-source-form*)))))
270 `(,@(unless (dsd-read-only dsd)
271 `((sb-c:xdefun (setf ,accessor-name) :accessor ,source-form (value instance)
272 ,(slot-access-transform :setf '(instance value) key))))
273 (sb-c:xdefun ,accessor-name :accessor ,source-form (instance)
274 ,(slot-access-transform :read '(instance) key))))))
275 ;; Return fragements of code that CLOS can use. We don't return
276 ;; the toplevel DEFUNs because those generally perform an
277 ;; unneeded type-check unless in safety 0. These CLOS-related
278 ;; lambdas don't need to check the type of the instance because
279 ;; it was already subject to type-based dispatch, and must let
280 ;; unbound markers through for the CLOS machinery to handle.
282 ;; FIXME: it seems like all these fragments should be packed
283 ;; into a single codebob which will have less overhead than
284 ;; separate blobs. Afaict, the only way to do that is to return
285 ;; one lambda that returns all the lambdas.
286 (collect ((result))
287 (dolist (dsd (dd-slots dd) (result))
288 (binding* ((key (cons dd dsd))
289 (name (string (dsd-name dsd))) ; anonymize by stringification
290 ;; reader and writer are the primitive operations
291 ((reader writer) (dsd-reader dsd (neq (dd-type dd) 'structure)))
292 ;; accessor is the global defun
293 (accessor (dsd-accessor-name dsd)))
294 (declare (dynamic-extent key))
295 (result (if (or (dsd-read-only dsd) (not (dsd-always-boundp dsd)))
296 `(named-lambda (setf ,name) (#1=#:v #2=#:x)
297 ,@(if (eql (dsd-type dsd) 't)
298 ;; no typecheck
299 `((,writer (truly-the ,(dd-name dd) #2#) ,(dsd-index dsd) #1#) #1#)
300 `(,(slot-access-transform :setf `(#1# (truly-the ,(dd-name dd) #2#))
301 key :function t))))
302 `'(setf ,accessor))
303 (if (not (dsd-always-boundp dsd))
304 `(named-lambda ,name (#2#)
305 ,(if (dsd-safe-p dsd)
306 ;; Most slots are safe-p (type-safe for reading),
307 ;; so we can be concise rather than use SLOT-ACCESS-TRANSFORM
308 ;; plus a rebinding of X with TRULY-THE.
309 `(,reader (truly-the ,(dd-name dd) #2#) ,(dsd-index dsd))
310 ;; Don't check X, but do check the the fetched value.
311 (slot-access-transform :read `((truly-the ,(dd-name dd) #2#))
312 key :function t)))
313 `',accessor)))))))
315 ;;; shared logic for host macroexpansion for SB-XC:DEFSTRUCT and
316 ;;; cross-compiler macroexpansion for CL:DEFSTRUCT
317 ;;; This monster has exactly one inline use in the final image,
318 ;;; and we can drop the definition.
320 ;;; The DELAYP argument deserves some explanation - Because :COMPILE-TOPLEVEL effects
321 ;;; of non-toplevel DEFSTRUCT forms don't happen, the compiler is unable to produce
322 ;;; good accessor code. By delaying compilation until the DEFSTRUCT happens, whenever
323 ;;; or if ever that may be, we can produce better code. DELAY, if true, says to defer
324 ;;; compilation, ignoring the original lexical environment. This approach produces a
325 ;;; nicer expansion in general, versus macroexpanding to yet another macro whose sole
326 ;;; purpose is to sense that earlier compile-time effects have happened.
328 ;;; Some caveats: (1) a non-toplevel defstruct compiled after already seeing
329 ;;; the same, due to repeated compilation of a file perhaps, will use the known
330 ;;; definition, since technically structures must not be incompatibly redefined.
331 ;;; (2) delayed DEFUNS don't get the right TLF index in their debug info.
332 ;;; We could expand into the internal expansion of DEFUN with an extra argument
333 ;;; for the source location, which would get whatever "here" is instead of random.
334 ;;; In other words: `(progn (sb-impl::%defun struct-slot (...) ... ,(source-location))
335 ;;; and then use that to stuff in the correct info at delayed-compile time.
337 ;;; Note also that sb-fasteval has some hairy logic to JIT-compile slot accessors.
338 ;;; It might be a lot nicer to pull out that junk, and have this expander know that
339 ;;; it is producing code for fasteval, and explicitly compile much the same way
340 ;;; that delayed accessor compilation happens. Here's a REPL session:
341 ;;; * (defstruct foo val) => FOO
342 ;;; * #'foo-val => #<INTERPRETED-FUNCTION FOO-VAL>
343 ;;; * (defun foovalx (afoo) (* (foo-val afoo) 2)) => FOOVALX
344 ;;; * (foovalx (make-foo :val 9)) => 18
345 ;;; * #'foo-val => #<FUNCTION FOO-VAL>
346 ;;; So FOO-VAL got compiled on demand.
348 (declaim (inline !expander-for-defstruct))
349 (defun !expander-for-defstruct (null-env-p optimize-speed delayp name-and-options
350 slot-descriptions expanding-into-code-for)
351 (binding*
352 (((name options)
353 (if (listp name-and-options)
354 (values (car name-and-options) (cdr name-and-options))
355 (values name-and-options nil)))
356 ((nil) (unless (symbolp name)
357 ;; Rather than hit MAKE-DEFSTRUCT-DESCRIPTION's type-check
358 ;; on the NAME slot, we can be a little more clear.
359 (error "DEFSTRUCT: ~S is not a symbol." name)))
360 (flagbits (logior #+sb-xc-host (if (eq name 'layout) +dd-varylen+ 0)
361 (if null-env-p +dd-nullenv+ 0)))
362 (dd (make-defstruct-description name flagbits))
363 (*dsd-source-form* nil)
364 ((inherits comparators) (parse-defstruct dd options slot-descriptions))
365 (constructor-definitions
366 (mapcar (lambda (ctor)
367 `(sb-c:xdefun ,(car ctor)
368 :constructor
370 ,@(structure-ctor-lambda-parts dd (cdr ctor))))
371 (dd-constructors dd)))
372 (print-method
373 (when (dd-print-option dd)
374 (let* ((x (make-symbol "OBJECT"))
375 (s (make-symbol "STREAM"))
376 (fname (dd-printer-fname dd))
377 (depthp (eq (dd-print-option dd) :print-function)))
378 ;; Giving empty :PRINT-OBJECT or :PRINT-FUNCTION options
379 ;; leaves FNAME eq to NIL. The user-level effect is
380 ;; to generate a PRINT-OBJECT method specialized for the type,
381 ;; implementing the default #S structure-printing behavior.
382 (cond ((not fname)
383 (setf fname 'default-structure-print depthp t))
384 ((not (symbolp fname))
385 ;; Don't dump the source form into the DD constant;
386 ;; just indicate that there was an expression there.
387 (setf (dd-printer-fname dd) 'lambda)))
388 `((defmethod print-object ((,x ,name) ,s)
389 (funcall #',fname ,x ,s
390 ,@(if depthp `(*current-level-in-print*)))))))))
391 ;; Return a list of forms
392 (if (dd-class-p dd)
393 `(,@(when (eq expanding-into-code-for :target)
394 ;; Note we intentionally enforce package locks, calling
395 ;; %DEFSTRUCT first. %DEFSTRUCT has the tests (and resulting
396 ;; CERROR) for collisions with LAYOUTs which already exist in
397 ;; the runtime. If there are collisions, we want the user's
398 ;; response to CERROR to control what happens. If the ABORT
399 ;; restart is chosen, %COMPILER-DEFSTRUCT should not modify
400 ;; the definition the class.
401 `((eval-when (:compile-toplevel :load-toplevel :execute)
402 (%defstruct-package-locks ',dd))))
403 (%defstruct ',dd ',inherits (sb-c:source-location))
404 (eval-when (:compile-toplevel :load-toplevel :execute)
405 (%compiler-defstruct ',dd ',inherits))
406 ,@(when (eq expanding-into-code-for :target)
407 `(,@(let ((defuns
408 `(,@(awhen (dd-copier-name dd)
409 `((sb-c:xdefun ,(dd-copier-name dd) :copier nil (instance)
410 (copy-structure (the ,(dd-name dd) instance)))))
411 ,@(awhen (dd-predicate-name dd)
412 `((sb-c:xdefun ,(dd-predicate-name dd) :predicate nil (object)
413 (typep object ',(dd-name dd)))))
414 ,@(accessor-definitions dd t))))
415 (if (and delayp (not (compiler-layout-ready-p name)))
416 `((sb-impl::%simple-eval ',(cons 'progn defuns)
417 (make-null-lexenv)))
418 defuns))
419 ;; This must be in the same lexical environment
420 ,@constructor-definitions
421 ,@print-method
422 ;; Various other operations only make sense on the target SBCL.
423 ;; %TARGET-DEFSTRUCT returns NAME
424 (%target-defstruct ',dd
425 ,(if optimize-speed
426 (gen-custom-equalp dd comparators))
427 ,@(accessor-definitions dd nil)))))
428 ;; Not DD-CLASS-P
429 ;; FIXME: missing package lock checks
430 `((eval-when (:compile-toplevel :load-toplevel :execute)
431 (%proclaim-defstruct-ctors ',dd)
432 (setf (info :typed-structure :info ',name) ',dd))
433 (setf (info :source-location :typed-structure ',name)
434 (sb-c:source-location))
435 ,@(when (eq expanding-into-code-for :target)
436 `(,@(typed-accessor-definitions dd)
437 ,@(typed-predicate-definitions dd)
438 ,@(typed-copier-definitions dd)
439 ,@constructor-definitions
440 ,@(when (dd-doc dd)
441 `((setf (documentation ',(dd-name dd) 'structure)
442 ',(dd-doc dd))))))
443 ',name))))
445 (defun gen-custom-equalp (dd comparators)
446 ;; Process the easiest slots first.
447 ;; TODO: consecutive word-sized slots should try to use instructions
448 ;; that compare more than one word at a time.
449 (collect ((group1) (group2) (group3))
450 (mapc (lambda (dsd comparator)
451 (let ((x `(truly-the ,(dsd-type dsd) (,(dsd-reader dsd nil) a ,(dsd-index dsd))))
452 (y `(truly-the ,(dsd-type dsd) (,(dsd-reader dsd nil) b ,(dsd-index dsd)))))
453 (cond ((member comparator '(= char-equal))
454 (group1 `(,comparator ,x ,y))) ; bounded amount of testing
455 ((member comparator '(bit-vector-=))
456 ;; unbounded but not recursive. Try EQ first though
457 (group2
458 `((lambda (x y) (or (eq x y) (bit-vector-= x y))) ,x ,y)))
460 (group3 `(,comparator ,x ,y)))))) ; recursive
461 (dd-slots dd)
462 comparators)
463 ;; use a string for the name since it's not a global function
464 `(named-lambda ,(format nil "~A-EQUALP" (dd-name dd)) (a b)
465 (declare (optimize (sb-c:store-source-form 0) (safety 0)) (type ,(dd-name dd) a b)
466 (ignorable a b)) ; if zero slots
467 (and ,@(group1) ,@(group2) ,@(group3)))))
469 #+sb-xc-host
470 (progn
471 ;; When compiling and loading the cross-compiler, SB-XC:DEFSTRUCT gets
472 ;; a bootstrap definition from src/code/defbangstruct.
473 ;; The old definition has to be uninstalled to avoid a redefinition warning here.
474 (eval-when (:compile-toplevel :load-toplevel :execute)
475 (fmakunbound 'sb-xc:defstruct))
476 (defmacro sb-xc:defstruct (name-and-options &rest slot-descriptions)
477 "Cause information about a target structure to be built into the
478 cross-compiler."
479 `(progn ,@(!expander-for-defstruct
480 t nil nil name-and-options slot-descriptions :host))))
482 (sb-xc:defmacro defstruct (name-and-options &rest slot-descriptions
483 &environment env)
484 "DEFSTRUCT {Name | (Name Option*)} [Documentation] {Slot | (Slot [Default] {Key Value}*)}
485 Define the structure type Name. Instances are created by MAKE-<name>,
486 which takes &KEY arguments allowing initial slot values to the specified.
487 A SETF'able function <name>-<slot> is defined for each slot to read and
488 write slot values. <name>-p is a type predicate.
490 Popular DEFSTRUCT options (see manual for others):
492 (:CONSTRUCTOR Name)
493 (:PREDICATE Name)
494 Specify the name for the constructor or predicate.
496 (:CONSTRUCTOR Name Lambda-List)
497 Specify the name and arguments for a BOA constructor
498 (which is more efficient when keyword syntax isn't necessary.)
500 (:INCLUDE Supertype Slot-Spec*)
501 Make this type a subtype of the structure type Supertype. The optional
502 Slot-Specs override inherited slot options.
504 Slot options:
506 :TYPE Type-Spec
507 Asserts that the value of this slot is always of the specified type.
509 :READ-ONLY {T | NIL}
510 If true, no setter function is defined for this slot."
511 (let* ((null-env-p
512 (etypecase env
513 (sb-kernel:lexenv (sb-c::null-lexenv-p env))
514 ;; a LOCALLY environment would be fine,
515 ;; but is not an important case to handle.
516 #+sb-fasteval (sb-interpreter:basic-env nil)
517 (null t)))
518 ;; Decide whether the expansion should delay reference
519 ;; to this structure type. (See explanation up above).
520 ;; This is about performance, not semantics. Non-toplevel
521 ;; effects happen when they should even if this were to
522 ;; produce the preferred expansion for toplevel.
523 (delayp (not (or *top-level-form-p* null-env-p)))
524 (optimize-speed
525 (and (not delayp) (sb-c:policy env (< space 3)))))
526 `(progn
527 ,@(!expander-for-defstruct null-env-p optimize-speed delayp
528 name-and-options slot-descriptions
529 :target))))
531 ;;;; functions to generate code for various parts of DEFSTRUCT definitions
533 ;;; First, a helper to determine whether a name names an inherited
534 ;;; accessor.
535 (defun accessor-inherited-data (name defstruct)
536 (assoc name (dd-inherited-accessor-alist defstruct) :test #'eq))
538 ;;; Return a list of forms which create a predicate function for a
539 ;;; typed DEFSTRUCT.
540 (defun typed-predicate-definitions (defstruct)
541 (let ((name (dd-name defstruct))
542 (predicate-name (dd-predicate-name defstruct))
543 (argname 'x)) ; KISS: no user code appears in the DEFUN
544 (when predicate-name
545 (aver (dd-named defstruct))
546 (let ((ltype (dd-lisp-type defstruct))
547 (name-index (cdr (car (last (find-name-indices defstruct))))))
548 `((defun ,predicate-name (,argname)
549 (and (typep ,argname ',ltype)
550 ,(cond
551 ((subtypep ltype 'list)
552 `(do ((head (the ,ltype ,argname) (cdr head))
553 (i 0 (1+ i)))
554 ((or (not (consp head)) (= i ,name-index))
555 (and (consp head) (eq ',name (car head))))))
556 ((subtypep ltype 'vector)
557 `(and (>= (length (the ,ltype ,argname))
558 ,(dd-length defstruct))
559 (eq ',name (aref (the ,ltype ,argname) ,name-index))))
560 (t (bug "Unhandled representation type in typed DEFSTRUCT: ~
561 ~/sb-impl:print-type-specifier/."
562 ltype))))))))))
564 ;;; Return a list of forms to create a copier function of a typed DEFSTRUCT.
565 (defun typed-copier-definitions (defstruct)
566 (when (dd-copier-name defstruct)
567 `((setf (fdefinition ',(dd-copier-name defstruct)) #'copy-seq)
568 (declaim (ftype function ,(dd-copier-name defstruct))))))
570 ;;; Return a list of function definitions for accessing and setting
571 ;;; the slots of a typed DEFSTRUCT. The functions are proclaimed to be
572 ;;; inline, and the types of their arguments and results are declared
573 ;;; as well. We count on the compiler to do clever things with ELT.
574 (defun typed-accessor-definitions (defstruct)
575 (collect ((stuff))
576 (let ((ltype (dd-lisp-type defstruct)))
577 (dolist (slot (dd-slots defstruct))
578 (let ((name (dsd-accessor-name slot))
579 (index (dsd-index slot))
580 (new-value '(value))
581 (structure '(structure))
582 (slot-type `(and ,(dsd-type slot)
583 ,(dd-%element-type defstruct))))
584 (let ((inherited (accessor-inherited-data name defstruct)))
585 (cond
586 ((not inherited)
587 (stuff `(declaim (inline ,name ,@(unless (dsd-read-only slot)
588 `((setf ,name))))))
589 (stuff `(defun ,name ,structure
590 (declare (type ,ltype . ,structure))
591 (the ,slot-type (elt ,(car structure) ,index))))
592 (unless (dsd-read-only slot)
593 (stuff
594 `(defun (setf ,name) (,(car new-value) . ,structure)
595 (declare (type ,ltype . ,structure) (type ,slot-type . ,new-value))
596 (setf (elt ,(car structure) ,index) . ,new-value)))))
597 ((not (= (cdr inherited) index))
598 (style-warn "~@<Non-overwritten accessor ~S does not access ~
599 slot with name ~S (accessing an inherited slot ~
600 instead).~:@>" name (dsd-name slot))))))))
601 (stuff)))
603 ;;;; parsing
605 ;;; CLHS says that
606 ;;; A defstruct option can be either a keyword or a list of a keyword
607 ;;; and arguments for that keyword; specifying the keyword by itself is
608 ;;; equivalent to specifying a list consisting of the keyword
609 ;;; and no arguments.
610 ;;; It is unclear whether that is meant to imply that any of the keywords
611 ;;; may be present in their atom form, or only if the grammar at the top
612 ;;; shows the atom form does <atom> have the meaning of (<atom>).
613 ;;; At least one other implementation accepts :NAMED as a singleton list.
614 ;; We take a more rigid view that the depicted grammar is exhaustive.
616 (defconstant-eqx +dd-option-names+
617 ;; Each keyword, except :CONSTRUCTOR which may appear more than once,
618 ;; and :NAMED which is trivial, and unambiguous if present more than
619 ;; once, though possibly worth a style-warning.
620 #(:include ; at least 1 argument
621 :initial-offset ; exactly 1 argument
622 :pure ; exactly 1 argument [nonstandard]
623 :type ; exactly 1 argument
624 :conc-name ; 0 or 1 arg
625 :copier ; "
626 :predicate ; "
627 :print-function ; "
628 :print-object) ; "
629 #'equalp)
631 ;;; Parse a single DEFSTRUCT option and store the results in DD.
632 (defun parse-1-dd-option (option dd seen-options)
633 (declare (type (unsigned-byte #.(length +dd-option-names+)) seen-options))
634 (let* ((keyword (first option))
635 (bit (position keyword +dd-option-names+))
636 (args (rest option))
637 (arg-p (consp args))
638 (arg (if arg-p (car args)))
639 (name (dd-name dd)))
640 (declare (type (unsigned-byte 9) seen-options)) ; mask over DD-OPTION-NAMES
641 (when bit
642 (if (logbitp bit seen-options)
643 (error "More than one ~S option is not allowed" keyword)
644 (setf seen-options (logior seen-options (ash 1 bit))))
645 (multiple-value-bind (syntax-group winp)
646 (cond ; Perform checking per comment at +DD-OPTION-NAMES+.
647 ((= bit 0) (values 0 (and arg-p (proper-list-p args)))) ; >1 arg
648 ((< bit 4) (values 1 (and arg-p (not (cdr args))))) ; exactly 1
649 (t (values 2 (or (not args) (singleton-p args))))) ; 0 or 1
650 (unless winp
651 (if (proper-list-p option)
652 (error "DEFSTRUCT option ~S ~[requires at least~;~
653 requires exactly~;accepts at most~] one argument" keyword syntax-group)
654 (error "Invalid syntax in DEFSTRUCT option ~S" option)))))
655 (case keyword
656 (:conc-name
657 ;; unlike (:predicate) and (:copier) which mean "yes" if supplied
658 ;; without their argument, (:conc-name) and :conc-name mean no conc-name.
659 ;; Also note a subtle difference in :conc-name "" vs :conc-name NIL.
660 ;; The former re-interns each slot name into *PACKAGE* which might
661 ;; not be the same as using the given name directly as an accessor.
662 (setf (dd-conc-name dd) (if arg (string arg))))
663 (:constructor ; takes 0 to 2 arguments.
664 (destructuring-bind (&optional (cname (symbolicate "MAKE-" name))
665 (lambda-list nil ll-supplied-p)) args
666 (setf lambda-list
667 (cond ((not cname)
668 ;; Implementations disagree on the meaning of
669 ;; (:CONSTRUCTOR NIL (A B C)).
670 ;; The choices seem to be: don't define a constructor,
671 ;; define a constructor named NIL, signal a user error,
672 ;; or crash the system itself. The spec implies
673 ;; the behavior that we have, but at least a
674 ;; style-warning seems appropriate.
675 (when ll-supplied-p
676 (style-warn "~S does not define a constructor" option)))
677 ((not ll-supplied-p) :default)
679 (multiple-value-call
680 (lambda (&rest x)
681 (declare (dynamic-extent x))
682 (subseq x 0 ; remove trailing NILs
683 (1+ (position-if #'identity x :from-end t))))
684 (parse-lambda-list
685 lambda-list
686 :accept (lambda-list-keyword-mask
687 '(&optional &rest &key &allow-other-keys &aux))
688 :silent t))))
689 (dd-constructors dd) ; preserve order, just because
690 (nconc (dd-constructors dd) (list (cons cname lambda-list))))))
691 (:copier
692 (setf (dd-copier-name dd) (if arg-p arg (symbolicate "COPY-" name))))
693 (:predicate
694 (setf (dd-predicate-name dd) (if arg-p arg (symbolicate name "-P"))))
695 (:include
696 (setf (dd-include dd) args))
697 ((:print-function :print-object)
698 (when (dd-print-option dd)
699 (error "~S and ~S may not both be specified"
700 (dd-print-option dd) keyword))
701 (setf (dd-flags dd) (logior (if (eq keyword :print-object) +dd-printobj+ +dd-printfun+)
702 (dd-flags dd))
703 (dd-printer-fname dd) arg))
704 (:type
705 (cond ((member arg '(list vector))
706 (setf (dd-type dd) arg (dd-%element-type dd) t))
707 ((and (listp arg) (eq (first arg) 'vector))
708 ;; The spec is self-contradictory about this!
709 ;; It defines:
710 ;; type-option::= (:type type)
711 ;; type --- one of the type specifiers list, vector, or (vector size),
712 ;; or some other type specifier defined by the implementation to be appropriate.
713 ;; However the description of the keyword makes it pretty clear that
714 ;; the option's syntax is (vector /element-type/).
715 ;; I'm not sure if it's valid to specify (VECTOR *) as the representation.
716 ;; CLISP thinks it is not, but only signals an error when the constructor
717 ;; is called. So at minimum it's unportable, if not illegal.
718 (destructuring-bind (elt-type) (cdr arg)
719 (setf (dd-type dd) 'vector (dd-%element-type dd) elt-type)))
721 (error "~S is a bad :TYPE for DEFSTRUCT." arg))))
722 (:named
723 (error "The DEFSTRUCT option :NAMED takes no arguments."))
724 (:initial-offset
725 (setf (dd-offset dd) arg)) ; FIXME: disallow (:INITIAL-OFFSET NIL)
726 (:pure
727 (setf (dd-flags dd) (logior (logandc2 (dd-flags dd) +dd-pure+)
728 (if arg +dd-pure+ 0))))
730 (error "unknown DEFSTRUCT option:~% ~S" option)))
731 seen-options))
733 ;;; Parse OPTIONS into the given DD.
734 (defun parse-defstruct-options (options dd)
735 (let ((seen-options 0)
736 (named-p nil))
737 (declare (type (unsigned-byte #.(length +dd-option-names+)) seen-options))
738 (dolist (option options)
739 (if (eq option :named)
740 (setf named-p t
741 (dd-flags dd) (logior (dd-flags dd) +dd-named+))
742 (setq seen-options
743 (parse-1-dd-option
744 (cond ((consp option) option)
745 ((member option
746 '(:conc-name :constructor :copier :predicate))
747 (list option))
749 ;; FIXME: ugly message (defstruct (s :include) a)
750 ;; saying "unrecognized" when it means "bad syntax"
751 (error "unrecognized DEFSTRUCT option: ~S" option)))
752 dd seen-options))))
753 (case (dd-type dd)
754 (structure
755 (when (dd-offset dd)
756 (error ":OFFSET can't be specified unless :TYPE is specified."))
757 #-compact-instance-header
758 (unless (dd-include dd)
759 ;; FIXME: It'd be cleaner to treat no-:INCLUDE as defaulting
760 ;; to :INCLUDE STRUCTURE-OBJECT, and then let the general-case
761 ;; (INCF (DD-LENGTH DD) (DD-LENGTH included-DD)) logic take
762 ;; care of this. (Except that the :TYPE VECTOR and :TYPE
763 ;; LIST cases, with their :NAMED and un-:NAMED flavors,
764 ;; make that messy, alas.)
765 (incf (dd-length dd))))
767 ;; In case we are here, :TYPE is specified.
768 (if named-p
769 ;; CLHS - "The structure can be :named only if the type SYMBOL
770 ;; is a subtype of the supplied element-type."
771 (multiple-value-bind (winp certainp)
772 (subtypep 'symbol (dd-%element-type dd))
773 (when (and (not winp) certainp)
774 (error ":NAMED option is incompatible with element ~
775 type ~/sb-impl:print-type-specifier/"
776 (dd-%element-type dd))))
777 (when (dd-predicate-name dd)
778 (error ":PREDICATE cannot be used with :TYPE ~
779 unless :NAMED is also specified.")))
780 (awhen (dd-print-option dd)
781 (error ":TYPE option precludes specification of ~S option" it))
782 (when named-p
783 (incf (dd-length dd)))
784 (let ((offset (dd-offset dd)))
785 (when offset (incf (dd-length dd) offset)))))
787 (let ((name (dd-name dd)))
788 (collect ((keyword-ctors) (boa-ctors))
789 (let (no-constructors)
790 (dolist (constructor (dd-constructors dd))
791 (destructuring-bind (ctor-name . ll) constructor
792 (cond ((not ctor-name) (setq no-constructors t))
793 ((eq ll :default) (keyword-ctors constructor))
794 (t (boa-ctors constructor)))))
795 ;; Remove (NIL) and sort so that BOA constructors are last.
796 (setf (dd-constructors dd)
797 (if no-constructors
798 (progn
799 (when (or (keyword-ctors) (boa-ctors))
800 (error "(:CONSTRUCTOR NIL) combined with other :CONSTRUCTORs"))
801 nil)
802 (append (or (keyword-ctors)
803 (unless (boa-ctors)
804 `((,(symbolicate "MAKE-" name) . :default))))
805 (boa-ctors))))))
807 ;; POSITION is constant-foldable, but folding happens _after_ transforming to
808 ;; a CASE expression which is surprising. CASE could invoke either POINTERP
809 ;; or NON-NULL-SYMBOL-P would would need to be emulated in the cross-compiler.
810 ;; That's easy to do, but it's even easier to reduce to a constant via macro
811 ;; as it doesn't require the extra support functions.
812 (macrolet ((option-present-p (bit-name)
813 `(logbitp ,(position bit-name +dd-option-names+) seen-options)))
814 (when (and (not (option-present-p :predicate))
815 (or (dd-class-p dd) named-p))
816 (setf (dd-predicate-name dd) (symbolicate name "-P")))
817 (unless (option-present-p :conc-name)
818 (setf (dd-conc-name dd) (string (gensymify* name "-"))))
819 (unless (option-present-p :copier)
820 (setf (dd-copier-name dd) (symbolicate "COPY-" name)))))
821 seen-options))
823 ;;; Given name and options and slot descriptions (and possibly doc
824 ;;; string at the head of slot descriptions) return a DD holding that
825 ;;; info.
826 (defun parse-defstruct (dd options slot-descriptions)
827 (declare (type defstruct-description dd))
828 (let* ((option-bits (parse-defstruct-options options dd))
829 (inherits
830 (if (dd-class-p dd)
831 #+sb-xc-host (!inherits-for-structure dd)
832 #-sb-xc-host
833 (let ((super (compiler-layout-or-lose (or (first (dd-include dd))
834 'structure-object))))
835 (concatenate 'simple-vector
836 (layout-inherits super) (vector super)))))
837 (proto-classoid
838 (if (dd-class-p dd)
839 ;; The classoid needs a layout whereby to convey inheritance.
840 ;; Classoids only store a *direct* superclass list.
841 ;; Both the layout and classoid are throwaway objects.
842 ;; It's probably too dangerous to stack-allocate, because references
843 ;; could leak from the type cache machinery.
844 (let* ((classoid (make-structure-classoid :name (dd-name dd)))
845 (layout (make-temporary-layout (hash-layout-name (dd-name dd))
846 classoid inherits)))
847 (setf (classoid-layout classoid) layout)
848 classoid)))
849 (ancestor-slot-comparator-list))
850 #+sb-xc-host
851 (when (member (dd-name dd) '(pathname logical-pathname))
852 (setf (dd-alternate-metaclass dd) '(t built-in-classoid nil)))
853 ;; Type parsing should be done assuming that prototype classoid
854 ;; exists, which fixes a problem when redefining a DEFTYPE which
855 ;; appeared to be a raw slot. e.g.
856 ;; (DEFTYPE X () 'SINGLE-FLOAT) and later (DEFSTRUCT X (A 0 :TYPE X)).
857 ;; This is probably undefined behavior, but at least we'll not crash.
858 ;; Also make self-referential definitions not signal PARSE-UNKNOWN-TYPE
859 ;; on slots whose :TYPE option allows an instance of itself
860 (when (dd-include dd)
861 (setq ancestor-slot-comparator-list
862 (frob-dd-inclusion-stuff proto-classoid dd option-bits)))
863 (when (stringp (car slot-descriptions))
864 (setf (dd-doc dd) (pop slot-descriptions)))
865 (collect ((comparator-list ancestor-slot-comparator-list))
866 (dolist (slot-description slot-descriptions)
867 (let ((comparator
868 (nth-value 1 (parse-1-dsd proto-classoid dd slot-description))))
869 (comparator-list comparator)))
870 (when (dd-class-p dd)
871 (multiple-value-bind (bitmap any-raw) (calculate-dd-bitmap dd)
872 (when any-raw (setf (dd-%element-type dd) '*))
873 (setf (dd-bitmap dd) bitmap)))
874 (values inherits (comparator-list)))))
876 (defmacro dd-has-raw-slot-p (dd) `(eq (dd-%element-type ,dd) '*))
878 ;;;; stuff to parse slot descriptions
880 ;;; Decide whether TYPE as stored in a structure can be a raw slot.
881 ;;; Return the index of the matching RAW-SLOT-DATA if it should be, NIL if not.
882 (defun choose-raw-slot-representation (ctype)
883 ;; If TYPE isn't a subtype of NUMBER, it can't go in a raw slot.
884 ;; In the negative case (which is most often), doing 1 SUBTYPEP test
885 ;; beats doing 5 or 6.
886 (when (and (csubtypep ctype (specifier-type 'number))
887 ;; FIXNUMs and smaller go in tagged slots, not raw slots
888 (not (csubtypep ctype (specifier-type 'fixnum))))
889 (dotimes (i (length *raw-slot-data*))
890 (let ((data (svref *raw-slot-data* i)))
891 (when (csubtypep ctype (specifier-type (raw-slot-data-raw-type data)))
892 (return i))))))
894 ;;; Parse a slot description for DEFSTRUCT, add it to the description
895 ;;; and return it. If supplied, INCLUDED-SLOT is used to get the default,
896 ;;; type, and read-only flag for the new slot.
897 (defun parse-1-dsd (proto-classoid defstruct spec &optional included-slot
898 &aux accessor-name (always-boundp t) (safe-p t)
899 ctype rsd-index index)
900 #-sb-xc-host (declare (muffle-conditions style-warning))
901 (multiple-value-bind (name default default-p type type-p read-only ro-p)
902 (typecase spec
903 (symbol
904 (typecase spec
905 ((member nil :conc-name :constructor :copier :predicate :named)
906 (warn "slot name of ~S indicates probable syntax error in DEFSTRUCT" spec))
907 (keyword
908 (style-warn "slot name of ~S indicates possible syntax error in DEFSTRUCT" spec)))
909 spec)
910 (cons
911 (destructuring-bind
912 (name &optional (default nil default-p)
913 &key (type nil type-p) (read-only nil ro-p))
914 spec
915 (when (dd-conc-name defstruct)
916 ;; the warning here is useful, but in principle we cannot
917 ;; distinguish between legitimate and erroneous use of
918 ;; these names when :CONC-NAME is NIL. In the common
919 ;; case (CONC-NAME non-NIL), there are alternative ways
920 ;; of writing code with the same effect, so a full
921 ;; warning is justified.
922 (typecase name
923 ((member :conc-name :constructor :copier :predicate :include
924 :print-function :print-object :type :initial-offset :pure)
925 (warn "slot name of ~S indicates probable syntax error in DEFSTRUCT" name))))
926 (values name default default-p
927 (uncross type) type-p
928 read-only ro-p)))
929 (t (%program-error "in DEFSTRUCT, ~S is not a legal slot description."
930 spec)))
932 (when (find name (dd-slots defstruct) :test #'string= :key #'dsd-name)
933 (let* ((parent-name (first (dd-include defstruct)))
934 (parent (and parent-name (find-defstruct-description parent-name)))
935 (included? (and parent (find name
936 (dd-slots parent)
937 :key #'dsd-name
938 :test #'string=))))
939 (if included?
940 (%program-error "slot name ~s duplicated via included ~a"
941 name
942 (dd-name parent))
943 (%program-error "duplicate slot name ~S" name))))
945 (setf accessor-name (if (dd-conc-name defstruct)
946 (symbolicate (dd-conc-name defstruct) name)
947 name))
948 (let ((predicate-name (dd-predicate-name defstruct)))
949 (when (eql accessor-name predicate-name)
950 ;; Some adventurous soul has named a slot so that its accessor
951 ;; collides with the structure type predicate. ANSI doesn't
952 ;; specify what to do in this case. As of 2001-09-04, Martin
953 ;; Atzmueller reports that CLISP and Lispworks both give
954 ;; priority to the slot accessor, so that the predicate is
955 ;; overwritten. We might as well do the same (as well as
956 ;; signalling a warning).
957 (style-warn
958 "~@<The structure accessor name ~S is the same as the name of the ~
959 structure type predicate. ANSI doesn't specify what to do in ~
960 this case. We'll overwrite the type predicate with the slot ~
961 accessor, but you can't rely on this behavior, so it'd be wise to ~
962 remove the ambiguity in your code.~@:>"
963 accessor-name)
964 (setf (dd-predicate-name defstruct) nil))
965 ;; FIXME: It would be good to check for name collisions here, but
966 ;; the easy check,
967 ;;x#-sb-xc-host
968 ;;x(when (and (fboundp accessor-name)
969 ;;x (not (accessor-inherited-data accessor-name defstruct)))
970 ;;x (style-warn "redefining ~/sb-ext:print-symbol-with-prefix/ ~
971 ;; in DEFSTRUCT" accessor-name))
972 ;; which was done until sbcl-0.8.11.18 or so, is wrong: it causes
973 ;; a warning at MACROEXPAND time, when instead the warning should
974 ;; occur not just because the code was constructed, but because it
975 ;; is actually compiled or loaded.
978 (when (and (not default-p) included-slot)
979 (setf default (dsd-default included-slot)))
981 (let ((inherited-type (if included-slot (dsd-type included-slot) t)))
982 (setf type (cond ((not type-p) inherited-type)
983 ((eq inherited-type t) type)
984 (t `(and ,inherited-type ,type)))))
986 #+sb-xc-host
987 ;; Test whether the type can hold NIL. This avoids a bootstrapping
988 ;; problem involving forward references to undefined types,
989 ;; because we want never to pass unknown types into CROSS-TYPEP.
990 ;; But also, don't call SB-XC:TYPEP on a type-specifier because it does
991 ;; not receive a type-context which specifies the proto-classoid.
992 (when (and (typep type '(cons (eql or))) (member 'null type))
993 (setq ctype *universal-type*)) ; a harmless lie
995 (unless ctype
996 (let ((context (make-type-context type proto-classoid
997 +type-parse-cache-inhibit+)))
998 (setq ctype (specifier-type type context)))) ; Parse once only
1000 (cond (included-slot
1001 (cond ((not ro-p)
1002 (setq read-only (dsd-read-only included-slot)))
1003 ((and ro-p (not read-only) (dsd-read-only included-slot))
1004 (error "~@<The slot ~S is :READ-ONLY in superclass, and so must ~
1005 be :READ-ONLY in subclass.~:@>"
1006 name)))
1007 (setf rsd-index (dsd-rsd-index included-slot)
1008 safe-p (dsd-safe-p included-slot)
1009 always-boundp (dsd-always-boundp included-slot)
1010 index (dsd-index included-slot))
1011 (when (and safe-p
1012 (not (equal type (dsd-type included-slot)))
1013 (not (subtypep (dsd-type included-slot) type)))
1014 (setf safe-p nil)))
1016 ;; Compute the index of this DSD. First decide whether the slot is raw.
1017 (setf rsd-index (and (eq (dd-type defstruct) 'structure)
1018 (choose-raw-slot-representation ctype)))
1019 (let ((n-words
1020 (if rsd-index
1021 (let ((rsd (svref *raw-slot-data* rsd-index)))
1022 ;; If slot requires alignment of 2, then ensure that
1023 ;; it has an odd (i.e. doubleword aligned) index.
1024 (when (and (eql (raw-slot-data-alignment rsd) 2)
1025 (evenp (dd-length defstruct)))
1026 (incf (dd-length defstruct)))
1027 (raw-slot-data-n-words rsd))
1028 1)))
1029 (setf index (dd-length defstruct))
1030 (incf (dd-length defstruct) n-words))))
1031 (when (eq ctype *empty-type*)
1032 (with-current-source-form (spec)
1033 (style-warn "The type of the slot ~s is the empty type NIL" name)))
1034 ;; Check for existence of any BOA constructor that leaves the
1035 ;; slot with an unspecified value, as when it's initialized
1036 ;; by an &AUX binding with no value (CLHS 3.4.6)
1037 (when (and always-boundp
1038 (some (lambda (ctor &aux (ll-parts (cdr ctor)))
1039 ;; Keyword constructors store :DEFAULT in the cdr of the cell.
1040 ;; BOA constructors store the parsed lambda list.
1041 (and (listp ll-parts) ; = (llks req opt rest key aux)
1042 (some (lambda (binding)
1043 (and (or (atom binding) (not (cdr binding)))
1044 (string= (if (atom binding) binding (car binding))
1045 name)))
1046 (sixth ll-parts))))
1047 (dd-constructors defstruct)))
1048 (setf always-boundp nil))
1049 (unless always-boundp
1050 ;; FIXME: the :TYPE option should not preclude storing #<unbound>
1051 ;; unless the storage is a specialized numeric vector.
1052 (when (or rsd-index (neq (dd-type defstruct) 'structure))
1053 (setf always-boundp t safe-p nil))) ; "demote" to unsafe.
1055 ;; Check for writable slots in pure structures
1056 #+nil
1057 (when (dd-pure defstruct)
1058 (unless read-only
1059 (format t "~&structure ~s slot ~s is writable" defstruct name)))
1061 (let* ((gc-ignorable
1062 (csubtypep ctype
1063 (specifier-type '(or fixnum boolean character
1064 #+64-bit single-float))))
1065 (dsd (make-dsd name type accessor-name
1066 (pack-dsd-bits index read-only safe-p
1067 always-boundp gc-ignorable
1068 rsd-index)
1069 default)))
1070 (push (cons dsd spec) *dsd-source-form*)
1071 (setf (dd-slots defstruct) (nconc (dd-slots defstruct) (list dsd)))
1072 (let ((comparator
1073 ;; this is enough specialization for now
1074 (cond ((csubtypep ctype (specifier-type 'character)) 'char-equal)
1075 ((csubtypep ctype (specifier-type 'number)) '=)
1076 ((csubtypep ctype (specifier-type 'bit-vector)) 'bit-vector-=)
1077 (t 'equalp))))
1078 (values dsd comparator)))))
1080 (defun typed-structure-info-or-lose (name)
1081 (or (info :typed-structure :info name)
1082 (error ":TYPE'd DEFSTRUCT ~S not found for inclusion." name)))
1084 (defmacro dd-element-type (dd)
1085 `(case (dd-type ,dd)
1086 (vector
1087 ;; %ELEMENT-TYPE might actually be * which is weird
1088 ;; but seems to mostly work. I suspect that it should not.
1089 (dd-%element-type ,dd))
1091 ;; In theory we have the ability to represent that all slots
1092 ;; of a classoid structure are of type SB-VM:WORD (for example),
1093 ;; but in practice that is not useful.
1094 ;; Just don't return * which is not a type specifier.
1095 t)))
1097 ;;; Process any included slots pretty much like they were specified.
1098 ;;; Also inherit various other attributes.
1099 (defun frob-dd-inclusion-stuff (proto-classoid dd option-bits)
1100 (destructuring-bind (included-name &rest modified-slots) (dd-include dd)
1101 (let* ((type (dd-type dd))
1102 (included-structure
1103 (if (dd-class-p dd)
1104 (layout-info (compiler-layout-or-lose included-name))
1105 (typed-structure-info-or-lose included-name))))
1107 ;; checks on legality
1108 (unless (and (eq type (dd-type included-structure))
1109 (type= (specifier-type (dd-element-type included-structure))
1110 (specifier-type (dd-element-type dd))))
1111 (error ":TYPE option mismatch between structures ~S and ~S"
1112 (dd-name dd) included-name))
1113 (let ((included-classoid (find-classoid included-name nil)))
1114 (when included-classoid
1115 ;; It's not particularly well-defined to :INCLUDE any of the
1116 ;; CMU CL INSTANCE weirdosities like CONDITION or
1117 ;; GENERIC-FUNCTION, and it's certainly not ANSI-compliant.
1118 (let* ((included-layout (classoid-layout included-classoid))
1119 (included-dd (layout-dd included-layout)))
1120 (when (dd-alternate-metaclass included-dd)
1121 (error "can't :INCLUDE class ~S (has alternate metaclass)"
1122 included-name)))))
1124 ;; A few more sanity checks: every allegedly modified slot exists
1125 ;; and no name appears more than once.
1126 (flet ((included-slot-name (slot-desc)
1127 (if (atom slot-desc) slot-desc (car slot-desc))))
1128 (mapl (lambda (slots &aux (name (included-slot-name (car slots))))
1129 (unless (find name (dd-slots included-structure)
1130 :test #'string= :key #'dsd-name)
1131 (%program-error "slot name ~S not present in included structure"
1132 name))
1133 (when (find name (cdr slots)
1134 :test #'string= :key #'included-slot-name)
1135 (%program-error "included slot name ~S specified more than once"
1136 name)))
1137 modified-slots))
1139 (incf (dd-length dd) (dd-length included-structure))
1140 (when (dd-class-p dd)
1141 ;; FIXME: This POSITION call should be foldable without read-time eval
1142 ;; since literals are immutable, and +DD-OPTION-NAMES+ was initialized
1143 ;; from a literal.
1144 (when (and (dd-pure included-structure)
1145 (not (logbitp #.(position :pure +dd-option-names+) option-bits)))
1146 (setf (dd-flags dd) (logior (dd-flags dd) +dd-pure+))))
1148 (setf (dd-inherited-accessor-alist dd)
1149 (dd-inherited-accessor-alist included-structure))
1150 (collect ((comparator-list))
1151 (dolist (included-slot (dd-slots included-structure)
1152 (comparator-list))
1153 (let* ((included-name (dsd-name included-slot))
1154 (modified (or (find included-name modified-slots
1155 :key (lambda (x) (if (atom x) x (car x)))
1156 :test #'string=)
1157 `(,included-name))))
1158 ;; We stash away an alist of accessors to parents' slots
1159 ;; that have already been created to avoid conflicts later
1160 ;; so that structures with :INCLUDE and :CONC-NAME (and
1161 ;; other edge cases) can work as specified.
1162 (when (dsd-accessor-name included-slot)
1163 ;; the "oldest" (i.e. highest up the tree of inheritance)
1164 ;; will prevail, so don't push new ones on if they
1165 ;; conflict.
1166 (pushnew (cons (dsd-accessor-name included-slot)
1167 (dsd-index included-slot))
1168 (dd-inherited-accessor-alist dd)
1169 :test #'eq :key #'car))
1170 (multiple-value-bind (new-slot comparator)
1171 (parse-1-dsd proto-classoid dd modified included-slot)
1172 (comparator-list comparator)
1173 (when (and (dsd-safe-p included-slot) (not (dsd-safe-p new-slot)))
1174 ;; XXX: notify?
1175 ))))))))
1177 ;;;; various helper functions for setting up DEFSTRUCTs
1179 ;;; This function is called at macroexpand time to compute the INHERITS
1180 ;;; vector for a structure type definition.
1181 ;;; The cross-compiler is allowed to magically compute LAYOUT-INHERITS.
1182 (defun !inherits-for-structure (info)
1183 (declare (type defstruct-description info))
1184 (let* ((include (dd-include info))
1185 (superclass-opt (dd-alternate-metaclass info))
1186 (super
1187 (if include
1188 (compiler-layout-or-lose (first include))
1189 (classoid-layout (find-classoid
1190 (or (first superclass-opt)
1191 'structure-object))))))
1192 (case (dd-name info)
1193 ((ansi-stream)
1194 ;; STREAM is an abstract class and you can't :include it,
1195 ;; so the inheritance has to be hardcoded.
1196 (concatenate 'simple-vector
1197 (layout-inherits super)
1198 (vector super (classoid-layout (find-classoid 'stream)))))
1199 ((fd-stream) ; Similarly, FILE-STREAM is abstract
1200 (concatenate 'simple-vector
1201 (layout-inherits super)
1202 (vector super
1203 (classoid-layout (find-classoid 'file-stream)))))
1204 ((sb-impl::string-input-stream ; etc
1205 sb-impl::string-output-stream
1206 sb-impl::fill-pointer-output-stream)
1207 (concatenate 'simple-vector
1208 (layout-inherits super)
1209 (vector super
1210 (classoid-layout (find-classoid 'string-stream)))))
1211 (pathname (vector (find-layout 't)))
1212 (logical-pathname (vector (find-layout 't) (find-layout 'pathname)))
1213 (t (concatenate 'simple-vector
1214 (layout-inherits super)
1215 (vector super))))))
1217 ;;; Do miscellaneous (LOAD EVAL) time actions for the structure
1218 ;;; described by DD. Create the class and LAYOUT, checking for
1219 ;;; incompatible redefinition.
1220 (defun %defstruct (dd inherits source-location)
1221 (declare (type defstruct-description dd))
1223 ;; We set up LAYOUTs even in the cross-compilation host.
1224 (multiple-value-bind (classoid layout old-layout)
1225 (ensure-structure-class dd inherits "current" "new")
1226 (cond ((not old-layout)
1227 (unless (eq (classoid-layout classoid) layout)
1228 (register-layout layout)))
1230 (%redefine-defstruct classoid old-layout layout)
1231 (let ((old-dd (layout-info old-layout)))
1232 (when (defstruct-description-p old-dd)
1233 (dolist (slot (dd-slots old-dd))
1234 (fmakunbound (dsd-accessor-name slot))
1235 (unless (dsd-read-only slot)
1236 (fmakunbound `(setf ,(dsd-accessor-name slot)))))))
1237 (setq layout (classoid-layout classoid))))
1238 ;; Don't want to (setf find-classoid) on a a built-in-classoid
1239 (unless (and (built-in-classoid-p classoid)
1240 (eq (find-classoid (dd-name dd) nil) classoid))
1241 (setf (find-classoid (dd-name dd)) classoid))
1243 (when source-location
1244 (setf (classoid-source-location classoid) source-location))))
1247 ;;; Return the transform of OPERATION which is either :READ or :SETF.
1248 ;;; as applied to ARGS, given SLOT-KEY which is a cons of a DD and a DSD.
1249 ;;; FUN-OR-MACRO, which is used only for the :SETF operation,
1250 ;;; indicates whether the argument order corresponds to
1251 ;;; (funcall #'(setf mystruct-myslot) newval s) ; :FUNCTION
1252 ;;; versus
1253 ;;; (setf (mystruct-myslot s) newval) ; :MACRO
1254 ;;; Return NIL on failure.
1255 (defun slot-access-transform (operation args slot-key
1256 &optional
1257 (fun-or-macro :macro)
1258 (external-unbound-handling nil))
1259 (binding* ((dd (car slot-key))
1260 (dsd (cdr slot-key))
1261 ((reader writer) (dsd-reader dsd (neq (dd-type dd) 'structure)))
1262 (type-spec (dsd-type dsd))
1263 (index (dsd-index dsd)))
1264 (ecase operation
1265 (:read
1266 (when (singleton-p args)
1267 (let* ((instance-form `(the ,(dd-name dd) ,(car args)))
1268 (place `(,reader ,instance-form ,index)))
1269 ;; There are 4 cases of {safe,unsafe} x {always-boundp,possibly-unbound}
1270 ;; If unsafe - which implies TYPE-SPEC other than type T - then we must
1271 ;; check the type on each read. Assuming that type-checks reject
1272 ;; the unbound-marker, then we needn't separately check for it, but if
1273 ;; we're generating code fragments for CLOS (which does its own
1274 ;; EXTERNAL-UNBOUND-HANDLING) we need to let it through explicitly.
1275 (cond ((not (dsd-safe-p dsd))
1276 (when (and (not (dsd-always-boundp dsd)) external-unbound-handling)
1277 (setq type-spec `(or ,type-spec (satisfies sb-vm::unbound-marker-p))))
1278 `(the ,type-spec ,place))
1280 ;; unless the slot is always bound, or unbound handling is external,
1281 ;; check here for unbound marker.
1282 (unless (or (dsd-always-boundp dsd) external-unbound-handling)
1283 (setf place
1284 `(the* ((not (satisfies sb-vm::unbound-marker-p))
1285 :context (struct-read-context ,(dd-name dd) . ,(dsd-name dsd)))
1286 ,place)))
1287 (cond
1288 ((eq type-spec t) place)
1290 (when (and (not (dsd-always-boundp dsd)) external-unbound-handling)
1291 (setq type-spec `(or ,type-spec (satisfies sb-vm::unbound-marker-p))))
1292 `(the* (,type-spec :derive-type-only t) ,place))))))))
1293 (:setf
1294 ;; The primitive object slot setting vops take newval last, which matches
1295 ;; the order in which a use of SETF has them, but because the vops
1296 ;; do not return anything, we have to bind both arguments.
1297 (when (and (listp args) (singleton-p (cdr args)))
1298 (multiple-value-bind (newval-form instance-form)
1299 (ecase fun-or-macro
1300 (:function (values (first args) (second args)))
1301 (:macro (values (second args) (first args))))
1302 (if (eq fun-or-macro :function)
1303 ;; This used only for source-transforming (funcall #'(setf myslot) ...).
1304 ;; (SETF x) writer functions have been defined as source-transforms instead of
1305 ;; inline functions, which improved the semantics around clobbering defstruct
1306 ;; writers with random DEFUNs either deliberately or accidentally.
1307 ;; Since users can't define source-transforms (not portably anyway),
1308 ;; we can easily discern which functions were system-generated.
1309 `(let ((#2=#:val
1310 #4=,(cond
1311 ((eq type-spec t) newval-form)
1313 (unless (or (dsd-always-boundp dsd) (not external-unbound-handling))
1314 (setq type-spec `(or ,type-spec (satisfies sb-vm::unbound-marker-p))))
1315 `(the* (,type-spec :context (struct-context ,(dd-name dd) . ,(dsd-name dsd)))
1316 ,newval-form))))
1317 (#1=#:instance #3=(the ,(dd-name dd) ,instance-form)))
1318 (,writer #1# ,index #2#)
1319 #2#)
1320 `(let ((#1# #3#) (#2# #4#)) (,writer #1# ,index #2#) #2#))))))))
1322 ;;; Apply TRANSFORM - a special indicator stored in :SOURCE-TRANSFORM
1323 ;;; for a DEFSTRUCT copier, accessor, or predicate - to SEXPR.
1324 ;;; NAME is needed to select between the reader and writer transform.
1325 (defun sb-c::struct-fun-transform (transform sexpr name)
1326 (let* ((snippet (cdr transform))
1327 (result
1328 (cond ((eq snippet :constructor)
1329 ;; All defstruct-defined things use the :source-transform as
1330 ;; an indicator of magic-ness, but actually doing the transform
1331 ;; for constructors could cause inadvertent variable capture.
1332 nil)
1333 ((symbolp snippet) ; predicate or copier
1334 (when (singleton-p (cdr sexpr)) ; exactly 1 arg
1335 (let ((type (dd-name (car transform)))
1336 (arg (cadr sexpr)))
1337 (ecase snippet
1338 (:predicate `(sb-c::%instance-typep ,arg ',type))
1339 (:copier `(copy-structure (the ,type ,arg)))))))
1341 (slot-access-transform (if (consp name) :setf :read)
1342 (cdr sexpr) transform :function)))))
1343 (values result (not result))))
1345 ;;; Blow away all the compiler info for the structure CLASS. Iterate
1346 ;;; over this type, clearing the compiler structure type info, and
1347 ;;; undefining all the associated functions. If SUBCLASSES-P, also do
1348 ;;; the same for subclasses. FIXME: maybe rename UNDEFINE-FUN-NAME to
1349 ;;; UNDECLARE-FUNCTION-NAME?
1350 (defun undeclare-structure (classoid subclasses-p)
1351 (let ((info (layout-%info (classoid-layout classoid))))
1352 (when (defstruct-description-p info)
1353 (let ((type (dd-name info)))
1354 (clear-info :type :compiler-layout type)
1355 ;; FIXME: shouldn't this undeclare any constructors too?
1356 (undefine-fun-name (dd-copier-name info))
1357 (undefine-fun-name (dd-predicate-name info))
1358 (dolist (slot (dd-slots info))
1359 (let ((fun (dsd-accessor-name slot)))
1360 (unless (accessor-inherited-data fun info)
1361 (undefine-fun-name fun)
1362 (unless (dsd-read-only slot)
1363 (undefine-fun-name `(setf ,fun)))))))
1364 ;; Clear out the SPECIFIER-TYPE cache so that subsequent
1365 ;; references are unknown types.
1366 (values-specifier-type-cache-clear)))
1367 (when subclasses-p
1368 (collect ((subs))
1369 (do-subclassoids ((classoid layout) classoid)
1370 (declare (ignore layout))
1371 (undeclare-structure classoid nil)
1372 (subs (classoid-proper-name classoid)))
1373 ;; Is it really necessary to warn about
1374 ;; undeclaring functions for subclasses?
1375 (when (subs)
1376 (warn "undeclaring functions for old subclasses of ~S:~% ~S"
1377 (classoid-name classoid) (subs))))))
1379 ;;; core compile-time setup of any class with a LAYOUT, used even by
1380 ;;; !DEFSTRUCT-WITH-ALTERNATE-METACLASS weirdosities
1381 (defun %compiler-set-up-layout (dd inherits)
1382 (multiple-value-bind (classoid layout old-layout)
1383 (multiple-value-bind (clayout clayout-p)
1384 (info :type :compiler-layout (dd-name dd))
1385 (ensure-structure-class dd
1386 inherits
1387 (if clayout-p
1388 "The most recently compiled"
1389 "The current")
1390 "the most recently loaded"
1391 :compiler-layout clayout))
1392 (cond (old-layout
1393 (undeclare-structure (layout-classoid old-layout)
1394 (and (classoid-subclasses classoid)
1395 (not (eq layout old-layout))))
1396 (setf (layout-invalid layout) nil)
1397 ;; FIXME: it might be polite to hold onto old-layout and
1398 ;; restore it at the end of the file. -- RMK 2008-09-19
1399 ;; (International Talk Like a Pirate Day).
1400 (warn "~@<Clobbering the compiler's idea of the layout of ~A.~:@>"
1401 classoid))
1403 (unless (eq (classoid-layout classoid) layout)
1404 (register-layout layout :invalidate nil))
1405 ;; Don't want to (setf find-classoid) on a a built-in-classoid
1406 (unless (and (built-in-classoid-p classoid)
1407 (eq (find-classoid (dd-name dd) nil) classoid))
1408 (setf (find-classoid (dd-name dd)) classoid))))
1410 ;; At this point the class should be set up in the INFO database.
1411 ;; But the logic that enforces this is a little tangled and
1412 ;; scattered, so it's not obvious, so let's check.
1413 (aver (find-classoid (dd-name dd) nil))
1415 (setf (info :type :compiler-layout (dd-name dd)) layout))
1416 (values))
1418 (defun %proclaim-defstruct-ctors (dd)
1419 (aver (not (dd-class-p dd)))
1420 (let ((info `(,dd . :constructor)))
1421 (dolist (ctor (dd-constructors dd))
1422 (setf (info :function :source-transform (car ctor)) info))))
1424 ;;; Do (COMPILE LOAD EVAL)-time actions for the structure described by DD
1425 ;;; which may be a "normal" defstruct or an alternate-metaclass struct.
1426 ;;; This includes generation of a style-warning about previously compiled
1427 ;;; calls to the accessors and/or predicate that weren't inlined.
1428 (defun %compiler-defstruct (dd inherits)
1429 (declare (type defstruct-description dd))
1431 (aver (dd-class-p dd)) ; LIST and VECTOR representation are not allowed
1432 (let ((check-inlining
1433 ;; Why use the secondary result of INFO, not the primary?
1434 ;; Because when DEFSTRUCT is evaluated, not via the file-compiler,
1435 ;; the first thing to happen is %DEFSTRUCT, which sets up FIND-CLASS.
1436 ;; Due to :COMPILER-LAYOUT's defaulting expression in globaldb,
1437 ;; it has a value - the layout of the classoid - that we don't want.
1438 ;; Also, since structures are technically not redefineable,
1439 ;; I don't worry about failure to inline a function that was
1440 ;; formerly not known as an accessor but now is.
1441 (null (nth-value 1 (info :type :compiler-layout (dd-name dd)))))
1442 (fnames))
1443 (%compiler-set-up-layout dd inherits)
1444 (let ((xform `(,dd . :constructor)))
1445 (dolist (ctor (dd-constructors dd))
1446 ;; Don't check-inlining because ctors aren't always inlined
1447 (setf (info :function :source-transform (car ctor)) xform)))
1448 (awhen (dd-copier-name dd)
1449 (when check-inlining (push it fnames))
1450 (setf (info :function :source-transform it) (cons dd :copier)))
1451 (awhen (dd-predicate-name dd)
1452 (when check-inlining (push it fnames))
1453 (setf (info :function :source-transform it) (cons dd :predicate)))
1455 (dolist (dsd (dd-slots dd))
1456 (let ((accessor-name (dsd-accessor-name dsd)))
1457 ;; Why this WHEN guard here, if there is neither a standards-specified
1458 ;; nor implementation-specific way to skip defining an accessor? Dunno.
1459 ;; And furthermore, by ignoring a package lock, it's possible to name
1460 ;; an accessor NIL: (defstruct (x (:conc-name "N")) IL)
1461 ;; making this test kinda bogus in two different ways.
1462 (when accessor-name
1463 (let ((inherited (accessor-inherited-data accessor-name dd)))
1464 (cond
1465 ((not inherited)
1466 (let ((writer `(setf ,accessor-name))
1467 (slot-key (cons dd dsd)))
1468 (when check-inlining
1469 (push accessor-name fnames))
1470 (setf (info :function :source-transform accessor-name)
1471 slot-key)
1472 (unless (dsd-read-only dsd)
1473 (when check-inlining
1474 (push writer fnames))
1475 (setf (info :function :source-transform writer) slot-key))))
1476 ((not (= (cdr inherited) (dsd-index dsd)))
1477 (style-warn "~@<Non-overwritten accessor ~S does not access ~
1478 slot with name ~S (accessing an inherited slot ~
1479 instead).~:@>"
1480 accessor-name
1481 (dsd-name dsd))))))))
1483 (awhen (remove-if-not #'sb-c::emitted-full-call-count fnames)
1484 (sb-c:compiler-style-warn
1485 'sb-c:inlining-dependency-failure
1486 ;; This message omits the http://en.wikipedia.org/wiki/Serial_comma
1487 :format-control "~@<Previously compiled call~P to ~
1488 ~{~/sb-ext:print-symbol-with-prefix/~^~#[~; and~:;,~] ~} ~
1489 could not be inlined because the structure definition for ~
1490 ~/sb-ext:print-symbol-with-prefix/ was not yet seen. To avoid this warning, ~
1491 DEFSTRUCT should precede references to the affected functions, ~
1492 or they must be declared locally notinline at each call site.~@:>"
1493 :format-arguments (list (length it) (nreverse it) (dd-name dd))))))
1495 ;;;; redefinition stuff
1497 ;;; Compare the slots of OLD and NEW, returning 3 lists of slot names:
1498 ;;; 1. Slots which have moved,
1499 ;;; 2. Slots whose type has changed,
1500 ;;; 3. Deleted slots.
1501 (defun compare-slots (old new)
1502 (let* ((oslots (dd-slots old))
1503 (nslots (dd-slots new))
1504 (onames (mapcar #'dsd-name oslots))
1505 (nnames (mapcar #'dsd-name nslots)))
1506 (collect ((moved)
1507 (retyped))
1508 (dolist (name (intersection onames nnames))
1509 (let ((os (find name oslots :key #'dsd-name :test #'string=))
1510 (ns (find name nslots :key #'dsd-name :test #'string=)))
1511 (unless (subtypep (dsd-type ns) (dsd-type os))
1512 (retyped name))
1513 (unless (and (= (dsd-index os) (dsd-index ns))
1514 (eq (dsd-raw-type os) (dsd-raw-type ns)))
1515 (moved name))))
1516 (values (moved)
1517 (retyped)
1518 (set-difference onames nnames :test #'string=)))))
1520 ;;; If we are redefining a structure with different slots than in the
1521 ;;; currently loaded version, give a warning and return true.
1522 (defun redefine-structure-warning (classoid old new)
1523 (declare (type defstruct-description old new)
1524 (type classoid classoid)
1525 (ignore classoid))
1526 (let ((name (dd-name new)))
1527 (multiple-value-bind (moved retyped deleted) (compare-slots old new)
1528 (when (or moved retyped deleted)
1529 (warn
1530 "incompatibly redefining slots of structure class ~S~@
1531 Make sure any uses of affected accessors are recompiled:~@
1532 ~@[ These slots were moved to new positions:~% ~S~%~]~
1533 ~@[ These slots have new incompatible types:~% ~S~%~]~
1534 ~@[ These slots were deleted:~% ~S~%~]"
1535 name moved retyped deleted)
1536 t))))
1538 ;;; Return true if destructively modifying OLD-LAYOUT into NEW-LAYOUT
1539 ;;; would be possible in as much as it won't harm the garbage collector.
1540 ;;; Harm potentially results from turning a raw word into a tagged word.
1541 ;;; There are additional mutations which would be permissible but don't
1542 ;;; strike me as important - e.g. permitting a fixnum slot to become type T
1543 ;;; is permissible, but the fixnum may or may not be marked as tagged
1544 ;;; in the bitmap, depending on whether any raw slot exists.
1545 ;;; I can't imagine that many users will complain that they can no longer
1546 ;;; incompatibly redefine defstructs involving raw slots.
1547 ;;; Additionally, it is no longer possible to RECKLESSLY-CONTINUE on a defstruct
1548 ;;; if the number of words in the layout would differ due to extra ID words,
1549 ;;; but given that it was already not possible if the bitmaps differ,
1550 ;;; it does not seem a big sacrifice to disallow redefining structures
1551 ;;; at depthoids in excess of 7 (LAYOUT-ID-VECTOR-FIXED-CAPACITY) unless
1552 ;;; both the old and new structure are at the same depthoid.
1553 #-sb-xc-host
1554 (defun mutable-layout-p (old-layout new-layout)
1555 (declare (type layout old-layout new-layout))
1556 (if (layout-info old-layout)
1557 (let ((old-bitmap (%layout-bitmap old-layout))
1558 (new-bitmap (%layout-bitmap new-layout)))
1559 ;; The number of extra ID words has to match, as does the number of bitmap
1560 ;; words, or else GC will croak when parsing the bitmap.
1561 (and (= (calculate-extra-id-words (layout-depthoid old-layout))
1562 (calculate-extra-id-words (layout-depthoid new-layout)))
1563 (= (bitmap-nwords new-layout)
1564 (bitmap-nwords old-layout))
1565 (dotimes (i (dd-length (layout-dd old-layout)) t)
1566 (when (and (logbitp i new-bitmap) ; a tagged (i.e. scavenged) slot
1567 (not (logbitp i old-bitmap))) ; that was opaque bits
1568 (return nil)))))
1571 ;;; This function is called when we are incompatibly redefining a
1572 ;;; structure CLASS to have the specified NEW-LAYOUT. We signal an
1573 ;;; error with some proceed options and return the layout that should
1574 ;;; be used.
1575 (defun %redefine-defstruct (classoid old-layout new-layout)
1576 (declare (type classoid classoid)
1577 (type layout old-layout new-layout))
1578 (declare (ignorable old-layout)) ; for host
1579 (let ((name (classoid-proper-name classoid)))
1580 (restart-case
1581 (error "~@<attempt to redefine the ~S class ~S incompatibly with the current definition~:@>"
1582 'structure-object
1583 name)
1584 (continue ()
1585 :report (lambda (s)
1586 (format s
1587 "~@<Use the new definition of ~S, invalidating ~
1588 already-loaded code and instances.~@:>"
1589 name))
1590 (register-layout new-layout))
1591 #-sb-xc-host
1592 (recklessly-continue ()
1593 :test (lambda (c)
1594 (declare (ignore c))
1595 (mutable-layout-p old-layout new-layout))
1596 :report (lambda (s)
1597 (format s
1598 "~@<Use the new definition of ~S as if it were ~
1599 compatible, allowing old accessors to use new ~
1600 instances and allowing new accessors to use old ~
1601 instances.~@:>"
1602 name))
1603 ;; classic CMU CL warning: "Any old ~S instances will be in a bad way.
1604 ;; I hope you know what you're doing..."
1605 (register-layout new-layout
1606 :invalidate nil
1607 :destruct-layout old-layout))))
1608 (values))
1610 (defun dd-custom-gc-method-p (dd)
1611 (cond ((eq (dd-name dd) 'sb-lockless::list-node) t)
1612 ((dd-include dd)
1613 (dd-custom-gc-method-p
1614 (layout-info (compiler-layout-or-lose (car (dd-include dd))))))))
1616 ;;; Compute DD's bitmap, storing 1 for each tagged word.
1617 ;;; The GC can parse signed fixnums and bignums, with which we can
1618 ;;; represent an unlimited number of "&rest" slots all with the same
1619 ;;; nature - tagged or raw. If REST is :TAGGED or :UNTAGGED, it
1620 ;;; specifies a particular nature. If :UNSPECIFIC, then we sign-extend
1621 ;;; from the last specified slot which tends to reduce the bitmap to
1622 ;;; -1 in the case of everything being tagged, (or -2 if non-compact
1623 ;;; header), or a small positive fixnum if the last is untagged.
1625 ;;; Bit indices correspond to physical word indices excluding
1626 ;;; the header word. So the least-significant bit of a bitmap is
1627 ;;; always the word just after the instance header word.
1629 ;;; Examples: (Legend: u=untaggged slot, t=tagged slot)
1631 ;;; logical arithmetic
1632 ;;; bitmap value
1633 ;;; Funcallable object:
1634 ;;; Executable w/ standard header: #b.101000 -24
1635 ;;; word0: header
1636 ;;; word1: (*) entry address
1637 ;;; word2: (u) machine instructions
1638 ;;; word3: (u) machine instructions
1639 ;;; word4: (t) implementation-fun
1640 ;;; word5: (u) layout
1641 ;;; word6: (t) tagged slots ...
1642 ;;; Executable w/ compact header: #b...1000 -8
1643 ;;; word0: header/layout
1644 ;;; word1: (*) entry address
1645 ;;; word2: (u) machine instructions
1646 ;;; word3: (u) machine instructions
1647 ;;; word4: (t) implementation-fun
1648 ;;; word5: (t) tagged slots ...
1649 ;;; Non-executable: #b...1010 -6
1650 ;;; word0: header
1651 ;;; word1: (*) entry address
1652 ;;; word2: (t) implementation-fun
1653 ;;; word3: (u) layout
1654 ;;; word4: (t) tagged slots ...
1655 ;;; (*) entry address can be treated as either tagged or raw.
1656 ;;; For some architectures it has a lowtag, but points to
1657 ;;; read-only space. For others it is a fixnum.
1658 ;;; In either case the GC need not observe the value.
1659 (defconstant funinstance-layout-bitmap
1660 #-executable-funinstances -6
1661 #+(and executable-funinstances (not compact-instance-header)) -24
1662 #+(and executable-funinstances compact-instance-header) -8)
1665 ;;; Ordinary instance with only tagged slots:
1666 ;;; Non-compact header: #b...1110 -2
1667 ;;; word0: header
1668 ;;; word1: (u) layout
1669 ;;; word2: (t) tagged slots ...
1670 ;;; Compact header: #b...1111 -1
1671 ;;; word0: header/layout
1672 ;;; word1: (t) tagged slots ...
1673 ;;; Ordinary instance with only raw slots slots:
1674 ;;; [this also includes objects whose slots all have types
1675 ;;; ignorable by GC such as fixum/character]
1676 ;;; Non-compact header: #b...0000 0
1677 ;;; word0: header
1678 ;;; word1: (u) layout
1679 ;;; word2: (u) raw slots ...
1680 ;;; Compact header: #b...0000 0
1681 ;;; word0: header/layout
1682 ;;; word1: (u) raw slots ...
1684 ;;; Notes:
1685 ;;; 1. LAYOUT has to be scanned separately regardless of where stored.
1686 ;;; (compact header or not). Hence it is regarded as an untagged slot.
1687 ;;; 2. For funcallable objects these examples are exhaustive of all
1688 ;;; possible bitmaps. The instance length can be anything,
1689 ;;; but untagged slots are not generally supported.
1690 ;;; For ordinary instance the examples are merely illustrative.
1692 (defun calculate-dd-bitmap (dd &optional (rest :unspecific))
1693 (declare (type (member :unspecific :tagged :untagged) rest))
1694 #+sb-xc-host
1695 (when (eq (dd-name dd) 'layout)
1696 (setf rest :untagged))
1697 (when (eq (car (dd-alternate-metaclass dd)) 'function)
1698 (return-from calculate-dd-bitmap funinstance-layout-bitmap))
1699 ;; Compute two masks with a 1 bit for each dsd-index which contains a descriptor.
1700 ;; The "mininal" bitmap contains a 1 for each slot which *must* be scanned in GC,
1701 ;; and the "maximal" bitmap contains a 1 for each which *may* be scanned.
1702 ;; If a non-raw slot type can be ignored - such as (OR FIXNUM NULL), then it
1703 ;; sets a 1 in the maximal bitmap but not in the minimal bitmap.
1704 ;; Note that the GC can always add one slot for a stable hash, but that slot
1705 ;; can only hold a fixnum, so need not be traced even though it is a descriptor.
1706 (let ((n-bits (dd-length dd))
1707 (any-raw)
1708 (maximal-bitmap 0)
1709 (minimal-bitmap 0))
1710 (dolist (slot (dd-slots dd))
1711 (cond ((eql t (dsd-raw-type slot))
1712 (let ((bit (ash 1 (dsd-index slot))))
1713 (setf maximal-bitmap (logior maximal-bitmap bit))
1714 (unless (dsd-gc-ignorable slot)
1715 (setf minimal-bitmap (logior minimal-bitmap bit)))))
1717 (setq any-raw t))))
1719 ;; If the structure has a custom GC scavenging method then always return
1720 ;; the minimal bitmap, and disallow arbitrary trailing slots.
1721 ;; The optimization for all-tagged (avoiding use of the bitmap)
1722 ;; indicates in addition to no raw slots, no custom GC method either.
1723 ;; As of now this only pertains to lockfree-singly-linked-list nodes
1724 ;; and descendant types. (The lockfree list uses one pointer bit
1725 ;; as a pending-deletion flag. See "src/code/target-lflist.lisp")
1726 (when (dd-custom-gc-method-p dd)
1727 (aver (eq rest :unspecific))
1728 ;; Pretend there are raw slots so that the layout
1729 ;; does not get the STRICTLY-BOXED flag set.
1730 (return-from calculate-dd-bitmap (values minimal-bitmap t)))
1732 ;; The minimal bitmap will have the least number of bits set, and the maximal
1733 ;; will have the most, but it is not always a performance improvement to prefer
1734 ;; fewer bits. If the total number of bits is large, and there are no raw slots,
1735 ;; then the "all tagged" treatment may be better because it does not need to
1736 ;; parse the bitmap. But if there are any raw slots, the minimal bitmap is best.
1737 (let ((bitmap
1738 (if (or (= minimal-bitmap 0) ; don't need a bitmap
1739 any-raw ; must use a bitmap
1740 ;; for other cases, it is not clear-cut
1741 (and (> (logcount maximal-bitmap) 10) ; arb
1742 (< (logcount minimal-bitmap)
1743 (floor (logcount maximal-bitmap) 2))))
1744 minimal-bitmap
1745 maximal-bitmap)))
1747 ;; If the trailing slots have tagged nature, extend bitmap with
1748 ;; an infinite sequence of 1 bits. If :UNSPECIFIC, replicate
1749 ;; the most-significant-bit whether it be 0 or 1.
1750 (values (cond ((or (eq rest :tagged)
1751 (and (eq rest :unspecific)
1752 (plusp n-bits)
1753 (logbitp (1- n-bits) bitmap)))
1754 (dpb bitmap (byte n-bits 0) -1))
1756 bitmap))
1757 any-raw))))
1759 ;;; This is called when we are about to define a structure class. It
1760 ;;; returns a (possibly new) class object and the layout which should
1761 ;;; be used for the new definition (may be the current layout, and
1762 ;;; also might be an uninstalled forward referenced layout.) The third
1763 ;;; value is true if this is an incompatible redefinition, in which
1764 ;;; case it is the old layout.
1765 (defun ensure-structure-class (info inherits old-context new-context
1766 &key compiler-layout
1767 &aux (flags 0))
1768 (declare (type defstruct-description info))
1769 (multiple-value-bind (classoid old-layout)
1770 (multiple-value-bind (class constructor)
1771 (acond ((cdr (dd-alternate-metaclass info))
1772 (values (first it) (second it)))
1774 (values 'structure-classoid 'make-structure-classoid)))
1775 (insured-find-classoid (dd-name info)
1776 (ecase class
1777 (structure-classoid #'structure-classoid-p)
1778 (built-in-classoid #'built-in-classoid-p)
1779 (static-classoid #'static-classoid-p)
1780 (condition-classoid #'condition-classoid-p))
1781 constructor))
1782 (setf (classoid-direct-superclasses classoid)
1783 (case (dd-name info)
1784 ;; Argh, could this case be any more opaque???
1785 ;; It's ostensibly the set of types whose superclasse would come out wrong
1786 ;; if we didn't fudge them manually. But the computation of the superclass
1787 ;; list is obfuscated. I think we have assertions about this somewhere.
1788 ;; But ideally we remove this junky case from the target image somehow
1789 ;; while leaving it in for self-build.
1790 ((ansi-stream
1791 fd-stream
1792 sb-impl::string-input-stream sb-impl::string-output-stream
1793 sb-impl::fill-pointer-output-stream)
1794 (list (layout-classoid (svref inherits (1- (length inherits))))
1795 (layout-classoid (svref inherits (- (length inherits) 2)))))
1797 (list (layout-classoid
1798 (svref inherits (1- (length inherits))))))))
1799 (unless (dd-alternate-metaclass info)
1800 (setq flags +structure-layout-flag+))
1801 (cond ((some #'dsd-rsd-index (dd-slots info))) ; mixed boxed + raw (or wholly raw)
1802 ((and (not (dd-alternate-metaclass info))
1803 (not (dd-custom-gc-method-p info)))
1804 (setf flags (logior flags +strictly-boxed-flag+))))
1805 ;; FIXME: explain why this is #-sb-xc-host.
1806 #-sb-xc-host
1807 (dovector (ancestor inherits)
1808 (setq flags (logior (logand (logior +stream-layout-flag+
1809 +file-stream-layout-flag+
1810 +string-stream-layout-flag+)
1811 (layout-flags ancestor))
1812 flags)))
1813 (let* ((old-layout (or compiler-layout old-layout))
1814 (new-layout
1815 (when (or (not old-layout) *type-system-initialized*)
1816 (make-layout (hash-layout-name (dd-name info))
1817 classoid
1818 :flags flags
1819 :inherits inherits
1820 :depthoid (length inherits)
1821 :length (dd-length info)
1822 :info info))))
1823 (cond
1824 ((not old-layout)
1825 (values classoid new-layout nil))
1826 ((not new-layout)
1827 ;; The assignment of INFO here can almost be deleted,
1828 ;; except for a few magical types that don't d.t.r.t. in cold-init:
1829 ;; STRUCTURE-OBJECT, CONDITION, ALIEN-VALUE, INTERPRETED-FUNCTION
1830 (setf (layout-info old-layout) info)
1831 (values classoid old-layout nil))
1832 (;; This clause corresponds to an assertion in REDEFINE-LAYOUT-WARNING
1833 ;; of classic CMU CL. I moved it out to here because it was only
1834 ;; exercised in this code path anyway. -- WHN 19990510
1835 (not (eq (layout-classoid new-layout) (layout-classoid old-layout)))
1836 (error "shouldn't happen: weird state of OLD-LAYOUT?"))
1837 ((warn-if-altered-layout old-context
1838 old-layout
1839 new-context
1840 (layout-length new-layout)
1841 (layout-inherits new-layout)
1842 (layout-depthoid new-layout)
1843 (layout-bitmap new-layout))
1844 (values classoid new-layout old-layout))
1846 (let ((old-info (layout-info old-layout)))
1847 (if old-info
1848 (cond ((redefine-structure-warning classoid old-info info)
1849 (values classoid new-layout old-layout))
1851 (setf (layout-info old-layout) info)
1852 (values classoid old-layout nil)))
1853 (progn
1854 (setf (layout-info old-layout) info)
1855 (values classoid old-layout nil)))))))))
1857 ;;; Return a list of pairs (name . index). Used for :TYPE'd
1858 ;;; constructors to find all the names that we have to splice in &
1859 ;;; where. Note that these types don't have a layout, so we can't look
1860 ;;; at LAYOUT-INHERITS.
1861 (defun find-name-indices (defstruct)
1862 (collect ((res))
1863 (let ((infos ()))
1864 (do ((info defstruct
1865 (typed-structure-info-or-lose (first (dd-include info)))))
1866 ((not (dd-include info))
1867 (push info infos))
1868 (push info infos))
1870 (let ((i 0))
1871 (dolist (info infos)
1872 (incf i (or (dd-offset info) 0))
1873 (when (dd-named info)
1874 (res (cons (dd-name info) i)))
1875 (setq i (dd-length info)))))
1877 (res)))
1879 ;;; These functions are called to actually make a constructor after we
1880 ;;; have processed the arglist. The correct variant (according to the
1881 ;;; DD-TYPE) should be called. The function is defined with the
1882 ;;; specified name and arglist. VARS and TYPES are used for argument
1883 ;;; type declarations. VALUES are the values for the slots (in order.)
1885 ;;; This is split into two functions:
1886 ;;; * INSTANCE-CONSTRUCTOR-FORM has to deal with raw slots
1887 ;;; * TYPED-CONSTRUCTOR-FORM deal with LIST & VECTOR
1888 ;;; which might have "name" symbols stuck in at various weird places.
1889 (defun instance-constructor-form (dd values &aux (dd-slots (dd-slots dd)))
1890 (aver (= (length dd-slots) (length values)))
1891 (collect ((slot-specs) (slot-values))
1892 (mapc (lambda (dsd value &aux (raw-type (dsd-raw-type dsd))
1893 (spec (list* :slot raw-type (dsd-index dsd))))
1894 (cond ((eq value '.do-not-initialize-slot.)
1895 (when (eq raw-type t)
1896 (rplaca spec :unbound)
1897 (slot-specs spec)))
1899 (slot-specs spec)
1900 (slot-values value))))
1901 dd-slots values)
1902 `(%make-structure-instance-macro ,dd ',(slot-specs) ,@(slot-values)))
1905 ;;; A "typed" constructor prefers to use a single call to LIST or VECTOR
1906 ;;; if possible, but can't always do that for VECTOR because it might not
1907 ;;; be a (VECTOR T). If not, we fallback to MAKE-ARRAY and (SETF AREF).
1908 (defun typed-constructor-form (dd values)
1909 (multiple-value-bind (operator initial-element)
1910 (cond ((and (eq (dd-type dd) 'vector) (eq (dd-%element-type dd) t))
1911 (values 'vector 0))
1912 ((eq (dd-type dd) 'list)
1913 (values 'list nil)))
1914 (let* ((length (dd-length dd))
1915 (slots (dd-slots dd))
1916 ;; Possibly the most useless feature ever: more than one name slot.
1917 (names (find-name-indices dd)))
1918 (aver (= (length slots) (length values)))
1919 (if operator
1920 ;; The initial-element provides values for slots that are skipped
1921 ;; due to :initial-offset, not slots that are skipped due to
1922 ;; &AUX variables with no initial value.
1923 (let ((vals (make-list length :initial-element initial-element)))
1924 (dolist (x names)
1925 (setf (elt vals (cdr x)) `',(car x)))
1926 (mapc (lambda (dsd val)
1927 ;; For both vectors and lists, .DO-NOT-INITIALIZE-SLOT.
1928 ;; becomes 0 even though lists otherwise use NIL for slots
1929 ;; that are skipped to due :initial-offset.
1930 (setf (elt vals (dsd-index dsd))
1931 ;; All VALs have been wrapped in THE if necessary.
1932 (if (eq val '.do-not-initialize-slot.) 0 val)))
1933 slots values)
1934 (cons operator vals))
1935 (let ((temp (make-symbol "OBJ")))
1936 `(let ((,temp (make-array ,length
1937 :element-type ',(dd-%element-type dd))))
1938 ,@(mapcar (lambda (x) `(setf (aref ,temp ,(cdr x)) ',(car x)))
1939 names)
1940 ,@(mapcan (lambda (dsd val)
1941 (unless (eq val '.do-not-initialize-slot.)
1942 `((setf (aref ,temp ,(dsd-index dsd)) ,val))))
1943 slots values)
1944 ,temp))))))
1946 ;;; Return the FTYPE for a DD constructor.
1947 ;;; This is tricky in uses such as the following:
1948 ;;; (DEFSTRUCT (S (:CONSTRUCTOR MS (A &AUX (A (ABS A))))) (A 0 :TYPE (MOD 4)))
1949 ;;; The constructor accepts integers betweeen -3 and 3 because the &AUX binding
1950 ;;; hides the positional argument A, and we can't actually put any constraint
1951 ;;; on A unless we figure out what the action of ABS is.
1953 ;;; The FTYPE is actually not a strong enough constraint anyway, so when IR1
1954 ;;; tests for the call compatibility it will test for correctness *after*
1955 ;;; argument defaulting.
1956 (defun %struct-ctor-ftype (dd args elt-type)
1957 (flet ((elt-type-intersect (dsd &aux (slot-type (dsd-type dsd)))
1958 (cond ((eq slot-type t) elt-type)
1959 ((eq elt-type t) slot-type)
1960 (t `(and ,elt-type ,slot-type)))))
1961 `(function
1962 ,(if (eq args :default)
1963 `(&key ,@(mapcar (lambda (dsd)
1964 `(,(keywordicate (dsd-name dsd))
1965 ,(elt-type-intersect dsd)))
1966 (dd-slots dd)))
1967 (destructuring-bind (llks &optional req opt rest keys aux) args
1968 (let ((aux (mapcar (lambda (var) (if (listp var) (car var) var))
1969 aux)))
1970 (flet ((get-arg-type (name)
1971 (let ((slot (unless (member name aux :test #'string=)
1972 (find name (dd-slots dd) :key #'dsd-name
1973 :test #'string=))))
1974 ;; If no slot, the arg restriction is T,
1975 ;; because we don't know where it goes.
1976 (if slot (elt-type-intersect slot) t))))
1977 (make-lambda-list
1978 llks nil (mapcar #'get-arg-type req)
1979 (mapcar (lambda (arg)
1980 (get-arg-type (parse-optional-arg-spec arg)))
1981 opt)
1982 (if rest (list t))
1983 (mapcar (lambda (arg)
1984 (multiple-value-bind (key var) (parse-key-arg-spec arg)
1985 `(,key ,(get-arg-type var))))
1986 keys))))))
1987 (values ,(cond ((dd-class-p dd) (dd-name dd))
1988 ((eq (dd-type dd) 'list) 'list)
1989 (t `(vector ,(dd-%element-type dd) ,(dd-length dd))))
1990 &optional))))
1992 ;;; Return the ftype of global function NAME.
1993 (defun global-ftype (name &aux xform)
1994 (multiple-value-bind (type foundp) (info :function :type name)
1995 (cond
1996 #-sb-xc-host ; PCL "doesn't exist" yet
1997 ((eq type :generic-function) (sb-pcl::compute-gf-ftype name))
1998 ((consp type) ; not parsed type
1999 ;; This case is used only for DEFKNOWN. It allows some out-of-order
2000 ;; definitions during bootstrap while avoiding the "uncertainty in typep"
2001 ;; error. It would work for user code as well, but users shouldn't write
2002 ;; out-of-order type definitions. In any case, it's not wrong to leave
2003 ;; this case in.
2004 (let ((ctype (specifier-type type)))
2005 (unless (contains-unknown-type-p ctype)
2006 (setf (info :function :type name) ctype))
2007 ctype))
2008 ;; In the absence of global info for a defstruct snippet, get the compiler's
2009 ;; opinion based on the defstruct definition, rather than reflecting on the
2010 ;; current function (as defined "now") which is what globaldb would get in
2011 ;; effect by calling FTYPE-FROM-FDEFN, that being less precise.
2012 ((and (not foundp)
2013 (typep (setq xform (info :function :source-transform name))
2014 '(cons defstruct-description)))
2015 (let* ((dd (car xform))
2016 (snippet (cdr xform))
2017 (dd-name (dd-name dd)))
2018 (specifier-type
2019 (case snippet
2020 (:constructor
2021 (let ((ctor (assq name (dd-constructors dd))))
2022 (aver ctor)
2023 (%struct-ctor-ftype dd (cdr ctor) (dd-element-type dd))))
2024 (:predicate `(function (t) (values boolean &optional)))
2025 (:copier `(function (,dd-name) (values ,dd-name &optional)))
2027 (let ((type (dsd-type snippet)))
2028 (if (consp name)
2029 `(function (,type ,dd-name) (values ,type &optional)) ; writer
2030 `(function (,dd-name) (values ,type &optional))))))))) ; reader
2032 type))))
2034 ;;; Given a DD and a constructor spec (a cons of name and pre-parsed
2035 ;;; BOA lambda list, or the symbol :DEFAULT), return the effective
2036 ;;; lambda list and the body of the lambda.
2037 (defun structure-ctor-lambda-parts
2038 (dd args &aux (creator (ecase (dd-type dd)
2039 (structure #'instance-constructor-form)
2040 ((list vector) #'typed-constructor-form))))
2041 (labels ((default-value (dsd &optional pretty)
2042 (let ((default (dsd-default dsd))
2043 (type (dsd-type dsd))
2044 (source-form (and (boundp '*dsd-source-form*)
2045 (cdr (assq dsd *dsd-source-form*)))))
2046 (cond ((and default
2047 (not pretty))
2048 `(the* (,type :source-form ,source-form
2049 :context ,dsd
2050 :use-annotations t)
2051 ,default))
2052 ((and default source-form
2053 (not pretty))
2054 `(sb-c::with-source-form ,source-form
2055 ,default))
2057 default))))
2058 (parse (&optional pretty)
2059 (mapcar (lambda (dsd)
2060 (let* ((temp (copy-symbol (dsd-name dsd)))
2061 (keyword (keywordicate temp)))
2062 `((,keyword ,temp)
2063 ,(default-value dsd pretty))))
2064 (dd-slots dd))))
2065 (when (eq args :default)
2066 (let ((lambda-list (parse)))
2067 (return-from structure-ctor-lambda-parts
2068 `((&key ,@lambda-list)
2069 (declare (explicit-check)
2070 (sb-c::lambda-list (&key ,@(parse t))))
2071 ,(funcall creator dd
2072 (mapcar (lambda (dsd arg)
2073 (let ((type (dsd-type dsd))
2074 (var (cadar arg)))
2075 (if (eq type t)
2077 `(the* (,type :context
2078 (struct-context ,(dd-name dd) . ,(dsd-name dsd)))
2079 ,var))))
2080 (dd-slots dd) lambda-list))))))
2081 (destructuring-bind (llks &optional req opt rest keys aux) args
2082 (collect ((vars (copy-list req)) ; list of bound vars
2083 (aux-vars)
2084 (skipped-vars))
2085 (dolist (binding aux)
2086 (let ((name (if (listp binding) (car binding) binding)))
2087 (aux-vars name)
2088 (unless (typep binding '(cons t cons))
2089 (skipped-vars name))))
2090 (macrolet ((rewrite (input key parse pretty)
2091 `(mapcar
2092 (lambda (arg)
2093 (multiple-value-bind (,@key var def sup-p) (,parse arg)
2094 (declare (ignore ,@key def))
2095 (rewrite-1 arg var sup-p ,pretty)))
2096 ,input)))
2097 (labels ((rewrite-1 (arg var sup-p-var pretty)
2098 (vars var)
2099 (when sup-p-var (vars (car sup-p-var)))
2100 (let* ((slot (unless (member var (aux-vars) :test #'string=)
2101 (find var (dd-slots dd)
2102 :key #'dsd-name :test #'string=)))
2103 (default (and slot (dsd-default slot))))
2104 ;; If VAR initializes a slot and did not have a default in
2105 ;; the lambda list, and DSD-DEFAULT is not NIL,
2106 ;; then change the lambda-list's default for the variable.
2107 ;; Always prefer to insert (CAR ARG) if ARG was a list
2108 ;; so that (:KEY var) syntax is preserved.
2109 (if (and slot (not (typep arg '(cons t cons)))
2110 default)
2111 `(,(if (consp arg) (car arg) var)
2112 ,(default-value slot pretty)
2113 ,@sup-p-var)
2114 arg))) ; keep it as it was
2115 (make-ll (opt rest keys aux-vars &optional pretty)
2116 ;; Can we substitute symbols that are not EQ to symbols
2117 ;; naming slots, so we don't have to compare by STRING= later?
2118 ;; Probably not because other symbols could reference them.
2119 (setq opt (rewrite opt () parse-optional-arg-spec pretty))
2120 (when rest (vars (car rest) pretty))
2121 (setq keys (rewrite keys (key) parse-key-arg-spec pretty))
2122 (dolist (arg aux-vars)
2123 (vars arg))
2124 (sb-c::make-lambda-list
2125 llks nil req opt rest keys
2126 ;; &AUX vars which do not initialize a slot are not mentioned
2127 ;; in the lambda list, though it's not clear what to do if
2128 ;; subsequent bindings refer to the deleted ones.
2129 ;; And worse, what if it's SETQd - is that even legal?
2130 (remove-if (lambda (x) (not (typep x '(cons t cons)))) aux))))
2131 `(,(make-ll opt rest keys (aux-vars))
2132 (declare (explicit-check)
2133 (sb-c::lambda-list ,(make-ll opt rest keys (aux-vars) t)))
2134 ,(funcall
2135 creator dd
2136 (mapcar
2137 (lambda (slot &aux (name (dsd-name slot)))
2138 (if (find name (skipped-vars) :test #'string=)
2139 ;; CLHS 3.4.6 Boa Lambda Lists
2140 '.do-not-initialize-slot.
2141 (let* ((type (dsd-type slot))
2142 (found (member (dsd-name slot) (vars) :test #'string=))
2143 (initform (if found (car found) (dsd-default slot))))
2144 ;; We can ignore the DD-ELEMENT-TYPE
2145 ;; because the container itself will check.
2146 (if (eq type t) initform `(the ,type ,initform)))))
2147 (dd-slots dd))))))))))
2149 ;;;; instances with ALTERNATE-METACLASS
2150 ;;;;
2151 ;;;; The CMU CL support for structures with ALTERNATE-METACLASS was a
2152 ;;;; fairly general extension embedded in the main DEFSTRUCT code, and
2153 ;;;; the result was an fairly impressive mess as ALTERNATE-METACLASS
2154 ;;;; extension mixed with ANSI CL generality (e.g. :TYPE and :INCLUDE)
2155 ;;;; and CMU CL implementation hairiness (esp. raw slots). This SBCL
2156 ;;;; version is much less ambitious, noticing that ALTERNATE-METACLASS
2157 ;;;; is only used to implement CONDITION, STANDARD-INSTANCE, and
2158 ;;;; GENERIC-FUNCTION, and defining a simple specialized
2159 ;;;; separate-from-DEFSTRUCT macro to provide only enough
2160 ;;;; functionality to support those.
2161 ;;;;
2162 ;;;; KLUDGE: The defining macro here is so specialized that it's ugly
2163 ;;;; in its own way. It also violates once-and-only-once by knowing
2164 ;;;; much about structures and layouts that is already known by the
2165 ;;;; main DEFSTRUCT macro. Hopefully it will go away presently
2166 ;;;; (perhaps when CL:CLASS and SB-PCL:CLASS meet) as per FIXME below.
2167 ;;;; -- WHN 2001-10-28
2168 ;;;;
2169 ;;;; FIXME: There seems to be no good reason to shoehorn CONDITION,
2170 ;;;; STANDARD-INSTANCE, and GENERIC-FUNCTION into mutated structures
2171 ;;;; instead of just implementing them as primitive objects. (This
2172 ;;;; reduced-functionality macro seems pretty close to the
2173 ;;;; functionality of !DEFINE-PRIMITIVE-OBJECT..)
2175 ;;; The complete list of alternate-metaclass DEFSTRUCTs:
2176 ;;; CONDITION SB-KERNEL:INTERPRETED-FUNCTION
2177 ;;; SB-PCL::STANDARD-INSTANCE SB-PCL::STANDARD-FUNCALLABLE-INSTANCE
2178 ;;; SB-PCL::CTOR SB-PCL::%METHOD-FUNCTION
2180 (defun make-dd-with-alternate-metaclass (&key (class-name (missing-arg))
2181 (superclass-name (missing-arg))
2182 (metaclass-name (missing-arg))
2183 (dd-type (missing-arg))
2184 metaclass-constructor
2185 slot-names)
2186 (let* ((dd (make-defstruct-description class-name +dd-nullenv+))
2187 (conc-name (string (gensymify* class-name "-")))
2188 (slot-index 0))
2189 ;; We do *not* fill in the COPIER-NAME and PREDICATE-NAME
2190 ;; because alternate-metaclass structures can not have either.
2191 (case dd-type
2192 ;; We don't fully support inheritance of alternate metaclass stuff,
2193 ;; so sanity check our own code.
2194 (structure
2195 (aver (eq superclass-name 't))
2196 ;; Without compact instance headers, the index starts at 1 for
2197 ;; named slots, because slot 0 is the LAYOUT.
2198 ;; This is the same in ordinary structures too: see (INCF DD-LENGTH)
2199 ;; in PARSE-DEFSTRUCT-NAME-AND-OPTIONS.
2200 ;; With compact instance headers, slot 0 is a data slot.
2201 (incf slot-index sb-vm:instance-data-start))
2202 (funcallable-structure
2203 (aver (eq superclass-name 'function)))
2204 (t (bug "Unknown DD-TYPE in ALTERNATE-METACLASS: ~S" dd-type)))
2205 (setf (dd-type dd) dd-type
2206 (dd-alternate-metaclass dd) (list superclass-name
2207 metaclass-name
2208 metaclass-constructor)
2209 (dd-slots dd)
2210 (mapcar (lambda (slot-name)
2211 (multiple-value-bind (slot-name type)
2212 (if (consp slot-name)
2213 (values (first slot-name) (second slot-name))
2214 (values slot-name t))
2215 (make-dsd slot-name type (symbolicate conc-name slot-name)
2216 (pack-dsd-bits (prog1 slot-index (incf slot-index))
2217 nil t t nil nil)
2218 nil)))
2219 slot-names)
2220 (dd-length dd) slot-index
2221 (dd-bitmap dd) (calculate-dd-bitmap dd))
2222 dd))
2224 (sb-xc:defmacro !defstruct-with-alternate-metaclass
2225 (class-name &key
2226 (slot-names (missing-arg))
2227 (constructor (missing-arg))
2228 (superclass-name (missing-arg))
2229 (metaclass-name (missing-arg))
2230 (metaclass-constructor (missing-arg))
2231 (dd-type (missing-arg)))
2233 (declare (type list slot-names))
2234 (declare (type (and symbol (not null))
2235 superclass-name
2236 metaclass-name
2237 metaclass-constructor))
2238 (declare (symbol constructor)) ; NIL for none
2239 (declare (type (member structure funcallable-structure) dd-type))
2241 (let ((dd (make-dd-with-alternate-metaclass
2242 :class-name class-name
2243 :slot-names slot-names
2244 :superclass-name superclass-name
2245 :metaclass-name metaclass-name
2246 :metaclass-constructor metaclass-constructor
2247 :dd-type dd-type)))
2248 `(progn
2249 (eval-when (:compile-toplevel :load-toplevel :execute)
2250 (%compiler-defstruct ',dd ',(!inherits-for-structure dd))
2251 (when (eq (info :type :kind ',class-name) :defined)
2252 (setf (info :type :kind ',class-name) :instance))
2253 ,@(when (eq metaclass-name 'static-classoid)
2254 `((declaim (freeze-type ,class-name)))))
2255 ,@(accessor-definitions dd t)
2256 ,@(when constructor
2257 (multiple-value-bind (allocate set-layout)
2258 (ecase dd-type
2259 (structure
2260 ;; I think the only nonfuncallable alternate-metaclass structure
2261 ;; is CONDITION, which has its own fancy constructor.
2262 ;; Maybe this should be (bug "Can't happen") ?
2263 (values `(%make-structure-instance-macro ,dd nil) nil))
2264 (funcallable-structure
2265 (values `(truly-the ,class-name
2266 (%make-funcallable-instance ,(dd-length dd)))
2267 `((macrolet ((the-layout ()
2268 (info :type :compiler-layout ',class-name)))
2269 (setf (%fun-layout object) (the-layout)))))))
2270 `((defun ,constructor (,@(mapcar (lambda (x)
2271 (if (consp x)
2272 (car x)
2274 slot-names) &aux (object ,allocate))
2275 ,@set-layout
2276 ,@(when (and (eq dd-type 'funcallable-structure)
2277 ;; fmt-control is not an executable function
2278 (neq class-name 'sb-format::fmt-control))
2279 '((sb-vm::write-funinstance-prologue object)))
2280 ,@(mapcar (lambda (dsd)
2281 `(setf (,(dsd-accessor-name dsd) object) ,(dsd-name dsd)))
2282 (dd-slots dd))
2283 object))))
2284 (!target-defstruct-altmetaclass ',dd ,@(accessor-definitions dd nil)))))
2285 #+sb-xc-host
2286 (defun !target-defstruct-altmetaclass (&rest args)
2287 (declare (ignore args)))
2289 ;;;; finalizing bootstrapping
2291 ;;; Set up DD and LAYOUT for STRUCTURE-OBJECT class itself.
2293 ;;; Ordinary structure classes effectively :INCLUDE STRUCTURE-OBJECT
2294 ;;; when they have no explicit :INCLUDEs, so (1) it needs to be set up
2295 ;;; before we can define ordinary structure classes, and (2) it's
2296 ;;; special enough (and simple enough) that we just build it by hand
2297 ;;; instead of trying to generalize the ordinary DEFSTRUCT code.
2298 (defun !set-up-structure-object-class ()
2299 (let ((dd (make-defstruct-description 'structure-object +dd-nullenv+)))
2300 (setf (dd-length dd) sb-vm:instance-data-start)
2301 (%compiler-set-up-layout dd (vector (find-layout 't)))))
2302 #+sb-xc-host(!set-up-structure-object-class)
2304 (defun find-defstruct-description (name &optional (errorp t))
2305 (let* ((classoid (find-classoid name errorp))
2306 (info (and classoid (layout-%info (classoid-layout classoid)))))
2307 (cond ((defstruct-description-p info)
2308 info)
2309 (errorp
2310 (error "No DEFSTRUCT-DESCRIPTION for ~S." name)))))
2312 (defun structure-instance-accessor-p (name)
2313 (let ((info (info :function :source-transform name)))
2314 (and (listp info)
2315 (defstruct-slot-description-p (cdr info))
2316 info)))
2318 (defun dd-default-constructor (dd)
2319 (let ((ctor (first (dd-constructors dd))))
2320 (when (typep ctor '(cons t (eql :default)))
2321 (car ctor))))
2323 #+sb-xc-host
2324 (defun %instance-ref (instance index)
2325 (let* ((layout (%instance-layout instance))
2326 (map (layout-index->accessor-map layout)))
2327 (when (zerop (length map)) ; construct it on demand
2328 (let ((slots (dd-slots (layout-%info layout))))
2329 (setf map (make-array (1+ (reduce #'max slots :key #'dsd-index))
2330 :initial-element nil)
2331 (layout-index->accessor-map layout) map)
2332 (dolist (dsd slots)
2333 (setf (aref map (dsd-index dsd)) (dsd-accessor-name dsd)))))
2334 (funcall (aref map index) instance)))
2336 #+sb-xc-host
2337 (defun %raw-instance-ref/word (instance index) (%instance-ref instance index))
2339 ;;; It is possible to produce instances of structure-object which violate
2340 ;;; the assumption throughout the compiler that slot readers are safe
2341 ;;; unless dictated otherwise by the SAFE-P flag in the DSD.
2342 ;;; * (defstruct S a (b (error "Must supply me") :type symbol))
2343 ;;; * (defmethod make-load-form ((x S) &optional e) (m-l-f-s-s x :slot-names '(a)))
2344 ;;; After these definitions, a dumped S will have #<unbound> in slot B.
2345 (defun make-load-form-saving-slots (object &key (slot-names nil slot-names-p)
2346 environment)
2347 (declare (ignore environment))
2348 (if (typep object 'structure-object)
2349 (let ((type (type-of object)))
2350 (collect ((inits))
2351 (dolist (dsd (dd-slots (layout-dd (%instance-layout object))))
2352 (declare (type defstruct-slot-description dsd))
2353 (let ((slot-name (dsd-name dsd)))
2354 (when (or (memq slot-name slot-names)
2355 (not slot-names-p))
2356 (let* ((accessor (dsd-reader dsd nil))
2357 (index (dsd-index dsd))
2358 (value (funcall accessor object index)))
2359 (inits `(setf (,accessor ,object ,index) ',value))))))
2360 (values `(allocate-struct ',(the symbol type)) ;; no anonymous defstructs
2361 `(progn ,@(inits)))))
2362 #-sb-xc-host
2363 (let ((class (class-of object)))
2364 (collect ((inits))
2365 (dolist (slot (sb-mop:class-slots class))
2366 (let ((slot-name (sb-mop:slot-definition-name slot)))
2367 (when (or (memq slot-name slot-names)
2368 (and (not slot-names-p)
2369 (eq :instance (sb-mop:slot-definition-allocation slot))))
2370 (if (slot-boundp object slot-name)
2371 (let ((value (slot-value object slot-name)))
2372 (inits `(setf (slot-value ,object ',slot-name) ',value)))
2373 (inits `(slot-makunbound ,object ',slot-name))))))
2374 (values `(allocate-instance (find-class ',(class-name class)))
2375 `(progn ,@(inits)))))))
2377 ;;; Compute a SAP to the specified slot in INSTANCE.
2378 ;;; This looks mildly redundant with DEFINE-STRUCTURE-SLOT-ADDRESSOR,
2379 ;;; but that one returns an integer, not a SAP.
2380 (defmacro struct-slot-sap (instance type-name slot-name)
2381 `(sap+ (int-sap (get-lisp-obj-address ,instance))
2382 (- (ash (+ (get-dsd-index ,type-name ,slot-name) sb-vm:instance-slots-offset)
2383 sb-vm:word-shift)
2384 sb-vm:instance-pointer-lowtag)))
2386 #+sb-xc-host
2387 (defun write-structure-definitions-as-text (pathname)
2388 (with-open-file (output pathname :direction :output :if-exists :supersede)
2389 (dolist (root '(structure-object function))
2390 (dolist (pair (let ((subclassoids (classoid-subclasses (find-classoid root))))
2391 (if (listp subclassoids)
2392 subclassoids
2393 (flet ((pred (x y)
2394 (or (string< x y)
2395 (and (string= x y)
2396 (let ((xpn (cl:package-name (cl:symbol-package x)))
2397 (ypn (cl:package-name (cl:symbol-package y))))
2398 (string< xpn ypn))))))
2399 (sort (%hash-table-alist subclassoids)
2400 #'pred
2401 ;; pair = (#<classoid> . #<layout>)
2402 :key (lambda (pair) (classoid-name (car pair))))))))
2403 (let* ((layout (cdr pair))
2404 (dd (layout-info layout)))
2405 (cond
2407 (let* ((*print-pretty* nil) ; output should be insensitive to host pprint
2408 (*print-readably* t)
2409 (classoid-name (classoid-name (car pair)))
2410 (*package* (cl:symbol-package classoid-name)))
2411 (format output "~/sb-ext:print-symbol-with-prefix/ ~S (~%"
2412 classoid-name
2413 (list* (the (unsigned-byte 16) (layout-flags layout))
2414 (layout-depthoid layout)
2415 (map 'list #'layout-classoid-name
2416 (layout-inherits layout))))
2417 (dolist (dsd (dd-slots dd) (format output ")~%"))
2418 (format output " (~d ~S ~S)~%"
2419 (dsd-bits dsd)
2420 (dsd-name dsd)
2421 (dsd-accessor-name dsd)))))
2423 (error "Missing DD for ~S" pair))))))
2424 (format output ";; EOF~%")))
2426 (/show0 "code/defstruct.lisp end of file")