summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--js/src/builtin/Array.js66
-rw-r--r--js/src/builtin/TypedArray.js85
-rw-r--r--js/src/jsarray.cpp6
-rw-r--r--js/src/vm/CommonPropertyNames.h2
-rw-r--r--js/src/vm/TypedArrayObject.cpp2
5 files changed, 161 insertions, 0 deletions
diff --git a/js/src/builtin/Array.js b/js/src/builtin/Array.js
index 1e7776e228..f97e1df571 100644
--- a/js/src/builtin/Array.js
+++ b/js/src/builtin/Array.js
@@ -1210,6 +1210,72 @@ function ArrayAt(index) {
return O[k];
}
+// https://github.com/tc39/proposal-array-find-from-last
+// Array.prototype.findLast ( predicate, thisArg )
+function ArrayFindLast(predicate/*, thisArg*/) {
+ /* Steps 1. */
+ var O = ToObject(this);
+
+ /* Steps 2. */
+ var len = ToLength(O.length);
+
+ /* Step 3. */
+ if (arguments.length === 0) {
+ ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.findLast");
+ }
+ if (!IsCallable(predicate)) {
+ ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate));
+ }
+
+ var T = arguments.length > 1 ? arguments[1] : undefined;
+
+ /* Step 4-5. */
+ for (var k = len - 1; k >= 0; k--) {
+ /* Steps 5.a-b. */
+ var kValue = O[k];
+ /* Steps 5.c-d. */
+ if (callContentFunction(predicate, T, kValue, k, O)) {
+ return kValue;
+ }
+ }
+
+ /* Step 6. */
+ return undefined;
+}
+
+// https://github.com/tc39/proposal-array-find-from-last
+// Array.prototype.findLastIndex ( predicate, thisArg )
+function ArrayFindLastIndex(predicate/*, thisArg*/) {
+ /* Steps 1. */
+ var O = ToObject(this);
+
+ /* Steps 2. */
+ var len = ToLength(O.length);
+
+ /* Step 3. */
+ if (arguments.length === 0) {
+ ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.findLastIndex");
+ }
+ if (!IsCallable(predicate)) {
+ ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate));
+ }
+
+ var T = arguments.length > 1 ? arguments[1] : undefined;
+
+ /* Step 4-5. */
+ for (var k = len - 1; k >= 0; k--) {
+ /* Steps 5.a-b. */
+ var kValue = O[k];
+ /* Steps 5.c-d. */
+ if (callContentFunction(predicate, T, kValue, k, O)) {
+ return k;
+ }
+ }
+
+ /* Step 6. */
+ return -1;
+}
+
function ArrayStaticConcat(arr, arg1) {
if (arguments.length < 1)
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.concat');
diff --git a/js/src/builtin/TypedArray.js b/js/src/builtin/TypedArray.js
index 5b7a1dfc22..22023aa7ca 100644
--- a/js/src/builtin/TypedArray.js
+++ b/js/src/builtin/TypedArray.js
@@ -1347,6 +1347,91 @@ function TypedArrayAt(index) {
return obj[k];
}
+// https://github.com/tc39/proposal-array-find-from-last
+// %TypedArray%.prototype.findLast ( predicate, thisArg )
+function TypedArrayFindLast(predicate/*, thisArg*/) {
+ // Step 1.
+ var O = this;
+
+ // Step 2.
+ var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+
+ // If we got here, `this` is either a typed array or a wrapper for one.
+
+ // Step 3.
+ var len;
+ if (isTypedArray) {
+ len = TypedArrayLength(O);
+ } else {
+ len = callFunction(CallTypedArrayMethodIfWrapped, O, "TypedArrayLengthMethod");
+ }
+
+ // Step 4.
+ if (arguments.length === 0) {
+ ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.findLast");
+ }
+ if (!IsCallable(predicate)) {
+ ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate));
+ }
+
+ var thisArg = arguments.length > 1 ? arguments[1] : void 0;
+
+ // Steps 5-6.
+ for (var k = len - 1; k >= 0; k--) {
+ // Steps 6.a-b.
+ var kValue = O[k];
+
+ // Steps 6.c-d.
+ if (callContentFunction(predicate, thisArg, kValue, k, O)) {
+ return kValue;
+ }
+ }
+
+ // Step 7.
+ return undefined;
+}
+
+// https://github.com/tc39/proposal-array-find-from-last
+// %TypedArray%.prototype.findLastIndex ( predicate, thisArg )
+function TypedArrayFindLastIndex(predicate/*, thisArg*/) {
+ // Step 1.
+ var O = this;
+
+ // Step 2.
+ var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+
+ // If we got here, `this` is either a typed array or a wrapper for one.
+
+ // Step 3.
+ var len;
+ if (isTypedArray) {
+ len = TypedArrayLength(O);
+ } else {
+ len = callFunction(CallTypedArrayMethodIfWrapped, O, "TypedArrayLengthMethod");
+ }
+
+ // Step 4.
+ if (arguments.length === 0) {
+ ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.findLastIndex");
+ }
+ if (!IsCallable(predicate)) {
+ ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate));
+ }
+
+ var thisArg = arguments.length > 1 ? arguments[1] : void 0;
+
+ // Steps 5-6.
+ for (var k = len - 1; k >= 0; k--) {
+ // Steps 6.a-f.
+ if (callContentFunction(predicate, thisArg, O[k], k, O)) {
+ return k;
+ }
+ }
+
+ // Step 7.
+ return -1;
+}
+
// ES6 draft rev30 (2014/12/24) 22.2.3.30 %TypedArray%.prototype.values()
function TypedArrayValues() {
// Step 1.
diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp
index 912f393942..b166a786ca 100644
--- a/js/src/jsarray.cpp
+++ b/js/src/jsarray.cpp
@@ -3191,6 +3191,10 @@ static const JSFunctionSpec array_methods[] = {
/* ES2022 additions */
JS_SELF_HOSTED_FN("at", "ArrayAt", 1,0),
+
+ /* ES2023 proposals */
+ JS_SELF_HOSTED_FN("findLast", "ArrayFindLast", 1,0),
+ JS_SELF_HOSTED_FN("findLastIndex", "ArrayFindLastIndex", 1,0),
JS_FS_END
};
@@ -3356,6 +3360,8 @@ array_proto_finish(JSContext* cx, JS::HandleObject ctor, JS::HandleObject proto)
!DefineProperty(cx, unscopables, cx->names().fill, value) ||
!DefineProperty(cx, unscopables, cx->names().find, value) ||
!DefineProperty(cx, unscopables, cx->names().findIndex, value) ||
+ !DefineProperty(cx, unscopables, cx->names().findLast, value) ||
+ !DefineProperty(cx, unscopables, cx->names().findLastIndex, value) ||
!DefineProperty(cx, unscopables, cx->names().flat, value) ||
!DefineProperty(cx, unscopables, cx->names().flatMap, value) ||
!DefineProperty(cx, unscopables, cx->names().includes, value) ||
diff --git a/js/src/vm/CommonPropertyNames.h b/js/src/vm/CommonPropertyNames.h
index e1e9f56c31..1d398190ae 100644
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -135,6 +135,8 @@
macro(finally, finally_, "finally") \
macro(find, find, "find") \
macro(findIndex, findIndex, "findIndex") \
+ macro(findLast, findLast, "findLast") \
+ macro(findLastIndex, findLastIndex, "findLastIndex") \
macro(firstDayOfWeek, firstDayOfWeek, "firstDayOfWeek") \
macro(fix, fix, "fix") \
macro(flags, flags, "flags") \
diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp
index 9dca828a3a..9d82fca6ec 100644
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -1486,6 +1486,8 @@ TypedArrayObject::protoFunctions[] = {
JS_SELF_HOSTED_FN("filter", "TypedArrayFilter", 1, 0),
JS_SELF_HOSTED_FN("find", "TypedArrayFind", 1, 0),
JS_SELF_HOSTED_FN("findIndex", "TypedArrayFindIndex", 1, 0),
+ JS_SELF_HOSTED_FN("findLast", "TypedArrayFindLast", 1, 0),
+ JS_SELF_HOSTED_FN("findLastIndex", "TypedArrayFindLastIndex", 1, 0),
JS_SELF_HOSTED_FN("forEach", "TypedArrayForEach", 1, 0),
JS_SELF_HOSTED_FN("indexOf", "TypedArrayIndexOf", 2, 0),
JS_SELF_HOSTED_FN("join", "TypedArrayJoin", 1, 0),