vector-copy!: fix for impersonated overlapping regions
Ensure memmove-like behavior when source and destination overlap.
This commit is contained in:
parent
e2e469240f
commit
a12a4a51b0
|
@ -732,6 +732,13 @@
|
|||
(err/rt-test (read (open-input-string "#1234567890(0)")) exn:fail:out-of-memory?))
|
||||
(test #t vector? (make-vector 0))
|
||||
|
||||
(let ([b (vector 1 2 3)])
|
||||
(vector-copy! b 0 b 1)
|
||||
(test '#(2 3 3) values b))
|
||||
(let ([b (vector 2 3 4)])
|
||||
(vector-copy! b 1 b 0 2)
|
||||
(test '#(2 2 3) values b))
|
||||
|
||||
(define f (make-string 3 #\*))
|
||||
(test "?**" 'string-set! (begin (string-set! f 0 #\?) f))
|
||||
(arity-test string-set! 3 3)
|
||||
|
|
|
@ -223,6 +223,20 @@
|
|||
(define-values (a b c) (vector->values b2))
|
||||
(test '(1 2 3) list a b c)))
|
||||
|
||||
;; vector-copy! and chaperones
|
||||
(let ([b (vector 1 2 3)])
|
||||
(let ([b2 (impersonate-vector b
|
||||
(lambda (b i v) v)
|
||||
(lambda (b i v) v))])
|
||||
(vector-copy! b 0 b2 1)
|
||||
(test '#(2 3 3) values b)))
|
||||
(let ([b (vector 2 3 4)])
|
||||
(let ([b2 (impersonate-vector b
|
||||
(lambda (b i v) v)
|
||||
(lambda (b i v) v))])
|
||||
(vector-copy! b 1 b2 0 2)
|
||||
(test '#(2 2 3) values b)))
|
||||
|
||||
(define unsafe-chaperone-vector-name "unsafe-chaperone-vector")
|
||||
(define unsafe-impersonate-vector-name "unsafe-impersonate-vector")
|
||||
(define chaperone-vector*-name "chaperone-vector*")
|
||||
|
|
|
@ -825,8 +825,19 @@ static Scheme_Object *vector_copy_bang(int argc, Scheme_Object *argv[])
|
|||
|
||||
if (slow) {
|
||||
int i, o;
|
||||
for (i = istart, o = ostart; i < ifinish; i++, o++) {
|
||||
scheme_chaperone_vector_set(argv[0], o, scheme_chaperone_vector_ref(argv[2], i));
|
||||
if ((s2 == s1)
|
||||
&& (((istart <= ostart) && (ifinish > ostart))
|
||||
|| ((ostart <= istart) && (ofinish > istart)))
|
||||
&& (istart < ostart)) {
|
||||
/* ranges overlap and shifting up: copy from end */
|
||||
for (i = ifinish, o = ofinish; i-- > istart; ) {
|
||||
o--;
|
||||
scheme_chaperone_vector_set(argv[0], o, scheme_chaperone_vector_ref(argv[2], i));
|
||||
}
|
||||
} else {
|
||||
for (i = istart, o = ostart; i < ifinish; i++, o++) {
|
||||
scheme_chaperone_vector_set(argv[0], o, scheme_chaperone_vector_ref(argv[2], i));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
memmove(SCHEME_VEC_ELS(s1) + ostart,
|
||||
|
|
Loading…
Reference in New Issue
Block a user