Bug 912734 - Take account of moving GC when copying from an Array into a TypedArray r=sfink

This commit is contained in:
Jon Coppeard 2013-09-27 10:16:56 +01:00
parent d3d1d3f4cf
commit c3b7700366
2 changed files with 63 additions and 8 deletions

View File

@ -0,0 +1,43 @@
(function() {
Object.defineProperty(this, "h2", {
e: false,
e: false,
get: function() {
return {}
}
})
})()
a2 = new Array
Object.create(a2);
(function() {
Object.defineProperty(this, "t2", {
e: true,
e: RegExp(""),
get: function() {
return Uint32Array(this.a2)
}
})
})()
r = (function() {
for each(let c in []) {}
})()
var r = 1;
s = ""
print(s.match(r));
r.l
with(b = 3);
t2;
(function() {
Object.defineProperty(a2, 3, {
e: false,
e: true,
get: (function() {
evalcx("[]", s.g)
})
})
})()
h2
r = RegExp("");
r.exec();
schedulegc(7);
t2;

View File

@ -2251,26 +2251,29 @@ class TypedArrayObjectTemplate : public TypedArrayObject
if (ar->is<TypedArrayObject>())
return copyFromTypedArray(cx, thisTypedArray, ar, offset);
const Value *src = NULL;
NativeType *dest = static_cast<NativeType*>(thisTypedArray->viewData()) + offset;
JSRuntime *runtime = cx->runtime();
uint64_t gcNumber = runtime->gcNumber;
// The only way the code below can GC is if nativeFromValue fails, but
// in that case we return false immediately, so we do not need to root
// |src| and |dest|. These SkipRoots are to protect from the
// unconditional MaybeCheckStackRoots done by ToNumber.
NativeType *dest = static_cast<NativeType*>(thisTypedArray->viewData()) + offset;
SkipRoot skipDest(cx, &dest);
SkipRoot skipSrc(cx, &src);
if (ar->is<ArrayObject>() && !ar->isIndexed() && ar->getDenseInitializedLength() >= len) {
JS_ASSERT(ar->as<ArrayObject>().length() == len);
src = ar->getDenseElements();
/*
* The only way the code below can GC is if nativeFromValue fails,
* but in that case we return false immediately, so we do not need
* to root |src| and |dest|.
*/
const Value *src = ar->getDenseElements();
SkipRoot skipSrc(cx, &src);
for (uint32_t i = 0; i < len; ++i) {
NativeType n;
if (!nativeFromValue(cx, src[i], &n))
return false;
dest[i] = n;
}
JS_ASSERT(runtime->gcNumber == gcNumber);
} else {
RootedValue v(cx);
@ -2280,6 +2283,15 @@ class TypedArrayObjectTemplate : public TypedArrayObject
NativeType n;
if (!nativeFromValue(cx, v, &n))
return false;
/*
* Detect when a GC has occurred so we can update the dest
* pointers in case it has been moved.
*/
if (runtime->gcNumber != gcNumber) {
dest = static_cast<NativeType*>(thisTypedArray->viewData()) + offset;
gcNumber = runtime->gcNumber;
}
dest[i] = n;
}
}