;;;; implementations, and the ordinary fop implementations are defined in terms
;;;; of fast-read operations.)
-(defmacro prepare-for-fast-read-byte (stream &body forms)
- `(let ((%frc-stream% ,stream))
- ,@forms))
-
-(defmacro fast-read-byte (&optional (eof-error-p t) (eof-value nil) any-type)
- (declare (ignore any-type))
- `(read-byte %frc-stream% ,eof-error-p ,eof-value))
-
-(defmacro done-with-fast-read-byte ()
- `(values))
+(defmacro with-fast-read-byte ((type stream &optional (eof-error-p t) eof-value)
+ &body body)
+ (declare (ignore type))
+ (let ((f-stream (gensym "STREAM"))
+ (f-eof-error-p (gensym "EOF-ERROR-P"))
+ (f-eof-value (gensym "EOF-VALUE")))
+ `(let ((,f-stream ,stream)
+ (,f-eof-error-p ,eof-error-p)
+ (,f-eof-value ,eof-value))
+ (flet ((fast-read-byte ()
+ (the ,type (read-byte ,f-stream ,f-eof-error-p ,f-eof-value))))
+ ,@body))))
(load-s-integer (clone-arg)))
(define-fop (fop-word-integer 35)
- (prepare-for-fast-read-byte *fasl-input-stream*
- (prog1
- (fast-read-s-integer #.sb!vm:n-word-bytes)
- (done-with-fast-read-byte))))
+ (with-fast-read-byte ((unsigned-byte 8) *fasl-input-stream*)
+ (fast-read-s-integer #.sb!vm:n-word-bytes)))
(define-fop (fop-byte-integer 36)
- (prepare-for-fast-read-byte *fasl-input-stream*
- (prog1
- (fast-read-s-integer 1)
- (done-with-fast-read-byte))))
+ (with-fast-read-byte ((unsigned-byte 8) *fasl-input-stream*)
+ (fast-read-s-integer 1)))
(define-fop (fop-ratio 70)
(let ((den (pop-stack)))
(macrolet ((define-complex-fop (name fop-code type)
(let ((reader (symbolicate "FAST-READ-" type)))
`(define-fop (,name ,fop-code)
- (prepare-for-fast-read-byte *fasl-input-stream*
- (prog1
- (complex (,reader) (,reader))
- (done-with-fast-read-byte))))))
+ (with-fast-read-byte ((unsigned-byte 8) *fasl-input-stream*)
+ (complex (,reader) (,reader))))))
(define-float-fop (name fop-code type)
(let ((reader (symbolicate "FAST-READ-" type)))
`(define-fop (,name ,fop-code)
- (prepare-for-fast-read-byte *fasl-input-stream*
- (prog1
- (,reader)
- (done-with-fast-read-byte)))))))
+ (with-fast-read-byte ((unsigned-byte 8) *fasl-input-stream*)
+ (,reader))))))
(define-complex-fop fop-complex-single-float 72 single-float)
(define-complex-fop fop-complex-double-float 73 double-float)
#!+long-float
;;; extra bits. This must be packed according to the local
;;; byte-ordering, allowing us to directly read the bits.
(define-fop (fop-int-vector 43)
- (prepare-for-fast-read-byte *fasl-input-stream*
- (let* ((len (fast-read-u-integer #.sb!vm:n-word-bytes))
- (size (fast-read-byte))
- (res (case size
- (0 (make-array len :element-type 'nil))
- (1 (make-array len :element-type 'bit))
- (2 (make-array len :element-type '(unsigned-byte 2)))
- (4 (make-array len :element-type '(unsigned-byte 4)))
- (7 (prog1 (make-array len :element-type '(unsigned-byte 7))
- (setf size 8)))
- (8 (make-array len :element-type '(unsigned-byte 8)))
- (15 (prog1 (make-array len :element-type '(unsigned-byte 15))
- (setf size 16)))
- (16 (make-array len :element-type '(unsigned-byte 16)))
- (31 (prog1 (make-array len :element-type '(unsigned-byte 31))
- (setf size 32)))
- (32 (make-array len :element-type '(unsigned-byte 32)))
- #!+#.(cl:if (cl:= 64 sb!vm:n-word-bits) '(and) '(or))
- (63 (prog1 (make-array len :element-type '(unsigned-byte 63))
- (setf size 64)))
- (64 (make-array len :element-type '(unsigned-byte 64)))
- (t (bug "losing i-vector element size: ~S" size)))))
- (declare (type index len))
- (done-with-fast-read-byte)
- (read-n-bytes *fasl-input-stream*
- res
- 0
- (ceiling (the index (* size len)) sb!vm:n-byte-bits))
- res)))
+ (let* ((len (read-word-arg))
+ (size (read-byte-arg))
+ (res (case size
+ (0 (make-array len :element-type 'nil))
+ (1 (make-array len :element-type 'bit))
+ (2 (make-array len :element-type '(unsigned-byte 2)))
+ (4 (make-array len :element-type '(unsigned-byte 4)))
+ (7 (prog1 (make-array len :element-type '(unsigned-byte 7))
+ (setf size 8)))
+ (8 (make-array len :element-type '(unsigned-byte 8)))
+ (15 (prog1 (make-array len :element-type '(unsigned-byte 15))
+ (setf size 16)))
+ (16 (make-array len :element-type '(unsigned-byte 16)))
+ (31 (prog1 (make-array len :element-type '(unsigned-byte 31))
+ (setf size 32)))
+ (32 (make-array len :element-type '(unsigned-byte 32)))
+ #!+#.(cl:if (cl:= 64 sb!vm:n-word-bits) '(and) '(or))
+ (63 (prog1 (make-array len :element-type '(unsigned-byte 63))
+ (setf size 64)))
+ (64 (make-array len :element-type '(unsigned-byte 64)))
+ (t (bug "losing i-vector element size: ~S" size)))))
+ (declare (type index len))
+ (read-n-bytes *fasl-input-stream*
+ res
+ 0
+ (ceiling (the index (* size len)) sb!vm:n-byte-bits))
+ res))
;;; This is the same as FOP-INT-VECTOR, except this is for signed
;;; SIMPLE-ARRAYs.
(define-fop (fop-signed-int-vector 50)
- (prepare-for-fast-read-byte *fasl-input-stream*
- (let* ((len (fast-read-u-integer #.sb!vm:n-word-bytes))
- (size (fast-read-byte))
- (res (case size
- (8 (make-array len :element-type '(signed-byte 8)))
- (16 (make-array len :element-type '(signed-byte 16)))
- #!+#.(cl:if (cl:= 32 sb!vm:n-word-bits) '(and) '(or))
- (29 (prog1 (make-array len :element-type '(unsigned-byte 29))
- (setf size 32)))
- #!+#.(cl:if (cl:= 32 sb!vm:n-word-bits) '(and) '(or))
- (30 (prog1 (make-array len :element-type '(signed-byte 30))
- (setf size 32)))
- (32 (make-array len :element-type '(signed-byte 32)))
- #!+#.(cl:if (cl:= 64 sb!vm:n-word-bits) '(and) '(or))
- (60 (prog1 (make-array len :element-type '(unsigned-byte 60))
- (setf size 64)))
- #!+#.(cl:if (cl:= 64 sb!vm:n-word-bits) '(and) '(or))
- (61 (prog1 (make-array len :element-type '(signed-byte 61))
- (setf size 64)))
- #!+#.(cl:if (cl:= 64 sb!vm:n-word-bits) '(and) '(or))
- (64 (make-array len :element-type '(signed-byte 64)))
- (t (bug "losing si-vector element size: ~S" size)))))
- (declare (type index len))
- (done-with-fast-read-byte)
- (read-n-bytes *fasl-input-stream*
- res
- 0
- (ceiling (the index (* size len)) sb!vm:n-byte-bits))
- res)))
+ (let* ((len (read-word-arg))
+ (size (read-byte-arg))
+ (res (case size
+ (8 (make-array len :element-type '(signed-byte 8)))
+ (16 (make-array len :element-type '(signed-byte 16)))
+ #!+#.(cl:if (cl:= 32 sb!vm:n-word-bits) '(and) '(or))
+ (29 (prog1 (make-array len :element-type '(unsigned-byte 29))
+ (setf size 32)))
+ #!+#.(cl:if (cl:= 32 sb!vm:n-word-bits) '(and) '(or))
+ (30 (prog1 (make-array len :element-type '(signed-byte 30))
+ (setf size 32)))
+ (32 (make-array len :element-type '(signed-byte 32)))
+ #!+#.(cl:if (cl:= 64 sb!vm:n-word-bits) '(and) '(or))
+ (60 (prog1 (make-array len :element-type '(unsigned-byte 60))
+ (setf size 64)))
+ #!+#.(cl:if (cl:= 64 sb!vm:n-word-bits) '(and) '(or))
+ (61 (prog1 (make-array len :element-type '(signed-byte 61))
+ (setf size 64)))
+ #!+#.(cl:if (cl:= 64 sb!vm:n-word-bits) '(and) '(or))
+ (64 (make-array len :element-type '(signed-byte 64)))
+ (t (bug "losing si-vector element size: ~S" size)))))
+ (declare (type index len))
+ (read-n-bytes *fasl-input-stream*
+ res
+ 0
+ (ceiling (the index (* size len)) sb!vm:n-byte-bits))
+ res))
(define-fop (fop-eval 53)
(if *skip-until*
;;; Just like PREPARE-FOR-FAST-READ-CHAR except that we get the BIN
;;; method. The stream is assumed to be a ANSI-STREAM.
;;;
-;;; KLUDGE: It seems weird to have to remember to explicitly call
-;;; DONE-WITH-FAST-READ-BYTE at the end of this, given that we're
-;;; already wrapping the stuff inside in a block. Why not rename this
-;;; macro to WITH-FAST-READ-BYTE, do the DONE-WITH-FAST-READ-BYTE stuff
-;;; automatically at the end of the block, and eliminate
-;;; DONE-WITH-FAST-READ-BYTE as a separate entity? (and similarly
-;;; for the FAST-READ-CHAR stuff) -- WHN 19990825
-(defmacro prepare-for-fast-read-byte (stream &body forms)
- `(let* ((%frc-stream% ,stream)
- (%frc-method% (ansi-stream-bin %frc-stream%))
- (%frc-buffer% (ansi-stream-in-buffer %frc-stream%))
- (%frc-index% (ansi-stream-in-index %frc-stream%)))
- (declare (type index %frc-index%)
- (type ansi-stream %frc-stream%))
- ,@forms))
-
-;;; Similar to fast-read-char, but we use a different refill routine & don't
-;;; convert to characters. If ANY-TYPE is true, then this can be used on any
-;;; integer streams, and we don't assert the result type.
-(defmacro fast-read-byte (&optional (eof-error-p t) (eof-value ()) any-type)
- ;; KLUDGE: should use ONCE-ONLY on EOF-ERROR-P and EOF-VALUE -- WHN 19990825
- `(truly-the
- ,(if (and (eq eof-error-p t) (not any-type)) '(unsigned-byte 8) t)
- (cond
- ((not %frc-buffer%)
- (funcall %frc-method% %frc-stream% ,eof-error-p ,eof-value))
- ((= %frc-index% +ansi-stream-in-buffer-length+)
- (prog1 (fast-read-byte-refill %frc-stream% ,eof-error-p ,eof-value)
- (setq %frc-index% (ansi-stream-in-index %frc-stream%))))
- (t
- (prog1 (aref %frc-buffer% %frc-index%)
- (incf %frc-index%))))))
-(defmacro done-with-fast-read-byte ()
- `(done-with-fast-read-char))
+;;; FIXME: Refactor PREPARE-FOR-FAST-READ-CHAR into similar shape.
+(defmacro with-fast-read-byte ((type stream &optional (eof-error-p t) eof-value)
+ &body body)
+ (aver (or (eq t eof-error-p) (eq t type)))
+ (with-unique-names (f-stream f-method f-buffer f-index eof-p eof-val)
+ `(let* ((,f-stream ,stream)
+ (,eof-p ,eof-error-p)
+ (,eof-val ,eof-value)
+ (,f-method (ansi-stream-bin ,f-stream))
+ (,f-buffer (ansi-stream-in-buffer ,f-stream))
+ (,f-index (ansi-stream-in-index ,f-stream)))
+ (declare (type ansi-stream ,f-stream)
+ (type index ,f-index))
+ (declare (disable-package-locks fast-read-byte))
+ (flet ((fast-read-byte ()
+ (,@(cond ((equal '(unsigned-byte 8) type)
+ ;; KLUDGE: For some reason I haven't tracked down
+ ;; this makes a difference even in given the TRULY-THE.
+ `(logand #xff))
+ (t
+ `(identity)))
+ (truly-the ,type
+ (cond
+ ((not ,f-buffer)
+ (funcall ,f-method ,f-stream ,eof-p ,eof-val))
+ ((= ,f-index +ansi-stream-in-buffer-length+)
+ (prog1 (fast-read-byte-refill ,f-stream ,eof-p ,eof-val)
+ (setq ,f-index (ansi-stream-in-index ,f-stream))))
+ (t
+ (prog1 (aref ,f-buffer ,f-index)
+ (incf ,f-index))))))))
+ (declare (inline fast-read-byte))
+ (declare (enable-package-locks read-byte))
+ (unwind-protect
+ (locally ,@body)
+ (setf (ansi-stream-in-index ,f-stream) ,f-index))))))