fix GC-cooperation bug in vector->values
The `vector->values` function set up multiple return values badly in the case that the given vector is chaperoned. The problem could lead to NULL as results for `vector->values`. Merge to v6.1
This commit is contained in:
parent
94bd5369b5
commit
f57c1c8e2a
|
@ -199,6 +199,14 @@
|
|||
(test #f vector-ref b 0)
|
||||
(test #f vector-ref b2 0)))
|
||||
|
||||
;; check interaction of chaperones and vector->values:
|
||||
(let ([b (vector 1 2 3)])
|
||||
(let ([b2 (impersonate-vector b
|
||||
(lambda (b i v) (collect-garbage) v)
|
||||
(lambda (b i v) #f))])
|
||||
(define-values (a b c) (vector->values b2))
|
||||
(test '(1 2 3) list a b c)))
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
(test #t chaperone?/impersonator (chaperone-procedure (lambda (x) x) (lambda (y) y)))
|
||||
|
|
|
@ -771,7 +771,7 @@ static Scheme_Object *vector_to_immutable (int argc, Scheme_Object *argv[])
|
|||
static Scheme_Object *vector_to_values (int argc, Scheme_Object *argv[])
|
||||
{
|
||||
Scheme_Thread *p;
|
||||
Scheme_Object *vec, **a;
|
||||
Scheme_Object *vec, **a, *plain_vec;
|
||||
intptr_t len, start, finish, i;
|
||||
|
||||
vec = argv[0];
|
||||
|
@ -807,6 +807,16 @@ static Scheme_Object *vector_to_values (int argc, Scheme_Object *argv[])
|
|||
return SCHEME_VEC_ELS(vec)[start];
|
||||
}
|
||||
|
||||
if (!SAME_OBJ(vec, argv[0])) {
|
||||
plain_vec = scheme_make_vector(len, NULL);
|
||||
for (i = 0; i < len; i++) {
|
||||
vec = scheme_chaperone_vector_ref(argv[0], start + i);
|
||||
SCHEME_VEC_ELS(plain_vec)[i] = vec;
|
||||
}
|
||||
vec = plain_vec;
|
||||
start = 0;
|
||||
}
|
||||
|
||||
p = scheme_current_thread;
|
||||
if (p->values_buffer && (p->values_buffer_size >= len))
|
||||
a = p->values_buffer;
|
||||
|
@ -819,16 +829,9 @@ static Scheme_Object *vector_to_values (int argc, Scheme_Object *argv[])
|
|||
p->ku.multiple.array = a;
|
||||
p->ku.multiple.count = len;
|
||||
|
||||
if (!SAME_OBJ(vec, argv[0])) {
|
||||
for (i = 0; i < len; i++) {
|
||||
vec = scheme_chaperone_vector_ref(argv[0], start + i);
|
||||
a[i] = vec;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < len; i++) {
|
||||
a[i] = SCHEME_VEC_ELS(vec)[start + i];
|
||||
}
|
||||
}
|
||||
|
||||
return SCHEME_MULTIPLE_VALUES;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user