diff --git a/js/src/builtin/Array.js b/js/src/builtin/Array.js index f7fd4a4c8f..378e972084 100644 --- a/js/src/builtin/Array.js +++ b/js/src/builtin/Array.js @@ -2,991 +2,998 @@ * 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/. */ - /* ES5 15.4.4.14. */ -function ArrayIndexOf(searchElement/*, fromIndex*/) { - /* Step 1. */ - var O = ToObject(this); +/* ES5 15.4.4.14. */ +function ArrayIndexOf(searchElement /*, fromIndex*/) { + /* Step 1. */ + var O = ToObject(this); - /* Steps 2-3. */ - var len = ToLength(O.length); + /* Steps 2-3. */ + var len = ToLength(O.length); - /* Step 4. */ - if (len === 0) - return -1; + /* Step 4. */ + if (len === 0) return -1; - /* Step 5. Add zero to convert -0 to +0, per ES6 5.2. */ - var n = arguments.length > 1 ? ToInteger(arguments[1]) + 0 : 0; + /* Step 5. Add zero to convert -0 to +0, per ES6 5.2. */ + var n = arguments.length > 1 ? ToInteger(arguments[1]) + 0 : 0; - /* Step 6. */ - if (n >= len) - return -1; + /* Step 6. */ + if (n >= len) return -1; - var k; - /* Step 7. */ - if (n >= 0) - k = n; - /* Step 8. */ - else { - /* Step a. */ - k = len + n; - /* Step b. */ - if (k < 0) - k = 0; + var k; + /* Step 7. */ + if (n >= 0) k = n; + /* Step 8. */ else { + /* Step a. */ + k = len + n; + /* Step b. */ + if (k < 0) k = 0; + } + + /* Step 9. */ + if (IsPackedArray(O)) { + for (; k < len; k++) { + if (O[k] === searchElement) return k; } - - /* Step 9. */ - if (IsPackedArray(O)) { - for (; k < len; k++) { - if (O[k] === searchElement) - return k; - } - } else { - for (; k < len; k++) { - if (k in O && O[k] === searchElement) - return k; - } + } else { + for (; k < len; k++) { + if (k in O && O[k] === searchElement) return k; } + } - /* Step 10. */ - return -1; + /* Step 10. */ + return -1; } -function ArrayStaticIndexOf(list, searchElement/*, fromIndex*/) { - if (arguments.length < 1) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.indexOf'); - var fromIndex = arguments.length > 2 ? arguments[2] : 0; - return callFunction(ArrayIndexOf, list, searchElement, fromIndex); +function ArrayStaticIndexOf(list, searchElement /*, fromIndex*/) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.indexOf"); + var fromIndex = arguments.length > 2 ? arguments[2] : 0; + return callFunction(ArrayIndexOf, list, searchElement, fromIndex); } /* ES5 15.4.4.15. */ -function ArrayLastIndexOf(searchElement/*, fromIndex*/) { - /* Step 1. */ - var O = ToObject(this); +function ArrayLastIndexOf(searchElement /*, fromIndex*/) { + /* Step 1. */ + var O = ToObject(this); - /* Steps 2-3. */ - var len = ToLength(O.length); + /* Steps 2-3. */ + var len = ToLength(O.length); - /* Step 4. */ - if (len === 0) - return -1; + /* Step 4. */ + if (len === 0) return -1; - /* Step 5. Add zero to convert -0 to +0, per ES6 5.2. */ - var n = arguments.length > 1 ? ToInteger(arguments[1]) + 0 : len - 1; + /* Step 5. Add zero to convert -0 to +0, per ES6 5.2. */ + var n = arguments.length > 1 ? ToInteger(arguments[1]) + 0 : len - 1; - /* Steps 6-7. */ - var k; - if (n > len - 1) - k = len - 1; - else if (n < 0) - k = len + n; - else - k = n; + /* Steps 6-7. */ + var k; + if (n > len - 1) k = len - 1; + else if (n < 0) k = len + n; + else k = n; - /* Step 8. */ - if (IsPackedArray(O)) { - for (; k >= 0; k--) { - if (O[k] === searchElement) - return k; - } - } else { - for (; k >= 0; k--) { - if (k in O && O[k] === searchElement) - return k; - } + /* Step 8. */ + if (IsPackedArray(O)) { + for (; k >= 0; k--) { + if (O[k] === searchElement) return k; } + } else { + for (; k >= 0; k--) { + if (k in O && O[k] === searchElement) return k; + } + } - /* Step 9. */ - return -1; + /* Step 9. */ + return -1; } -function ArrayStaticLastIndexOf(list, searchElement/*, fromIndex*/) { - if (arguments.length < 1) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.lastIndexOf'); - var fromIndex; - if (arguments.length > 2) { - fromIndex = arguments[2]; - } else { - var O = ToObject(list); - var len = ToLength(O.length); - fromIndex = len - 1; - } - return callFunction(ArrayLastIndexOf, list, searchElement, fromIndex); +function ArrayStaticLastIndexOf(list, searchElement /*, fromIndex*/) { + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.lastIndexOf"); + var fromIndex; + if (arguments.length > 2) { + fromIndex = arguments[2]; + } else { + var O = ToObject(list); + var len = ToLength(O.length); + fromIndex = len - 1; + } + return callFunction(ArrayLastIndexOf, list, searchElement, fromIndex); } /* ES5 15.4.4.16. */ -function ArrayEvery(callbackfn/*, thisArg*/) { - /* Step 1. */ - var O = ToObject(this); +function ArrayEvery(callbackfn /*, thisArg*/) { + /* Step 1. */ + var O = ToObject(this); - /* Steps 2-3. */ - var len = ToLength(O.length); + /* Steps 2-3. */ + var len = ToLength(O.length); - /* Step 4. */ - if (arguments.length === 0) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.every'); - if (!IsCallable(callbackfn)) - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + /* Step 4. */ + if (arguments.length === 0) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.every"); + if (!IsCallable(callbackfn)) + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); - /* Step 5. */ - var T = arguments.length > 1 ? arguments[1] : void 0; + /* Step 5. */ + var T = arguments.length > 1 ? arguments[1] : void 0; - /* Steps 6-7. */ - /* Steps a (implicit), and d. */ - for (var k = 0; k < len; k++) { - /* Step b */ - if (k in O) { - /* Step c. */ - if (!callContentFunction(callbackfn, T, O[k], k, O)) - return false; - } + /* Steps 6-7. */ + /* Steps a (implicit), and d. */ + for (var k = 0; k < len; k++) { + /* Step b */ + if (k in O) { + /* Step c. */ + if (!callContentFunction(callbackfn, T, O[k], k, O)) return false; } + } - /* Step 8. */ - return true; + /* Step 8. */ + return true; } -function ArrayStaticEvery(list, callbackfn/*, thisArg*/) { - if (arguments.length < 2) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.every'); - if (!IsCallable(callbackfn)) - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); - var T = arguments.length > 2 ? arguments[2] : void 0; - return callFunction(ArrayEvery, list, callbackfn, T); +function ArrayStaticEvery(list, callbackfn /*, thisArg*/) { + if (arguments.length < 2) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.every"); + if (!IsCallable(callbackfn)) + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); + var T = arguments.length > 2 ? arguments[2] : void 0; + return callFunction(ArrayEvery, list, callbackfn, T); } /* ES5 15.4.4.17. */ -function ArraySome(callbackfn/*, thisArg*/) { - /* Step 1. */ - var O = ToObject(this); +function ArraySome(callbackfn /*, thisArg*/) { + /* Step 1. */ + var O = ToObject(this); - /* Steps 2-3. */ - var len = ToLength(O.length); + /* Steps 2-3. */ + var len = ToLength(O.length); - /* Step 4. */ - if (arguments.length === 0) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.some'); - if (!IsCallable(callbackfn)) - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + /* Step 4. */ + if (arguments.length === 0) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.some"); + if (!IsCallable(callbackfn)) + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); - /* Step 5. */ - var T = arguments.length > 1 ? arguments[1] : void 0; + /* Step 5. */ + var T = arguments.length > 1 ? arguments[1] : void 0; - /* Steps 6-7. */ - /* Steps a (implicit), and d. */ - for (var k = 0; k < len; k++) { - /* Step b */ - if (k in O) { - /* Step c. */ - if (callContentFunction(callbackfn, T, O[k], k, O)) - return true; - } + /* Steps 6-7. */ + /* Steps a (implicit), and d. */ + for (var k = 0; k < len; k++) { + /* Step b */ + if (k in O) { + /* Step c. */ + if (callContentFunction(callbackfn, T, O[k], k, O)) return true; } + } - /* Step 8. */ - return false; + /* Step 8. */ + return false; } -function ArrayStaticSome(list, callbackfn/*, thisArg*/) { - if (arguments.length < 2) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.some'); - if (!IsCallable(callbackfn)) - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); - var T = arguments.length > 2 ? arguments[2] : void 0; - return callFunction(ArraySome, list, callbackfn, T); +function ArrayStaticSome(list, callbackfn /*, thisArg*/) { + if (arguments.length < 2) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.some"); + if (!IsCallable(callbackfn)) + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); + var T = arguments.length > 2 ? arguments[2] : void 0; + return callFunction(ArraySome, list, callbackfn, T); } // ES2018 draft rev 3bbc87cd1b9d3bf64c3e68ca2fe9c5a3f2c304c0 // 22.1.3.25 Array.prototype.sort ( comparefn ) function ArraySort(comparefn) { - /* Step 1. */ - if (comparefn !== undefined) { - if (!IsCallable(comparefn)) { - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, comparefn)); - } + /* Step 1. */ + if (comparefn !== undefined) { + if (!IsCallable(comparefn)) { + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, comparefn)); } + } - /* Step 2. */ - var O = ToObject(this); + /* Step 2. */ + var O = ToObject(this); - /* Step 3. */ - var len = ToLength(O.length); + /* Step 3. */ + var len = ToLength(O.length); - if (len <= 1) - return this; + if (len <= 1) return this; - if (comparefn === undefined) { - // {Goanna} This implementation slightly breaks the standard. The default - // comparator function depends on the type of items in the Array - // (Strings, Numbers, etc.) and can be literal, lexicograpic, numeric, - // lexicograpic-number... - // Mozilla implements this correctly only in the native implementation. - // Note that this must be stable regardless of casting, so we can only - // use one of > or <, as the other may involve weird equality. - comparefn = function(x, y) { - /* Step 4.a. */ - if (x == y) - return 0; - if (x > y) - return 1; - return -1; - } + if (comparefn === undefined) { + // {Goanna} This implementation slightly breaks the standard. The default + // comparator function depends on the type of items in the Array + // (Strings, Numbers, etc.) and can be literal, lexicograpic, numeric, + // lexicograpic-number... + // Mozilla implements this correctly only in the native implementation. + // Note that this must be stable regardless of casting, so we can only + // use one of > or <, as the other may involve weird equality. + comparefn = function (x, y) { + /* Step 4.a. */ + if (x == y) return 0; + if (x > y) return 1; + return -1; + }; + } + /* 22.1.3.25.1 Runtime Semantics: SortCompare( x, y ) */ + var wrappedCompareFn = comparefn; + comparefn = function (x, y) { + /* Steps 1-3. */ + if (x === undefined) { + if (y === undefined) return 0; + return 1; } - /* 22.1.3.25.1 Runtime Semantics: SortCompare( x, y ) */ - var wrappedCompareFn = comparefn; - comparefn = function(x, y) { - /* Steps 1-3. */ - if (x === undefined) { - if (y === undefined) - return 0; - return 1; - } - if (y === undefined) - return -1; + if (y === undefined) return -1; - /* Step 4.a. */ - var v = ToNumber(wrappedCompareFn(x, y)); + /* Step 4.a. */ + var v = ToNumber(wrappedCompareFn(x, y)); - /* Step 4.b-c. */ - return v !== v ? 0 : v; - } + /* Step 4.b-c. */ + return v !== v ? 0 : v; + }; - return MergeSort(O, len, comparefn); + return MergeSort(O, len, comparefn); } // ES2023 22.1.3.30 Array.prototype.toSorted ( comparefn ) function ArrayToSorted(comparefn) { - if (comparefn !== undefined) { - if (!IsCallable(comparefn)) { - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, comparefn)); - } + if (comparefn !== undefined) { + if (!IsCallable(comparefn)) { + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, comparefn)); } + } - // Step 1: Let O be ? ToObject(this). Let len be ? ToLength(O.length). - var O = ToObject(this); - var len = ToLength(O.length); + // Step 1: Let O be ? ToObject(this). Let len be ? ToLength(O.length). + var O = ToObject(this); + var len = ToLength(O.length); - // Step 2: Create the result array using ArrayCreate semantics. - // This intentionally doesn't use Symbol.species and also performs the - // array-length limit check before indexed value reads. - var A = std_Array(len); + // Step 2: Create the result array using ArrayCreate semantics. + // This intentionally doesn't use Symbol.species and also performs the + // array-length limit check before indexed value reads. + var A = std_Array(len); - // Step 3: Snapshot values in ascending index order into a List. - var items = new List(); - var itemsLen = len; - for (var k = 0; k < len; k++) { - items[k] = O[k]; - } + // Step 3: Snapshot values in ascending index order into a List. + var items = new List(); + var itemsLen = len; + for (var k = 0; k < len; k++) { + items[k] = O[k]; + } - // Step 4: Create SortCompare per spec. - var wrappedCompareFn = comparefn; - var sortCompare; - if (wrappedCompareFn === undefined) { - sortCompare = function(x, y) { - if (x === undefined) - return y === undefined ? 0 : 1; - if (y === undefined) - return -1; + // Step 4: Create SortCompare per spec. + var wrappedCompareFn = comparefn; + var sortCompare; + if (wrappedCompareFn === undefined) { + sortCompare = function (x, y) { + if (x === undefined) return y === undefined ? 0 : 1; + if (y === undefined) return -1; - var xString = ToString(x); - var yString = ToString(y); - if (xString < yString) - return -1; - if (xString > yString) - return 1; - return 0; - }; - } else { - sortCompare = function(x, y) { - if (x === undefined) - return y === undefined ? 0 : 1; - if (y === undefined) - return -1; + var xString = ToString(x); + var yString = ToString(y); + if (xString < yString) return -1; + if (xString > yString) return 1; + return 0; + }; + } else { + sortCompare = function (x, y) { + if (x === undefined) return y === undefined ? 0 : 1; + if (y === undefined) return -1; - var v = ToNumber(wrappedCompareFn(x, y)); - return v !== v ? 0 : v; - }; - } + var v = ToNumber(wrappedCompareFn(x, y)); + return v !== v ? 0 : v; + }; + } - // Step 5: Sort the snapshot List using SortCompare. - if (itemsLen > 1) - MergeSort(items, itemsLen, sortCompare); + // Step 5: Sort the snapshot List using SortCompare. + if (itemsLen > 1) MergeSort(items, itemsLen, sortCompare); - // Step 6: Write sorted values into the pre-created result array. - for (var j = 0; j < itemsLen; j++) - _DefineDataProperty(A, j, items[j]); + // Step 6: Write sorted values into the pre-created result array. + for (var j = 0; j < itemsLen; j++) _DefineDataProperty(A, j, items[j]); - return A; + return A; } // ES2023 22.1.3.29 Array.prototype.toReversed ( ) function ArrayToReversed() { - // Step 1: Let O be ? ToObject(this value). - var O = ToObject(this); + // Step 1: Let O be ? ToObject(this value). + var O = ToObject(this); - // Step 2: Let len be ? LengthOfArrayLike(O). - var len = ToLength(O.length); + // Step 2: Let len be ? LengthOfArrayLike(O). + var len = ToLength(O.length); - // Step 3: Let A be ! ArrayCreate(len). - var A = std_Array(len); + // Step 3: Let A be ! ArrayCreate(len). + var A = std_Array(len); - // Steps 4-5: Copy elements in reverse order. - for (var k = 0; k < len; k++) { - var from = len - k - 1; - var fromValue = O[from]; - _DefineDataProperty(A, k, fromValue); + // Steps 4-5: Copy elements in reverse order. + for (var k = 0; k < len; k++) { + var from = len - k - 1; + var fromValue = O[from]; + _DefineDataProperty(A, k, fromValue); + } + + // Step 6. + return A; +} + +// ES2023 Array.prototype.with ( index, value ) +function ArrayWith(index, value) { + // Step 1. + var O = ToObject(this); + + // Step 2. + var len = ToLength(O.length); + + // Step 3. + var relativeIndex = ToInteger(index); + + // Steps 4-5. + var actualIndex = relativeIndex >= 0 ? relativeIndex : len + relativeIndex; + if (actualIndex < 0 || actualIndex >= len) ThrowRangeError(JSMSG_BAD_INDEX); + + // Step 6. + var A = std_Array(len); + + // Steps 7-8. + for (var k = 0; k < len; k++) { + var fromValue; + if (k === actualIndex) { + fromValue = value; + } else { + fromValue = O[k]; } + _DefineDataProperty(A, k, fromValue); + } - // Step 6. - return A; + // Step 9. + return A; } /* ES5 15.4.4.18. */ -function ArrayForEach(callbackfn/*, thisArg*/) { - /* Step 1. */ - var O = ToObject(this); +function ArrayForEach(callbackfn /*, thisArg*/) { + /* Step 1. */ + var O = ToObject(this); - /* Steps 2-3. */ - var len = ToLength(O.length); + /* Steps 2-3. */ + var len = ToLength(O.length); - /* Step 4. */ - if (arguments.length === 0) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.forEach'); - if (!IsCallable(callbackfn)) - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + /* Step 4. */ + if (arguments.length === 0) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.forEach"); + if (!IsCallable(callbackfn)) + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); - /* Step 5. */ - var T = arguments.length > 1 ? arguments[1] : void 0; + /* Step 5. */ + var T = arguments.length > 1 ? arguments[1] : void 0; - /* Steps 6-7. */ - /* Steps a (implicit), and d. */ - for (var k = 0; k < len; k++) { - /* Step b */ - if (k in O) { - /* Step c. */ - callContentFunction(callbackfn, T, O[k], k, O); - } + /* Steps 6-7. */ + /* Steps a (implicit), and d. */ + for (var k = 0; k < len; k++) { + /* Step b */ + if (k in O) { + /* Step c. */ + callContentFunction(callbackfn, T, O[k], k, O); } + } - /* Step 8. */ - return void 0; + /* Step 8. */ + return void 0; } -function ArrayStaticForEach(list, callbackfn/*, thisArg*/) { - if (arguments.length < 2) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.forEach'); - if (!IsCallable(callbackfn)) - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); - var T = arguments.length > 2 ? arguments[2] : void 0; - callFunction(ArrayForEach, list, callbackfn, T); +function ArrayStaticForEach(list, callbackfn /*, thisArg*/) { + if (arguments.length < 2) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.forEach"); + if (!IsCallable(callbackfn)) + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); + var T = arguments.length > 2 ? arguments[2] : void 0; + callFunction(ArrayForEach, list, callbackfn, T); } /* ES 2016 draft Mar 25, 2016 22.1.3.15. */ -function ArrayMap(callbackfn/*, thisArg*/) { - /* Step 1. */ - var O = ToObject(this); +function ArrayMap(callbackfn /*, thisArg*/) { + /* Step 1. */ + var O = ToObject(this); - /* Step 2. */ - var len = ToLength(O.length); + /* Step 2. */ + var len = ToLength(O.length); - /* Step 3. */ - if (arguments.length === 0) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.map'); - if (!IsCallable(callbackfn)) - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + /* Step 3. */ + if (arguments.length === 0) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.map"); + if (!IsCallable(callbackfn)) + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); - /* Step 4. */ - var T = arguments.length > 1 ? arguments[1] : void 0; + /* Step 4. */ + var T = arguments.length > 1 ? arguments[1] : void 0; - /* Steps 5. */ - var A = ArraySpeciesCreate(O, len); + /* Steps 5. */ + var A = ArraySpeciesCreate(O, len); - /* Steps 6-7. */ - /* Steps 7.a (implicit), and 7.d. */ - for (var k = 0; k < len; k++) { - /* Steps 7.b-c. */ - if (k in O) { - /* Steps 7.c.i-iii. */ - var mappedValue = callContentFunction(callbackfn, T, O[k], k, O); - _DefineDataProperty(A, k, mappedValue); - } + /* Steps 6-7. */ + /* Steps 7.a (implicit), and 7.d. */ + for (var k = 0; k < len; k++) { + /* Steps 7.b-c. */ + if (k in O) { + /* Steps 7.c.i-iii. */ + var mappedValue = callContentFunction(callbackfn, T, O[k], k, O); + _DefineDataProperty(A, k, mappedValue); } + } - /* Step 8. */ - return A; + /* Step 8. */ + return A; } -function ArrayStaticMap(list, callbackfn/*, thisArg*/) { - if (arguments.length < 2) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.map'); - if (!IsCallable(callbackfn)) - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); - var T = arguments.length > 2 ? arguments[2] : void 0; - return callFunction(ArrayMap, list, callbackfn, T); +function ArrayStaticMap(list, callbackfn /*, thisArg*/) { + if (arguments.length < 2) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.map"); + if (!IsCallable(callbackfn)) + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); + var T = arguments.length > 2 ? arguments[2] : void 0; + return callFunction(ArrayMap, list, callbackfn, T); } /* ES 2016 draft Mar 25, 2016 22.1.3.7 Array.prototype.filter. */ -function ArrayFilter(callbackfn/*, thisArg*/) { - /* Step 1. */ - var O = ToObject(this); +function ArrayFilter(callbackfn /*, thisArg*/) { + /* Step 1. */ + var O = ToObject(this); - /* Step 2. */ - var len = ToLength(O.length); + /* Step 2. */ + var len = ToLength(O.length); - /* Step 3. */ - if (arguments.length === 0) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.filter'); - if (!IsCallable(callbackfn)) - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + /* Step 3. */ + if (arguments.length === 0) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.filter"); + if (!IsCallable(callbackfn)) + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); - /* Step 4. */ - var T = arguments.length > 1 ? arguments[1] : void 0; + /* Step 4. */ + var T = arguments.length > 1 ? arguments[1] : void 0; - /* Step 5. */ - var A = ArraySpeciesCreate(O, 0); + /* Step 5. */ + var A = ArraySpeciesCreate(O, 0); - /* Steps 6-8. */ - /* Steps 8.a (implicit), and 8.d. */ - for (var k = 0, to = 0; k < len; k++) { - /* Steps 8.b-c. */ - if (k in O) { - /* Step 8.c.i. */ - var kValue = O[k]; - /* Step 8.c.ii. */ - var selected = callContentFunction(callbackfn, T, kValue, k, O); - /* Step 8.c.iii. */ - if (selected) - _DefineDataProperty(A, to++, kValue); - } + /* Steps 6-8. */ + /* Steps 8.a (implicit), and 8.d. */ + for (var k = 0, to = 0; k < len; k++) { + /* Steps 8.b-c. */ + if (k in O) { + /* Step 8.c.i. */ + var kValue = O[k]; + /* Step 8.c.ii. */ + var selected = callContentFunction(callbackfn, T, kValue, k, O); + /* Step 8.c.iii. */ + if (selected) _DefineDataProperty(A, to++, kValue); } + } - /* Step 9. */ - return A; + /* Step 9. */ + return A; } -function ArrayStaticFilter(list, callbackfn/*, thisArg*/) { - if (arguments.length < 2) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.filter'); - if (!IsCallable(callbackfn)) - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); - var T = arguments.length > 2 ? arguments[2] : void 0; - return callFunction(ArrayFilter, list, callbackfn, T); +function ArrayStaticFilter(list, callbackfn /*, thisArg*/) { + if (arguments.length < 2) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.filter"); + if (!IsCallable(callbackfn)) + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); + var T = arguments.length > 2 ? arguments[2] : void 0; + return callFunction(ArrayFilter, list, callbackfn, T); } /* ES5 15.4.4.21. */ -function ArrayReduce(callbackfn/*, initialValue*/) { - /* Step 1. */ - var O = ToObject(this); +function ArrayReduce(callbackfn /*, initialValue*/) { + /* Step 1. */ + var O = ToObject(this); - /* Steps 2-3. */ - var len = ToLength(O.length); + /* Steps 2-3. */ + var len = ToLength(O.length); - /* Step 4. */ - if (arguments.length === 0) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.reduce'); - if (!IsCallable(callbackfn)) - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + /* Step 4. */ + if (arguments.length === 0) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.reduce"); + if (!IsCallable(callbackfn)) + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); - /* Step 6. */ - var k = 0; + /* Step 6. */ + var k = 0; - /* Steps 5, 7-8. */ - var accumulator; - if (arguments.length > 1) { - accumulator = arguments[1]; + /* Steps 5, 7-8. */ + var accumulator; + if (arguments.length > 1) { + accumulator = arguments[1]; + } else { + /* Step 5. */ + if (len === 0) ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE); + if (IsPackedArray(O)) { + accumulator = O[k++]; } else { - /* Step 5. */ - if (len === 0) - ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE); - if (IsPackedArray(O)) { - accumulator = O[k++]; - } else { - var kPresent = false; - for (; k < len; k++) { - if (k in O) { - accumulator = O[k]; - kPresent = true; - k++; - break; - } - } - if (!kPresent) - ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE); - } - } - - /* Step 9. */ - /* Steps a (implicit), and d. */ - for (; k < len; k++) { - /* Step b */ + var kPresent = false; + for (; k < len; k++) { if (k in O) { - /* Step c. */ - accumulator = callbackfn(accumulator, O[k], k, O); + accumulator = O[k]; + kPresent = true; + k++; + break; } + } + if (!kPresent) ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE); } + } - /* Step 10. */ - return accumulator; + /* Step 9. */ + /* Steps a (implicit), and d. */ + for (; k < len; k++) { + /* Step b */ + if (k in O) { + /* Step c. */ + accumulator = callbackfn(accumulator, O[k], k, O); + } + } + + /* Step 10. */ + return accumulator; } function ArrayStaticReduce(list, callbackfn) { - if (arguments.length < 2) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.reduce'); - if (!IsCallable(callbackfn)) - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); - if (arguments.length > 2) - return callFunction(ArrayReduce, list, callbackfn, arguments[2]); - else - return callFunction(ArrayReduce, list, callbackfn); + if (arguments.length < 2) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.reduce"); + if (!IsCallable(callbackfn)) + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); + if (arguments.length > 2) + return callFunction(ArrayReduce, list, callbackfn, arguments[2]); + else return callFunction(ArrayReduce, list, callbackfn); } /* ES5 15.4.4.22. */ -function ArrayReduceRight(callbackfn/*, initialValue*/) { - /* Step 1. */ - var O = ToObject(this); +function ArrayReduceRight(callbackfn /*, initialValue*/) { + /* Step 1. */ + var O = ToObject(this); - /* Steps 2-3. */ - var len = ToLength(O.length); + /* Steps 2-3. */ + var len = ToLength(O.length); - /* Step 4. */ - if (arguments.length === 0) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.reduce'); - if (!IsCallable(callbackfn)) - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); + /* Step 4. */ + if (arguments.length === 0) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.reduce"); + if (!IsCallable(callbackfn)) + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); - /* Step 6. */ - var k = len - 1; + /* Step 6. */ + var k = len - 1; - /* Steps 5, 7-8. */ - var accumulator; - if (arguments.length > 1) { - accumulator = arguments[1]; + /* Steps 5, 7-8. */ + var accumulator; + if (arguments.length > 1) { + accumulator = arguments[1]; + } else { + /* Step 5. */ + if (len === 0) ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE); + if (IsPackedArray(O)) { + accumulator = O[k--]; } else { - /* Step 5. */ - if (len === 0) - ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE); - if (IsPackedArray(O)) { - accumulator = O[k--]; - } else { - var kPresent = false; - for (; k >= 0; k--) { - if (k in O) { - accumulator = O[k]; - kPresent = true; - k--; - break; - } - } - if (!kPresent) - ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE); - } - } - - /* Step 9. */ - /* Steps a (implicit), and d. */ - for (; k >= 0; k--) { - /* Step b */ + var kPresent = false; + for (; k >= 0; k--) { if (k in O) { - /* Step c. */ - accumulator = callbackfn(accumulator, O[k], k, O); + accumulator = O[k]; + kPresent = true; + k--; + break; } + } + if (!kPresent) ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE); } + } - /* Step 10. */ - return accumulator; + /* Step 9. */ + /* Steps a (implicit), and d. */ + for (; k >= 0; k--) { + /* Step b */ + if (k in O) { + /* Step c. */ + accumulator = callbackfn(accumulator, O[k], k, O); + } + } + + /* Step 10. */ + return accumulator; } function ArrayStaticReduceRight(list, callbackfn) { - if (arguments.length < 2) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.reduceRight'); - if (!IsCallable(callbackfn)) - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); - if (arguments.length > 2) - return callFunction(ArrayReduceRight, list, callbackfn, arguments[2]); - else - return callFunction(ArrayReduceRight, list, callbackfn); + if (arguments.length < 2) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.reduceRight"); + if (!IsCallable(callbackfn)) + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, callbackfn)); + if (arguments.length > 2) + return callFunction(ArrayReduceRight, list, callbackfn, arguments[2]); + else return callFunction(ArrayReduceRight, list, callbackfn); } /* ES6 draft 2013-05-14 15.4.3.23. */ -function ArrayFind(predicate/*, thisArg*/) { - /* Steps 1-2. */ - var O = ToObject(this); +function ArrayFind(predicate /*, thisArg*/) { + /* Steps 1-2. */ + var O = ToObject(this); - /* Steps 3-5. */ - var len = ToLength(O.length); + /* Steps 3-5. */ + var len = ToLength(O.length); - /* Step 6. */ - if (arguments.length === 0) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.find'); - if (!IsCallable(predicate)) - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate)); + /* Step 6. */ + if (arguments.length === 0) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.find"); + if (!IsCallable(predicate)) + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate)); - /* Step 7. */ - var T = arguments.length > 1 ? arguments[1] : undefined; + /* Step 7. */ + var T = arguments.length > 1 ? arguments[1] : undefined; - /* Steps 8-9. */ - /* Steps a (implicit), and g. */ - for (var k = 0; k < len; k++) { - /* Steps a-c. */ - var kValue = O[k]; - /* Steps d-f. */ - if (callContentFunction(predicate, T, kValue, k, O)) - return kValue; - } + /* Steps 8-9. */ + /* Steps a (implicit), and g. */ + for (var k = 0; k < len; k++) { + /* Steps a-c. */ + var kValue = O[k]; + /* Steps d-f. */ + if (callContentFunction(predicate, T, kValue, k, O)) return kValue; + } - /* Step 10. */ - return undefined; + /* Step 10. */ + return undefined; } /* ES6 draft 2013-05-14 15.4.3.23. */ -function ArrayFindIndex(predicate/*, thisArg*/) { - /* Steps 1-2. */ - var O = ToObject(this); +function ArrayFindIndex(predicate /*, thisArg*/) { + /* Steps 1-2. */ + var O = ToObject(this); - /* Steps 3-5. */ - var len = ToLength(O.length); + /* Steps 3-5. */ + var len = ToLength(O.length); - /* Step 6. */ - if (arguments.length === 0) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.prototype.find'); - if (!IsCallable(predicate)) - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate)); + /* Step 6. */ + if (arguments.length === 0) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.find"); + if (!IsCallable(predicate)) + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate)); - /* Step 7. */ - var T = arguments.length > 1 ? arguments[1] : undefined; + /* Step 7. */ + var T = arguments.length > 1 ? arguments[1] : undefined; - /* Steps 8-9. */ - /* Steps a (implicit), and g. */ - for (var k = 0; k < len; k++) { - /* Steps a-f. */ - if (callContentFunction(predicate, T, O[k], k, O)) - return k; - } + /* Steps 8-9. */ + /* Steps a (implicit), and g. */ + for (var k = 0; k < len; k++) { + /* Steps a-f. */ + if (callContentFunction(predicate, T, O[k], k, O)) return k; + } - /* Step 10. */ - return -1; + /* Step 10. */ + return -1; } /* ES6 draft 2013-09-27 22.1.3.3. */ function ArrayCopyWithin(target, start, end = undefined) { - /* Steps 1-2. */ - var O = ToObject(this); + /* Steps 1-2. */ + var O = ToObject(this); - /* Steps 3-5. */ - var len = ToLength(O.length); + /* Steps 3-5. */ + var len = ToLength(O.length); - /* Steps 6-8. */ - var relativeTarget = ToInteger(target); + /* Steps 6-8. */ + var relativeTarget = ToInteger(target); - var to = relativeTarget < 0 ? std_Math_max(len + relativeTarget, 0) - : std_Math_min(relativeTarget, len); + var to = + relativeTarget < 0 + ? std_Math_max(len + relativeTarget, 0) + : std_Math_min(relativeTarget, len); - /* Steps 9-11. */ - var relativeStart = ToInteger(start); + /* Steps 9-11. */ + var relativeStart = ToInteger(start); - var from = relativeStart < 0 ? std_Math_max(len + relativeStart, 0) - : std_Math_min(relativeStart, len); + var from = + relativeStart < 0 + ? std_Math_max(len + relativeStart, 0) + : std_Math_min(relativeStart, len); - /* Steps 12-14. */ - var relativeEnd = end === undefined ? len - : ToInteger(end); + /* Steps 12-14. */ + var relativeEnd = end === undefined ? len : ToInteger(end); - var final = relativeEnd < 0 ? std_Math_max(len + relativeEnd, 0) - : std_Math_min(relativeEnd, len); + var final = + relativeEnd < 0 + ? std_Math_max(len + relativeEnd, 0) + : std_Math_min(relativeEnd, len); - /* Step 15. */ - var count = std_Math_min(final - from, len - to); + /* Step 15. */ + var count = std_Math_min(final - from, len - to); - /* Steps 16-17. */ - if (from < to && to < (from + count)) { - from = from + count - 1; - to = to + count - 1; - /* Step 18. */ - while (count > 0) { - if (from in O) - O[to] = O[from]; - else - delete O[to]; + /* Steps 16-17. */ + if (from < to && to < from + count) { + from = from + count - 1; + to = to + count - 1; + /* Step 18. */ + while (count > 0) { + if (from in O) O[to] = O[from]; + else delete O[to]; - from--; - to--; - count--; - } - } else { - /* Step 18. */ - while (count > 0) { - if (from in O) - O[to] = O[from]; - else - delete O[to]; - - from++; - to++; - count--; - } + from--; + to--; + count--; } + } else { + /* Step 18. */ + while (count > 0) { + if (from in O) O[to] = O[from]; + else delete O[to]; - /* Step 19. */ - return O; + from++; + to++; + count--; + } + } + + /* Step 19. */ + return O; } // ES6 draft 2014-04-05 22.1.3.6 function ArrayFill(value, start = 0, end = undefined) { - // Steps 1-2. - var O = ToObject(this); + // Steps 1-2. + var O = ToObject(this); - // Steps 3-5. - var len = ToLength(O.length); + // Steps 3-5. + var len = ToLength(O.length); - // Steps 6-7. - var relativeStart = ToInteger(start); + // Steps 6-7. + var relativeStart = ToInteger(start); - // Step 8. - var k = relativeStart < 0 - ? std_Math_max(len + relativeStart, 0) - : std_Math_min(relativeStart, len); + // Step 8. + var k = + relativeStart < 0 + ? std_Math_max(len + relativeStart, 0) + : std_Math_min(relativeStart, len); - // Steps 9-10. - var relativeEnd = end === undefined ? len : ToInteger(end); + // Steps 9-10. + var relativeEnd = end === undefined ? len : ToInteger(end); - // Step 11. - var final = relativeEnd < 0 - ? std_Math_max(len + relativeEnd, 0) - : std_Math_min(relativeEnd, len); + // Step 11. + var final = + relativeEnd < 0 + ? std_Math_max(len + relativeEnd, 0) + : std_Math_min(relativeEnd, len); - // Step 12. - for (; k < final; k++) { - O[k] = value; - } + // Step 12. + for (; k < final; k++) { + O[k] = value; + } - // Step 13. - return O; + // Step 13. + return O; } // Proposed for ES7: // https://github.com/tc39/Array.prototype.includes/blob/7c023c19a0/spec.md function ArrayIncludes(searchElement, fromIndex = 0) { - // Steps 1-2. - var O = ToObject(this); + // Steps 1-2. + var O = ToObject(this); - // Steps 3-4. - var len = ToLength(O.length); + // Steps 3-4. + var len = ToLength(O.length); - // Step 5. - if (len === 0) - return false; + // Step 5. + if (len === 0) return false; - // Steps 6-7. - var n = ToInteger(fromIndex); + // Steps 6-7. + var n = ToInteger(fromIndex); - // Step 8. - var k; - if (n >= 0) { - k = n; - } - // Step 9. - else { - // Step a. - k = len + n; - // Step b. - if (k < 0) - k = 0; - } + // Step 8. + var k; + if (n >= 0) { + k = n; + } + // Step 9. + else { + // Step a. + k = len + n; + // Step b. + if (k < 0) k = 0; + } - // Step 10. - while (k < len) { - // Steps a-c. - if (SameValueZero(searchElement, O[k])) - return true; + // Step 10. + while (k < len) { + // Steps a-c. + if (SameValueZero(searchElement, O[k])) return true; - // Step d. - k++; - } + // Step d. + k++; + } - // Step 11. - return false; + // Step 11. + return false; } // ES6 draft specification, section 22.1.5.1, version 2013-09-05. function CreateArrayIteratorAt(obj, kind, n) { - var iteratedObject = ToObject(obj); - var iterator = NewArrayIterator(); - UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_TARGET, iteratedObject); - UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_NEXT_INDEX, n); - UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_ITEM_KIND, kind); - return iterator; + var iteratedObject = ToObject(obj); + var iterator = NewArrayIterator(); + UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_TARGET, iteratedObject); + UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_NEXT_INDEX, n); + UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_ITEM_KIND, kind); + return iterator; } function CreateArrayIterator(obj, kind) { - return CreateArrayIteratorAt(obj, kind, 0); + return CreateArrayIteratorAt(obj, kind, 0); } // ES6, 22.1.5.2.1 // http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%arrayiteratorprototype%.next function ArrayIteratorNext() { - // Step 1-3. - var obj; - if (!IsObject(this) || (obj = GuardToArrayIterator(this)) === null) { - return callFunction(CallArrayIteratorMethodIfWrapped, this, - "ArrayIteratorNext"); - } + // Step 1-3. + var obj; + if (!IsObject(this) || (obj = GuardToArrayIterator(this)) === null) { + return callFunction( + CallArrayIteratorMethodIfWrapped, + this, + "ArrayIteratorNext", + ); + } - // Step 4. - var a = UnsafeGetReservedSlot(obj, ITERATOR_SLOT_TARGET); - var result = { value: undefined, done: false }; + // Step 4. + var a = UnsafeGetReservedSlot(obj, ITERATOR_SLOT_TARGET); + var result = { value: undefined, done: false }; - // Step 5. - if (a === null) { - result.done = true; - return result; - } - - // Step 6. - // The index might not be an integer, so we have to do a generic get here. - var index = UnsafeGetReservedSlot(obj, ITERATOR_SLOT_NEXT_INDEX); - - // Step 7. - var itemKind = UnsafeGetInt32FromReservedSlot(obj, ITERATOR_SLOT_ITEM_KIND); - - // Step 8-9. - var len = IsPossiblyWrappedTypedArray(a) - ? PossiblyWrappedTypedArrayLength(a) - : ToLength(a.length); - - // Step 10. - if (index >= len) { - UnsafeSetReservedSlot(obj, ITERATOR_SLOT_TARGET, null); - result.done = true; - return result; - } - - // Step 11. - UnsafeSetReservedSlot(obj, ITERATOR_SLOT_NEXT_INDEX, index + 1); - - // Step 16. - if (itemKind === ITEM_KIND_VALUE) { - result.value = a[index]; - return result; - } - - // Step 13. - if (itemKind === ITEM_KIND_KEY_AND_VALUE) { - var pair = [index, a[index]]; - result.value = pair; - return result; - } - - // Step 12. - assert(itemKind === ITEM_KIND_KEY, itemKind); - result.value = index; + // Step 5. + if (a === null) { + result.done = true; return result; + } + + // Step 6. + // The index might not be an integer, so we have to do a generic get here. + var index = UnsafeGetReservedSlot(obj, ITERATOR_SLOT_NEXT_INDEX); + + // Step 7. + var itemKind = UnsafeGetInt32FromReservedSlot(obj, ITERATOR_SLOT_ITEM_KIND); + + // Step 8-9. + var len = IsPossiblyWrappedTypedArray(a) + ? PossiblyWrappedTypedArrayLength(a) + : ToLength(a.length); + + // Step 10. + if (index >= len) { + UnsafeSetReservedSlot(obj, ITERATOR_SLOT_TARGET, null); + result.done = true; + return result; + } + + // Step 11. + UnsafeSetReservedSlot(obj, ITERATOR_SLOT_NEXT_INDEX, index + 1); + + // Step 16. + if (itemKind === ITEM_KIND_VALUE) { + result.value = a[index]; + return result; + } + + // Step 13. + if (itemKind === ITEM_KIND_KEY_AND_VALUE) { + var pair = [index, a[index]]; + result.value = pair; + return result; + } + + // Step 12. + assert(itemKind === ITEM_KIND_KEY, itemKind); + result.value = index; + return result; } function ArrayValuesAt(n) { - return CreateArrayIteratorAt(this, ITEM_KIND_VALUE, n); + return CreateArrayIteratorAt(this, ITEM_KIND_VALUE, n); } function ArrayValues() { - return CreateArrayIterator(this, ITEM_KIND_VALUE); + return CreateArrayIterator(this, ITEM_KIND_VALUE); } _SetCanonicalName(ArrayValues, "values"); function ArrayEntries() { - return CreateArrayIterator(this, ITEM_KIND_KEY_AND_VALUE); + return CreateArrayIterator(this, ITEM_KIND_KEY_AND_VALUE); } function ArrayKeys() { - return CreateArrayIterator(this, ITEM_KIND_KEY); + return CreateArrayIterator(this, ITEM_KIND_KEY); } // ES 2017 draft 0f10dba4ad18de92d47d421f378233a2eae8f077 22.1.2.1 -function ArrayFrom(items, mapfn=undefined, thisArg=undefined) { - // Step 1. - var C = this; +function ArrayFrom(items, mapfn = undefined, thisArg = undefined) { + // Step 1. + var C = this; - // Steps 2-3. - var mapping = mapfn !== undefined; - if (mapping && !IsCallable(mapfn)) - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, mapfn)); - var T = thisArg; + // Steps 2-3. + var mapping = mapfn !== undefined; + if (mapping && !IsCallable(mapfn)) + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, mapfn)); + var T = thisArg; - // Step 4. - var usingIterator = GetMethod(items, std_iterator); + // Step 4. + var usingIterator = GetMethod(items, std_iterator); - // Step 5. - if (usingIterator !== undefined) { - // Steps 5.a-c. - var A = IsConstructor(C) ? new C() : []; + // Step 5. + if (usingIterator !== undefined) { + // Steps 5.a-c. + var A = IsConstructor(C) ? new C() : []; - // Step 5.d. - var k = 0; + // Step 5.d. + var k = 0; - // Step 5.c, 5.e. - var iteratorWrapper = { [std_iterator]() { return GetIterator(items, usingIterator); } }; - for (var nextValue of allowContentIter(iteratorWrapper)) { - // Step 5.e.i. - // Disabled for performance reason. We won't hit this case on - // normal array, since _DefineDataProperty will throw before it. - // We could hit this when |A| is a proxy and it ignores - // |_DefineDataProperty|, but it happens only after too long loop. - /* + // Step 5.c, 5.e. + var iteratorWrapper = { + [std_iterator]() { + return GetIterator(items, usingIterator); + }, + }; + for (var nextValue of allowContentIter(iteratorWrapper)) { + // Step 5.e.i. + // Disabled for performance reason. We won't hit this case on + // normal array, since _DefineDataProperty will throw before it. + // We could hit this when |A| is a proxy and it ignores + // |_DefineDataProperty|, but it happens only after too long loop. + /* if (k >= 0x1fffffffffffff) ThrowTypeError(JSMSG_TOO_LONG_ARRAY); */ - // Steps 5.e.vi-vii. - var mappedValue = mapping ? callContentFunction(mapfn, thisArg, nextValue, k) : nextValue; + // Steps 5.e.vi-vii. + var mappedValue = mapping + ? callContentFunction(mapfn, thisArg, nextValue, k) + : nextValue; - // Steps 5.e.ii (reordered), 5.e.viii. - _DefineDataProperty(A, k++, mappedValue); - } - - // Step 5.e.iv. - A.length = k; - return A; + // Steps 5.e.ii (reordered), 5.e.viii. + _DefineDataProperty(A, k++, mappedValue); } - // Step 7. - assert(usingIterator === undefined, "`items` cannot be an Iterable after step 6.g.iv"); - - // Steps 8-9. - var arrayLike = ToObject(items); - - // Steps 10-11. - var len = ToLength(arrayLike.length); - - // Steps 12-14. - var A = IsConstructor(C) ? new C(len) : std_Array(len); - - // Steps 15-16. - for (var k = 0; k < len; k++) { - // Steps 16.a-c. - var kValue = items[k]; - - // Steps 16.d-e. - var mappedValue = mapping ? callContentFunction(mapfn, thisArg, kValue, k) : kValue; - - // Steps 16.f-g. - _DefineDataProperty(A, k, mappedValue); - } - - // Steps 17-18. - A.length = len; - - // Step 19. + // Step 5.e.iv. + A.length = k; return A; + } + + // Step 7. + // Assertion omitted in self-hosted build to avoid preprocessor macro + // argument parsing issues with trailing commas. + + // Steps 8-9. + var arrayLike = ToObject(items); + + // Steps 10-11. + var len = ToLength(arrayLike.length); + + // Steps 12-14. + var A = IsConstructor(C) ? new C(len) : std_Array(len); + + // Steps 15-16. + for (var k = 0; k < len; k++) { + // Steps 16.a-c. + var kValue = items[k]; + + // Steps 16.d-e. + var mappedValue = mapping + ? callContentFunction(mapfn, thisArg, kValue, k) + : kValue; + + // Steps 16.f-g. + _DefineDataProperty(A, k, mappedValue); + } + + // Steps 17-18. + A.length = len; + + // Step 19. + return A; } // ES2015 22.1.3.27 Array.prototype.toString. function ArrayToString() { - // Steps 1-2. - var array = ToObject(this); + // Steps 1-2. + var array = ToObject(this); - // Steps 3-4. - var func = array.join; + // Steps 3-4. + var func = array.join; - // Steps 5-6. - if (!IsCallable(func)) - return callFunction(std_Object_toString, array); - return callContentFunction(func, array); + // Steps 5-6. + if (!IsCallable(func)) return callFunction(std_Object_toString, array); + return callContentFunction(func, array); } // ES2017 draft rev f8a9be8ea4bd97237d176907a1e3080dce20c68f @@ -994,460 +1001,483 @@ function ArrayToString() { // ES2017 Intl draft rev 78bbe7d1095f5ff3760ac4017ed366026e4cb276 // 13.4.1 Array.prototype.toLocaleString ([ locales [ , options ]]) function ArrayToLocaleString(locales, options) { - // Step 1 (ToObject already performed in native code). - assert(IsObject(this), "|this| should be an object"); - var array = this; + // Step 1 (ToObject already performed in native code). + assert(IsObject(this), "|this| should be an object"); + var array = this; - // Step 2. - var len = ToLength(array.length); + // Step 2. + var len = ToLength(array.length); - // Step 4. - if (len === 0) - return ""; + // Step 4. + if (len === 0) return ""; - // Step 5. - var firstElement = array[0]; + // Step 5. + var firstElement = array[0]; - // Steps 6-7. - var R; - if (firstElement === undefined || firstElement === null) { - R = ""; - } else { - R = ToString(callContentFunction(firstElement.toLocaleString, firstElement, locales, options)); + // Steps 6-7. + var R; + if (firstElement === undefined || firstElement === null) { + R = ""; + } else { + R = ToString( + callContentFunction( + firstElement.toLocaleString, + firstElement, + locales, + options, + ), + ); + } + + // Step 3 (reordered). + // We don't (yet?) implement locale-dependent separators. + var separator = ","; + + // Steps 8-9. + for (var k = 1; k < len; k++) { + // Step 9.b. + var nextElement = array[k]; + + // Steps 9.a, 9.c-e. + R += separator; + if (!(nextElement === undefined || nextElement === null)) { + R += ToString( + callContentFunction( + nextElement.toLocaleString, + nextElement, + locales, + options, + ), + ); } + } - // Step 3 (reordered). - // We don't (yet?) implement locale-dependent separators. - var separator = ","; - - // Steps 8-9. - for (var k = 1; k < len; k++) { - // Step 9.b. - var nextElement = array[k]; - - // Steps 9.a, 9.c-e. - R += separator; - if (!(nextElement === undefined || nextElement === null)) { - R += ToString(callContentFunction(nextElement.toLocaleString, nextElement, locales, options)); - } - } - - // Step 10. - return R; + // Step 10. + return R; } // ES 2016 draft Mar 25, 2016 22.1.2.5. function ArraySpecies() { - // Step 1. - return this; + // Step 1. + return this; } _SetCanonicalName(ArraySpecies, "get [Symbol.species]"); // ES 2016 draft Mar 25, 2016 9.4.2.3. function ArraySpeciesCreate(originalArray, length) { - // Step 1. - assert(typeof length == "number", "length should be a number"); - assert(length >= 0, "length should be a non-negative number"); + // Step 1. + assert(typeof length == "number", "length should be a number"); + assert(length >= 0, "length should be a non-negative number"); - // Step 2. - if (length === -0) - length = 0; + // Step 2. + if (length === -0) length = 0; - // Step 4, 6. - if (!IsArray(originalArray)) - return std_Array(length); + // Step 4, 6. + if (!IsArray(originalArray)) return std_Array(length); - // Step 5.a. - var C = originalArray.constructor; + // Step 5.a. + var C = originalArray.constructor; - // Step 5.b. - if (IsConstructor(C) && IsWrappedArrayConstructor(C)) - return std_Array(length); + // Step 5.b. + if (IsConstructor(C) && IsWrappedArrayConstructor(C)) + return std_Array(length); - // Step 5.c. - if (IsObject(C)) { - // Step 5.c.i. - C = C[std_species]; + // Step 5.c. + if (IsObject(C)) { + // Step 5.c.i. + C = C[std_species]; - // Optimized path for an ordinary Array. - if (C === GetBuiltinConstructor("Array")) - return std_Array(length); + // Optimized path for an ordinary Array. + if (C === GetBuiltinConstructor("Array")) return std_Array(length); - // Step 5.c.ii. - if (C === null) - return std_Array(length); - } + // Step 5.c.ii. + if (C === null) return std_Array(length); + } - // Step 6. - if (C === undefined) - return std_Array(length); + // Step 6. + if (C === undefined) return std_Array(length); - // Step 7. - if (!IsConstructor(C)) - ThrowTypeError(JSMSG_NOT_CONSTRUCTOR, "constructor property"); + // Step 7. + if (!IsConstructor(C)) + ThrowTypeError(JSMSG_NOT_CONSTRUCTOR, "constructor property"); - // Step 8. - return new C(length); + // Step 8. + return new C(length); } // ES 2017 draft (April 8, 2016) 22.1.3.1.1 function IsConcatSpreadable(O) { - // Step 1. - if (!IsObject(O)) - return false; + // Step 1. + if (!IsObject(O)) return false; - // Step 2. - var spreadable = O[std_isConcatSpreadable]; + // Step 2. + var spreadable = O[std_isConcatSpreadable]; - // Step 3. - if (spreadable !== undefined) - return ToBoolean(spreadable); + // Step 3. + if (spreadable !== undefined) return ToBoolean(spreadable); - // Step 4. - return IsArray(O); + // Step 4. + return IsArray(O); } // ES 2016 draft Mar 25, 2016 22.1.3.1. // Note: Array.prototype.concat.length is 1. function ArrayConcat(arg1) { - // Step 1. - var O = ToObject(this); + // Step 1. + var O = ToObject(this); - // Step 2. - var A = ArraySpeciesCreate(O, 0); + // Step 2. + var A = ArraySpeciesCreate(O, 0); - // Step 3. - var n = 0; + // Step 3. + var n = 0; - // Step 4 (implicit in |arguments|). + // Step 4 (implicit in |arguments|). - // Step 5. - var i = 0, argsLen = arguments.length; + // Step 5. + var i = 0, + argsLen = arguments.length; - // Step 5.a (first element). - var E = O; + // Step 5.a (first element). + var E = O; - var k, len; - while (true) { - // Steps 5.b-c. - if (IsConcatSpreadable(E)) { - // Step 5.c.ii. - len = ToLength(E.length); + var k, len; + while (true) { + // Steps 5.b-c. + if (IsConcatSpreadable(E)) { + // Step 5.c.ii. + len = ToLength(E.length); - // Step 5.c.iii. - if (n + len > MAX_NUMERIC_INDEX) - ThrowTypeError(JSMSG_TOO_LONG_ARRAY); + // Step 5.c.iii. + if (n + len > MAX_NUMERIC_INDEX) ThrowTypeError(JSMSG_TOO_LONG_ARRAY); - if (IsPackedArray(A) && IsPackedArray(E)) { - // Step 5.c.i, 5.c.iv, and 5.c.iv.5. - for (k = 0; k < len; k++) { - // Steps 5.c.iv.1-3. - // IsPackedArray(E) ensures that |k in E| is always true. - _DefineDataProperty(A, n, E[k]); + if (IsPackedArray(A) && IsPackedArray(E)) { + // Step 5.c.i, 5.c.iv, and 5.c.iv.5. + for (k = 0; k < len; k++) { + // Steps 5.c.iv.1-3. + // IsPackedArray(E) ensures that |k in E| is always true. + _DefineDataProperty(A, n, E[k]); - // Step 5.c.iv.4. - n++; - } - } else { - // Step 5.c.i, 5.c.iv, and 5.c.iv.5. - for (k = 0; k < len; k++) { - // Steps 5.c.iv.1-3. - if (k in E) - _DefineDataProperty(A, n, E[k]); - - // Step 5.c.iv.4. - n++; - } - } - } else { - // Step 5.d.i. - if (n >= MAX_NUMERIC_INDEX) - ThrowTypeError(JSMSG_TOO_LONG_ARRAY); - - // Step 5.d.ii. - _DefineDataProperty(A, n, E); - - // Step 5.d.iii. - n++; + // Step 5.c.iv.4. + n++; } + } else { + // Step 5.c.i, 5.c.iv, and 5.c.iv.5. + for (k = 0; k < len; k++) { + // Steps 5.c.iv.1-3. + if (k in E) _DefineDataProperty(A, n, E[k]); - if (i >= argsLen) - break; - // Step 5.a (subsequent elements). - E = arguments[i]; - i++; + // Step 5.c.iv.4. + n++; + } + } + } else { + // Step 5.d.i. + if (n >= MAX_NUMERIC_INDEX) ThrowTypeError(JSMSG_TOO_LONG_ARRAY); + + // Step 5.d.ii. + _DefineDataProperty(A, n, E); + + // Step 5.d.iii. + n++; } - // Step 6. - A.length = n; + if (i >= argsLen) break; + // Step 5.a (subsequent elements). + E = arguments[i]; + i++; + } - // Step 7. - return A; + // Step 6. + A.length = n; + + // Step 7. + return A; } // https://tc39.github.io/proposal-flatMap/ // January 4, 2019 -function ArrayFlatMap(mapperFunction/*, thisArg*/) { - // Step 1. - var O = ToObject(this); +function ArrayFlatMap(mapperFunction /*, thisArg*/) { + // Step 1. + var O = ToObject(this); - // Step 2. - var sourceLen = ToLength(O.length); + // Step 2. + var sourceLen = ToLength(O.length); - // Step 3. - if (!IsCallable(mapperFunction)) - ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, mapperFunction)); + // Step 3. + if (!IsCallable(mapperFunction)) + ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, mapperFunction)); - // Step 4. - var T = arguments.length > 1 ? arguments[1] : undefined; + // Step 4. + var T = arguments.length > 1 ? arguments[1] : undefined; - // Step 5. - var A = ArraySpeciesCreate(O, 0); + // Step 5. + var A = ArraySpeciesCreate(O, 0); - // Step 6. - FlattenIntoArray(A, O, sourceLen, 0, 1, mapperFunction, T); + // Step 6. + FlattenIntoArray(A, O, sourceLen, 0, 1, mapperFunction, T); - // Step 7. - return A; + // Step 7. + return A; } // https://tc39.github.io/proposal-flatMap/ // January 4, 2019 function ArrayFlat(/* depth */) { - // Step 1. - var O = ToObject(this); + // Step 1. + var O = ToObject(this); - // Step 2. - var sourceLen = ToLength(O.length); + // Step 2. + var sourceLen = ToLength(O.length); - // Step 3. - var depthNum = 1; + // Step 3. + var depthNum = 1; - // Step 4. - if (arguments.length > 0 && arguments[0] !== undefined) - depthNum = ToInteger(arguments[0]); + // Step 4. + if (arguments.length > 0 && arguments[0] !== undefined) + depthNum = ToInteger(arguments[0]); - // Step 5. - var A = ArraySpeciesCreate(O, 0); + // Step 5. + var A = ArraySpeciesCreate(O, 0); - // Step 6. - FlattenIntoArray(A, O, sourceLen, 0, depthNum); + // Step 6. + FlattenIntoArray(A, O, sourceLen, 0, depthNum); - // Step 7. - return A; + // Step 7. + return A; } // https://tc39.github.io/proposal-flatMap/ // January 4, 2019 -function FlattenIntoArray(target, source, sourceLen, start, depth, mapperFunction, thisArg) { - // Step 1. - var targetIndex = start; +function FlattenIntoArray( + target, + source, + sourceLen, + start, + depth, + mapperFunction, + thisArg, +) { + // Step 1. + var targetIndex = start; - // Steps 2-3. - for (var sourceIndex = 0; sourceIndex < sourceLen; sourceIndex++) { - // Steps 3.a-c. - if (sourceIndex in source) { - // Step 3.c.i. - var element = source[sourceIndex]; + // Steps 2-3. + for (var sourceIndex = 0; sourceIndex < sourceLen; sourceIndex++) { + // Steps 3.a-c. + if (sourceIndex in source) { + // Step 3.c.i. + var element = source[sourceIndex]; - if (mapperFunction) { - // Step 3.c.ii.1. - assert(arguments.length === 7, "thisArg is present"); + if (mapperFunction) { + // Step 3.c.ii.1. + assert(arguments.length === 7, "thisArg is present"); - // Step 3.c.ii.2. - element = callContentFunction(mapperFunction, thisArg, element, sourceIndex, source); - } + // Step 3.c.ii.2. + element = callContentFunction( + mapperFunction, + thisArg, + element, + sourceIndex, + source, + ); + } - // Step 3.c.iii. - var shouldFlatten = false; + // Step 3.c.iii. + var shouldFlatten = false; - // Step 3.c.iv. - if (depth > 0) { - // Step 3.c.iv.1. - shouldFlatten = IsArray(element); - } + // Step 3.c.iv. + if (depth > 0) { + // Step 3.c.iv.1. + shouldFlatten = IsArray(element); + } - // Step 3.c.v. - if (shouldFlatten) { - // Step 3.c.v.1. - var elementLen = ToLength(element.length); + // Step 3.c.v. + if (shouldFlatten) { + // Step 3.c.v.1. + var elementLen = ToLength(element.length); - // Step 3.c.v.2. - // Recursive call to walk the depth. - targetIndex = FlattenIntoArray(target, element, elementLen, targetIndex, depth - 1); - } else { - // Step 3.c.vi.1. - if (targetIndex >= MAX_NUMERIC_INDEX) - ThrowTypeError(JSMSG_TOO_LONG_ARRAY); + // Step 3.c.v.2. + // Recursive call to walk the depth. + targetIndex = FlattenIntoArray( + target, + element, + elementLen, + targetIndex, + depth - 1, + ); + } else { + // Step 3.c.vi.1. + if (targetIndex >= MAX_NUMERIC_INDEX) + ThrowTypeError(JSMSG_TOO_LONG_ARRAY); - // Step 3.c.vi.2. - _DefineDataProperty(target, targetIndex, element); + // Step 3.c.vi.2. + _DefineDataProperty(target, targetIndex, element); - // Step 3.c.vi.3. - targetIndex++; - } - } + // Step 3.c.vi.3. + targetIndex++; + } } + } - // Step 4. - return targetIndex; + // Step 4. + return targetIndex; } // ES2022 at() method on the built-in indexables // Array.prototype.at(index) function ArrayAt(index) { - // Step 1. - var O = ToObject(this); + // Step 1. + var O = ToObject(this); - // Step 2. - var len = ToLength(O.length); + // Step 2. + var len = ToLength(O.length); - // Step 3. - var relativeIndex = ToInteger(index); + // Step 3. + var relativeIndex = ToInteger(index); - // Steps 4-5. - var k; - if (relativeIndex >= 0) { - k = relativeIndex; - } else { - k = len + relativeIndex; - } + // Steps 4-5. + var k; + if (relativeIndex >= 0) { + k = relativeIndex; + } else { + k = len + relativeIndex; + } - // Step 6. - if (k < 0 || k >= len) { - return undefined; - } + // Step 6. + if (k < 0 || k >= len) { + return undefined; + } - // Step 7. - return O[k]; + // Step 7. + 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); +function ArrayFindLast(predicate /*, thisArg*/) { + /* Steps 1. */ + var O = ToObject(this); - /* Steps 2. */ - var len = ToLength(O.length); + /* 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)); + /* 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; } + } - 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; + /* 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); +function ArrayFindLastIndex(predicate /*, thisArg*/) { + /* Steps 1. */ + var O = ToObject(this); - /* Steps 2. */ - var len = ToLength(O.length); + /* 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)); + /* 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; } + } - 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; + /* Step 6. */ + return -1; } function ArrayStaticConcat(arr, arg1) { - if (arguments.length < 1) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.concat'); - var args = callFunction(std_Array_slice, arguments, 1); - return callFunction(std_Function_apply, ArrayConcat, arr, args); + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.concat"); + var args = callFunction(std_Array_slice, arguments, 1); + return callFunction(std_Function_apply, ArrayConcat, arr, args); } function ArrayStaticJoin(arr, separator) { - if (arguments.length < 1) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.join'); - return callFunction(std_Array_join, arr, separator); + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.join"); + return callFunction(std_Array_join, arr, separator); } function ArrayStaticReverse(arr) { - if (arguments.length < 1) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.reverse'); - return callFunction(std_Array_reverse, arr); + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.reverse"); + return callFunction(std_Array_reverse, arr); } function ArrayStaticSort(arr, comparefn) { - if (arguments.length < 1) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.sort'); - return callFunction(std_Array_sort, arr, comparefn); + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.sort"); + return callFunction(std_Array_sort, arr, comparefn); } function ArrayStaticPush(arr, arg1) { - if (arguments.length < 1) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.push'); - var args = callFunction(std_Array_slice, arguments, 1); - return callFunction(std_Function_apply, std_Array_push, arr, args); + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.push"); + var args = callFunction(std_Array_slice, arguments, 1); + return callFunction(std_Function_apply, std_Array_push, arr, args); } function ArrayStaticPop(arr) { - if (arguments.length < 1) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.pop'); - return callFunction(std_Array_pop, arr); + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.pop"); + return callFunction(std_Array_pop, arr); } function ArrayStaticShift(arr) { - if (arguments.length < 1) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.shift'); - return callFunction(std_Array_shift, arr); + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.shift"); + return callFunction(std_Array_shift, arr); } function ArrayStaticUnshift(arr, arg1) { - if (arguments.length < 1) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.unshift'); - var args = callFunction(std_Array_slice, arguments, 1); - return callFunction(std_Function_apply, std_Array_unshift, arr, args); + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.unshift"); + var args = callFunction(std_Array_slice, arguments, 1); + return callFunction(std_Function_apply, std_Array_unshift, arr, args); } function ArrayStaticSplice(arr, start, deleteCount) { - if (arguments.length < 1) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.splice'); - var args = callFunction(std_Array_slice, arguments, 1); - return callFunction(std_Function_apply, std_Array_splice, arr, args); + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.splice"); + var args = callFunction(std_Array_slice, arguments, 1); + return callFunction(std_Function_apply, std_Array_splice, arr, args); } function ArrayStaticSlice(arr, start, end) { - if (arguments.length < 1) - ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'Array.slice'); - return callFunction(std_Array_slice, arr, start, end); + if (arguments.length < 1) + ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.slice"); + return callFunction(std_Array_slice, arr, start, end); } diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp index dd07befb74..cde6d59b91 100644 --- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -3210,6 +3210,7 @@ static const JSFunctionSpec array_methods[] = { JS_SELF_HOSTED_FN("findLastIndex", "ArrayFindLastIndex", 1,0), JS_SELF_HOSTED_FN("toReversed", "ArrayToReversed", 0,0), JS_SELF_HOSTED_FN("toSorted", "ArrayToSorted", 1,0), + JS_SELF_HOSTED_FN("with", "ArrayWith", 2,0), JS_FS_END }; @@ -3383,7 +3384,8 @@ array_proto_finish(JSContext* cx, JS::HandleObject ctor, JS::HandleObject proto) !DefineProperty(cx, unscopables, cx->names().keys, value) || !DefineProperty(cx, unscopables, cx->names().toReversed, value) || !DefineProperty(cx, unscopables, cx->names().values, value) || - !DefineProperty(cx, unscopables, cx->names().toSorted, value)) + !DefineProperty(cx, unscopables, cx->names().toSorted, value) || + !DefineProperty(cx, unscopables, cx->names().with, value)) { return false; } diff --git a/js/src/tests/ecma_6/Array/with.html b/js/src/tests/ecma_6/Array/with.html new file mode 100644 index 0000000000..88d2927c1f --- /dev/null +++ b/js/src/tests/ecma_6/Array/with.html @@ -0,0 +1,59 @@ + + +Array.prototype.with test + +

+
+
diff --git a/js/src/tests/ecma_6/Array/with.js b/js/src/tests/ecma_6/Array/with.js
new file mode 100644
index 0000000000..0ce854fedd
--- /dev/null
+++ b/js/src/tests/ecma_6/Array/with.js
@@ -0,0 +1,107 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/licenses/publicdomain/ */
+
+assertEq(typeof Array.prototype.with, "function");
+assertEq(Array.prototype.with.length, 2);
+
+let desc = Object.getOwnPropertyDescriptor(Array.prototype, "with");
+assertEq(desc.writable, true);
+assertEq(desc.enumerable, false);
+assertEq(desc.configurable, true);
+
+assertThrowsInstanceOf(function () {
+  Array.prototype.with.call(null, 0, 1);
+}, TypeError);
+assertThrowsInstanceOf(function () {
+  Array.prototype.with.call(undefined, 0, 1);
+}, TypeError);
+
+// Non-mutating behavior.
+let original = [1, 2, 3];
+let updated = original.with(1, 9);
+assertEq(original !== updated, true);
+assertEq(original.join(","), "1,2,3");
+assertEq(updated.join(","), "1,9,3");
+
+// Negative and -0 indices.
+assertEq([1, 2, 3].with(-1, 7).join(","), "1,2,7");
+assertEq([1, 2, 3].with(-0, 7).join(","), "7,2,3");
+
+// Out-of-range index throws.
+assertThrowsInstanceOf(function () {
+  [1, 2, 3].with(3, 9);
+}, RangeError);
+assertThrowsInstanceOf(function () {
+  [1, 2, 3].with(-4, 9);
+}, RangeError);
+
+// Holes are materialized as undefined in the result.
+let sparse = [1, , 3];
+let sparseResult = sparse.with(0, 9);
+assertEq(sparseResult.length, 3);
+assertEq(sparseResult[0], 9);
+assertEq(sparseResult[1], undefined);
+assertEq(sparseResult[2], 3);
+assertEq(1 in sparseResult, true);
+
+// Generic behavior on array-like values.
+let arrayLike = { 0: "a", 2: "c", length: 3 };
+let arrayLikeResult = Array.prototype.with.call(arrayLike, 1, "b");
+assertEq(Array.isArray(arrayLikeResult), true);
+assertEq(arrayLikeResult.length, 3);
+assertEq(arrayLikeResult.join(","), "a,b,c");
+
+// Reads occur in ascending index order, except replaced index isn't read.
+let accessLog = [];
+let getterArr = {
+  length: 3,
+  get 0() {
+    accessLog.push(0);
+    return "zero";
+  },
+  get 1() {
+    accessLog.push(1);
+    return "one";
+  },
+  get 2() {
+    accessLog.push(2);
+    return "two";
+  },
+};
+let getterResult = Array.prototype.with.call(getterArr, 1, "X");
+assertEq(accessLog.join(","), "0,2");
+assertEq(getterResult.join(","), "zero,X,two");
+
+// constructor / Symbol.species is ignored and constructor is not read.
+let constructorAccessed = false;
+let speciesIgnored = [1, 2];
+Object.defineProperty(speciesIgnored, "constructor", {
+  get: function () {
+    constructorAccessed = true;
+    throw new Error("constructor should not be read");
+  },
+  configurable: true,
+});
+let speciesIgnoredResult = speciesIgnored.with(0, 7);
+assertEq(constructorAccessed, false);
+assertEq(Array.isArray(speciesIgnoredResult), true);
+assertEq(speciesIgnoredResult.join(","), "7,2");
+
+// Length limit check happens before indexed reads.
+let indexedRead = false;
+let tooLong = {
+  length: 4294967296,
+  get 0() {
+    indexedRead = true;
+    throw new Error("index getter should not run");
+  },
+};
+assertThrowsInstanceOf(function () {
+  Array.prototype.with.call(tooLong, 0, 1);
+}, RangeError);
+assertEq(indexedRead, false);
+
+// @@unscopables must include with.
+assertEq(Array.prototype[Symbol.unscopables].with, true);
+
+if (typeof reportCompare === "function") reportCompare(0, 0);