run-program: support I/O redirection to binary streams on win32.
[sbcl.git] / src / code / specializable-array.lisp
blob4ecfc7b053889672afd797a6793ca568b59b4785
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 ;;; ANSI doesn't guarantee the existence of specialized vectors
13 ;;; other than T, BIT, CHARACTER.
14 ;;; Thus, if we do
15 ;;; (MAKE-ARRAY 10 :ELEMENT-TYPE '(UNSIGNED-BYTE 4))
16 ;;; in the cross-compilation host, we could easily end up with a
17 ;;; vector of (UNSIGNED-BYTE 8) or of T, and the dumped result would
18 ;;; reflect this.
19 ;;;
20 ;;; To reduce the prominence of this issue in cross-compilation, we
21 ;;; record arrays that should be specialized in a hashtable.
22 ;;; Fasl dumping will complain about a specialized array that does not
23 ;;; have an entry in the table.
25 ;;; Previously some specialized arrays were "weakened" to (ARRAY T) in the
26 ;;; cross-compiler which served to show that the code was indifferent to
27 ;;; specialization, but made no guarantees about what array type was dumped.
28 ;;; Explicit code was needed to make correct constant arrays at load-time.
29 ;;; The current approach permits use of array constants in an easy way that
30 ;;; avoids host-Lisp-based reflection, and avoids having a DEFTYPE that
31 ;;; changes its meaning between the host and target compilations.
33 ;;; The motivation for this host-agnostic approach is that it supports dumping
34 ;;; (UNSIGNED-BYTE 64) array literals in a 32-bit cross-compilation host,
35 ;;; where that array type is almost surely upgraded to (ARRAY T).
36 ;;; Therefore a host-reflection-based mechanism would be almost certain to fail.
38 ;;; In case anyone wants to rewrite this yet again, here's an alternate way
39 ;;; that was deemed unworkable: in cross-compilation, all specialized arrays
40 ;;; were wrapped in an XC-ARRAY-WRAPPER struct consisting of one slot for
41 ;;; the desired element-type and one slot with the real array. All affected
42 ;;; uses of AREF and (SETF AREF) had to be macroized so that the cross-compiler
43 ;;; could use (AREF (XC-ARRAY-WRAPPER-DATA obj) index) where the real compiler,
44 ;;; and all code compiled by it, would just use AREF using a single abstraction.
45 ;;; CTYPE-OF was hacked to return ARRAY for an xc-array-wrapper which
46 ;;; meant that the cross-compiler thought that transforms on arrays should run
47 ;;; on wrappers, e.g. the foldable function LENGTH should look into wrappers,
48 ;;; as could bounds-checks (ARRAY-DIMENSION). This technique led to confusing
49 ;;; code within the compiler and was abandoned in favor of the hashtable.
51 #-sb-xc-host
52 ;; The target code is trivial
53 (defmacro !make-specialized-array (length element-type &optional contents)
54 `(make-array ,length :element-type ,element-type
55 ,@(if contents `(:initial-contents ,contents))))
57 #+sb-xc-host
58 (progn
59 ;; Use this only for array specializations that are not required by ANSI.
60 (defmacro !make-specialized-array (length element-type &optional contents)
61 (once-only ((et element-type))
62 `(register-specialized-array
63 (make-array ,length :element-type ,et
64 ,@(if contents
65 `(:initial-contents ,contents)
66 ;; Initialize in case it upgrades to (ARRAY T)
67 ;; and gets filled with NIL where SBCL would 0-fill.
68 `(:initial-element 0)))
69 ,et)))
70 (defun !coerce-to-specialized (data element-type)
71 (register-specialized-array (coerce data `(simple-array ,element-type 1))
72 element-type))
73 ;; The specialized array registry has file-wide scope. Hacking that aspect
74 ;; into the xc build scaffold seemed preferable to hacking the compiler.
75 (defun register-specialized-array (array element-type)
76 (setf (gethash array sb-cold::*array-to-specialization*) element-type)
77 array)
78 (defun !specialized-array-element-type (array)
79 (cond ((gethash array sb-cold::*array-to-specialization*))
80 ((bit-vector-p array) 'bit)
81 ((stringp array) 'base-char)
82 (t t))))