commit 16a2781a8c683c5d10fee560baee00e6da2f055b Author: Jeff Walden jwalden@mit.edu Date: Fri Mar 14 20:01:37 2014 -0400
Bug 983344. r=sfink, a=dveditz --- js/src/jstypedarray.cpp | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-)
diff --git a/js/src/jstypedarray.cpp b/js/src/jstypedarray.cpp index b8cf614..1630c5a 100644 --- a/js/src/jstypedarray.cpp +++ b/js/src/jstypedarray.cpp @@ -2335,6 +2335,10 @@ class TypedArrayTemplate copyFromArray(JSContext *cx, HandleObject thisTypedArrayObj, HandleObject ar, uint32_t len, uint32_t offset = 0) { + // Exit early if nothing to copy, to simplify loop conditions below. + if (len == 0) + return true; + JS_ASSERT(thisTypedArrayObj->isTypedArray()); JS_ASSERT(offset <= length(thisTypedArrayObj)); JS_ASSERT(len <= length(thisTypedArrayObj) - offset); @@ -2344,34 +2348,47 @@ class TypedArrayTemplate const Value *src = NULL; NativeType *dest = static_cast<NativeType*>(viewData(thisTypedArrayObj)) + offset;
- // 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. + // These SkipRoots are to protect from the unconditional + // MaybeCheckStackRoots done by ToNumber. SkipRoot skipDest(cx, &dest); SkipRoot skipSrc(cx, &src);
+#ifdef DEBUG + JSRuntime *runtime = cx->runtime(); + uint64_t gcNumber = runtime->gcNumber; +#endif + if (ar->isArray() && !ar->isIndexed() && ar->getDenseInitializedLength() >= len) { JS_ASSERT(ar->getArrayLength() == len);
src = ar->getDenseElements(); - for (uint32_t i = 0; i < len; ++i) { + uint32_t i = 0; + do { NativeType n; if (!nativeFromValue(cx, src[i], &n)) return false; dest[i] = n; - } + } while (++i < len); + JS_ASSERT(runtime->gcNumber == gcNumber); } else { RootedValue v(cx);
- for (uint32_t i = 0; i < len; ++i) { + uint32_t i = 0; + do { if (!JSObject::getElement(cx, ar, ar, i, &v)) return false; NativeType n; if (!nativeFromValue(cx, v, &n)) return false; + + len = Min(len, length(thisTypedArrayObj)); + if (i >= len) + break; + + // Compute every iteration in case getElement acts wacky. + dest = static_cast<NativeType*>(viewData(thisTypedArrayObj)) + offset; dest[i] = n; - } + } while (++i < len); }
return true;
tor-commits@lists.torproject.org