Change in-fXvector (for flvector and fxvector) to allow start, stop, and end args. Tests segfault in repeatable but apparently unrelated places

This commit is contained in:
Noel Welsh 2010-12-03 12:15:59 +00:00
parent 6761ae8618
commit 319ea7ea00
6 changed files with 79 additions and 38 deletions

View File

@ -1,6 +1,7 @@
#lang scheme/base #lang scheme/base
(require '#%flfxnum (require '#%flfxnum
"private/vector-wraps.rkt") "private/vector-wraps.rkt"
"unsafe/ops.rkt")
(provide fx->fl fl->fx (provide fx->fl fl->fx
fxabs fxabs
@ -18,6 +19,7 @@
(define-vector-wraps "fxvector" (define-vector-wraps "fxvector"
fxvector? fxvector-length fxvector-ref fxvector-set! make-fxvector fxvector? fxvector-length fxvector-ref fxvector-set! make-fxvector
unsafe-fxvector-ref unsafe-fxvector-set! unsafe-fxvector-length
in-fxvector* in-fxvector*
in-fxvector in-fxvector
for/fxvector for/fxvector

View File

@ -1,6 +1,7 @@
#lang racket/base #lang racket/base
(require '#%flfxnum (require '#%flfxnum
"private/vector-wraps.rkt") "private/vector-wraps.rkt"
"unsafe/ops.rkt")
(provide fl+ fl- fl* fl/ (provide fl+ fl- fl* fl/
flabs flsqrt flexp fllog flabs flsqrt flexp fllog
@ -17,6 +18,7 @@
(define-vector-wraps "flvector" (define-vector-wraps "flvector"
flvector? flvector-length flvector-ref flvector-set! make-flvector flvector? flvector-length flvector-ref flvector-set! make-flvector
unsafe-flvector-ref unsafe-flvector-set! unsafe-flvector-length
in-flvector* in-flvector*
in-flvector in-flvector
for/flvector for/flvector

View File

@ -60,7 +60,11 @@
define-sequence-syntax define-sequence-syntax
make-do-sequence make-do-sequence
:do-in) :do-in
define-in-vector-like
define-:vector-like-gen
(for-syntax make-in-vector-like))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; sequence transformers: ;; sequence transformers:

View File

@ -7,6 +7,7 @@
(define-syntax-rule (define-vector-wraps (define-syntax-rule (define-vector-wraps
fXvector-str fXvector-str
fXvector? fXvector-length fXvector-ref fXvector-set! make-fXvector fXvector? fXvector-length fXvector-ref fXvector-set! make-fXvector
unsafe-fXvector-ref unsafe-fXvector-set! unsafe-fXvector-length
in-fXvector* in-fXvector*
in-fXvector in-fXvector
for/fXvector for/fXvector
@ -14,32 +15,17 @@
fXvector-copy) fXvector-copy)
(... (...
(begin (begin
(define (in-fXvector* flv) (define-:vector-like-gen :fXvector-gen unsafe-fXvector-ref)
(let ((n (fXvector-length flv)))
(make-do-sequence (define-in-vector-like in-fXvector*
(lambda () fXvector-str fXvector? fXvector-length :fXvector-gen)
(values (lambda (i) (fXvector-ref flv i))
add1
0
(lambda (i) (fx< i n))
(lambda (x) #t)
(lambda (i x) #t))))))
(define-sequence-syntax in-fXvector (define-sequence-syntax in-fXvector
(lambda () (syntax in-fXvector*)) (lambda () #'in-fXvector*)
(lambda (stx) (make-in-vector-like #'fXvector?
(syntax-case stx () #'unsafe-fXvector-length
(((x) (in-fXvector flv-expr)) #'in-fXvector*
(syntax/loc stx #'unsafe-fXvector-ref))
(() (:do-in (((v) flv-expr))
(when (not (fXvector? v))
(error 'in-fXvector "expecting a ~a, got ~a" fXvector-str v))
((i 0) (n (fXvector-length v)))
(fx< i n)
(((x) (fXvector-ref v i)))
#t
#t
((add1 i) n))))))))
(define (list->fXvector l) (define (list->fXvector l)
(let ((n (length l))) (let ((n (length l)))
@ -108,5 +94,5 @@
(let* ([len (- end start)] (let* ([len (- end start)]
[vec (make-fXvector len)]) [vec (make-fXvector len)])
(for ([i (in-range len)]) (for ([i (in-range len)])
(fXvector-set! vec i (fXvector-ref flv (+ i start)))) (unsafe-fXvector-set! vec i (unsafe-fXvector-ref flv (+ i start))))
vec))))) vec)))))

View File

@ -155,12 +155,35 @@ Creates a fresh @tech{fxvector} of size @racket[(- end start)], with all of the
elements of @racket[vec] from @racket[start] (inclusive) to elements of @racket[vec] from @racket[start] (inclusive) to
@racket[end] (exclusive).} @racket[end] (exclusive).}
@defproc[(in-fxvector (v fxvector?)) sequence?]{ @defproc[(in-fxvector [vec vector?]
[start exact-nonnegative-integer? 0]
[stop (or/c exact-nonnegative-integer? #f) #f]
[step (and/c exact-integer? (not/c zero?)) 1])
sequence?]{
Returns a sequence equivalent to @racket[vec] when no optional
arguments are supplied.
Produces a sequence that gives the elements of @scheme[v] in order. The optional arguments @racket[start], @racket[stop], and
Inside a @scheme[for] form, this can be optimized to step through the @racket[step] are analogous to @racket[in-range], except that a
elements of @scheme[v] efficiently as in @scheme[in-list], @racket[#f] value for @racket[stop] is equivalent to
@scheme[in-vector], etc.} @racket[(vector-length vec)]. That is, the first element in the
sequence is @racket[(vector-ref vec start)], and each successive
element is generated by adding @racket[step] to index of the previous
element. The sequence stops before an index that would be greater or
equal to @racket[end] if @racket[step] is non-negative, or less or
equal to @racket[end] if @racket[step] is negative.
If @racket[start] is less than @racket[stop] and @racket[step] is
negative, then the @exnraise[exn:fail:contract:mismatch]. Similarly,
if @racket[start] is more than @racket[stop] and @racket[step] is
positive, then the @exnraise[exn:fail:contract:mismatch]. The
@racket[start] and @racket[stop] values are @emph{not} checked against
the size of @racket[vec], so access can fail when an element is
demanded from the sequence.
An @racket[in-fxvector] application can provide better
performance for @tech{fxvector} iteration when it appears directly in a @racket[for] clause.
}
@deftogether[( @deftogether[(
@defform*[((for/fxvector (for-clause ...) body ...) @defform*[((for/fxvector (for-clause ...) body ...)

View File

@ -171,12 +171,36 @@ Creates a fresh @tech{flvector} of size @racket[(- end start)], with all of the
elements of @racket[vec] from @racket[start] (inclusive) to elements of @racket[vec] from @racket[start] (inclusive) to
@racket[end] (exclusive).} @racket[end] (exclusive).}
@defproc[(in-flvector (v flvector?)) sequence?]{
Produces a sequence that gives the elements of @scheme[v] in order. @defproc[(in-flvector [vec vector?]
Inside a @scheme[for] form, this can be optimized to step through the [start exact-nonnegative-integer? 0]
elements of @scheme[v] efficiently as in @scheme[in-list], [stop (or/c exact-nonnegative-integer? #f) #f]
@scheme[in-vector], etc.} [step (and/c exact-integer? (not/c zero?)) 1])
sequence?]{
Returns a sequence equivalent to @racket[vec] when no optional
arguments are supplied.
The optional arguments @racket[start], @racket[stop], and
@racket[step] are analogous to @racket[in-range], except that a
@racket[#f] value for @racket[stop] is equivalent to
@racket[(vector-length vec)]. That is, the first element in the
sequence is @racket[(vector-ref vec start)], and each successive
element is generated by adding @racket[step] to index of the previous
element. The sequence stops before an index that would be greater or
equal to @racket[end] if @racket[step] is non-negative, or less or
equal to @racket[end] if @racket[step] is negative.
If @racket[start] is less than @racket[stop] and @racket[step] is
negative, then the @exnraise[exn:fail:contract:mismatch]. Similarly,
if @racket[start] is more than @racket[stop] and @racket[step] is
positive, then the @exnraise[exn:fail:contract:mismatch]. The
@racket[start] and @racket[stop] values are @emph{not} checked against
the size of @racket[vec], so access can fail when an element is
demanded from the sequence.
An @racket[in-flvector] application can provide better
performance for @tech{flvector} iteration when it appears directly in a @racket[for] clause.
}
@deftogether[( @deftogether[(
@defform*[((for/flvector (for-clause ...) body ...) @defform*[((for/flvector (for-clause ...) body ...)