Skip to content
Permalink
Browse files
Array.prototype.find and findIndex should skip holes
https://bugs.webkit.org/show_bug.cgi?id=132658

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:
Skip holes in the array when iterating such that callback isn't called.

* builtins/Array.prototype.js:
(find):
(findIndex):

LayoutTests:
* js/array-find-expected.txt:
* js/array-findIndex-expected.txt:
* js/script-tests/array-find.js:
* js/script-tests/array-findIndex.js:


Canonical link: https://commits.webkit.org/151174@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@169162 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
graouts committed May 21, 2014
1 parent 6729d21 commit bb7bcac7d19d9370682b13013a507ee08f2d2e3d
Showing 7 changed files with 73 additions and 6 deletions.
@@ -1,3 +1,15 @@
2014-05-21 Antoine Quint <graouts@webkit.org>

Array.prototype.find and findIndex should skip holes
https://bugs.webkit.org/show_bug.cgi?id=132658

Reviewed by Geoffrey Garen.

* js/array-find-expected.txt:
* js/array-findIndex-expected.txt:
* js/script-tests/array-find.js:
* js/script-tests/array-findIndex.js:

2014-05-21 Radu Stavila <stavila@adobe.com>

REGRESSION (r168046): Invalid layout in WebCore::RenderBox::containingBlockLogicalWidthForPositioned
@@ -40,6 +40,12 @@ PASS [].find([]) threw exception TypeError: Array.prototype.find callback must b
PASS [].find({}) threw exception TypeError: Array.prototype.find callback must be a function.
PASS [].find(null) threw exception TypeError: Array.prototype.find callback must be a function.
PASS [].find(undefined) threw exception TypeError: Array.prototype.find callback must be a function.
find callback called with index 10
find callback called with index 20
find callback called with index 30
find callback called with index 40
find callback called with index 50
PASS numberOfCallbacksInFindInArrayWithHoles() is 5
PASS successfullyParsed is true

TEST COMPLETE
@@ -13,12 +13,13 @@ PASS [undefined, 0, false, ''].findIndex(passNull) is -1
PASS [undefined, 0, null, ''].findIndex(passFalse) is -1
PASS [undefined, 0, null, false].findIndex(passEmptyString) is -1
PASS [undefined, null, false, ''].findIndex(passZero) is -1
PASS (new Array(20)).findIndex(passUndefined) is 0
PASS arrayWithHoles.findIndex(passUndefined) is 0
PASS (new Array(20)).findIndex(passUndefined) is -1
PASS arrayWithHoles.findIndex(passUndefined) is -1
PASS arrayWithHoles.findIndex(passZero) is 10
PASS arrayWithHoles.findIndex(passNull) is 20
PASS arrayWithHoles.findIndex(passFalse) is 30
PASS arrayWithHoles.findIndex(passEmptyString) is 40
PASS arrayWithHoles.findIndex(passUndefined) is 50
PASS toObject([undefined, 0, null, false, '']).findIndex(passUndefined) is 0
PASS toObject([undefined, 0, null, false, '']).findIndex(passZero) is 1
PASS toObject([undefined, 0, null, false, '']).findIndex(passNull) is 2
@@ -29,7 +30,7 @@ PASS toObject([undefined, 0, false, '']).findIndex(passNull) is -1
PASS toObject([undefined, 0, null, '']).findIndex(passFalse) is -1
PASS toObject([undefined, 0, null, false]).findIndex(passEmptyString) is -1
PASS toObject([undefined, null, false, '']).findIndex(passZero) is -1
PASS toObject(new Array(20)).findIndex(passUndefined) is 0
PASS toObject(new Array(20)).findIndex(passUndefined) is -1
PASS [0,1,2,3,4,5,6,7,8,9].findIndex(findItemAddedDuringSearch) is -1
PASS [0,1,2,3,4,5,6,7,8,9].findIndex(findItemRemovedDuringSearch) is -1
PASS Array.prototype.findIndex.call(undefined, function() {}) threw exception TypeError: Array.prototype.findIndex requires that |this| not be undefined.
@@ -40,6 +41,12 @@ PASS [].findIndex([]) threw exception TypeError: Array.prototype.findIndex callb
PASS [].findIndex({}) threw exception TypeError: Array.prototype.findIndex callback must be a function.
PASS [].findIndex(null) threw exception TypeError: Array.prototype.findIndex callback must be a function.
PASS [].findIndex(undefined) threw exception TypeError: Array.prototype.findIndex callback must be a function.
find callback called with index 10
find callback called with index 20
find callback called with index 30
find callback called with index 40
find callback called with index 50
PASS numberOfCallbacksInFindIndexInArrayWithHoles() is 5
PASS successfullyParsed is true

TEST COMPLETE
@@ -44,6 +44,15 @@ arrayWithHoles[10] = 0;
arrayWithHoles[20] = null;
arrayWithHoles[30] = false;
arrayWithHoles[40] = "";
arrayWithHoles[50] = undefined;
function numberOfCallbacksInFindInArrayWithHoles() {
var count = 0;
arrayWithHoles.find(function(element, index, array) {
debug("find callback called with index " + index);
count++;
});
return count;
}

shouldBe("[undefined, 0, null, false, ''].find(passUndefined)", "undefined");
shouldBe("[undefined, 0, null, false, ''].find(passZero)", "0");
@@ -90,3 +99,6 @@ shouldThrow("[].find([])", "'TypeError: Array.prototype.find callback must be a
shouldThrow("[].find({})", "'TypeError: Array.prototype.find callback must be a function'");
shouldThrow("[].find(null)", "'TypeError: Array.prototype.find callback must be a function'");
shouldThrow("[].find(undefined)", "'TypeError: Array.prototype.find callback must be a function'");

// Callbacks in the expected order and skipping holes.
shouldBe("numberOfCallbacksInFindInArrayWithHoles()", "5");
@@ -44,6 +44,14 @@ arrayWithHoles[10] = 0;
arrayWithHoles[20] = null;
arrayWithHoles[30] = false;
arrayWithHoles[40] = "";
function numberOfCallbacksInFindIndexInArrayWithHoles() {
var count = 0;
arrayWithHoles.find(function(element, index, array) {
debug("find callback called with index " + index);
count++;
});
return count;
}

shouldBe("[undefined, 0, null, false, ''].findIndex(passUndefined)", "0");
shouldBe("[undefined, 0, null, false, ''].findIndex(passZero)", "1");
@@ -55,14 +63,16 @@ shouldBe("[undefined, 0, false, ''].findIndex(passNull)", "-1");
shouldBe("[undefined, 0, null, ''].findIndex(passFalse)", "-1");
shouldBe("[undefined, 0, null, false].findIndex(passEmptyString)", "-1");
shouldBe("[undefined, null, false, ''].findIndex(passZero)", "-1");
shouldBe("(new Array(20)).findIndex(passUndefined)", "0");
shouldBe("(new Array(20)).findIndex(passUndefined)", "-1");

// Array with holes.
shouldBe("arrayWithHoles.findIndex(passUndefined)", "0");
shouldBe("arrayWithHoles.findIndex(passUndefined)", "-1");
shouldBe("arrayWithHoles.findIndex(passZero)", "10");
shouldBe("arrayWithHoles.findIndex(passNull)", "20");
shouldBe("arrayWithHoles.findIndex(passFalse)", "30");
shouldBe("arrayWithHoles.findIndex(passEmptyString)", "40");
arrayWithHoles[50] = undefined;
shouldBe("arrayWithHoles.findIndex(passUndefined)", "50");

// Generic Object
shouldBe("toObject([undefined, 0, null, false, '']).findIndex(passUndefined)", "0");
@@ -75,7 +85,7 @@ shouldBe("toObject([undefined, 0, false, '']).findIndex(passNull)", "-1");
shouldBe("toObject([undefined, 0, null, '']).findIndex(passFalse)", "-1");
shouldBe("toObject([undefined, 0, null, false]).findIndex(passEmptyString)", "-1");
shouldBe("toObject([undefined, null, false, '']).findIndex(passZero)", "-1");
shouldBe("toObject(new Array(20)).findIndex(passUndefined)", "0");
shouldBe("toObject(new Array(20)).findIndex(passUndefined)", "-1");

// Modification during search
shouldBe("[0,1,2,3,4,5,6,7,8,9].findIndex(findItemAddedDuringSearch)", "-1");
@@ -90,3 +100,6 @@ shouldThrow("[].findIndex([])", "'TypeError: Array.prototype.findIndex callback
shouldThrow("[].findIndex({})", "'TypeError: Array.prototype.findIndex callback must be a function'");
shouldThrow("[].findIndex(null)", "'TypeError: Array.prototype.findIndex callback must be a function'");
shouldThrow("[].findIndex(undefined)", "'TypeError: Array.prototype.findIndex callback must be a function'");

// Callbacks in the expected order and skipping holes.
shouldBe("numberOfCallbacksInFindIndexInArrayWithHoles()", "5");
@@ -1,3 +1,16 @@
2014-05-21 Antoine Quint <graouts@webkit.org>

Array.prototype.find and findIndex should skip holes
https://bugs.webkit.org/show_bug.cgi?id=132658

Reviewed by Geoffrey Garen.

Skip holes in the array when iterating such that callback isn't called.

* builtins/Array.prototype.js:
(find):
(findIndex):

2014-05-21 Eva Balazsfalvi <evab.u-szeged@partner.samsung.com>

REGRESSION(r169092 and r169102): Skip failing JSC tests on ARM64 properly
@@ -205,6 +205,8 @@ function find(callback /*, thisArg */) {

var thisArg = arguments.length > 1 ? arguments[1] : undefined;
for (var i = 0; i < length; i++) {
if (!(i in array))
continue;
if (callback.@call(thisArg, array[i], i, array))
return array[i];
}
@@ -227,6 +229,8 @@ function findIndex(callback /*, thisArg */) {

var thisArg = arguments.length > 1 ? arguments[1] : undefined;
for (var i = 0; i < length; i++) {
if (!(i in array))
continue;
if (callback.@call(thisArg, array[i], i, array))
return i;
}

0 comments on commit bb7bcac

Please sign in to comment.