diff --git a/js/src/builtin/Array.js b/js/src/builtin/Array.js index 302955de7..2c0452abc 100644 --- a/js/src/builtin/Array.js +++ b/js/src/builtin/Array.js @@ -839,7 +839,7 @@ function ArrayFrom(items, mapfn=undefined, thisArg=undefined) { } // Step 7. - assert(usingIterator === undefined, "`items` can't be an Iterable after step 6.g.iv"); + assert(usingIterator === undefined, "`items` cannot be an Iterable after step 6.g.iv"); // Steps 8-9. var arrayLike = ToObject(items); @@ -1187,6 +1187,35 @@ function FlattenIntoArray(target, source, sourceLen, start, depth, mapperFunctio return targetIndex; } +// ES2022 at() method on the built-in indexables +// Array.prototype.at(index) +function ArrayAt(index) { + // Step 1. + var O = ToObject(this); + + // Step 2. + var len = ToLength(O.length); + + // Step 3. + var relativeIndex = ToInteger(index); + + // Steps 4-5. + var k; + if (relativeIndex >= 0) { + k = relativeIndex; + } else { + k = len + relativeIndex; + } + + // Step 6. + if (k < 0 || k >= len) { + return undefined; + } + + // Step 7. + return O[k]; +} + function ArrayStaticConcat(arr, arg1) { if (arguments.length < 1) ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.concat'); diff --git a/js/src/builtin/String.js b/js/src/builtin/String.js index c19ff2df0..5abd3fd34 100644 --- a/js/src/builtin/String.js +++ b/js/src/builtin/String.js @@ -791,6 +791,39 @@ function String_static_raw(callSite, ...substitutions) { } } +// ES2022 at() method on the built-in indexables +// String.prototype.at(index) +function String_at(index) { + // Step 1. + if (this === undefined || this === null) + ThrowIncompatibleMethod("at", this); + + // Step 2. + var string = ToString(this); + + // Step 3. + var len = string.length; + + // Step 4. + var relativeIndex = ToInteger(index); + + // Steps 5-6. + var k; + if (relativeIndex >= 0) { + k = relativeIndex; + } else { + k = len + relativeIndex; + } + + // Step 7. + if (k < 0 || k >= len) { + return undefined; + } + + // Step 8. + return string[k]; +} + /** * Compare String str1 against String str2, using the locale and collation * options provided. diff --git a/js/src/builtin/TypedArray.js b/js/src/builtin/TypedArray.js index a056fc2fd..b4266bb6b 100644 --- a/js/src/builtin/TypedArray.js +++ b/js/src/builtin/TypedArray.js @@ -1317,6 +1317,45 @@ function TypedArraySubarray(begin, end) { return TypedArraySpeciesCreateWithBuffer(obj, buffer, beginByteOffset, newLength); } +// ES2022 at() method on the built-in indexables +// %TypedArray%.prototype.at(index) +function TypedArrayAt(index) { + // Step 1. + var obj = this; + + // Step 2. + // This function is not generic. + if (!IsObject(obj) || !IsTypedArray(obj)) { + return callFunction(CallTypedArrayMethodIfWrapped, obj, index, + "TypedArrayAt"); + } + GetAttachedArrayBuffer(obj); + + // If we got here, `this` is either a typed array or a wrapper for one. + + // Step 3. + var len = TypedArrayLength(obj); + + // Step 4. + var relativeIndex = ToInteger(index); + + // Steps 5-6. + var k; + if (relativeIndex >= 0) { + k = relativeIndex; + } else { + k = len + relativeIndex; + } + + // Step 7. + if (k < 0 || k >= len) { + return undefined; + } + + // Step 8. + return obj[k]; +} + // 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 844a7179e..4c201fe4d 100644 --- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -3171,6 +3171,9 @@ static const JSFunctionSpec array_methods[] = { JS_SELF_HOSTED_FN("flat", "ArrayFlat", 0,0), JS_SELF_HOSTED_FN("flatMap", "ArrayFlatMap", 1,0), + /* ES2022 additions */ + JS_SELF_HOSTED_FN("at", "ArrayAt", 1,0), + JS_FS_END }; diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index ec684e410..97100b39d 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -2911,6 +2911,9 @@ static const JSFunctionSpec string_methods[] = { /* Python-esque sequence methods. */ JS_FN("concat", str_concat, 1,0), JS_SELF_HOSTED_FN("slice", "String_slice", 2,0), + + /* ES2022 additions */ + JS_SELF_HOSTED_FN("at", "String_at", 1,0), /* HTML string methods. */ JS_SELF_HOSTED_FN("bold", "String_bold", 0,0), diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index 8adb93d3f..ea3917a56 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -1540,6 +1540,10 @@ TypedArrayObject::protoFunctions[] = { JS_SELF_HOSTED_FN("includes", "TypedArrayIncludes", 2, 0), JS_SELF_HOSTED_FN("toString", "ArrayToString", 0, 0), JS_SELF_HOSTED_FN("toLocaleString", "TypedArrayToLocaleString", 2, 0), + + /* ES2022 additions */ + JS_SELF_HOSTED_FN("at", "TypedArrayAt", 1, 0), + JS_FS_END };