/* 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/. */ /* ES5 15.4.4.14. */ function ArrayIndexOf(searchElement/*, fromIndex*/) { /* Step 1. */ var O = ToObject(this); /* Steps 2-3. */ var len = ToLength(O.length); /* 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 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; } /* 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; } } /* 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); } /* ES5 15.4.4.15. */ function ArrayLastIndexOf(searchElement/*, fromIndex*/) { /* Step 1. */ var O = ToObject(this); /* Steps 2-3. */ var len = ToLength(O.length); /* 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; /* 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 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); } /* ES5 15.4.4.16. */ function ArrayEvery(callbackfn/*, thisArg*/) { /* Step 1. */ var O = ToObject(this); /* 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 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; } } /* 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); } /* ES5 15.4.4.17. */ function ArraySome(callbackfn/*, thisArg*/) { /* Step 1. */ var O = ToObject(this); /* 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 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; } } /* 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); } /* ES6 draft 2016-1-15 22.1.3.25 Array.prototype.sort (comparefn) */ function ArraySort(comparefn) { /* Step 1. */ var O = ToObject(this); /* Step 2. */ var len = ToLength(O.length); if (len <= 1) return this; /* 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; /* Step 4.a. */ var v = ToNumber(wrappedCompareFn(x, y)); /* Step 4.b-c. */ return v !== v ? 0 : v; } return MergeSort(O, len, comparefn); } /* ES5 15.4.4.18. */ function ArrayForEach(callbackfn/*, thisArg*/) { /* Step 1. */ var O = ToObject(this); /* 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 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); } } /* 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); } /* ES 2016 draft Mar 25, 2016 22.1.3.15. */ function ArrayMap(callbackfn/*, thisArg*/) { /* Step 1. */ var O = ToObject(this); /* 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 4. */ var T = arguments.length > 1 ? arguments[1] : void 0; /* 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); } } /* 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); } /* ES 2016 draft Mar 25, 2016 22.1.3.7 Array.prototype.filter. */ function ArrayFilter(callbackfn/*, thisArg*/) { /* Step 1. */ var O = ToObject(this); /* 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 4. */ var T = arguments.length > 1 ? arguments[1] : void 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); } } /* 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); } /* ES5 15.4.4.21. */ function ArrayReduce(callbackfn/*, initialValue*/) { /* Step 1. */ var O = ToObject(this); /* 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 6. */ var k = 0; /* 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 { 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 */ 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); } /* ES5 15.4.4.22. */ function ArrayReduceRight(callbackfn/*, initialValue*/) { /* Step 1. */ var O = ToObject(this); /* 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 6. */ var k = len - 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 { 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 */ 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); } /* ES6 draft 2013-05-14 15.4.3.23. */ function ArrayFind(predicate/*, thisArg*/) { /* Steps 1-2. */ var O = ToObject(this); /* 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 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; } /* Step 10. */ return undefined; } /* ES6 draft 2013-05-14 15.4.3.23. */ function ArrayFindIndex(predicate/*, thisArg*/) { /* Steps 1-2. */ var O = ToObject(this); /* 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 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; } /* 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 3-5. */ var len = ToLength(O.length); /* Steps 6-8. */ var relativeTarget = ToInteger(target); var to = relativeTarget < 0 ? std_Math_max(len + relativeTarget, 0) : std_Math_min(relativeTarget, len); /* Steps 9-11. */ var relativeStart = ToInteger(start); 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); 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); /* 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--; } } /* 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 3-5. var len = ToLength(O.length); // Steps 6-7. var relativeStart = ToInteger(start); // 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); // 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 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 3-4. var len = ToLength(O.length); // Step 5. if (len === 0) return false; // 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 10. while (k < len) { // Steps a-c. if (SameValueZero(searchElement, O[k])) return true; // Step d. k++; } // 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; } function CreateArrayIterator(obj, kind) { 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 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; return result; } function ArrayValuesAt(n) { return CreateArrayIteratorAt(this, ITEM_KIND_VALUE, n); } function ArrayValues() { return CreateArrayIterator(this, ITEM_KIND_VALUE); } _SetCanonicalName(ArrayValues, "values"); function ArrayEntries() { return CreateArrayIterator(this, ITEM_KIND_KEY_AND_VALUE); } function ArrayKeys() { 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; // 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 5. if (usingIterator !== undefined) { // Steps 5.a-c. var A = IsConstructor(C) ? new C() : []; // 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. /* 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.ii (reordered), 5.e.viii. _DefineDataProperty(A, k++, mappedValue); } // Step 5.e.iv. A.length = k; return A; } // Step 7. assert(usingIterator === undefined, "`items` can't 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. return A; } // ES2015 22.1.3.27 Array.prototype.toString. function ArrayToString() { // Steps 1-2. var array = ToObject(this); // Steps 3-4. var func = array.join; // Steps 5-6. if (!IsCallable(func)) return callFunction(std_Object_toString, array); return callContentFunction(func, array); } // ES2017 draft rev f8a9be8ea4bd97237d176907a1e3080dce20c68f // 22.1.3.27 Array.prototype.toLocaleString ([ reserved1 [ , reserved2 ] ]) // 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 2. var len = ToLength(array.length); // Step 4. if (len === 0) return ""; // 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)); } // 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; } // ES 2016 draft Mar 25, 2016 22.1.2.5. function ArraySpecies() { // 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 2. if (length === -0) length = 0; // Step 4, 6. if (!IsArray(originalArray)) return std_Array(length); // Step 5.a. var C = originalArray.constructor; // 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]; // 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 6. if (C === undefined) return std_Array(length); // Step 7. if (!IsConstructor(C)) ThrowTypeError(JSMSG_NOT_CONSTRUCTOR, "constructor property"); // 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 2. var spreadable = O[std_isConcatSpreadable]; // Step 3. if (spreadable !== undefined) return ToBoolean(spreadable); // 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 2. var A = ArraySpeciesCreate(O, 0); // Step 3. var n = 0; // Step 4 (implicit in |arguments|). // Step 5. var i = 0, argsLen = arguments.length; // 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); // 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]); // 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++; } if (i >= argsLen) break; // Step 5.a (subsequent elements). E = arguments[i]; i++; } // 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); // Step 2. var sourceLen = ToLength(O.length); // Step 3. if (!IsCallable(mapperFunction)) ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, mapperFunction)); // Step 4. var T = arguments.length > 1 ? arguments[1] : undefined; // Step 5. var A = ArraySpeciesCreate(O, 0); // Step 6. FlattenIntoArray(A, O, sourceLen, 0, 1, mapperFunction, T); // Step 7. return A; } // https://tc39.github.io/proposal-flatMap/ // January 4, 2019 function ArrayFlat(/* depth */) { // Step 1. var O = ToObject(this); // Step 2. var sourceLen = ToLength(O.length); // Step 3. var depthNum = 1; // Step 4. if (arguments.length > 0 && arguments[0] !== undefined) depthNum = ToInteger(arguments[0]); // Step 5. var A = ArraySpeciesCreate(O, 0); // Step 6. FlattenIntoArray(A, O, sourceLen, 0, depthNum); // 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; // 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"); // Step 3.c.ii.2. element = callContentFunction(mapperFunction, thisArg, element, sourceIndex, source); } // 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.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.vi.2. _DefineDataProperty(target, targetIndex, element); // Step 3.c.vi.3. targetIndex++; } } } // Step 4. return targetIndex; } 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); } function ArrayStaticJoin(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); } function ArrayStaticSort(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); } function ArrayStaticPop(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); } 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); } 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); } 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); }