Diff
Modified: trunk/JSTests/ChangeLog (228265 => 228266)
--- trunk/JSTests/ChangeLog 2018-02-08 10:14:01 UTC (rev 228265)
+++ trunk/JSTests/ChangeLog 2018-02-08 10:43:13 UTC (rev 228266)
@@ -1,3 +1,23 @@
+2018-02-06 Yusuke Suzuki <[email protected]>
+
+ [JSC] Implement Array.prototype.flatMap and Array.prototype.flatten
+ https://bugs.webkit.org/show_bug.cgi?id=182440
+
+ Reviewed by Darin Adler.
+
+ * stress/array-flatmap.js: Added.
+ (shouldBe):
+ (shouldBeArray):
+ (shouldThrow):
+ (var):
+ * stress/array-flatten.js: Added.
+ (shouldBe):
+ (shouldBeArray):
+ * test262.yaml:
+ * test262/test/built-ins/Array/prototype/flatMap/depth-always-one.js:
+ (3.flatMap):
+ Pick test262 82c6148980332febe92a544a1fb653718e9fdb57 change.
+
2018-02-06 Keith Miller <[email protected]>
put_to_scope/get_from_scope should not cache lexical scopes when expecting a global object
Added: trunk/JSTests/stress/array-flatmap.js (0 => 228266)
--- trunk/JSTests/stress/array-flatmap.js (rev 0)
+++ trunk/JSTests/stress/array-flatmap.js 2018-02-08 10:43:13 UTC (rev 228266)
@@ -0,0 +1,97 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+function shouldBeArray(actual, expected) {
+ shouldBe(actual.length, expected.length);
+ for (var i = 0; i < expected.length; ++i) {
+ try {
+ if (Array.isArray(expected[i])) {
+ shouldBe(Array.isArray(actual[i]), true);
+ shouldBeArray(actual[i], expected[i]);
+ } else
+ shouldBe(actual[i], expected[i]);
+ } catch(e) {
+ print(JSON.stringify(actual));
+ throw e;
+ }
+ }
+}
+
+function shouldThrow(func, errorMessage) {
+ var errorThrown = false;
+ var error = null;
+ try {
+ func();
+ } catch (e) {
+ errorThrown = true;
+ error = e;
+ }
+ if (!errorThrown)
+ throw new Error('not thrown');
+ if (String(error) !== errorMessage)
+ throw new Error(`bad error: ${String(error)}`);
+}
+
+shouldThrow(() => {
+ [].flatMap();
+}, `TypeError: Array.prototype.flatMap callback must be a function`);
+
+var array = [42];
+shouldBeArray(array.flatMap(function (v) {
+ "use strict";
+ shouldBe(v, 42);
+ return this;
+}, `Cocoa`), [`Cocoa`]);
+
+shouldBeArray([].flatMap((v) => v), []);
+shouldBeArray([42].flatMap((v) => v), [42]);
+shouldBeArray([42].flatMap((v) => [v]), [42]);
+shouldBeArray([42].flatMap((v) => [[v]]), [[42]]);
+shouldBeArray([42].flatMap((v) => [v, v, v]), [42,42,42]);
+shouldBeArray([42,[43],44].flatMap((v) => [v, v]), [42,42,[43],[43],44,44]);
+shouldBeArray([,,,,,,].flatMap((v) => [v, v]), []);
+shouldBeArray([42,43,44].flatMap((v) => []), []);
+shouldBeArray([42,[43],44].flatMap((v) => v), [42,43,44]);
+
+class DerivedArray extends Array { }
+shouldBe((new DerivedArray).flatMap(() => {}) instanceof DerivedArray, true);
+var flatMap = [].flatMap;
+var realm = createGlobalObject();
+shouldBe(flatMap.call({}, () => {}) instanceof Array, true);
+shouldBe(flatMap.call(new realm.Array, () => {}) instanceof Array, true);
+var array2 = new realm.Array;
+array2.constructor = 0;
+
+shouldThrow(() => {
+ flatMap.call(array2, () => {});
+}, `TypeError: 0 is not a constructor`);
+
+var array2 = new realm.Array;
+array2.constructor = undefined;
+shouldBe(flatMap.call(array2, () => {}) instanceof Array, true);
+
+var array2 = new realm.Array;
+array2.constructor = {
+ get [Symbol.species]() {
+ return null;
+ }
+};
+shouldBe(flatMap.call(array2, () => {}) instanceof Array, true);
+
+var array2 = new realm.Array;
+array2.constructor = {
+ get [Symbol.species]() {
+ return undefined;
+ }
+};
+shouldBe(flatMap.call(array2, () => {}) instanceof Array, true);
+
+var array2 = new realm.Array;
+array2.constructor = {
+ get [Symbol.species]() {
+ return DerivedArray;
+ }
+};
+shouldBe(flatMap.call(array2, () => {}) instanceof DerivedArray, true);
Added: trunk/JSTests/stress/array-flatten.js (0 => 228266)
--- trunk/JSTests/stress/array-flatten.js (rev 0)
+++ trunk/JSTests/stress/array-flatten.js 2018-02-08 10:43:13 UTC (rev 228266)
@@ -0,0 +1,108 @@
+function shouldBe(actual, expected) {
+ if (actual !== expected)
+ throw new Error('bad value: ' + actual);
+}
+
+function shouldBeArray(actual, expected) {
+ shouldBe(actual.length, expected.length);
+ for (var i = 0; i < expected.length; ++i) {
+ try {
+ if (Array.isArray(expected[i])) {
+ shouldBe(Array.isArray(actual[i]), true);
+ shouldBeArray(actual[i], expected[i]);
+ } else
+ shouldBe(actual[i], expected[i]);
+ } catch(e) {
+ print(JSON.stringify(actual));
+ throw e;
+ }
+ }
+}
+
+function shouldThrow(func, errorMessage) {
+ var errorThrown = false;
+ var error = null;
+ try {
+ func();
+ } catch (e) {
+ errorThrown = true;
+ error = e;
+ }
+ if (!errorThrown)
+ throw new Error('not thrown');
+ if (String(error) !== errorMessage)
+ throw new Error(`bad error: ${String(error)}`);
+}
+
+shouldBe([].flatten.length, 0);
+shouldBe([].flatten.name, `flatten`);
+
+shouldBeArray([].flatten(), []);
+shouldBeArray([0, 1, 2, 3, , 4].flatten(), [0, 1, 2, 3, 4]);
+shouldBeArray([,,,,,].flatten(), []);
+
+shouldBeArray([].flatten(0), []);
+shouldBeArray([0, 1, 2, 3, , 4].flatten(0), [0, 1, 2, 3, 4]);
+shouldBeArray([,,,,,].flatten(0), []);
+
+shouldBeArray([].flatten(-1), []);
+shouldBeArray([0, 1, 2, 3, , 4].flatten(-1), [0, 1, 2, 3, 4]);
+shouldBeArray([,,,,,].flatten(-1), []);
+
+shouldBeArray([[],[]].flatten(), []);
+shouldBeArray([[0],[1]].flatten(), [0,1]);
+shouldBeArray([[0],[],1].flatten(), [0,1]);
+shouldBeArray([[0],[[]],1].flatten(), [0,[],1]);
+shouldBeArray([[0],[[]],1].flatten(1), [0,[],1]);
+shouldBeArray([[0],[[]],1].flatten(2), [0,1]);
+
+shouldBeArray([[],[]].flatten(0), [[],[]]);
+shouldBeArray([[0],[1]].flatten(0), [[0],[1]]);
+shouldBeArray([[0],[],1].flatten(0), [[0],[],1]);
+shouldBeArray([[0],[[]],1].flatten(0), [[0],[[]],1]);
+
+shouldBeArray([[[[[[[[[[[[[[[[[[[[[42]]]]]]]]]]]]]]]]]]]]].flatten(Infinity), [42]);
+
+var array = [];
+shouldBe(array.flatten() !== array, true);
+
+class DerivedArray extends Array { }
+shouldBe((new DerivedArray).flatten() instanceof DerivedArray, true);
+var flatten = [].flatten;
+var realm = createGlobalObject();
+shouldBe(flatten.call({}) instanceof Array, true);
+shouldBe(flatten.call(new realm.Array) instanceof Array, true);
+var array2 = new realm.Array;
+array2.constructor = 0;
+
+shouldThrow(() => {
+ flatten.call(array2);
+}, `TypeError: 0 is not a constructor`);
+
+var array2 = new realm.Array;
+array2.constructor = undefined;
+shouldBe(flatten.call(array2) instanceof Array, true);
+
+var array2 = new realm.Array;
+array2.constructor = {
+ get [Symbol.species]() {
+ return null;
+ }
+};
+shouldBe(flatten.call(array2) instanceof Array, true);
+
+var array2 = new realm.Array;
+array2.constructor = {
+ get [Symbol.species]() {
+ return undefined;
+ }
+};
+shouldBe(flatten.call(array2) instanceof Array, true);
+
+var array2 = new realm.Array;
+array2.constructor = {
+ get [Symbol.species]() {
+ return DerivedArray;
+ }
+};
+shouldBe(flatten.call(array2) instanceof DerivedArray, true);
Modified: trunk/JSTests/test262/test/built-ins/Array/prototype/flatMap/depth-always-one.js (228265 => 228266)
--- trunk/JSTests/test262/test/built-ins/Array/prototype/flatMap/depth-always-one.js 2018-02-08 10:14:01 UTC (rev 228265)
+++ trunk/JSTests/test262/test/built-ins/Array/prototype/flatMap/depth-always-one.js 2018-02-08 10:43:13 UTC (rev 228266)
@@ -14,7 +14,7 @@
var result = [1, 2, 3].flatMap(function(ele) {
return [[ele * 2]];
-};
+});
assert.sameValue(result.length, 3, 'array depth is more than 1 - length');
assert.compareArray(result[0], [2], 'array depth is more than 1 - 1st element');
assert.compareArray(result[1], [4], 'array depth is more than 1 - 2nd element');
Modified: trunk/JSTests/test262.yaml (228265 => 228266)
--- trunk/JSTests/test262.yaml 2018-02-08 10:14:01 UTC (rev 228265)
+++ trunk/JSTests/test262.yaml 2018-02-08 10:43:13 UTC (rev 228266)
@@ -5588,25 +5588,25 @@
- path: test262/test/built-ins/Array/prototype/findIndex/return-negative-one-if-predicate-returns-false-value.js
cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatMap/array-like-objects.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
- path: test262/test/built-ins/Array/prototype/flatMap/array-like-objects.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatMap/bound-function-argument.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
- path: test262/test/built-ins/Array/prototype/flatMap/bound-function-argument.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatMap/depth-always-one.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
- path: test262/test/built-ins/Array/prototype/flatMap/depth-always-one.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatMap/length.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], []
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], []
- path: test262/test/built-ins/Array/prototype/flatMap/length.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], [:strict]
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatMap/name.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], []
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], []
- path: test262/test/built-ins/Array/prototype/flatMap/name.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], [:strict]
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatMap/non-callable-argument-throws.js
cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
- path: test262/test/built-ins/Array/prototype/flatMap/non-callable-argument-throws.js
@@ -5620,55 +5620,55 @@
- path: test262/test/built-ins/Array/prototype/flatMap/null-undefined-input-throws.js
cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatMap/thisArg-argument.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatten/array-like-objects.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
- path: test262/test/built-ins/Array/prototype/flatten/array-like-objects.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatten/bound-function-call.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
- path: test262/test/built-ins/Array/prototype/flatten/bound-function-call.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatten/empty-array-elements.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
- path: test262/test/built-ins/Array/prototype/flatten/empty-array-elements.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatten/empty-object-elements.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
- path: test262/test/built-ins/Array/prototype/flatten/empty-object-elements.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatten/length.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], []
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], []
- path: test262/test/built-ins/Array/prototype/flatten/length.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], [:strict]
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatten/name.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], []
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], []
- path: test262/test/built-ins/Array/prototype/flatten/name.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], [:strict]
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatten/non-numeric-depth-should-not-throw.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
- path: test262/test/built-ins/Array/prototype/flatten/non-numeric-depth-should-not-throw.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatten/non-object-ctor-throws.js
cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
- path: test262/test/built-ins/Array/prototype/flatten/non-object-ctor-throws.js
cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatten/null-undefined-elements.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
- path: test262/test/built-ins/Array/prototype/flatten/null-undefined-elements.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatten/null-undefined-input-throws.js
cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
- path: test262/test/built-ins/Array/prototype/flatten/null-undefined-input-throws.js
cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatten/positive-infinity.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], []
- path: test262/test/built-ins/Array/prototype/flatten/positive-infinity.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatten/prop-desc.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], []
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], []
- path: test262/test/built-ins/Array/prototype/flatten/prop-desc.js
- cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], [:strict]
+ cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/propertyHelper.js"], [:strict]
- path: test262/test/built-ins/Array/prototype/flatten/symbol-object-create-null-depth-throws.js
cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js"], []
- path: test262/test/built-ins/Array/prototype/flatten/symbol-object-create-null-depth-throws.js
Modified: trunk/LayoutTests/ChangeLog (228265 => 228266)
--- trunk/LayoutTests/ChangeLog 2018-02-08 10:14:01 UTC (rev 228265)
+++ trunk/LayoutTests/ChangeLog 2018-02-08 10:43:13 UTC (rev 228266)
@@ -1,3 +1,14 @@
+2018-02-06 Yusuke Suzuki <[email protected]>
+
+ [JSC] Implement Array.prototype.flatMap and Array.prototype.flatten
+ https://bugs.webkit.org/show_bug.cgi?id=182440
+
+ Reviewed by Darin Adler.
+
+ * inspector/model/remote-object-get-properties-expected.txt:
+ * js/Object-getOwnPropertyNames-expected.txt:
+ * js/script-tests/Object-getOwnPropertyNames.js:
+
2018-01-13 Darin Adler <[email protected]>
Event improvements
Modified: trunk/LayoutTests/inspector/model/remote-object-get-properties-expected.txt (228265 => 228266)
--- trunk/LayoutTests/inspector/model/remote-object-get-properties-expected.txt 2018-02-08 10:14:01 UTC (rev 228265)
+++ trunk/LayoutTests/inspector/model/remote-object-get-properties-expected.txt 2018-02-08 10:43:13 UTC (rev 228266)
@@ -74,6 +74,8 @@
indexOf
lastIndexOf
filter
+ flatMap
+ flatten
reduce
reduceRight
map
@@ -125,6 +127,8 @@
indexOf
lastIndexOf
filter
+ flatMap
+ flatten
reduce
reduceRight
map
@@ -161,6 +165,8 @@
indexOf
lastIndexOf
filter
+ flatMap
+ flatten
reduce
reduceRight
map
@@ -197,6 +203,8 @@
indexOf
lastIndexOf
filter
+ flatMap
+ flatten
reduce
reduceRight
map
Modified: trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt (228265 => 228266)
--- trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt 2018-02-08 10:14:01 UTC (rev 228265)
+++ trunk/LayoutTests/js/Object-getOwnPropertyNames-expected.txt 2018-02-08 10:43:13 UTC (rev 228266)
@@ -47,7 +47,7 @@
PASS getSortedOwnPropertyNames(Function) is ['length', 'name', 'prototype']
PASS getSortedOwnPropertyNames(Function.prototype) is ['apply', 'arguments', 'bind', 'call', 'caller', 'constructor', 'length', 'name', 'toString']
PASS getSortedOwnPropertyNames(Array) is ['from', 'isArray', 'length', 'name', 'of', 'prototype']
-PASS getSortedOwnPropertyNames(Array.prototype) is ['concat', 'constructor', 'copyWithin', 'entries', 'every', 'fill', 'filter', 'find', 'findIndex', 'forEach', 'includes', 'indexOf', 'join', 'keys', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift', 'values']
+PASS getSortedOwnPropertyNames(Array.prototype) is ['concat', 'constructor', 'copyWithin', 'entries', 'every', 'fill', 'filter', 'find', 'findIndex', 'flatMap', 'flatten', 'forEach', 'includes', 'indexOf', 'join', 'keys', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift', 'values']
PASS getSortedOwnPropertyNames(String) is ['fromCharCode', 'fromCodePoint', 'length', 'name', 'prototype', 'raw']
PASS getSortedOwnPropertyNames(String.prototype) is ['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'codePointAt', 'concat', 'constructor', 'endsWith', 'fixed', 'fontcolor', 'fontsize', 'includes', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'normalize', 'padEnd', 'padStart', 'repeat', 'replace', 'search', 'slice', 'small', 'split', 'startsWith', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimEnd', 'trimLeft', 'trimRight', 'trimStart', 'valueOf']
PASS getSortedOwnPropertyNames(Boolean) is ['length', 'name', 'prototype']
Modified: trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js (228265 => 228266)
--- trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js 2018-02-08 10:14:01 UTC (rev 228265)
+++ trunk/LayoutTests/js/script-tests/Object-getOwnPropertyNames.js 2018-02-08 10:43:13 UTC (rev 228266)
@@ -56,7 +56,7 @@
"Function": "['length', 'name', 'prototype']",
"Function.prototype": "['apply', 'arguments', 'bind', 'call', 'caller', 'constructor', 'length', 'name', 'toString']",
"Array": "['from', 'isArray', 'length', 'name', 'of', 'prototype']",
- "Array.prototype": "['concat', 'constructor', 'copyWithin', 'entries', 'every', 'fill', 'filter', 'find', 'findIndex', 'forEach', 'includes', 'indexOf', 'join', 'keys', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift', 'values']",
+ "Array.prototype": "['concat', 'constructor', 'copyWithin', 'entries', 'every', 'fill', 'filter', 'find', 'findIndex', 'flatMap', 'flatten', 'forEach', 'includes', 'indexOf', 'join', 'keys', 'lastIndexOf', 'length', 'map', 'pop', 'push', 'reduce', 'reduceRight', 'reverse', 'shift', 'slice', 'some', 'sort', 'splice', 'toLocaleString', 'toString', 'unshift', 'values']",
"String": "['fromCharCode', 'fromCodePoint', 'length', 'name', 'prototype', 'raw']",
"String.prototype": "['anchor', 'big', 'blink', 'bold', 'charAt', 'charCodeAt', 'codePointAt', 'concat', 'constructor', 'endsWith', 'fixed', 'fontcolor', 'fontsize', 'includes', 'indexOf', 'italics', 'lastIndexOf', 'length', 'link', 'localeCompare', 'match', 'normalize', 'padEnd', 'padStart', 'repeat', 'replace', 'search', 'slice', 'small', 'split', 'startsWith', 'strike', 'sub', 'substr', 'substring', 'sup', 'toLocaleLowerCase', 'toLocaleUpperCase', 'toLowerCase', 'toString', 'toUpperCase', 'trim', 'trimEnd', 'trimLeft', 'trimRight', 'trimStart', 'valueOf']",
"Boolean": "['length', 'name', 'prototype']",
Modified: trunk/Source/_javascript_Core/ChangeLog (228265 => 228266)
--- trunk/Source/_javascript_Core/ChangeLog 2018-02-08 10:14:01 UTC (rev 228265)
+++ trunk/Source/_javascript_Core/ChangeLog 2018-02-08 10:43:13 UTC (rev 228266)
@@ -1,3 +1,30 @@
+2018-02-06 Yusuke Suzuki <[email protected]>
+
+ [JSC] Implement Array.prototype.flatMap and Array.prototype.flatten
+ https://bugs.webkit.org/show_bug.cgi?id=182440
+
+ Reviewed by Darin Adler.
+
+ This patch implements Array.prototype.flatMap and Array.prototype.flatten
+ since they are now stage 3 [1].
+
+ [1]: https://tc39.github.io/proposal-flatMap/#sec-FlattenIntoArray
+
+ * builtins/ArrayPrototype.js:
+ (filter):
+ (map):
+ (globalPrivate.concatSlowPath):
+ (globalPrivate.arraySpeciesCreate):
+ (globalPrivate.flattenIntoArray):
+ (flatten):
+ (globalPrivate.flattenIntoArrayWithCallback):
+ We separate flattenIntoArray from flattenIntoArrayWithCallback due to performance reason.
+ We carefully keep both functions small to encourage inlining.
+
+ (flatMap):
+ * runtime/ArrayPrototype.cpp:
+ (JSC::ArrayPrototype::finishCreation):
+
2018-01-13 Darin Adler <[email protected]>
Event improvements
Modified: trunk/Source/_javascript_Core/builtins/ArrayPrototype.js (228265 => 228266)
--- trunk/Source/_javascript_Core/builtins/ArrayPrototype.js 2018-02-08 10:14:01 UTC (rev 228265)
+++ trunk/Source/_javascript_Core/builtins/ArrayPrototype.js 2018-02-08 10:43:13 UTC (rev 228266)
@@ -184,7 +184,7 @@
// We have this check so that if some array from a different global object
// calls this map they don't get an array with the Array.prototype of the
// other global object.
- if (@isArrayConstructor(constructor) && @Array !== constructor)
+ if (@Array !== constructor && @isArrayConstructor(constructor))
constructor = @undefined;
if (@isObject(constructor)) {
constructor = constructor.@speciesSymbol;
@@ -230,7 +230,7 @@
// We have this check so that if some array from a different global object
// calls this map they don't get an array with the Array.prototype of the
// other global object.
- if (@isArrayConstructor(constructor) && @Array !== constructor)
+ if (@Array !== constructor && @isArrayConstructor(constructor))
constructor = @undefined;
if (@isObject(constructor)) {
constructor = constructor.@speciesSymbol;
@@ -623,7 +623,7 @@
// We have this check so that if some array from a different global object
// calls this map they don't get an array with the Array.prototype of the
// other global object.
- if (@isArrayConstructor(constructor) && @Array !== constructor)
+ if (@Array !== constructor && @isArrayConstructor(constructor))
constructor = @undefined;
else if (@isObject(constructor)) {
constructor = constructor.@speciesSymbol;
@@ -738,3 +738,107 @@
return array;
}
+
+@globalPrivate
+function arraySpeciesCreate(array, length)
+{
+ "use strict";
+
+ if (!@isArray(array))
+ return @newArrayWithSize(length);
+
+ var constructor = array.constructor;
+ var arrayConstructorInRealm = @Array;
+ // We have this check so that if some array from a different global object
+ // calls this map they don't get an array with the Array.prototype of the
+ // other global object.
+ if (arrayConstructorInRealm !== constructor && @isArrayConstructor(constructor))
+ return @newArrayWithSize(length);
+
+ if (@isObject(constructor)) {
+ constructor = constructor.@speciesSymbol;
+ if (constructor == null)
+ return @newArrayWithSize(length);
+ }
+
+ if (constructor === arrayConstructorInRealm || constructor === @undefined)
+ return @newArrayWithSize(length);
+ return new constructor(length);
+}
+
+@globalPrivate
+function flattenIntoArray(target, source, sourceLength, targetIndex, depth)
+{
+ "use strict";
+
+ for (var sourceIndex = 0; sourceIndex < sourceLength; ++sourceIndex) {
+ if (sourceIndex in source) {
+ var element = source[sourceIndex];
+ if (depth > 0 && @isArray(element))
+ targetIndex = @flattenIntoArray(target, element, @toLength(element.length), targetIndex, depth - 1);
+ else {
+ if (targetIndex >= @MAX_SAFE_INTEGER)
+ @throwTypeError("flatten array exceeds 2**53 - 1");
+ @putByValDirect(target, targetIndex, element);
+ ++targetIndex;
+ }
+ }
+ }
+ return targetIndex;
+}
+
+function flatten()
+{
+ "use strict";
+
+ var array = @toObject(this, "Array.prototype.flatten requires that |this| not be null or undefined");
+ var length = @toLength(array.length);
+
+ var depthNum = 1;
+ var depth = @argument(0);
+ if (depth !== @undefined)
+ depthNum = @toInteger(depth);
+
+ var result = @arraySpeciesCreate(array, 0);
+
+ @flattenIntoArray(result, array, length, 0, depthNum);
+ return result;
+}
+
+@globalPrivate
+function flattenIntoArrayWithCallback(target, source, sourceLength, targetIndex, callback, thisArg)
+{
+ "use strict";
+
+ for (var sourceIndex = 0; sourceIndex < sourceLength; ++sourceIndex) {
+ if (sourceIndex in source) {
+ var element = callback.@call(thisArg, source[sourceIndex], sourceIndex, source);
+ if (@isArray(element))
+ targetIndex = @flattenIntoArray(target, element, @toLength(element.length), targetIndex, 0);
+ else {
+ if (targetIndex >= @MAX_SAFE_INTEGER)
+ @throwTypeError("flatten array exceeds 2**53 - 1");
+ @putByValDirect(target, targetIndex, element);
+ ++targetIndex;
+ }
+ }
+ }
+ return target;
+}
+
+function flatMap(callback)
+{
+ "use strict";
+
+ var array = @toObject(this, "Array.prototype.flatMap requires that |this| not be null or undefined");
+ var length = @toLength(array.length);
+
+ if (typeof callback !== "function")
+ @throwTypeError("Array.prototype.flatMap callback must be a function");
+
+ var thisArg = @argument(1);
+
+ var result = @arraySpeciesCreate(array, 0);
+
+ return @flattenIntoArrayWithCallback(result, array, length, 0, callback, thisArg);
+}
Modified: trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp (228265 => 228266)
--- trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2018-02-08 10:14:01 UTC (rev 228265)
+++ trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2018-02-08 10:43:13 UTC (rev 228266)
@@ -107,6 +107,8 @@
JSC_NATIVE_INTRINSIC_FUNCTION_WITHOUT_TRANSITION("indexOf", arrayProtoFuncIndexOf, static_cast<unsigned>(PropertyAttribute::DontEnum), 1, ArrayIndexOfIntrinsic);
JSC_NATIVE_FUNCTION_WITHOUT_TRANSITION("lastIndexOf", arrayProtoFuncLastIndexOf, static_cast<unsigned>(PropertyAttribute::DontEnum), 1);
JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("filter", arrayPrototypeFilterCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum));
+ JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("flatMap", arrayPrototypeFlatMapCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum));
+ JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("flatten", arrayPrototypeFlattenCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum));
JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("reduce", arrayPrototypeReduceCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum));
JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("reduceRight", arrayPrototypeReduceRightCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum));
JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION("map", arrayPrototypeMapCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum));