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

View File

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

View File

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

View File

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

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
@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.
Inside a @scheme[for] form, this can be optimized to step through the
elements of @scheme[v] efficiently as in @scheme[in-list],
@scheme[in-vector], etc.}
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-fxvector] application can provide better
performance for @tech{fxvector} iteration when it appears directly in a @racket[for] clause.
}
@deftogether[(
@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
@racket[end] (exclusive).}
@defproc[(in-flvector (v flvector?)) sequence?]{
Produces a sequence that gives the elements of @scheme[v] in order.
Inside a @scheme[for] form, this can be optimized to step through the
elements of @scheme[v] efficiently as in @scheme[in-list],
@scheme[in-vector], etc.}
@defproc[(in-flvector [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.
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[(
@defform*[((for/flvector (for-clause ...) body ...)