mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 912734 - Take account of moving GC when copying from an Array into a TypedArray r=sfink
This commit is contained in:
parent
d3d1d3f4cf
commit
c3b7700366
43
js/src/jit-test/tests/gc/bug-912734.js
Normal file
43
js/src/jit-test/tests/gc/bug-912734.js
Normal 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;
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user