Don't expose Array.prototype.values as it breaks webcompat

Some versions of Outlook Web Access test for the existence of a 'values'
property on Array instances, so adding the 'values' iterator to the prototype
(even with @@unscopeables) causes breakage.

This matches Gecko: they ship Array.prototype.{keys,entries} but not 'values'.

BUG=409858
LOG=Y
R=arv@chromium.org, danno@chromium.org

Review URL: https://codereview.chromium.org/647703003

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24706 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
adamk@chromium.org 2014-10-17 20:11:47 +00:00
parent e3ad693020
commit 730c3fa3e0
5 changed files with 20 additions and 24 deletions

View File

@ -120,8 +120,8 @@ function ExtendArrayPrototype() {
%CheckIsBootstrapping(); %CheckIsBootstrapping();
InstallFunctions($Array.prototype, DONT_ENUM, $Array( InstallFunctions($Array.prototype, DONT_ENUM, $Array(
// No 'values' since it breaks webcompat: http://crbug.com/409858
'entries', ArrayEntries, 'entries', ArrayEntries,
'values', ArrayValues,
'keys', ArrayKeys 'keys', ArrayKeys
)); ));

View File

@ -1499,7 +1499,6 @@ function SetUpArray() {
find: true, find: true,
findIndex: true, findIndex: true,
keys: true, keys: true,
values: true,
}; };
%AddNamedProperty($Array.prototype, symbolUnscopables, unscopables, %AddNamedProperty($Array.prototype, symbolUnscopables, unscopables,
DONT_ENUM | READ_ONLY); DONT_ENUM | READ_ONLY);

View File

@ -16,8 +16,8 @@ function TestDirectArgumentsIteratorProperty() {
assertTrue(descriptor.writable); assertTrue(descriptor.writable);
assertFalse(descriptor.enumerable); assertFalse(descriptor.enumerable);
assertTrue(descriptor.configurable); assertTrue(descriptor.configurable);
assertEquals(descriptor.value, [].values); assertEquals(descriptor.value, [][Symbol.iterator]);
assertEquals(arguments[Symbol.iterator], [].values); assertEquals(arguments[Symbol.iterator], [][Symbol.iterator]);
} }
TestDirectArgumentsIteratorProperty(); TestDirectArgumentsIteratorProperty();
@ -26,7 +26,7 @@ function TestIndirectArgumentsIteratorProperty() {
var o = arguments; var o = arguments;
assertTrue(o.hasOwnProperty(Symbol.iterator)); assertTrue(o.hasOwnProperty(Symbol.iterator));
assertFalse(o.propertyIsEnumerable(Symbol.iterator)); assertFalse(o.propertyIsEnumerable(Symbol.iterator));
assertEquals(o[Symbol.iterator], [].values); assertEquals(o[Symbol.iterator], [][Symbol.iterator]);
} }
TestIndirectArgumentsIteratorProperty(); TestIndirectArgumentsIteratorProperty();
@ -204,27 +204,27 @@ function TestArgumentsAsProto() {
"use strict"; "use strict";
var o = {__proto__:arguments}; var o = {__proto__:arguments};
assertSame([].values, o[Symbol.iterator]); assertSame([][Symbol.iterator], o[Symbol.iterator]);
// Make o dict-mode. // Make o dict-mode.
%OptimizeObjectForAddingMultipleProperties(o, 0); %OptimizeObjectForAddingMultipleProperties(o, 0);
assertFalse(o.hasOwnProperty(Symbol.iterator)); assertFalse(o.hasOwnProperty(Symbol.iterator));
assertSame([].values, o[Symbol.iterator]); assertSame([][Symbol.iterator], o[Symbol.iterator]);
o[Symbol.iterator] = 10; o[Symbol.iterator] = 10;
assertTrue(o.hasOwnProperty(Symbol.iterator)); assertTrue(o.hasOwnProperty(Symbol.iterator));
assertEquals(10, o[Symbol.iterator]); assertEquals(10, o[Symbol.iterator]);
assertSame([].values, arguments[Symbol.iterator]); assertSame([][Symbol.iterator], arguments[Symbol.iterator]);
// Frozen o. // Frozen o.
o = Object.freeze({__proto__:arguments}); o = Object.freeze({__proto__:arguments});
assertSame([].values, o[Symbol.iterator]); assertSame([][Symbol.iterator], o[Symbol.iterator]);
assertFalse(o.hasOwnProperty(Symbol.iterator)); assertFalse(o.hasOwnProperty(Symbol.iterator));
assertSame([].values, o[Symbol.iterator]); assertSame([][Symbol.iterator], o[Symbol.iterator]);
// This should throw, but currently it doesn't, because // This should throw, but currently it doesn't, because
// ExecutableAccessorInfo callbacks don't see the current strict mode. // ExecutableAccessorInfo callbacks don't see the current strict mode.
// See note in accessors.cc:SetPropertyOnInstanceIfInherited. // See note in accessors.cc:SetPropertyOnInstanceIfInherited.
o[Symbol.iterator] = 10; o[Symbol.iterator] = 10;
assertFalse(o.hasOwnProperty(Symbol.iterator)); assertFalse(o.hasOwnProperty(Symbol.iterator));
assertEquals([].values, o[Symbol.iterator]); assertEquals([][Symbol.iterator], o[Symbol.iterator]);
assertSame([].values, arguments[Symbol.iterator]); assertSame([][Symbol.iterator], arguments[Symbol.iterator]);
} }
TestArgumentsAsProto(); TestArgumentsAsProto();

View File

@ -45,11 +45,8 @@ function assertHasOwnProperty(object, name, attrs) {
function TestArrayPrototype() { function TestArrayPrototype() {
assertHasOwnProperty(Array.prototype, 'entries', DONT_ENUM); assertHasOwnProperty(Array.prototype, 'entries', DONT_ENUM);
assertHasOwnProperty(Array.prototype, 'values', DONT_ENUM);
assertHasOwnProperty(Array.prototype, 'keys', DONT_ENUM); assertHasOwnProperty(Array.prototype, 'keys', DONT_ENUM);
assertHasOwnProperty(Array.prototype, Symbol.iterator, DONT_ENUM); assertHasOwnProperty(Array.prototype, Symbol.iterator, DONT_ENUM);
assertEquals(Array.prototype.values, Array.prototype[Symbol.iterator]);
} }
TestArrayPrototype(); TestArrayPrototype();
@ -61,7 +58,7 @@ function assertIteratorResult(value, done, result) {
function TestValues() { function TestValues() {
var array = ['a', 'b', 'c']; var array = ['a', 'b', 'c'];
var iterator = array.values(); var iterator = array[Symbol.iterator]();
assertIteratorResult('a', false, iterator.next()); assertIteratorResult('a', false, iterator.next());
assertIteratorResult('b', false, iterator.next()); assertIteratorResult('b', false, iterator.next());
assertIteratorResult('c', false, iterator.next()); assertIteratorResult('c', false, iterator.next());
@ -75,7 +72,7 @@ TestValues();
function TestValuesMutate() { function TestValuesMutate() {
var array = ['a', 'b', 'c']; var array = ['a', 'b', 'c'];
var iterator = array.values(); var iterator = array[Symbol.iterator]();
assertIteratorResult('a', false, iterator.next()); assertIteratorResult('a', false, iterator.next());
assertIteratorResult('b', false, iterator.next()); assertIteratorResult('b', false, iterator.next());
assertIteratorResult('c', false, iterator.next()); assertIteratorResult('c', false, iterator.next());
@ -142,17 +139,17 @@ TestEntriesMutate();
function TestArrayIteratorPrototype() { function TestArrayIteratorPrototype() {
var array = []; var array = [];
var iterator = array.values(); var iterator = array.keys();
var ArrayIteratorPrototype = iterator.__proto__; var ArrayIteratorPrototype = iterator.__proto__;
assertEquals(ArrayIteratorPrototype, array.values().__proto__); assertEquals(ArrayIteratorPrototype, array[Symbol.iterator]().__proto__);
assertEquals(ArrayIteratorPrototype, array.keys().__proto__); assertEquals(ArrayIteratorPrototype, array.keys().__proto__);
assertEquals(ArrayIteratorPrototype, array.entries().__proto__); assertEquals(ArrayIteratorPrototype, array.entries().__proto__);
assertEquals(Object.prototype, ArrayIteratorPrototype.__proto__); assertEquals(Object.prototype, ArrayIteratorPrototype.__proto__);
assertEquals('Array Iterator', %_ClassOf(array.values())); assertEquals('Array Iterator', %_ClassOf(array[Symbol.iterator]()));
assertEquals('Array Iterator', %_ClassOf(array.keys())); assertEquals('Array Iterator', %_ClassOf(array.keys()));
assertEquals('Array Iterator', %_ClassOf(array.entries())); assertEquals('Array Iterator', %_ClassOf(array.entries()));
@ -169,7 +166,7 @@ function TestForArrayValues() {
var buffer = []; var buffer = [];
var array = [0, 'a', true, false, null, /* hole */, undefined, NaN]; var array = [0, 'a', true, false, null, /* hole */, undefined, NaN];
var i = 0; var i = 0;
for (var value of array.values()) { for (var value of array[Symbol.iterator]()) {
buffer[i++] = value; buffer[i++] = value;
} }
@ -239,7 +236,7 @@ TestForArrayValues();
function TestNonOwnSlots() { function TestNonOwnSlots() {
var array = [0]; var array = [0];
var iterator = array.values(); var iterator = array[Symbol.iterator]();
var object = {__proto__: iterator}; var object = {__proto__: iterator};
assertThrows(function() { assertThrows(function() {

View File

@ -21,9 +21,9 @@ function TestTypedArrayPrototype(constructor) {
assertFalse(constructor.prototype.propertyIsEnumerable(Symbol.iterator)); assertFalse(constructor.prototype.propertyIsEnumerable(Symbol.iterator));
assertEquals(Array.prototype.entries, constructor.prototype.entries); assertEquals(Array.prototype.entries, constructor.prototype.entries);
assertEquals(Array.prototype.values, constructor.prototype.values); assertEquals(Array.prototype[Symbol.iterator], constructor.prototype.values);
assertEquals(Array.prototype.keys, constructor.prototype.keys); assertEquals(Array.prototype.keys, constructor.prototype.keys);
assertEquals(Array.prototype.values, constructor.prototype[Symbol.iterator]); assertEquals(Array.prototype[Symbol.iterator], constructor.prototype[Symbol.iterator]);
} }
constructors.forEach(TestTypedArrayPrototype); constructors.forEach(TestTypedArrayPrototype);