Skip to content

Commit

Permalink
Add Array.findLast and findLastIndex from ES2023
Browse files Browse the repository at this point in the history
Also implement these methods for the typed arrays variants.
  • Loading branch information
andreabergia committed Aug 13, 2024
1 parent 0bd385d commit 7e652a0
Show file tree
Hide file tree
Showing 12 changed files with 879 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public enum IterativeOperation {
SOME,
FIND,
FIND_INDEX,
FIND_LAST,
FIND_LAST_INDEX,
}

public enum ReduceOperation {
Expand All @@ -35,7 +37,10 @@ public static Object iterativeMethod(
Object[] args) {
Scriptable o = ScriptRuntime.toObject(cx, scope, thisObj);

if (IterativeOperation.FIND == operation || IterativeOperation.FIND_INDEX == operation) {
if (IterativeOperation.FIND == operation
|| IterativeOperation.FIND_INDEX == operation
|| IterativeOperation.FIND_LAST == operation
|| IterativeOperation.FIND_LAST_INDEX == operation) {
requireObjectCoercible(cx, o, fun);
}

Expand All @@ -62,12 +67,29 @@ public static Object iterativeMethod(
array = cx.newArray(scope, resultLength);
}
long j = 0;
for (long i = 0; i < length; i++) {
long start =
(operation == IterativeOperation.FIND_LAST
|| operation == IterativeOperation.FIND_LAST_INDEX)
? length - 1
: 0;
long end =
(operation == IterativeOperation.FIND_LAST
|| operation == IterativeOperation.FIND_LAST_INDEX)
? -1
: length;
long increment =
(operation == IterativeOperation.FIND_LAST
|| operation == IterativeOperation.FIND_LAST_INDEX)
? -1
: +1;
for (long i = start; i != end; i += increment) {
Object[] innerArgs = new Object[3];
Object elem = getRawElem(o, i);
if (elem == NOT_FOUND) {
if (operation == IterativeOperation.FIND
|| operation == IterativeOperation.FIND_INDEX) {
|| operation == IterativeOperation.FIND_INDEX
|| operation == IterativeOperation.FIND_LAST
|| operation == IterativeOperation.FIND_LAST_INDEX) {
elem = Undefined.instance;
} else {
continue;
Expand All @@ -93,9 +115,11 @@ public static Object iterativeMethod(
if (ScriptRuntime.toBoolean(result)) return Boolean.TRUE;
break;
case FIND:
case FIND_LAST:
if (ScriptRuntime.toBoolean(result)) return elem;
break;
case FIND_INDEX:
case FIND_LAST_INDEX:
if (ScriptRuntime.toBoolean(result)) return ScriptRuntime.wrapNumber(i);
break;
}
Expand All @@ -109,6 +133,7 @@ public static Object iterativeMethod(
case SOME:
return Boolean.FALSE;
case FIND_INDEX:
case FIND_LAST_INDEX:
return ScriptRuntime.wrapNumber(-1);
case FOR_EACH:
default:
Expand Down
59 changes: 44 additions & 15 deletions rhino/src/main/java/org/mozilla/javascript/NativeArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ protected void fillConstructorProperties(IdFunctionObject ctor) {
addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_some, "some", 1);
addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_find, "find", 1);
addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_findIndex, "findIndex", 1);
addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_findLast, "findLast", 1);
addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_findLastIndex, "findLastIndex", 1);
addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_reduce, "reduce", 1);
addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_reduceRight, "reduceRight", 1);
addIdFunctionProperty(ctor, ARRAY_TAG, ConstructorId_isArray, "isArray", 1);
Expand Down Expand Up @@ -279,6 +281,14 @@ protected void initPrototypeId(int id) {
arity = 1;
s = "findIndex";
break;
case Id_findLast:
arity = 1;
s = "findLast";
break;
case Id_findLastIndex:
arity = 1;
s = "findLastIndex";
break;
case Id_reduce:
arity = 1;
s = "reduce";
Expand Down Expand Up @@ -359,6 +369,8 @@ public Object execIdCall(
case ConstructorId_some:
case ConstructorId_find:
case ConstructorId_findIndex:
case ConstructorId_findLast:
case ConstructorId_findLastIndex:
case ConstructorId_reduce:
case ConstructorId_reduceRight:
{
Expand Down Expand Up @@ -491,6 +503,13 @@ public Object execIdCall(
case Id_findIndex:
return ArrayLikeAbstractOperations.iterativeMethod(
cx, f, IterativeOperation.FIND_INDEX, scope, thisObj, args);
case Id_findLast:
return ArrayLikeAbstractOperations.iterativeMethod(
cx, f, IterativeOperation.FIND_LAST, scope, thisObj, args);
case Id_findLastIndex:
return ArrayLikeAbstractOperations.iterativeMethod(
cx, f, IterativeOperation.FIND_LAST_INDEX, scope, thisObj, args);

case Id_reduce:
return ArrayLikeAbstractOperations.reduceMethod(
cx, ReduceOperation.REDUCE, scope, thisObj, args);
Expand Down Expand Up @@ -2504,6 +2523,12 @@ protected int findPrototypeId(String s) {
case "findIndex":
id = Id_findIndex;
break;
case "findLast":
id = Id_findLast;
break;
case "findLastIndex":
id = Id_findLastIndex;
break;
case "reduce":
id = Id_reduce;
break;
Expand Down Expand Up @@ -2567,18 +2592,20 @@ protected int findPrototypeId(String s) {
Id_some = 21,
Id_find = 22,
Id_findIndex = 23,
Id_reduce = 24,
Id_reduceRight = 25,
Id_fill = 26,
Id_keys = 27,
Id_values = 28,
Id_entries = 29,
Id_includes = 30,
Id_copyWithin = 31,
Id_at = 32,
Id_flat = 33,
Id_flatMap = 34,
SymbolId_unscopables = 35,
Id_findLast = 24,
Id_findLastIndex = 25,
Id_reduce = 26,
Id_reduceRight = 27,
Id_fill = 28,
Id_keys = 29,
Id_values = 30,
Id_entries = 31,
Id_includes = 32,
Id_copyWithin = 33,
Id_at = 34,
Id_flat = 35,
Id_flatMap = 36,
SymbolId_unscopables = 37,
MAX_PROTOTYPE_ID = SymbolId_unscopables;
private static final int ConstructorId_join = -Id_join,
ConstructorId_reverse = -Id_reverse,
Expand All @@ -2599,11 +2626,13 @@ protected int findPrototypeId(String s) {
ConstructorId_some = -Id_some,
ConstructorId_find = -Id_find,
ConstructorId_findIndex = -Id_findIndex,
ConstructorId_findLast = -Id_findLast,
ConstructorId_findLastIndex = -Id_findLastIndex,
ConstructorId_reduce = -Id_reduce,
ConstructorId_reduceRight = -Id_reduceRight,
ConstructorId_isArray = -26,
ConstructorId_of = -27,
ConstructorId_from = -28;
ConstructorId_isArray = -28,
ConstructorId_of = -29,
ConstructorId_from = -30;

/** Internal representation of the JavaScript array's length property. */
private long length;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,12 @@ public Object execIdCall(
case Id_findIndex:
return ArrayLikeAbstractOperations.iterativeMethod(
cx, f, IterativeOperation.FIND_INDEX, scope, thisObj, args);
case Id_findLast:
return ArrayLikeAbstractOperations.iterativeMethod(
cx, f, IterativeOperation.FIND_LAST, scope, thisObj, args);
case Id_findLastIndex:
return ArrayLikeAbstractOperations.iterativeMethod(
cx, f, IterativeOperation.FIND_LAST_INDEX, scope, thisObj, args);
case Id_reduce:
return ArrayLikeAbstractOperations.reduceMethod(
cx, ReduceOperation.REDUCE, scope, thisObj, args);
Expand Down Expand Up @@ -898,6 +904,14 @@ protected void initPrototypeId(int id) {
arity = 1;
s = "findIndex";
break;
case Id_findLast:
arity = 1;
s = "findLast";
break;
case Id_findLastIndex:
arity = 1;
s = "findLastIndex";
break;
case Id_reduce:
arity = 1;
s = "reduce";
Expand Down Expand Up @@ -1002,6 +1016,12 @@ protected int findPrototypeId(String s) {
case "findIndex":
id = Id_findIndex;
break;
case "findLast":
id = Id_findLast;
break;
case "findLastIndex":
id = Id_findLastIndex;
break;
case "reduce":
id = Id_reduce;
break;
Expand Down Expand Up @@ -1042,9 +1062,11 @@ protected int findPrototypeId(String s) {
Id_some = 24,
Id_find = 25,
Id_findIndex = 26,
Id_reduce = 27,
Id_reduceRight = 28,
SymbolId_iterator = 29;
Id_findLast = 27,
Id_findLastIndex = 28,
Id_reduce = 29,
Id_reduceRight = 30,
SymbolId_iterator = 31;

protected static final int MAX_PROTOTYPE_ID = SymbolId_iterator;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.javascript.tests.es2023;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.drivers.LanguageVersion;
import org.mozilla.javascript.drivers.RhinoTest;
import org.mozilla.javascript.drivers.ScriptTestsBase;

@RhinoTest("testsrc/jstests/es2023/array-findLastIndex.js")
@LanguageVersion(Context.VERSION_ES6)
public class ArrayFindLastIndexTest extends ScriptTestsBase {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.javascript.tests.es2023;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.drivers.LanguageVersion;
import org.mozilla.javascript.drivers.RhinoTest;
import org.mozilla.javascript.drivers.ScriptTestsBase;

@RhinoTest("testsrc/jstests/es2023/array-findLast.js")
@LanguageVersion(Context.VERSION_ES6)
public class ArrayFindLastTest extends ScriptTestsBase {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.javascript.tests.es2023;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.drivers.LanguageVersion;
import org.mozilla.javascript.drivers.RhinoTest;
import org.mozilla.javascript.drivers.ScriptTestsBase;

@RhinoTest("testsrc/jstests/es2023/typed-array-find-last-index.js")
@LanguageVersion(Context.VERSION_ES6)
public class TypedArrayFindLastIndexTest extends ScriptTestsBase {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

package org.mozilla.javascript.tests.es2023;

import org.mozilla.javascript.Context;
import org.mozilla.javascript.drivers.LanguageVersion;
import org.mozilla.javascript.drivers.RhinoTest;
import org.mozilla.javascript.drivers.ScriptTestsBase;

@RhinoTest("testsrc/jstests/es2023/typed-array-find-last.js")
@LanguageVersion(Context.VERSION_ES6)
public class TypedArrayFindLastTest extends ScriptTestsBase {}
Loading

0 comments on commit 7e652a0

Please sign in to comment.