|
1 | 1 | (in-package :cl-binary-store) |
2 | 2 |
|
3 | 3 | (defun restore-array (storage restore-object) |
4 | | - (declare (type function restore-object)) |
| 4 | + (declare (type function restore-object) (optimize (speed 3) (safety 1))) |
5 | 5 | (let* ((has-fill-pointer (funcall restore-object)) |
6 | 6 | (fill-pointer (when has-fill-pointer (restore-tagged-unsigned-fixnum storage))) |
7 | 7 | (adjustable (funcall restore-object)) |
8 | 8 | (array-rank (the (unsigned-byte 8) (restore-ub8 storage))) |
9 | 9 | (dimensions (loop repeat array-rank |
10 | 10 | collect (restore-tagged-unsigned-fixnum storage))) |
11 | | - (displaced (funcall restore-object))) |
12 | | - (check-if-too-much-data (read-storage-max-to-read storage) (reduce #'* dimensions)) |
| 11 | + (displaced (funcall restore-object)) |
| 12 | + (array-total-size (reduce #'* dimensions))) |
| 13 | + (unless (and (typep array-total-size 'fixnum) (>= array-total-size 0)) |
| 14 | + (unexpected-data "Array total size is too large")) |
| 15 | + (check-if-too-much-data (read-storage-max-to-read storage) array-total-size) |
13 | 16 | (labels ((check-fill-pointer (dimensions) |
14 | 17 | (when has-fill-pointer |
15 | 18 | (unless (= array-rank 1) |
16 | 19 | (unexpected-data "found fill-pointer for a non-vector")) |
17 | | - (unless (<= fill-pointer (length (first dimensions))) |
18 | | - (unexpected-data (format nil "fill-pointer ~A > dimensions ~A" |
19 | | - fill-pointer dimensions)))))) |
| 20 | + (unless (<= fill-pointer (first dimensions)) |
| 21 | + (unexpected-data "fill-pointer > vector length"))) |
| 22 | + (values))) |
20 | 23 | (if displaced |
21 | 24 | (let ((element-type (funcall restore-object)) |
22 | 25 | (offset (restore-tagged-unsigned-fixnum storage)) |
23 | 26 | (displaced-to (funcall restore-object))) |
24 | 27 | (unless (typep displaced-to 'array) |
25 | | - (unexpected-data "array" displaced-to)) |
| 28 | + (unexpected-data "displaced to a non array?!")) |
26 | 29 | (unless (typep (array-element-type displaced-to) element-type) |
27 | | - (unexpected-data (format nil "array with element-type ~A" element-type) |
28 | | - displaced-to)) |
| 30 | + (unexpected-data "array displaced to array of different element-type")) |
29 | 31 | (unless (< offset (array-total-size displaced-to)) |
30 | | - (unexpected-data (format nil "array of total size > ~A" offset) |
31 | | - displaced-to)) |
| 32 | + (unexpected-data "array displaced to too small array")) |
32 | 33 | (when has-fill-pointer (check-fill-pointer dimensions)) |
33 | 34 | (make-array dimensions :element-type element-type :adjustable adjustable |
34 | 35 | :fill-pointer fill-pointer :displaced-to displaced-to |
|
42 | 43 | ;; We need to make our array first in case any of the array elements refer to it! |
43 | 44 | ;; If we are ever referred to, then there will already be a fixup in place for |
44 | 45 | ;; our array handled by `restore-new-reference-indicator'. |
45 | | - (loop for idx fixnum from 0 below (array-total-size array) |
| 46 | + (loop for idx fixnum from 0 below array-total-size |
46 | 47 | do (restore-object-to (row-major-aref array idx) restore-object)) |
47 | 48 | array)))))) |
48 | 49 |
|
|
0 commit comments