Speed up vector extension in VECTOR-PUSH-EXTEND.
[sbcl.git] / src / code / early-type.lisp
blobdfd1806b7163950e112193180eb87c68036706d3
1 ;;;; This software is part of the SBCL system. See the README file for
2 ;;;; more information.
3 ;;;;
4 ;;;; This software is derived from the CMU CL system, which was
5 ;;;; written at Carnegie Mellon University and released into the
6 ;;;; public domain. The software is in the public domain and is
7 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
8 ;;;; files for more information.
10 (in-package "SB!KERNEL")
12 (eval-when (:compile-toplevel #+sb-xc-host :load-toplevel :execute)
13 ;; The following macros expand into either constructor calls,
14 ;; if building the cross-compiler, or forms which reference
15 ;; previously constructed objects, if running the cross-compiler.
16 #+sb-xc-host
17 (progn
18 (defmacro literal-ctype (constructor &optional specifier)
19 (declare (ignore specifier))
20 ;; Technically the instances are not read-only,
21 ;; because the hash-value slot is rewritten.
22 `(load-time-value (mark-ctype-interned ,constructor) nil))
24 (defmacro literal-ctype-vector (var)
25 `(load-time-value ,var nil)))
27 #-sb-xc-host
28 (progn
29 ;; Omitting the specifier works only if the unparser method has been
30 ;; defined in time to use it, and you're sure that constructor's result
31 ;; can be unparsed - some unparsers may be confused if called on a
32 ;; non-canonical object, such as an instance of (CONS T T) that is
33 ;; not EQ to the interned instance.
34 (sb!xc:defmacro literal-ctype (constructor
35 &optional (specifier nil specifier-p))
36 ;; The source-transform for SPECIFIER-TYPE turns this call into
37 ;; (LOAD-TIME-VALUE (!SPECIFIER-TYPE ',specifier)).
38 ;; It's best to go through the transform rather than expand directly
39 ;; into that, because the transform canonicalizes the spec,
40 ;; ensuring correctness of the hash lookups performed during genesis.
41 `(specifier-type ',(if specifier-p
42 specifier
43 (type-specifier (symbol-value constructor)))))
45 (sb!xc:defmacro literal-ctype-vector (var)
46 (let ((vector (symbol-value var)))
47 `(truly-the (simple-vector ,(length vector))
48 (load-time-value
49 (vector ,@(map 'list
50 (lambda (x)
51 (if (ctype-p x)
52 `(!specifier-type ',(type-specifier x))
53 x)) ; allow NIL or 0 in the vector
54 vector)) t))))))
56 (!begin-collecting-cold-init-forms)
58 ;;;; representations of types
60 ;;; A HAIRY-TYPE represents anything too weird to be described
61 ;;; reasonably or to be useful, such as NOT, SATISFIES, unknown types,
62 ;;; and unreasonably complicated types involving AND. We just remember
63 ;;; the original type spec.
64 ;;; A possible improvement would be for HAIRY-TYPE to have a subtype
65 ;;; named SATISFIES-TYPE for the hairy types which are specifically
66 ;;; of the form (SATISFIES pred) so that we don't have to examine
67 ;;; the sexpr repeatedly to decide whether it takes that form.
68 ;;; And as a further improvement, we might want a table that maps
69 ;;; predicates to their exactly recognized type when possible.
70 ;;; We have such a table in fact - *BACKEND-PREDICATE-TYPES*
71 ;;; as a starting point. But something like PLUSP isn't in there.
72 ;;; On the other hand, either of these points may not be sources of
73 ;;; inefficiency, and the latter if implemented might have undesirable
74 ;;; user-visible ramifications, though it seems unlikely.
75 (defstruct (hairy-type (:include ctype
76 (class-info (type-class-or-lose 'hairy)))
77 (:constructor %make-hairy-type (specifier))
78 (:copier nil)
79 #!+cmu (:pure nil))
80 ;; the Common Lisp type-specifier of the type we represent
81 (specifier nil :type t :read-only t))
83 ;; ENUMERABLE-P is T because a hairy type could be equivalent to a MEMBER type.
84 ;; e.g. any SATISFIES with a predicate returning T over a finite domain.
85 ;; But in practice there's nothing that can be done with this information,
86 ;; because we don't call random predicates when performing operations on types
87 ;; as objects, only when checking for inclusion of something in the type.
88 (!define-type-class hairy :enumerable t :might-contain-other-types t)
90 ;;; Without some special HAIRY cases, we massively pollute the type caches
91 ;;; with objects that are all equivalent to *EMPTY-TYPE*. e.g.
92 ;;; (AND (SATISFIES LEGAL-FUN-NAME-P) (SIMPLE-ARRAY CHARACTER (*))) and
93 ;;; (AND (SATISFIES KEYWORDP) CONS). Since the compiler doesn't know
94 ;;; that they're just *EMPTY-TYPE*, its keeps building more and more complex
95 ;;; expressions involving them. I'm not sure why those two are so prevalent
96 ;;; but they definitely seem to be. We can improve performance by reducing
97 ;;; them to *EMPTY-TYPE* which means we need a way to recognize those hairy
98 ;;; types in order reason about them. Interning them is how we recognize
99 ;;; them, as they can be compared by EQ.
100 #+sb-xc-host
101 (progn
102 (defvar *satisfies-keywordp-type*
103 (mark-ctype-interned (%make-hairy-type '(satisfies keywordp))))
104 (defvar *fun-name-type*
105 (mark-ctype-interned (%make-hairy-type '(satisfies legal-fun-name-p)))))
107 ;;; An UNKNOWN-TYPE is a type not known to the type system (not yet
108 ;;; defined). We make this distinction since we don't want to complain
109 ;;; about types that are hairy but defined.
110 (defstruct (unknown-type (:include hairy-type)
111 (:copier nil)))
113 (defun maybe-reparse-specifier (type)
114 (when (unknown-type-p type)
115 (let* ((spec (unknown-type-specifier type))
116 (name (if (consp spec)
117 (car spec)
118 spec)))
119 (when (info :type :kind name)
120 (let ((new-type (specifier-type spec)))
121 (unless (unknown-type-p new-type)
122 new-type))))))
124 ;;; Evil macro.
125 (defmacro maybe-reparse-specifier! (type)
126 (assert (symbolp type))
127 (with-unique-names (new-type)
128 `(let ((,new-type (maybe-reparse-specifier ,type)))
129 (when ,new-type
130 (setf ,type ,new-type)
131 t))))
133 (defstruct (negation-type (:include ctype
134 (class-info (type-class-or-lose 'negation)))
135 (:copier nil)
136 (:constructor make-negation-type (type))
137 #!+cmu (:pure nil))
138 (type (missing-arg) :type ctype :read-only t))
140 ;; Former comment was:
141 ;; FIXME: is this right? It's what they had before, anyway
142 ;; But I think the reason it's right is that "enumerable :t" is equivalent
143 ;; to "maybe" which is actually the conservative assumption, same as HAIRY.
144 (!define-type-class negation :enumerable t :might-contain-other-types t)
146 (defun canonicalize-args-type-args (required optional rest &optional keyp)
147 (when (eq rest *empty-type*)
148 ;; or vice-versa?
149 (setq rest nil))
150 (loop with last-not-rest = nil
151 for i from 0
152 for opt in optional
153 do (cond ((eq opt *empty-type*)
154 (return (values required (subseq optional i) rest)))
155 ((and (not keyp) (neq opt rest))
156 (setq last-not-rest i)))
157 finally (return (values required
158 (cond (keyp
159 optional)
160 (last-not-rest
161 (subseq optional 0 (1+ last-not-rest))))
162 rest))))
164 ;; CONTEXT is the cookie passed down from the outermost surrounding call
165 ;; of VALUES-SPECIFIER-TYPE. INNER-CONTEXT-KIND is an indicator of whether
166 ;; we are currently parsing a FUNCTION or a VALUES compound type specifier.
167 (defun parse-args-types (context lambda-listy-thing inner-context-kind)
168 (multiple-value-bind (llks required optional rest keys)
169 (parse-lambda-list
170 lambda-listy-thing
171 :context inner-context-kind
172 :accept (ecase inner-context-kind
173 (:values-type (lambda-list-keyword-mask '(&optional &rest)))
174 (:function-type (lambda-list-keyword-mask
175 '(&optional &rest &key &allow-other-keys))))
176 :silent t)
177 (flet ((parse-list (list)
178 (mapcar (lambda (x) (single-value-specifier-type-r context x))
179 list)))
180 (let ((required (parse-list required))
181 (optional (parse-list optional))
182 (rest (when rest (single-value-specifier-type-r context (car rest))))
183 (keywords
184 (collect ((key-info))
185 (dolist (key keys)
186 (unless (proper-list-of-length-p key 2)
187 (error "Keyword type description is not a two-list: ~S." key))
188 (let ((kwd (first key)))
189 (when (find kwd (key-info) :key #'key-info-name)
190 (error "~@<repeated keyword ~S in lambda list: ~2I~_~S~:>"
191 kwd lambda-listy-thing))
192 (key-info
193 (make-key-info
194 ;; MAKE-KEY-INFO will complain if KWD is not a symbol.
195 ;; That's good enough - we don't need an extra check here.
196 :name kwd
197 :type (single-value-specifier-type-r context (second key))))))
198 (key-info))))
199 (multiple-value-bind (required optional rest)
200 (canonicalize-args-type-args required optional rest
201 (ll-kwds-keyp llks))
202 (values llks required optional rest keywords))))))
204 (defstruct (values-type
205 (:include args-type
206 (class-info (type-class-or-lose 'values)))
207 (:constructor %make-values-type)
208 (:predicate %values-type-p)
209 (:copier nil)))
211 (declaim (inline values-type-p))
212 (defun values-type-p (x)
213 (or (eq x *wild-type*)
214 (%values-type-p x)))
216 (defun-cached (make-values-type-cached
217 :hash-bits 8
218 :hash-function
219 (lambda (req opt rest allowp)
220 (logxor (type-list-cache-hash req)
221 (type-list-cache-hash opt)
222 (if rest
223 (type-hash-value rest)
225 ;; Results (logand #xFF (sxhash t/nil))
226 ;; hardcoded to avoid relying on the xc host.
227 ;; [but (logand (sxhash nil) #xff) => 2
228 ;; for me, so the code and comment disagree,
229 ;; but not in a way that matters.]
230 (if allowp
232 11))))
233 ((required equal-but-no-car-recursion)
234 (optional equal-but-no-car-recursion)
235 (rest eq)
236 (allowp eq))
237 (%make-values-type :required required
238 :optional optional
239 :rest rest
240 :allowp allowp))
242 (defun make-values-type (&key required optional rest allowp)
243 (multiple-value-bind (required optional rest)
244 (canonicalize-args-type-args required optional rest)
245 (cond ((and (null required)
246 (null optional)
247 (eq rest *universal-type*))
248 *wild-type*)
249 ((memq *empty-type* required)
250 *empty-type*)
251 (t (make-values-type-cached required optional
252 rest allowp)))))
254 (!define-type-class values :enumerable nil
255 :might-contain-other-types nil)
257 (!define-type-class function :enumerable nil
258 :might-contain-other-types nil)
260 #+sb-xc-host
261 (defvar *interned-fun-types*
262 (flet ((fun-type (n)
263 (mark-ctype-interned
264 (%make-fun-type (make-list n :initial-element *universal-type*)
265 nil nil nil nil nil nil *wild-type*))))
266 (vector (fun-type 0) (fun-type 1) (fun-type 2) (fun-type 3))))
268 (defun make-fun-type (&key required optional rest
269 keyp keywords allowp
270 wild-args returns)
271 (let ((rest (if (eq rest *empty-type*) nil rest))
272 (n (length required)))
273 (if (and (<= n 3)
274 (not optional) (not rest) (not keyp)
275 (not keywords) (not allowp) (not wild-args)
276 (eq returns *wild-type*)
277 (not (find *universal-type* required :test #'neq)))
278 (svref (literal-ctype-vector *interned-fun-types*) n)
279 (%make-fun-type required optional rest keyp keywords
280 allowp wild-args returns))))
282 ;; This seems to be used only by cltl2, and within 'cross-type',
283 ;; where it is never used, which makes sense, since pretty much we
284 ;; never want this object, but instead the classoid FUNCTION
285 ;; if we know nothing about a function's signature.
286 ;; Maybe this should not exist unless cltl2 is loaded???
287 (defvar *universal-fun-type*
288 (make-fun-type :wild-args t :returns *wild-type*))
290 ;;; The CONSTANT-TYPE structure represents a use of the CONSTANT-ARG
291 ;;; "type specifier", which is only meaningful in function argument
292 ;;; type specifiers used within the compiler. (It represents something
293 ;;; that the compiler knows to be a constant.)
294 (defstruct (constant-type
295 (:include ctype
296 (class-info (type-class-or-lose 'constant)))
297 (:copier nil))
298 ;; The type which the argument must be a constant instance of for this type
299 ;; specifier to win.
300 (type (missing-arg) :type ctype :read-only t))
302 (!define-type-class number :enumerable #'numeric-type-enumerable
303 :might-contain-other-types nil)
305 #+sb-xc-host
306 (progn
307 ;; Work around an ABCL bug. This fails to load:
308 ;; (macrolet ((foo-it (x) `(- ,x))) (defvar *var* (foo-it 3)))
309 (defvar *interned-signed-byte-types*)
310 (defvar *interned-unsigned-byte-types*)
311 (macrolet ((int-type (low high)
312 `(mark-ctype-interned
313 (%make-numeric-type :class 'integer :enumerable t
314 :low ,low :high ,high))))
315 (setq *interned-signed-byte-types*
316 (let ((v (make-array sb!vm:n-word-bits))
317 (j -1))
318 (dotimes (i sb!vm:n-word-bits v)
319 (setf (svref v i) (int-type j (lognot j)) j (ash j 1)))))
320 (setq *interned-unsigned-byte-types*
321 (let ((v (make-array (1+ sb!vm:n-word-bits))))
322 (dotimes (i (length v) v)
323 (setf (svref v i) (int-type 0 (1- (ash 1 i)))))))))
325 ;;; Impose canonicalization rules for NUMERIC-TYPE. Note that in some
326 ;;; cases, despite the name, we return *EMPTY-TYPE* instead of a
327 ;;; NUMERIC-TYPE.
328 ;;; FIXME: The ENUMERABLE flag is unexpectedly NIL for types that
329 ;;; come from parsing MEMBER. But bounded integer ranges,
330 ;;; however large, are enumerable:
331 ;;; (TYPE-ENUMERABLE (SPECIFIER-TYPE '(SIGNED-BYTE 99))) => T
332 ;;; (TYPE-ENUMERABLE (SPECIFIER-TYPE '(COMPLEX (SIGNED-BYTE 99)))) => T
333 ;;; but, in contrast,
334 ;;; (TYPE-ENUMERABLE (SPECIFIER-TYPE '(EQL 5))) => NIL.
335 ;;; I can't figure out whether this is supposed to matter.
336 ;;; Moreover, it seems like this function should be responsible
337 ;;; for figuring out the right value so that callers don't have to.
338 (defun make-numeric-type (&key class format (complexp :real) low high
339 enumerable)
340 (multiple-value-bind (low high)
341 (case class
342 (integer
343 ;; INTEGER types always have their LOW and HIGH bounds
344 ;; represented as inclusive, not exclusive values.
345 (values (if (consp low) (1+ (type-bound-number low)) low)
346 (if (consp high) (1- (type-bound-number high)) high)))
348 ;; no canonicalization necessary
349 (values low high)))
350 ;; if interval is empty
351 (when (and low high
352 (if (or (consp low) (consp high)) ; if either bound is exclusive
353 (>= (type-bound-number low) (type-bound-number high))
354 (> low high)))
355 (return-from make-numeric-type *empty-type*))
356 (when (and (eq class 'rational) (integerp low) (eql low high))
357 (setf class 'integer))
358 ;; Either lookup the canonical interned object for
359 ;; a point in the type lattice, or construct a new one.
360 (or (case class
361 (float
362 (macrolet ((float-type (fmt complexp)
363 `(literal-ctype
364 (%make-numeric-type :class 'float :complexp ,complexp
365 :format ',fmt :enumerable nil)
366 ,(if (eq complexp :complex) `(complex ,fmt) fmt))))
367 (when (and (null low) (null high))
368 (case format
369 (single-float
370 (case complexp
371 (:real (float-type single-float :real))
372 (:complex (float-type single-float :complex))))
373 (double-float
374 (case complexp
375 (:real (float-type double-float :real))
376 (:complex (float-type double-float :complex))))))))
377 (integer
378 (macrolet ((int-type (low high)
379 `(literal-ctype
380 (%make-numeric-type
381 :class 'integer :low ,low :high ,high
382 :enumerable (if (and ,low ,high) t nil))
383 (integer ,(or low '*) ,(or high '*)))))
384 (cond ((neq complexp :real) nil)
385 ((and (eql low 0) (eql high (1- sb!xc:array-dimension-limit)))
386 (int-type 0 #.(1- sb!xc:array-dimension-limit))) ; INDEX type
387 ((null high)
388 (cond ((not low) (int-type nil nil))
389 ((eql low 0) (int-type 0 nil))
390 ((eql low (1+ sb!xc:most-positive-fixnum))
391 ;; positive bignum
392 (int-type #.(1+ sb!xc:most-positive-fixnum) nil))))
393 ((or (eql high most-positive-word)
394 ;; is (1+ high) a power-of-2 ?
395 (and (typep high 'word) (zerop (logand (1+ high) high))))
396 (cond ((eql low 0)
397 (svref (literal-ctype-vector *interned-unsigned-byte-types*)
398 (integer-length (truly-the word high))))
399 ((and (< high most-positive-word) (eql low (lognot high)))
400 (svref (literal-ctype-vector *interned-signed-byte-types*)
401 (integer-length (truly-the word high))))))
402 ((and (not low) (eql high (1- sb!xc:most-negative-fixnum)))
403 ;; negative bignum
404 (int-type nil #.(1- sb!xc:most-negative-fixnum))))))
405 (rational
406 (when (and (eq complexp :real) (null low) (eq high low))
407 (literal-ctype (%make-numeric-type :class 'rational) rational))))
408 (let ((result (%make-numeric-type :class class :format format
409 :complexp complexp
410 :low low :high high
411 :enumerable enumerable)))
412 (setf (type-hash-value result)
413 (logior (type-hash-value result) +type-admits-type=-optimization+))
414 result))))
416 (defun modified-numeric-type (base
417 &key
418 (class (numeric-type-class base))
419 (format (numeric-type-format base))
420 (complexp (numeric-type-complexp base))
421 (low (numeric-type-low base))
422 (high (numeric-type-high base))
423 (enumerable (type-enumerable base)))
424 (make-numeric-type :class class
425 :format format
426 :complexp complexp
427 :low low
428 :high high
429 :enumerable enumerable))
431 ;; all character-set types are enumerable, but it's not possible
432 ;; for one to be TYPE= to a MEMBER type because (MEMBER #\x)
433 ;; is not internally represented as a MEMBER type.
434 ;; So in case it wasn't clear already ENUMERABLE-P does not mean
435 ;; "possibly a MEMBER type in the Lisp-theoretic sense",
436 ;; but means "could be implemented in SBCL as a MEMBER type".
437 (!define-type-class character-set :enumerable nil
438 :might-contain-other-types nil)
440 (defun make-character-set-type (pairs)
441 ; (aver (equal (mapcar #'car pairs)
442 ; (sort (mapcar #'car pairs) #'<)))
443 ;; aver that the cars of the list elements are sorted into increasing order
444 (when pairs
445 (do ((p pairs (cdr p)))
446 ((null (cdr p)))
447 (aver (<= (caar p) (caadr p)))))
448 (let ((pairs (let (result)
449 (do ((pairs pairs (cdr pairs)))
450 ((null pairs) (nreverse result))
451 (destructuring-bind (low . high) (car pairs)
452 (loop for (low1 . high1) in (cdr pairs)
453 if (<= low1 (1+ high))
454 do (progn (setf high (max high high1))
455 (setf pairs (cdr pairs)))
456 else do (return nil))
457 (cond
458 ((>= low sb!xc:char-code-limit))
459 ((< high 0))
460 (t (push (cons (max 0 low)
461 (min high (1- sb!xc:char-code-limit)))
462 result))))))))
463 (unless pairs
464 (return-from make-character-set-type *empty-type*))
465 (unless (cdr pairs)
466 (macrolet ((range (low high)
467 `(return-from make-character-set-type
468 (literal-ctype (%make-character-set-type '((,low . ,high)))
469 (character-set ((,low . ,high)))))))
470 (let* ((pair (car pairs))
471 (low (car pair))
472 (high (cdr pair)))
473 (cond ((eql high (1- sb!xc:char-code-limit))
474 (cond ((eql low 0) (range 0 #.(1- sb!xc:char-code-limit)))
475 #!+sb-unicode
476 ((eql low base-char-code-limit)
477 (range #.base-char-code-limit
478 #.(1- sb!xc:char-code-limit)))))
479 #!+sb-unicode
480 ((and (eql low 0) (eql high (1- base-char-code-limit)))
481 (range 0 #.(1- base-char-code-limit)))))))
482 (%make-character-set-type pairs)))
484 (!define-type-class array :enumerable nil
485 :might-contain-other-types nil)
487 ;; For all ctypes which are the element types of specialized arrays,
488 ;; 3 ctype objects are stored for the rank-1 arrays of that specialization,
489 ;; one for each of simple, maybe-simple, and non-simple (in that order),
490 ;; and 2 ctype objects for unknown-rank arrays, one each for simple
491 ;; and maybe-simple. (Unknown rank, known-non-simple isn't important)
492 #+sb-xc-host
493 (progn
494 (defvar *interned-array-types*
495 (labels ((make-1 (type-index dims complexp type)
496 (setf (!ctype-saetp-index type) type-index)
497 (mark-ctype-interned (%make-array-type dims complexp type type)))
498 (make-all (element-type type-index array)
499 (replace array
500 (list (make-1 type-index '(*) nil element-type)
501 (make-1 type-index '(*) :maybe element-type)
502 (make-1 type-index '(*) t element-type)
503 (make-1 type-index '* nil element-type)
504 (make-1 type-index '* :maybe element-type))
505 :start1 (* type-index 5)))
506 (integer-range (low high)
507 (make-numeric-type :class 'integer :complexp :real
508 :enumerable t :low low :high high)))
509 (let ((array (make-array (* 32 5)))
510 (index 0))
511 ;; Index 31 is available to store *WILD-TYPE*
512 ;; because there are fewer than 32 array widetags.
513 (make-all *wild-type* 31 array)
514 (dolist (x *specialized-array-element-types*
515 (progn (aver (< index 31)) array))
516 (make-all
517 ;; Produce element-type representation without parsing a spec.
518 ;; (SPECIFIER-TYPE doesn't work when bootstrapping.)
519 ;; The MAKE- constructors return an interned object as appropriate.
520 (etypecase x
521 ((cons (eql unsigned-byte))
522 (integer-range 0 (1- (ash 1 (second x)))))
523 ((cons (eql signed-byte))
524 (let ((lim (ash 1 (1- (second x)))))
525 (integer-range (- lim) (1- lim))))
526 ((eql bit) (integer-range 0 1))
527 ;; FIXNUM is its own thing, why? See comment in vm-array
528 ;; saying to "See the comment in PRIMITIVE-TYPE-AUX"
529 ((eql fixnum) ; One good kludge deserves another.
530 (integer-range sb!xc:most-negative-fixnum
531 sb!xc:most-positive-fixnum))
532 ((member single-float double-float)
533 (make-numeric-type :class 'float :format x :complexp :real))
534 ((cons (eql complex))
535 (make-numeric-type :class 'float :format (cadr x)
536 :complexp :complex))
537 ((eql character)
538 (make-character-set-type `((0 . ,(1- sb!xc:char-code-limit)))))
539 #!+sb-unicode
540 ((eql base-char)
541 (make-character-set-type `((0 . ,(1- base-char-code-limit)))))
542 ((eql t) *universal-type*)
543 ((eql nil) *empty-type*))
544 index array)
545 (incf index)))))
546 (defvar *parsed-specialized-array-element-types*
547 (let ((a (make-array (length *specialized-array-element-types*))))
548 (loop for i below (length a)
549 do (setf (aref a i) (array-type-specialized-element-type
550 (aref *interned-array-types* (* i 5)))))
551 a)))
553 (declaim (ftype (sfunction (t &key (:complexp t)
554 (:element-type t)
555 (:specialized-element-type t))
556 ctype) make-array-type))
557 (defun make-array-type (dimensions &key (complexp :maybe) element-type
558 (specialized-element-type *wild-type*))
559 (if (and (eq element-type specialized-element-type)
560 (or (and (eq dimensions '*) (neq complexp t))
561 (typep dimensions '(cons (eql *) null))))
562 (let ((res (svref (literal-ctype-vector *interned-array-types*)
563 (+ (* (!ctype-saetp-index element-type) 5)
564 (if (listp dimensions) 0 3)
565 (ecase complexp ((nil) 0) ((:maybe) 1) ((t) 2))))))
566 (aver (eq (array-type-element-type res) element-type))
567 res)
568 (%make-array-type dimensions
569 complexp element-type specialized-element-type)))
571 (!define-type-class member :enumerable t
572 :might-contain-other-types nil)
574 (declaim (ftype (sfunction (xset list) ctype) make-member-type))
575 (defun member-type-from-list (members)
576 (let ((xset (alloc-xset))
577 (fp-zeroes))
578 (dolist (elt members (make-member-type xset fp-zeroes))
579 (if (fp-zero-p elt)
580 (pushnew elt fp-zeroes)
581 (add-to-xset elt xset)))))
582 (defun make-eql-type (elt) (member-type-from-list (list elt)))
583 ;; Return possibly a union of a MEMBER type and a NUMERIC type,
584 ;; or just one or the other, or *EMPTY-TYPE* depending on what's in the XSET
585 ;; and the FP-ZEROES. XSET should not contains characters or real numbers.
586 (defun make-member-type (xset fp-zeroes)
587 ;; if we have a pair of zeros (e.g. 0.0d0 and -0.0d0), then we can
588 ;; canonicalize to (DOUBLE-FLOAT 0.0d0 0.0d0), because numeric
589 ;; ranges are compared by arithmetic operators (while MEMBERship is
590 ;; compared by EQL). -- CSR, 2003-04-23
591 (let ((presence 0)
592 (unpaired nil)
593 (float-types nil))
594 (when fp-zeroes ; avoid doing two passes of nothing
595 (dotimes (pass 2)
596 (dolist (z fp-zeroes)
597 (let ((sign (if (minusp (nth-value 2 (integer-decode-float z))) 1 0))
598 (pair-idx
599 (etypecase z
600 (single-float 0)
601 (double-float 2
602 #!+long-float (long-float 4)))))
603 (if (= pass 0)
604 (setf (ldb (byte 1 (+ pair-idx sign)) presence) 1)
605 (if (= (ldb (byte 2 pair-idx) presence) #b11)
606 (when (= sign 0)
607 (push (ctype-of z) float-types))
608 (push z unpaired)))))))
609 (let ((member-type
610 (block nil
611 (unless unpaired
612 (macrolet ((member-type (&rest elts)
613 `(literal-ctype
614 (%make-member-type (xset-from-list ',elts) nil)
615 (member ,@elts))))
616 (let ((elts (xset-data xset)))
617 (when (singleton-p elts)
618 (case (first elts)
619 ((nil) (return (member-type nil)))
620 ((t) (return (member-type t)))))
621 (when (or (equal elts '(t nil)) (equal elts '(nil t)))
622 ;; Semantically this is fine - XSETs
623 ;; are not order-preserving except by accident
624 ;; (when not represented as a hash-table).
625 (return (member-type t nil))))))
626 (when (or unpaired (not (xset-empty-p xset)))
627 (let ((result (%make-member-type xset unpaired)))
628 (setf (type-hash-value result)
629 (logior (type-hash-value result)
630 +type-admits-type=-optimization+))
631 result)))))
632 ;; The actual member-type contains the XSET (with no FP zeroes),
633 ;; and a list of unpaired zeroes.
634 (if float-types
635 (make-union-type t (if member-type
636 (cons member-type float-types)
637 float-types))
638 (or member-type *empty-type*)))))
640 (defun member-type-size (type)
641 (+ (length (member-type-fp-zeroes type))
642 (xset-count (member-type-xset type))))
644 (defun member-type-member-p (x type)
645 (if (fp-zero-p x)
646 (and (member x (member-type-fp-zeroes type)) t)
647 (xset-member-p x (member-type-xset type))))
649 (defun mapcar-member-type-members (function type)
650 (declare (function function))
651 (collect ((results))
652 (map-xset (lambda (x)
653 (results (funcall function x)))
654 (member-type-xset type))
655 (dolist (zero (member-type-fp-zeroes type))
656 (results (funcall function zero)))
657 (results)))
659 (defun mapc-member-type-members (function type)
660 (declare (function function))
661 (map-xset function (member-type-xset type))
662 (dolist (zero (member-type-fp-zeroes type))
663 (funcall function zero)))
665 (defun member-type-members (type)
666 (append (member-type-fp-zeroes type)
667 (xset-members (member-type-xset type))))
669 ;;; Return TYPE converted to canonical form for a situation where the
670 ;;; "type" '* (which SBCL still represents as a type even though ANSI
671 ;;; CL defines it as a related but different kind of placeholder) is
672 ;;; equivalent to type T.
673 (defun type-*-to-t (type)
674 (if (type= type *wild-type*)
675 *universal-type*
676 type))
678 (!define-type-class cons :enumerable nil :might-contain-other-types nil)
680 #+sb-xc-host
681 (declaim (ftype (sfunction (ctype ctype) (values t t)) type=))
682 (defun make-cons-type (car-type cdr-type)
683 (aver (not (or (eq car-type *wild-type*)
684 (eq cdr-type *wild-type*))))
685 (cond ((or (eq car-type *empty-type*)
686 (eq cdr-type *empty-type*))
687 *empty-type*)
688 ;; It's not a requirement that (CONS T T) be interned,
689 ;; but it improves the hit rate in the function caches.
690 ((and (type= car-type *universal-type*)
691 (type= cdr-type *universal-type*))
692 (literal-ctype (%make-cons-type *universal-type* *universal-type*)
693 cons))
695 (%make-cons-type car-type cdr-type))))
697 ;;; A SIMD-PACK-TYPE is used to represent a SIMD-PACK type.
698 #!+sb-simd-pack
699 (defstruct (simd-pack-type
700 (:include ctype (class-info (type-class-or-lose 'simd-pack)))
701 (:constructor %make-simd-pack-type (element-type))
702 (:copier nil))
703 (element-type (missing-arg)
704 :type (cons #||(member #.*simd-pack-element-types*) ||#)
705 :read-only t))
707 #!+sb-simd-pack
708 (defun make-simd-pack-type (element-type)
709 (aver (neq element-type *wild-type*))
710 (if (eq element-type *empty-type*)
711 *empty-type*
712 (%make-simd-pack-type
713 (dolist (pack-type *simd-pack-element-types*
714 (error "~S element type must be a subtype of ~
715 ~{~S~#[~;, or ~:;, ~]~}."
716 'simd-pack *simd-pack-element-types*))
717 (when (csubtypep element-type (specifier-type pack-type))
718 (return (list pack-type)))))))
721 ;;;; type utilities
723 ;;; Return the type structure corresponding to a type specifier.
725 ;;; Note: VALUES-SPECIFIER-TYPE-CACHE-CLEAR must be called whenever a
726 ;;; type is defined (or redefined).
728 ;;; As I understand things, :FORTHCOMING-DEFCLASS-TYPE behaves contrarily
729 ;;; to the CLHS intent, which is to make the type known to the compiler.
730 ;;; If we compile in one file:
731 ;;; (DEFCLASS FRUITBAT () ())
732 ;;; (DEFUN FRUITBATP (X) (TYPEP X 'FRUITBAT))
733 ;;; we see that it emits a call to %TYPEP with the symbol FRUITBAT as its
734 ;;; argument, whereas it should involve CLASSOID-CELL-TYPEP and LAYOUT-OF,
735 ;;; which (correctly) signals an error if the class were not defined by the
736 ;;; time of the call. Delayed re-parsing of FRUITBAT into any random specifier
737 ;;; at call time is wrong.
739 ;;; FIXME: symbols which are :PRIMITIVE are inconsistently accepted as singleton
740 ;;; lists. e.g. (BIT) and (ATOM) are considered legal, but (FIXNUM) and
741 ;;; (CHARACTER) are not. It has to do with whether the primitive is actually
742 ;;; a DEFTYPE. The CLHS glossary implies that the singleton is *always* legal.
743 ;;; "For every atomic type specifier, x, there is an _equivalent_ [my emphasis]
744 ;;; compound type specifier with no arguments supplied, (x)."
745 ;;; By that same reasonining, is (x) accepted if x names a class?
748 ;;; The xc host uses an ordinary hash table for memoization.
749 #+sb-xc-host
750 (let ((table (make-hash-table :test 'equal)))
751 (defun !values-specifier-type-memo-wrapper (thunk specifier)
752 (multiple-value-bind (type yesp) (gethash specifier table)
753 (if yesp
754 type
755 (setf (gethash specifier table) (funcall thunk)))))
756 (defun values-specifier-type-cache-clear ()
757 (clrhash table)))
758 ;;; This cache is sized extremely generously, which has payoff
759 ;;; elsewhere: it improves the TYPE= and CSUBTYPEP functions,
760 ;;; since EQ types are an immediate win.
761 #-sb-xc-host
762 (sb!impl::!define-hash-cache values-specifier-type
763 ((orig equal-but-no-car-recursion)) ()
764 :hash-function #'sxhash :hash-bits 10)
766 (defvar *pending-defstruct-type*)
767 (declaim (type classoid *pending-defstruct-type*))
769 ;;; The recursive ("-R" suffixed) entry point for this function
770 ;;; should be used for each nested parser invocation.
771 (defun values-specifier-type-r (context type-specifier)
772 (declare (type cons context))
773 (labels ((fail (spec) ; Q: Shouldn't this signal a TYPE-ERROR ?
774 (error "bad thing to be a type specifier: ~S" spec))
775 (instance-to-ctype (x)
776 (flet ((translate (classoid)
777 ;; Hmm, perhaps this should signal PARSE-UNKNOWN-TYPE
778 ;; if CLASSOID is an instance of UNDEFINED-CLASSOID ?
779 ;; Can that happen?
780 (or (and (built-in-classoid-p classoid)
781 (built-in-classoid-translation classoid))
782 classoid)))
783 (cond ((classoid-p x) (translate x))
784 ;; Avoid TYPEP on SB!MOP:EQL-SPECIALIZER and CLASS because
785 ;; the fake metaobjects do not allow type analysis, and
786 ;; would cause a compiler error as it tries to decide
787 ;; whether any clause of this COND subsumes another.
788 ;; Moreover, we don't require the host to support MOP.
789 #-sb-xc-host
790 ((sb!pcl::classp x) (translate (sb!pcl::class-classoid x)))
791 #-sb-xc-host
792 ((sb!pcl::eql-specializer-p type-specifier)
793 ;; FIXME: these aren't always cached. Should they be?
794 ;; It seems so, as "parsing" constructs a new object.
795 ;; Perhaps better, the EQL specializer itself could store
796 ;; (by memoizing, if not precomputing) a CTYPE
797 (make-eql-type
798 (sb!mop:eql-specializer-object type-specifier)))
799 (t (fail x))))))
800 (when (typep type-specifier 'instance)
801 (return-from values-specifier-type-r (instance-to-ctype type-specifier)))
802 (when (atom type-specifier)
803 ;; Try to bypass the cache, which avoids using a cache line for standard
804 ;; atomic specifiers. This is a trade-off- cache seek might be faster,
805 ;; but this solves the problem that a full call to (TYPEP #\A 'FIXNUM)
806 ;; consed a cache line every time the cache missed on FIXNUM (etc).
807 (awhen (info :type :builtin type-specifier)
808 (return-from values-specifier-type-r it)))
809 (!values-specifier-type-memo-wrapper
810 (lambda ()
811 (labels
812 ((recurse (spec)
813 (prog* ((head (if (listp spec) (car spec) spec))
814 (builtin (if (symbolp head)
815 (info :type :builtin head)
816 (return (fail spec)))))
817 (when (deprecated-thing-p 'type head)
818 (setf (cdr context) nil)
819 (signal 'parse-deprecated-type :specifier spec))
820 (when (atom spec)
821 ;; If spec is non-atomic, the :BUILTIN value is inapplicable.
822 ;; There used to be compound builtins, but not any more.
823 (when builtin (return builtin))
824 ;; Any spec that apparently refers to a defstruct form
825 ;; that's being macroexpanded should refer to that type.
826 (when (boundp '*pending-defstruct-type*)
827 (let ((classoid *pending-defstruct-type*))
828 (when (eq (classoid-name classoid) spec)
829 (setf (cdr context) nil) ; don't cache
830 (return classoid))))
831 (case (info :type :kind spec)
832 (:instance (return (find-classoid spec)))
833 (:forthcoming-defclass-type (go unknown))))
834 ;; Expansion brings up an interesting question - should the cache
835 ;; contain entries for intermediary types? Say A -> B -> REAL.
836 ;; As it stands, we cache the ctype corresponding to A but not B.
837 (awhen (info :type :expander head)
838 (when (listp it) ; The function translates directly to a CTYPE.
839 (return (or (funcall (car it) context spec) (fail spec))))
840 ;; The function produces a type expression.
841 (let ((expansion (funcall it (ensure-list spec))))
842 (return (if (typep expansion 'instance)
843 (instance-to-ctype expansion)
844 (recurse expansion)))))
845 ;; If the spec is (X ...) and X has neither a translator
846 ;; nor expander, and is a builtin, such as FIXNUM, fail now.
847 ;; But - see FIXME at top - it would be consistent with
848 ;; DEFTYPE to reject spec only if not a singleton.
849 (when builtin (return (fail spec)))
850 ;; SPEC has a legal form, so return an unknown type.
851 (signal 'parse-unknown-type :specifier spec)
852 UNKNOWN
853 (setf (cdr context) nil)
854 (return (make-unknown-type :specifier spec)))))
855 (let ((result (recurse (uncross type-specifier))))
856 (if (cdr context) ; cacheable
857 result
858 ;; (The RETURN-FROM here inhibits caching; this makes sense
859 ;; not only from a compiler diagnostics point of view,
860 ;; but also for proper workingness of VALID-TYPE-SPECIFIER-P.
861 (return-from values-specifier-type-r result)))))
862 type-specifier)))
863 (defun values-specifier-type (type-specifier)
864 (dx-let ((context (cons type-specifier t)))
865 (values-specifier-type-r context type-specifier)))
867 ;;; This is like VALUES-SPECIFIER-TYPE, except that we guarantee to
868 ;;; never return a VALUES type.
869 (defun specifier-type-r (context type-specifier)
870 (let ((ctype (values-specifier-type-r context type-specifier)))
871 (when (values-type-p ctype)
872 (error "VALUES type illegal in this context:~% ~S" type-specifier))
873 ctype))
874 (defun specifier-type (type-specifier)
875 (dx-let ((context (cons type-specifier t)))
876 (specifier-type-r context type-specifier)))
878 ;;; Parse TYPE-SPECIFIER, returning NIL if any sub-part of it is unknown
879 (defun type-or-nil-if-unknown (type-specifier &optional allow-values)
880 (dx-let ((context (cons type-specifier t)))
881 (let ((result (values-specifier-type-r context type-specifier)))
882 (when (and (not allow-values) (values-type-p result))
883 (error "VALUES type illegal in this context:~% ~S" type-specifier))
884 ;; If it was non-cacheable, either it contained a deprecated type
885 ;; or unknown type, or was a pending defstruct definition.
886 (if (and (not (cdr context)) (contains-unknown-type-p result))
888 result))))
890 (defun single-value-specifier-type-r (context x)
891 (if (eq x '*) *universal-type* (specifier-type-r context x)))
892 (defun single-value-specifier-type (x)
893 (if (eq x '*)
894 *universal-type*
895 (specifier-type x)))
897 (defun typexpand-1 (type-specifier &optional env)
898 #!+sb-doc
899 "Takes and expands a type specifier once like MACROEXPAND-1.
900 Returns two values: the expansion, and a boolean that is true when
901 expansion happened."
902 (declare (type type-specifier type-specifier))
903 (declare (type lexenv-designator env) (ignore env))
904 (let* ((spec type-specifier)
905 (atom (if (listp spec) (car spec) spec))
906 (expander (and (symbolp atom) (info :type :expander atom))))
907 ;; We do not expand builtins even though it'd be
908 ;; possible to do so sometimes (e.g. STRING) for two
909 ;; reasons:
911 ;; a) From a user's point of view, CL types are opaque.
913 ;; b) so (EQUAL (TYPEXPAND 'STRING) (TYPEXPAND-ALL 'STRING))
914 (if (and (functionp expander) (not (info :type :builtin atom)))
915 (values (funcall expander (if (symbolp spec) (list spec) spec)) t)
916 (values type-specifier nil))))
918 (defun typexpand (type-specifier &optional env)
919 #!+sb-doc
920 "Takes and expands a type specifier repeatedly like MACROEXPAND.
921 Returns two values: the expansion, and a boolean that is true when
922 expansion happened."
923 ;; TYPE-SPECIFIER is of type TYPE-SPECIFIER, but it is preferable to
924 ;; defer to TYPEXPAND-1 for the typecheck. Similarly for ENV.
925 (multiple-value-bind (expansion expanded)
926 (typexpand-1 type-specifier env)
927 (if expanded
928 (values (typexpand expansion env) t)
929 (values expansion expanded))))
931 ;;; Note that the type NAME has been (re)defined, updating the
932 ;;; undefined warnings and VALUES-SPECIFIER-TYPE cache.
933 (defun %note-type-defined (name)
934 (declare (symbol name))
935 (note-name-defined name :type)
936 (values-specifier-type-cache-clear)
937 (values))
940 (!defun-from-collected-cold-init-forms !early-type-cold-init)
942 ;;; When cross-compiling SPECIFIER-TYPE with a quoted argument,
943 ;;; it can be rendered as a literal object unless it:
944 ;;; - mentions a classoid or unknown type
945 ;;; - uses a floating-point literal (perhaps positive zero could be allowed?)
947 ;;; This is important for type system initialization, but it will also
948 ;;; apply to hand-written calls and make-load-form expressions.
950 ;;; After the target is built, we remove this transform, both because calls
951 ;;; to SPECIFIER-TYPE do not arise organically through user code,
952 ;;; and because it is possible that user changes to types could make parsing
953 ;;; return a different thing, e.g. changing a DEFTYPE to a DEFCLASS.
955 #+sb-xc-host
956 (progn
957 (sb!c::define-source-transform specifier-type (type-spec &environment env)
958 (or (and (sb!xc:constantp type-spec env)
959 (let ((parse (specifier-type (constant-form-value type-spec env))))
960 (cond
961 ((contains-unknown-type-p parse)
962 (bug "SPECIFIER-TYPE transform parsed an unknown type"))
963 ((cold-dumpable-type-p parse)
964 ;; Obtain a canonical form by unparsing so that TYPE= specs
965 ;; coalesce in presence of DEFTYPEs. LOAD-TIME-VALUE in the
966 ;; cross-compiler has a special-case to turn !SPECIFIER-TYPE
967 ;; into a fop-funcall, which is handled by genesis.
968 `(load-time-value (!specifier-type ',(type-specifier parse))
969 t)))))
970 (values nil t)))
972 (defun cold-dumpable-type-p (ctype)
973 (named-let recurse ((ctype ctype))
974 (typecase ctype
975 (args-type
976 (and (every #'recurse (args-type-required ctype))
977 (every #'recurse (args-type-optional ctype))
978 (acond ((args-type-rest ctype) (recurse it)) (t))
979 (every (lambda (x) (recurse (key-info-type x)))
980 (args-type-keywords ctype))
981 (if (fun-type-p ctype) (recurse (fun-type-returns ctype)) t)))
982 (compound-type (every #'recurse (compound-type-types ctype)))
983 (negation-type (recurse (negation-type-type ctype)))
984 (array-type (recurse (array-type-element-type ctype)))
985 (cons-type (and (recurse (cons-type-car-type ctype))
986 (recurse (cons-type-cdr-type ctype))))
987 (member-type
988 (and (listp (xset-data (member-type-xset ctype))) ; can't dump hashtable
989 (not (member-type-fp-zeroes ctype)))) ; nor floats
990 (numeric-type
991 ;; Floating-point constants are not dumpable. (except maybe +0.0)
992 (if (or (typep (numeric-type-low ctype) '(or float (cons float)))
993 (typep (numeric-type-high ctype) '(or float (cons float))))
996 (built-in-classoid t)
997 (classoid nil)
998 ;; HAIRY is just an s-expression, so it's dumpable. Same for simd-pack
999 ((or named-type character-set-type hairy-type #!+sb-simd-pack simd-pack-type)
1000 t))))
1002 (setf (get '!specifier-type :sb-cold-funcall-handler/for-value)
1003 (lambda (arg)
1004 (let ((specifier
1005 (if (symbolp arg) arg (sb!fasl::host-object-from-core arg))))
1006 (sb!fasl::ctype-to-core specifier (specifier-type specifier)))))
1008 (setf (info :function :where-from '!specifier-type) :declared) ; lie
1009 ) ; end PROGN