The (ARRAY NIL) has landed.
... implement a SIMPLE-ARRAY-NIL primitive type, including in
garbage collection and (ROOM) logic;
... adjust implementation of array creation and reference to
deal with arrays that can't contain anything;
... (HAIRY-)DATA-VECTOR-REF are can no longer be FLUSHABLE;
Enjoy!
compiler gets its hands on the code needing compilation from the REPL,
it has been macroexpanded several times.
-241:
- "DEFCLASS mysteriously remembers uninterned accessor names."
+241: "DEFCLASS mysteriously remembers uninterned accessor names."
(from tonyms on #lisp IRC 2003-02-25)
In sbcl-0.7.12.55, typing
(defclass foo () ((bar :accessor foo-bar)))
DEFSTRUCT-SLOT-DESCRIPTION structure.
changes in sbcl-0.7.14 relative to sbcl-0.7.13:
+ * fixed CEILING optimization for a divisor of form 2^k.
+ * fixed bug 240 (emitting extra style warnings "using the lexical
+ binding of the symbol *XXX*" for &OPTIONAL arguments). (reported
+ by Antonio Martinez)
* fixed some bugs revealed by Paul Dietz' test suite:
** a bug in the CONS type specifier, whereby the CAR and CDR
types got intertwined, has been fixed;
** the type system is now able to reason about the interaction
between INTEGER and RATIO types more completely;
** APPEND checks its arguments for being proper lists;
- * fixed CEILING optimization for a divisor of form 2^k.
- * fixed bug 240 (emitting extra style warnings "using the lexical
- binding of the symbol *XXX*" for &OPTIONAL arguments). (reported
- by Antonio Martinez)
+ ** An array specialized to be unable to hold elements has been
+ implemented (as required -- yes, really) by ANSI;
planned incompatible changes in 0.7.x:
* (not done yet, but planned:) When the profiling interface settles
;; what the problem is and fix it. (See the comments in
;; src/compiler/x86/array for a candidate patch.) -- WHN 19990323
:ignore-failure-p)
+ ("src/compiler/generic/array")
("src/compiler/target/pred")
("src/compiler/target/type-vops")
"NAMED-TYPE" "NAMED-TYPE-NAME" "NAMED-TYPE-P"
"NATIVE-BYTE-ORDER" "NEGATE"
"NEGATION-TYPE" "NEGATION-TYPE-TYPE"
- "NEVER-SUBTYPEP" "NIL-FUN-RETURNED-ERROR"
+ "NEVER-SUBTYPEP" "NIL-ARRAY-ACCESSED-ERROR"
+ "NIL-FUN-RETURNED-ERROR"
"NOT-<=-ERROR" "NOT-=-ERROR"
"NOT-DUMPED-AT-ALL"
"NUMERIC-CONTAGION" "NUMERIC-TYPE"
"OBJECT-NOT-SIMPLE-ARRAY-DOUBLE-FLOAT-ERROR"
"OBJECT-NOT-SIMPLE-ARRAY-ERROR"
#!+long-float "OBJECT-NOT-SIMPLE-ARRAY-LONG-FLOAT-ERROR"
+ "OBJECT-NOT-SIMPLE-ARRAY-NIL-ERROR"
"OBJECT-NOT-SIMPLE-ARRAY-SINGLE-FLOAT-ERROR"
"OBJECT-NOT-SIMPLE-ARRAY-UNSIGNED-BYTE-16-ERROR"
"OBJECT-NOT-SIMPLE-ARRAY-UNSIGNED-BYTE-2-ERROR"
"SIMPLE-ARRAY-COMPLEX-SINGLE-FLOAT-P"
"SIMPLE-ARRAY-DOUBLE-FLOAT-P"
#!+long-float "SIMPLE-ARRAY-LONG-FLOAT-P"
+ "SIMPLE-ARRAY-NIL-P"
"SIMPLE-ARRAY-P"
"SIMPLE-ARRAY-SINGLE-FLOAT-P"
"SIMPLE-ARRAY-UNSIGNED-BYTE-16-P"
"SIMPLE-ARRAY-COMPLEX-SINGLE-FLOAT-WIDETAG"
"SIMPLE-ARRAY-DOUBLE-FLOAT-WIDETAG"
#!+long-float "SIMPLE-ARRAY-LONG-FLOAT-WIDETAG"
+ "SIMPLE-ARRAY-NIL-WIDETAG"
"SIMPLE-ARRAY-SINGLE-FLOAT-WIDETAG"
"SIMPLE-ARRAY-WIDETAG" "SIMPLE-ARRAY-UNSIGNED-BYTE-16-WIDETAG"
"SIMPLE-ARRAY-UNSIGNED-BYTE-2-WIDETAG"
;; FIXME: The data here are redundant with
;; *SPECIALIZED-ARRAY-ELEMENT-TYPE-PROPERTIES*.
(pick-vector-type type
+ (nil (values #.sb!vm:simple-array-nil-widetag 0))
(base-char (values #.sb!vm:simple-string-widetag #.sb!vm:n-byte-bits))
(bit (values #.sb!vm:simple-bit-vector-widetag 1))
((unsigned-byte 2)
(when (and displaced-index-offset (null displaced-to))
(error "can't specify :DISPLACED-INDEX-OFFSET without :DISPLACED-TO"))
(if (and simple (= array-rank 1))
- ;; Its a (simple-array * (*))
+ ;; it's a (SIMPLE-ARRAY * (*))
(multiple-value-bind (type n-bits)
(%vector-widetag-and-n-bits element-type)
(declare (type (unsigned-byte 8) type)
- (type (integer 1 256) n-bits))
+ (type (integer 0 256) n-bits))
(let* ((length (car dimensions))
(array (allocate-vector
type
length))
(replace array initial-contents))
array))
- ;; It's either a complex array or a multidimensional array.
+ ;; it's either a complex array or a multidimensional array.
(let* ((total-size (reduce #'* dimensions))
(data (or displaced-to
(data-vector-from-inits
#!+long-float long-float
(complex single-float)
(complex double-float)
- #!+long-float (complex long-float))))
+ #!+long-float (complex long-float)
+ nil)))
(defun hairy-data-vector-ref (array index)
(with-array-data ((vector array) (index index) (end))
;; FIXME: The data here are redundant with
;; *SPECIALIZED-ARRAY-ELEMENT-TYPE-PROPERTIES*.
(pick-element-type
+ (sb!vm:simple-array-nil-widetag nil)
((sb!vm:simple-string-widetag sb!vm:complex-string-widetag) 'base-char)
((sb!vm:simple-bit-vector-widetag
sb!vm:complex-bit-vector-widetag) 'bit)
(unless (array-header-p vector)
(macrolet ((frob (name &rest things)
`(etypecase ,name
+ ((simple-array nil (*)) (error 'cell-error
+ :name 'nil-array-element))
,@(mapcar (lambda (thing)
(destructuring-bind (type-spec fill-value)
thing
"The START and END parameters ~S and ~S are bad for an array of total size ~S."
start end (array-total-size object))))))))
+(define-condition nil-array-accessed-error (type-error)
+ ()
+ (:report (lambda (condition stream)
+ (format stream
+ "An attempt to access an array of element-type ~
+ NIL was made. Congratulations!"))))
+
(define-condition io-timeout (stream-error)
((direction :reader io-timeout-direction :initarg :direction))
(:report
"A function with declared result type NIL returned:~% ~S"
:format-arguments (list function)))
+(deferr nil-array-accessed-error (array)
+ (error 'nil-array-accessed-error
+ :datum array :expected-type '(not (array nil))))
+
(deferr division-by-zero-error (this that)
(error 'division-by-zero
:operation 'division
:datum object
:expected-type '(unsigned-byte 32)))
+(deferr object-not-simple-array-nil-error (object)
+ (error 'type-error
+ :datum object
+ :expected-type '(simple-array nil (*))))
+
(deferr object-not-simple-array-unsigned-byte-2-error (object)
(error 'type-error
:datum object
(simple-array-double-float-widetag . 3)
(simple-array-complex-single-float-widetag . 3)
(simple-array-complex-double-float-widetag . 4)))
- (let ((name (car stuff))
- (size (cdr stuff)))
+ (let* ((name (car stuff))
+ (size (cdr stuff))
+ (sname (string name)))
(setf (svref *meta-room-info* (symbol-value name))
- (make-room-info :name name
+ (make-room-info :name (intern (subseq sname
+ 0
+ (mismatch sname "-WIDETAG"
+ :from-end t)))
:kind :vector
:length size))))
(setf (svref *meta-room-info* simple-string-widetag)
- (make-room-info :name 'simple-string-widetag
+ (make-room-info :name 'simple-string
:kind :string
:length 0))
+(setf (svref *meta-room-info* simple-array-nil-widetag)
+ (make-room-info :name 'simple-array-nil
+ :kind :fixed
+ :length 2))
+
(setf (svref *meta-room-info* code-header-widetag)
(make-room-info :name 'code
:kind :code))
(:fixed
(aver (or (eql (room-info-length info)
(1+ (get-header-data obj)))
- (floatp obj)))
+ (floatp obj)
+ (simple-array-nil-p obj)))
(round-to-dualword
(* (room-info-length info) n-word-bytes)))
((:vector :string)
stem
*target-obj-suffix*)))
(unless (output-up-to-date-wrt-input-p objname srcname)
- (target-compile-stem stem)))))
+ (target-compile-stem stem
+ :assem-p (find :assem flags)
+ :ignore-failure-p (find :ignore-failure-p flags))))))
(destructuring-bind (type-spec &rest rest) args
(let ((ctype (specifier-type type-spec)))
(apply #'!make-saetp ctype rest))))
- `((base-char ,(code-char 0) 8 ,sb!vm:simple-string-widetag
+ `(;; Erm. Yeah. There aren't a lot of things that make sense
+ ;; for an initial element for (ARRAY NIL). -- CSR, 2002-03-07
+ (nil '#:mu 0 ,sb!vm:simple-array-nil-widetag)
+ (base-char ,(code-char 0) 8 ,sb!vm:simple-string-widetag
;; (SIMPLE-STRINGs are stored with an extra trailing
;; #\NULL for convenience in calling out to C.)
:n-pad-elements 1)
'length
`(+ length ,n-pad-elements)))
(n-words-form
- (if (>= n-bits-per-element sb!vm:n-word-bits)
- `(* ,padded-length-form
- (the fixnum ; i.e., not RATIO
- ,(/ n-bits-per-element sb!vm:n-word-bits)))
- (let ((n-elements-per-word (/ sb!vm:n-word-bits
- n-bits-per-element)))
- (declare (type index n-elements-per-word)) ; i.e., not RATIO
- `(ceiling ,padded-length-form ,n-elements-per-word)))))
+ (cond
+ ((= n-bits-per-element 0) 0)
+ ((>= n-bits-per-element sb!vm:n-word-bits)
+ `(* ,padded-length-form
+ (the fixnum ; i.e., not RATIO
+ ,(/ n-bits-per-element sb!vm:n-word-bits))))
+ (t
+ (let ((n-elements-per-word (/ sb!vm:n-word-bits
+ n-bits-per-element)))
+ (declare (type index n-elements-per-word)) ; i.e., not RATIO
+ `(ceiling ,padded-length-form ,n-elements-per-word))))))
(values
`(truly-the ,result-type-spec
(allocate-vector ,typecode length ,n-words-form))
(defknown vector (&rest t) simple-vector (flushable unsafe))
-(defknown aref (array &rest index) t (foldable flushable))
-(defknown row-major-aref (array index) t (foldable flushable))
+(defknown aref (array &rest index) t (foldable))
+(defknown row-major-aref (array index) t (foldable))
(defknown array-element-type (array)
type-specifier
(defknown %negate (number) number (movable foldable flushable explicit-check))
(defknown %check-bound (array index fixnum) index (movable foldable flushable))
(defknown data-vector-ref (simple-array index) t
- (foldable flushable explicit-check))
+ (foldable explicit-check))
(defknown data-vector-set (array index t) t (unsafe explicit-check))
(defknown hairy-data-vector-ref (array index) t
- (foldable flushable explicit-check))
+ (foldable explicit-check))
(defknown hairy-data-vector-set (array index t) t (unsafe explicit-check))
(defknown %caller-frame-and-pc () (values t t) (flushable))
(defknown %with-array-data (array index (or index null))
simple-string
simple-bit-vector
simple-vector
+ simple-array-nil
simple-array-unsigned-byte-2
simple-array-unsigned-byte-4
simple-array-unsigned-byte-8
"Object is not of type (SIGNED-BYTE 32).")
(object-not-unsigned-byte-32
"Object is not of type (UNSIGNED-BYTE 32).")
+ (object-not-simple-array-nil
+ "Object is not of type (SIMPLE-ARRAY NIL (*)).")
(object-not-simple-array-unsigned-byte-2
"Object is not of type (SIMPLE-ARRAY (UNSIGNED-BYTE 2) (*)).")
(object-not-simple-array-unsigned-byte-4
"Object is not of type BASE-CHAR.")
(nil-fun-returned
"A function with declared result type NIL returned.")
+ (nil-array-accessed
+ "An array with element-type NIL was accessed.")
(layout-invalid
"Object layout is invalid. (indicates obsolete instance)")
(object-not-complex-vector
object-not-simple-vector-error
(simple-vector-widetag))
+(!define-type-vops simple-array-nil-p
+ check-simple-array-nil
+ simple-array-nil
+ object-not-simple-array-nil-error
+ (simple-array-nil-widetag))
+
(!define-type-vops simple-array-unsigned-byte-2-p
check-simple-array-unsigned-byte-2
simple-array-unsigned-byte-2
(!define-type-vops vectorp check-vector nil object-not-vector-error
(simple-string-widetag
+ simple-array-nil-widetag
simple-bit-vector-widetag
simple-vector-widetag
simple-array-unsigned-byte-2-widetag
object-not-simple-array-error
(simple-array-widetag
simple-string-widetag
+ simple-array-nil-widetag
simple-bit-vector-widetag
simple-vector-widetag
simple-array-unsigned-byte-2-widetag
(!define-type-vops arrayp check-array nil object-not-array-error
(simple-array-widetag
simple-string-widetag
+ simple-array-nil-widetag
simple-bit-vector-widetag
simple-vector-widetag
simple-array-unsigned-byte-2-widetag
;;; primitive other-pointer array types
(/show0 "primtype.lisp 96")
+(!def-primitive-type simple-array-nil (descriptor-reg)
+ :type (simple-array nil (*)))
(!def-primitive-type simple-string (descriptor-reg)
:type simple-base-string)
(!def-primitive-type simple-bit-vector (descriptor-reg))
*backend-t-primitive-type*))))
(defvar *simple-array-primitive-types*
- '((base-char . simple-string)
+ '((nil . simple-array-nil)
+ (base-char . simple-string)
(bit . simple-bit-vector)
((unsigned-byte 2) . simple-array-unsigned-byte-2)
((unsigned-byte 4) . simple-array-unsigned-byte-4)
complex-vector-p
base-char-p %standard-char-p %instancep
array-header-p
- simple-array-p simple-array-unsigned-byte-2-p
+ simple-array-p simple-array-nil-p
+ simple-array-unsigned-byte-2-p
simple-array-unsigned-byte-4-p simple-array-unsigned-byte-8-p
simple-array-unsigned-byte-16-p simple-array-unsigned-byte-32-p
simple-array-signed-byte-8-p simple-array-signed-byte-16-p
(defvar *specialized-array-element-types*)
(!cold-init-forms
(setf *specialized-array-element-types*
- '(bit
+ '(nil
+ bit
(unsigned-byte 2)
(unsigned-byte 4)
(unsigned-byte 8)
(define-type-predicate short-float-p short-float)
(define-type-predicate single-float-p single-float)
(define-type-predicate simple-array-p simple-array)
+(define-type-predicate simple-array-nil-p (simple-array nil (*)))
(define-type-predicate simple-array-unsigned-byte-2-p
(simple-array (unsigned-byte 2) (*)))
(define-type-predicate simple-array-unsigned-byte-4-p
}
static int
+scav_vector_nil(lispobj *where, lispobj object)
+{
+ return 2;
+}
+
+static lispobj
+trans_vector_nil(lispobj object)
+{
+ gc_assert(is_lisp_pointer(object));
+ return copy_unboxed_object(object, 2);
+}
+
+static int
+size_vector_nil(lispobj *where)
+{
+ /* Just the header word and the length word */
+ return 2;
+}
+
+static int
scav_vector_bit(lispobj *where, lispobj object)
{
struct vector *vector;
scavtab[SIMPLE_ARRAY_WIDETAG] = scav_boxed;
scavtab[SIMPLE_STRING_WIDETAG] = scav_string;
scavtab[SIMPLE_BIT_VECTOR_WIDETAG] = scav_vector_bit;
+ scavtab[SIMPLE_ARRAY_NIL_WIDETAG] = scav_vector_nil;
scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG] =
scav_vector_unsigned_byte_2;
scavtab[SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG] =
transother[SIMPLE_STRING_WIDETAG] = trans_string;
transother[SIMPLE_BIT_VECTOR_WIDETAG] = trans_vector_bit;
transother[SIMPLE_VECTOR_WIDETAG] = trans_vector;
+ transother[SIMPLE_ARRAY_NIL_WIDETAG] = trans_vector_nil;
transother[SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG] =
trans_vector_unsigned_byte_2;
transother[SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG] =
sizetab[SIMPLE_STRING_WIDETAG] = size_string;
sizetab[SIMPLE_BIT_VECTOR_WIDETAG] = size_vector_bit;
sizetab[SIMPLE_VECTOR_WIDETAG] = size_vector;
+ sizetab[SIMPLE_ARRAY_NIL_WIDETAG] = size_vector_nil;
sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG] =
size_vector_unsigned_byte_2;
sizetab[SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG] =
#endif
case SIMPLE_STRING_WIDETAG:
case SIMPLE_BIT_VECTOR_WIDETAG:
+ case SIMPLE_ARRAY_NIL_WIDETAG:
case SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG:
case SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG:
case SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG:
case BIGNUM_WIDETAG:
case SIMPLE_STRING_WIDETAG:
case SIMPLE_BIT_VECTOR_WIDETAG:
+ case SIMPLE_ARRAY_NIL_WIDETAG:
case SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG:
case SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG:
case SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG:
#endif
case SIMPLE_STRING_WIDETAG:
case SIMPLE_BIT_VECTOR_WIDETAG:
+ case SIMPLE_ARRAY_NIL_WIDETAG:
case SIMPLE_ARRAY_UNSIGNED_BYTE_2_WIDETAG:
case SIMPLE_ARRAY_UNSIGNED_BYTE_4_WIDETAG:
case SIMPLE_ARRAY_UNSIGNED_BYTE_8_WIDETAG:
(let ((x (copy-seq #*0011))
(y (copy-seq #*0101)))
(assert (equalp (bit-and x y nil) #*0001)))
+
+;;; arrays of NIL should work, FSVO "work".
+(let ((a (make-array '(10 10) :element-type 'nil)))
+ (assert (= (array-total-size a) 100))
+ (assert (equal (array-dimensions a) '(10 10)))
+ (assert (eq (array-element-type a) 'nil)))
+
+(assert (eq (upgraded-array-element-type 'nil) 'nil))
;;; versions, especially for internal versions off the main CVS
;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"0.7.13.20"
+"0.7.13.21"