[typedarrays] remove invalid optimization in NAMEConstructor()

Before, we were treating objects with the builtin ArrayValues iterator
method as array-like, where the iterator would iterate through to the
full length of the object.

This optimization was not sound, because it does not ensure that the
next method hasn't been modified. Even if it hasn't been modified,
it's entirely possible to be modified during iteration. Thus, this
optimization has been removed due to its observability.

BUG=v8:5699
R=littledan@chromium.org, cbruni@chromium.org

Review-Url: https://codereview.chromium.org/2544503002
Cr-Commit-Position: refs/heads/master@{#41394}
This commit is contained in:
caitp 2016-11-30 09:12:57 -08:00 committed by Commit bot
parent 80b920124c
commit 77df8c67d9
2 changed files with 26 additions and 1 deletions

View File

@ -260,7 +260,7 @@ function NAMEConstructor(arg1, arg2, arg3) {
NAMEConstructByTypedArray(this, arg1);
} else if (IS_RECEIVER(arg1)) {
var iteratorFn = arg1[iteratorSymbol];
if (IS_UNDEFINED(iteratorFn) || iteratorFn === ArrayValues) {
if (IS_UNDEFINED(iteratorFn)) {
NAMEConstructByArrayLike(this, arg1, arg1.length);
} else {
NAMEConstructByIterable(this, arg1, iteratorFn);

View File

@ -334,6 +334,31 @@ function TestTypedArray(constr, elementSize, typicalElement) {
assertEquals(0, genArr[0]);
assertEquals(9, genArr[9]);
assertEquals(1, iteratorReadCount);
// Modified %ArrayIteratorPrototype%.next() method is honoured (v8:5699)
const ArrayIteratorPrototype = Object.getPrototypeOf([][Symbol.iterator]());
const ArrayIteratorPrototypeNext = ArrayIteratorPrototype.next;
ArrayIteratorPrototype.next = function() {
return { done: true };
};
genArr = new constr([1, 2, 3]);
assertEquals(0, genArr.length);
ArrayIteratorPrototype.next = ArrayIteratorPrototypeNext;
// Modified %ArrayIteratorPrototype%.next() during iteration is honoured as
// well.
genArr = new constr(Object.defineProperty([1, , 3], 1, {
get() {
ArrayIteratorPrototype.next = function() {
return { done: true };
}
return 2;
}
}));
assertEquals(2, genArr.length);
assertEquals(1, genArr[0]);
assertEquals(2, genArr[1]);
ArrayIteratorPrototype.next = ArrayIteratorPrototypeNext;
}
TestTypedArray(Uint8Array, 1, 0xFF);