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 it for the typed arrays variants.
There are no test262 changes because our version of test262 is old and
does not contain them yet.
  • Loading branch information
andreabergia committed Aug 7, 2024
1 parent cc302b4 commit cea8320
Show file tree
Hide file tree
Showing 11 changed files with 877 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import java.util.Comparator;
import org.mozilla.javascript.regexp.NativeRegExp;

/** Contains implementation of shared methods useful for arrays and typed arrays. */
public class ArrayLikeAbstractOperations {
public enum IterativeOperation {
EVERY,
Expand All @@ -18,6 +17,8 @@ public enum IterativeOperation {
SOME,
FIND,
FIND_INDEX,
FIND_LAST,
FIND_LAST_INDEX,
}

public enum ReduceOperation {
Expand All @@ -35,7 +36,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 +66,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 +114,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 +132,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
58 changes: 44 additions & 14 deletions rhino/src/main/java/org/mozilla/javascript/NativeArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,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 @@ -255,6 +257,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 @@ -335,6 +345,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 @@ -467,6 +479,14 @@ 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 @@ -2459,6 +2479,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 @@ -2522,17 +2548,19 @@ 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,
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,
MAX_PROTOTYPE_ID = Id_flatMap;
private static final int ConstructorId_join = -Id_join,
ConstructorId_reverse = -Id_reverse,
Expand All @@ -2553,11 +2581,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 cea8320

Please sign in to comment.