diff options
-rw-r--r-- | js/src/builtin/Array.js | 66 | ||||
-rw-r--r-- | js/src/builtin/TypedArray.js | 85 | ||||
-rw-r--r-- | js/src/jsarray.cpp | 6 | ||||
-rw-r--r-- | js/src/vm/CommonPropertyNames.h | 2 | ||||
-rw-r--r-- | js/src/vm/TypedArrayObject.cpp | 2 |
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), |