1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 function ArrayEvery(callbackfn /*, thisArg*/) {
8 var O = ToObject(this);
11 var len = ToLength(O.length);
14 if (ArgumentsLength() === 0) {
15 ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.every");
17 if (!IsCallable(callbackfn)) {
18 ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
22 var T = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
25 /* Steps a (implicit), and d. */
26 for (var k = 0; k < len; k++) {
30 if (!callContentFunction(callbackfn, T, O[k], k, O)) {
39 // Inlining this enables inlining of the callback function.
40 SetIsInlinableLargeFunction(ArrayEvery);
43 function ArraySome(callbackfn /*, thisArg*/) {
45 var O = ToObject(this);
48 var len = ToLength(O.length);
51 if (ArgumentsLength() === 0) {
52 ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.some");
54 if (!IsCallable(callbackfn)) {
55 ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
59 var T = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
62 /* Steps a (implicit), and d. */
63 for (var k = 0; k < len; k++) {
67 if (callContentFunction(callbackfn, T, O[k], k, O)) {
76 // Inlining this enables inlining of the callback function.
77 SetIsInlinableLargeFunction(ArraySome);
80 function ArrayForEach(callbackfn /*, thisArg*/) {
82 var O = ToObject(this);
85 var len = ToLength(O.length);
88 if (ArgumentsLength() === 0) {
89 ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.forEach");
91 if (!IsCallable(callbackfn)) {
92 ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
96 var T = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
99 /* Steps a (implicit), and d. */
100 for (var k = 0; k < len; k++) {
104 callContentFunction(callbackfn, T, O[k], k, O);
111 // Inlining this enables inlining of the callback function.
112 SetIsInlinableLargeFunction(ArrayForEach);
114 /* ES 2016 draft Mar 25, 2016 22.1.3.15. */
115 function ArrayMap(callbackfn /*, thisArg*/) {
117 var O = ToObject(this);
120 var len = ToLength(O.length);
123 if (ArgumentsLength() === 0) {
124 ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.map");
126 if (!IsCallable(callbackfn)) {
127 ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
131 var T = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
134 var A = ArraySpeciesCreate(O, len);
137 /* Steps 7.a (implicit), and 7.d. */
138 for (var k = 0; k < len; k++) {
141 /* Steps 7.c.i-iii. */
142 var mappedValue = callContentFunction(callbackfn, T, O[k], k, O);
143 DefineDataProperty(A, k, mappedValue);
150 // Inlining this enables inlining of the callback function.
151 SetIsInlinableLargeFunction(ArrayMap);
153 /* ES 2016 draft Mar 25, 2016 22.1.3.7 Array.prototype.filter. */
154 function ArrayFilter(callbackfn /*, thisArg*/) {
156 var O = ToObject(this);
159 var len = ToLength(O.length);
162 if (ArgumentsLength() === 0) {
163 ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.filter");
165 if (!IsCallable(callbackfn)) {
166 ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
170 var T = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
173 var A = ArraySpeciesCreate(O, 0);
176 /* Steps 8.a (implicit), and 8.d. */
177 for (var k = 0, to = 0; k < len; k++) {
182 /* Steps 8.c.ii-iii. */
183 if (callContentFunction(callbackfn, T, kValue, k, O)) {
184 DefineDataProperty(A, to++, kValue);
192 // Inlining this enables inlining of the callback function.
193 SetIsInlinableLargeFunction(ArrayFilter);
196 function ArrayReduce(callbackfn /*, initialValue*/) {
198 var O = ToObject(this);
201 var len = ToLength(O.length);
204 if (ArgumentsLength() === 0) {
205 ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.reduce");
207 if (!IsCallable(callbackfn)) {
208 ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
216 if (ArgumentsLength() > 1) {
217 accumulator = GetArgument(1);
220 // Add an explicit |throw| here and below to inform Ion that the
221 // ThrowTypeError calls exit this function.
223 throw ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE);
226 // Use a |do-while| loop to let Ion know that the loop will definitely
227 // be entered at least once. When Ion is then also able to inline the
228 // |in| operator, it can optimize away the whole loop.
229 var kPresent = false;
237 throw ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE);
240 // Moved outside of the loop to ensure the assignment is non-conditional.
241 accumulator = O[k++];
245 /* Steps a (implicit), and d. */
246 for (; k < len; k++) {
250 accumulator = callContentFunction(
266 function ArrayReduceRight(callbackfn /*, initialValue*/) {
268 var O = ToObject(this);
271 var len = ToLength(O.length);
274 if (ArgumentsLength() === 0) {
275 ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.reduce");
277 if (!IsCallable(callbackfn)) {
278 ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
286 if (ArgumentsLength() > 1) {
287 accumulator = GetArgument(1);
290 // Add an explicit |throw| here and below to inform Ion that the
291 // ThrowTypeError calls exit this function.
293 throw ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE);
296 // Use a |do-while| loop to let Ion know that the loop will definitely
297 // be entered at least once. When Ion is then also able to inline the
298 // |in| operator, it can optimize away the whole loop.
299 var kPresent = false;
307 throw ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE);
310 // Moved outside of the loop to ensure the assignment is non-conditional.
311 accumulator = O[k--];
315 /* Steps a (implicit), and d. */
316 for (; k >= 0; k--) {
320 accumulator = callContentFunction(
335 /* ES6 draft 2013-05-14 15.4.3.23. */
336 function ArrayFind(predicate /*, thisArg*/) {
338 var O = ToObject(this);
341 var len = ToLength(O.length);
344 if (ArgumentsLength() === 0) {
345 ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.find");
347 if (!IsCallable(predicate)) {
348 ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate));
352 var T = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
355 /* Steps a (implicit), and g. */
356 for (var k = 0; k < len; k++) {
360 if (callContentFunction(predicate, T, kValue, k, O)) {
368 // Inlining this enables inlining of the callback function.
369 SetIsInlinableLargeFunction(ArrayFind);
371 /* ES6 draft 2013-05-14 15.4.3.23. */
372 function ArrayFindIndex(predicate /*, thisArg*/) {
374 var O = ToObject(this);
377 var len = ToLength(O.length);
380 if (ArgumentsLength() === 0) {
381 ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.find");
383 if (!IsCallable(predicate)) {
384 ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate));
388 var T = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
391 /* Steps a (implicit), and g. */
392 for (var k = 0; k < len; k++) {
394 if (callContentFunction(predicate, T, O[k], k, O)) {
402 // Inlining this enables inlining of the callback function.
403 SetIsInlinableLargeFunction(ArrayFindIndex);
405 // ES2020 draft rev dc1e21c454bd316810be1c0e7af0131a2d7f38e9
406 // 22.1.3.3 Array.prototype.copyWithin ( target, start [ , end ] )
407 function ArrayCopyWithin(target, start, end = undefined) {
409 var O = ToObject(this);
412 var len = ToLength(O.length);
415 var relativeTarget = ToInteger(target);
420 ? std_Math_max(len + relativeTarget, 0)
421 : std_Math_min(relativeTarget, len);
424 var relativeStart = ToInteger(start);
429 ? std_Math_max(len + relativeStart, 0)
430 : std_Math_min(relativeStart, len);
433 var relativeEnd = end === undefined ? len : ToInteger(end);
438 ? std_Math_max(len + relativeEnd, 0)
439 : std_Math_min(relativeEnd, len);
442 var count = std_Math_min(final - from, len - to);
445 if (from < to && to < from + count) {
447 from = from + count - 1;
481 // ES2020 draft rev dc1e21c454bd316810be1c0e7af0131a2d7f38e9
482 // 22.1.3.6 Array.prototype.fill ( value [ , start [ , end ] ] )
483 function ArrayFill(value, start = 0, end = undefined) {
485 var O = ToObject(this);
488 var len = ToLength(O.length);
491 var relativeStart = ToInteger(start);
496 ? std_Math_max(len + relativeStart, 0)
497 : std_Math_min(relativeStart, len);
500 var relativeEnd = end === undefined ? len : ToInteger(end);
505 ? std_Math_max(len + relativeEnd, 0)
506 : std_Math_min(relativeEnd, len);
509 for (; k < final; k++) {
517 // ES6 draft specification, section 22.1.5.1, version 2013-09-05.
518 function CreateArrayIterator(obj, kind) {
519 var iteratedObject = ToObject(obj);
520 var iterator = NewArrayIterator();
521 UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_TARGET, iteratedObject);
522 UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_NEXT_INDEX, 0);
523 UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_ITEM_KIND, kind);
528 // http://www.ecma-international.org/ecma-262/6.0/index.html#sec-%arrayiteratorprototype%.next
529 function ArrayIteratorNext() {
532 if (!IsObject(obj) || (obj = GuardToArrayIterator(obj)) === null) {
534 CallArrayIteratorMethodIfWrapped,
541 var a = UnsafeGetReservedSlot(obj, ITERATOR_SLOT_TARGET);
542 var result = { value: undefined, done: false };
551 // The index might not be an integer, so we have to do a generic get here.
552 var index = UnsafeGetReservedSlot(obj, ITERATOR_SLOT_NEXT_INDEX);
555 var itemKind = UnsafeGetInt32FromReservedSlot(obj, ITERATOR_SLOT_ITEM_KIND);
559 if (IsPossiblyWrappedTypedArray(a)) {
560 len = PossiblyWrappedTypedArrayLength(a);
562 // If the length is non-zero, the buffer can't be detached.
564 if (PossiblyWrappedTypedArrayHasDetachedBuffer(a)) {
565 ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
569 len = ToLength(a.length);
574 UnsafeSetReservedSlot(obj, ITERATOR_SLOT_TARGET, null);
580 UnsafeSetReservedSlot(obj, ITERATOR_SLOT_NEXT_INDEX, index + 1);
583 if (itemKind === ITEM_KIND_VALUE) {
584 result.value = a[index];
589 if (itemKind === ITEM_KIND_KEY_AND_VALUE) {
590 var pair = [index, a[index]];
596 assert(itemKind === ITEM_KIND_KEY, itemKind);
597 result.value = index;
600 // We want to inline this to do scalar replacement of the result object.
601 SetIsInlinableLargeFunction(ArrayIteratorNext);
603 // Uncloned functions with `$` prefix are allocated as extended function
604 // to store the original name in `SetCanonicalName`.
605 function $ArrayValues() {
606 return CreateArrayIterator(this, ITEM_KIND_VALUE);
608 SetCanonicalName($ArrayValues, "values");
610 function ArrayEntries() {
611 return CreateArrayIterator(this, ITEM_KIND_KEY_AND_VALUE);
614 function ArrayKeys() {
615 return CreateArrayIterator(this, ITEM_KIND_KEY);
618 // https://tc39.es/proposal-array-from-async/
619 // TODO: Bug 1834560 The step numbers in this will need updating when this is merged
620 // into the main spec.
621 function ArrayFromAsync(asyncItems, mapfn = undefined, thisArg = undefined) {
622 // Step 1. Let C be the this value.
625 // Step 2. Let promiseCapability be ! NewPromiseCapability(%Promise%).
626 // Step 3. Let fromAsyncClosure be a new Abstract Closure with no parameters that captures C, mapfn, and thisArg and performs the following steps when called:
627 var fromAsyncClosure = async () => {
628 // Step 3.a. If mapfn is undefined, let mapping be false.
630 // Step 3.b.i. If IsCallable(mapfn) is false, throw a TypeError exception.
631 // Step 3.b.ii. Let mapping be true.
632 var mapping = mapfn !== undefined;
633 if (mapping && !IsCallable(mapfn)) {
634 ThrowTypeError(JSMSG_NOT_FUNCTION, ToSource(mapfn));
637 // Step 3.c. Let usingAsyncIterator be ? GetMethod(asyncItems, @@asyncIterator).
638 var usingAsyncIterator = asyncItems[GetBuiltinSymbol("asyncIterator")];
639 if (usingAsyncIterator === null) {
640 usingAsyncIterator = undefined;
643 var usingSyncIterator = undefined;
644 if (usingAsyncIterator !== undefined) {
645 if (!IsCallable(usingAsyncIterator)) {
646 ThrowTypeError(JSMSG_NOT_ITERABLE, ToSource(asyncItems));
649 // Step 3.d. If usingAsyncIterator is undefined, then
651 // Step 3.d.i. Let usingSyncIterator be ? GetMethod(asyncItems, @@iterator).
652 usingSyncIterator = asyncItems[GetBuiltinSymbol("iterator")];
653 if (usingSyncIterator === null) {
654 usingSyncIterator = undefined;
657 if (usingSyncIterator !== undefined) {
658 if (!IsCallable(usingSyncIterator)) {
659 ThrowTypeError(JSMSG_NOT_ITERABLE, ToSource(asyncItems));
664 // Step 3.g. Let iteratorRecord be undefined.
665 // Step 3.j. If iteratorRecord is not undefined, then ...
666 if (usingAsyncIterator !== undefined || usingSyncIterator !== undefined) {
667 // Note: The published spec as of f6acfc4f0277e625f13fd22068138aec61a12df3
668 // is incorrect. See https://github.com/tc39/proposal-array-from-async/issues/33
669 // Here we use the implementation provided by @bakkot in that bug
670 // in lieu for now; This allows to use a for-await loop below.
672 // Steps 3.h-i are implicit through the for-await loop.
674 // Step 3.h. If usingAsyncIterator is not undefined, then
675 // Step 3.h.i. Set iteratorRecord to ? GetIterator(asyncItems, async, usingAsyncIterator).
676 // Step 3.i. Else if usingSyncIterator is not undefined, then
677 // Set iteratorRecord to ? CreateAsyncFromSyncIterator(GetIterator(asyncItems, sync, usingSyncIterator)).
679 // https://github.com/tc39/proposal-array-from-async/pull/41
680 // Step 3.e. If IsConstructor(C) is true, then
681 // Step 3.e.i. Let A be ? Construct(C).
683 // Step 3.f.i. Let A be ! ArrayCreate(0).
684 var A = IsConstructor(C) ? constructContentFunction(C, C) : [];
687 // Step 3.j.i. Let k be 0.
690 // Step 3.j.ii. Repeat,
691 for await (var nextValue of allowContentIterWith(
696 // Following in the steps of Array.from, we don't actually implement 3.j.ii.1.
697 // The comment in Array.from also applies here; we should only encounter this
698 // after a huge loop around a proxy
699 // Step 3.j.ii.1. If k ≥ 2**53 - 1, then
700 // Step 3.j.ii.1.a. Let error be ThrowCompletion(a newly created TypeError object).
701 // Step 3.j.ii.1.b. Return ? AsyncIteratorClose(iteratorRecord, error).
702 // Step 3.j.ii.2. Let Pk be ! ToString(𝔽(k)).
704 // Step 3.j.ii.3. Let next be ? Await(IteratorStep(iteratorRecord)).
706 // Step 3.j.ii.5. Let nextValue be ? IteratorValue(next). (Implicit through the for-await loop).
708 // Step 3.j.ii.7. Else, let mappedValue be nextValue. (Reordered)
709 var mappedValue = nextValue;
711 // Step 3.j.ii.6. If mapping is true, then
713 // Step 3.j.ii.6.a. Let mappedValue be Call(mapfn, thisArg, « nextValue, 𝔽(k) »).
714 // Step 3.j.ii.6.b. IfAbruptCloseAsyncIterator(mappedValue, iteratorRecord).
715 // Abrupt completion will be handled by the for-await loop.
716 mappedValue = callContentFunction(mapfn, thisArg, nextValue, k);
718 // Step 3.j.ii.6.c. Set mappedValue to Await(mappedValue).
719 // Step 3.j.ii.6.d. IfAbruptCloseAsyncIterator(mappedValue, iteratorRecord).
720 mappedValue = await mappedValue;
723 // Step 3.j.ii.8. Let defineStatus be CreateDataPropertyOrThrow(A, Pk, mappedValue).
724 // Step 3.j.ii.9. If defineStatus is an abrupt completion, return ? AsyncIteratorClose(iteratorRecord, defineStatus).
725 DefineDataProperty(A, k, mappedValue);
727 // Step 3.j.ii.10. Set k to k + 1.
731 // Step 3.j.ii.4. If next is false, then (Reordered)
733 // Step 3.j.ii.4.a. Perform ? Set(A, "length", 𝔽(k), true).
736 // Step 3.j.ii.4.b. Return Completion Record { [[Type]]: return, [[Value]]: A, [[Target]]: empty }.
742 // Step 3.k.i. NOTE: asyncItems is neither an AsyncIterable nor an Iterable so assume it is an array-like object.
743 // Step 3.k.ii. Let arrayLike be ! ToObject(asyncItems).
744 var arrayLike = ToObject(asyncItems);
746 // Step 3.k.iii. Let len be ? LengthOfArrayLike(arrayLike).
747 var len = ToLength(arrayLike.length);
749 // Step 3.k.iv. If IsConstructor(C) is true, then
750 // Step 3.k.iv.1. Let A be ? Construct(C, « 𝔽(len) »).
752 // Step 3.k.v.1. Let A be ? ArrayCreate(len).
753 var A = IsConstructor(C) ? constructContentFunction(C, C, len) : std_Array(len);
755 // Step 3.k.vi. Let k be 0.
758 // Step 3.k.vii. Repeat, while k < len,
760 // Step 3.k.vii.1. Let Pk be ! ToString(𝔽(k)).
761 // Step 3.k.vii.2. Let kValue be ? Get(arrayLike, Pk).
762 // Step 3.k.vii.3. Let kValue be ? Await(kValue).
763 var kValue = await arrayLike[k];
765 // Step 3.k.vii.4. If mapping is true, then
766 // Step 3.k.vii.4.a. Let mappedValue be ? Call(mapfn, thisArg, « kValue, 𝔽(k) »).
767 // Step 3.k.vii.4.b. Let mappedValue be ? Await(mappedValue).
768 // Step 3.k.vii.5. Else, let mappedValue be kValue.
769 var mappedValue = mapping
770 ? await callContentFunction(mapfn, thisArg, kValue, k)
773 // Step 3.k.vii.6. Perform ? CreateDataPropertyOrThrow(A, Pk, mappedValue).
774 DefineDataProperty(A, k, mappedValue);
776 // Step 3.k.vii.7. Set k to k + 1.
780 // Step 3.k.viii. Perform ? Set(A, "length", 𝔽(len), true).
783 // Step 3.k.ix. Return Completion Record { [[Type]]: return, [[Value]]: A, [[Target]]: empty }.
787 // Step 4. Perform AsyncFunctionStart(promiseCapability, fromAsyncClosure).
788 // Step 5. Return promiseCapability.[[Promise]].
789 return fromAsyncClosure();
792 // ES 2017 draft 0f10dba4ad18de92d47d421f378233a2eae8f077 22.1.2.1
793 function ArrayFrom(items, mapfn = undefined, thisArg = undefined) {
798 var mapping = mapfn !== undefined;
799 if (mapping && !IsCallable(mapfn)) {
800 ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, mapfn));
805 // Inlined: GetMethod, steps 1-2.
806 var usingIterator = items[GetBuiltinSymbol("iterator")];
809 // Inlined: GetMethod, step 3.
810 if (!IsNullOrUndefined(usingIterator)) {
811 // Inlined: GetMethod, step 4.
812 if (!IsCallable(usingIterator)) {
813 ThrowTypeError(JSMSG_NOT_ITERABLE, DecompileArg(0, items));
817 var A = IsConstructor(C) ? constructContentFunction(C, C) : [];
823 for (var nextValue of allowContentIterWith(items, usingIterator)) {
825 // Disabled for performance reason. We won't hit this case on
826 // normal array, since DefineDataProperty will throw before it.
827 // We could hit this when |A| is a proxy and it ignores
828 // |DefineDataProperty|, but it happens only after too long loop.
830 if (k >= 0x1fffffffffffff) {
831 ThrowTypeError(JSMSG_TOO_LONG_ARRAY);
836 var mappedValue = mapping
837 ? callContentFunction(mapfn, T, nextValue, k)
840 // Steps 5.e.ii (reordered), 5.e.viii.
841 DefineDataProperty(A, k++, mappedValue);
849 // Step 7 is an assertion: items is not an Iterator. Testing this is
850 // literally the very last thing we did, so we don't assert here.
853 var arrayLike = ToObject(items);
856 var len = ToLength(arrayLike.length);
859 var A = IsConstructor(C)
860 ? constructContentFunction(C, C, len)
864 for (var k = 0; k < len; k++) {
866 var kValue = items[k];
869 var mappedValue = mapping
870 ? callContentFunction(mapfn, T, kValue, k)
874 DefineDataProperty(A, k, mappedValue);
884 // ES2015 22.1.3.27 Array.prototype.toString.
885 function ArrayToString() {
887 var array = ToObject(this);
890 var func = array.join;
893 if (!IsCallable(func)) {
894 return callFunction(std_Object_toString, array);
896 return callContentFunction(func, array);
899 // ES2017 draft rev f8a9be8ea4bd97237d176907a1e3080dce20c68f
900 // 22.1.3.27 Array.prototype.toLocaleString ([ reserved1 [ , reserved2 ] ])
901 // ES2017 Intl draft rev 78bbe7d1095f5ff3760ac4017ed366026e4cb276
902 // 13.4.1 Array.prototype.toLocaleString ([ locales [ , options ]])
903 function ArrayToLocaleString(locales, options) {
904 // Step 1 (ToObject already performed in native code).
905 assert(IsObject(this), "|this| should be an object");
909 var len = ToLength(array.length);
917 var firstElement = array[0];
921 if (IsNullOrUndefined(firstElement)) {
927 firstElement.toLocaleString,
935 callContentFunction(firstElement.toLocaleString, firstElement)
940 // Step 3 (reordered).
941 // We don't (yet?) implement locale-dependent separators.
945 for (var k = 1; k < len; k++) {
947 var nextElement = array[k];
951 if (!IsNullOrUndefined(nextElement)) {
955 nextElement.toLocaleString,
963 callContentFunction(nextElement.toLocaleString, nextElement)
973 // ES 2016 draft Mar 25, 2016 22.1.2.5.
974 function $ArraySpecies() {
978 SetCanonicalName($ArraySpecies, "get [Symbol.species]");
980 // ES 2016 draft Mar 25, 2016 9.4.2.3.
981 function ArraySpeciesCreate(originalArray, length) {
983 assert(typeof length === "number", "length should be a number");
984 assert(length >= 0, "length should be a non-negative number");
987 // eslint-disable-next-line no-compare-neg-zero
993 if (!IsArray(originalArray)) {
994 return std_Array(length);
998 var C = originalArray.constructor;
1001 if (IsConstructor(C) && IsCrossRealmArrayConstructor(C)) {
1002 return std_Array(length);
1008 C = C[GetBuiltinSymbol("species")];
1010 // Optimized path for an ordinary Array.
1011 if (C === GetBuiltinConstructor("Array")) {
1012 return std_Array(length);
1017 return std_Array(length);
1022 if (C === undefined) {
1023 return std_Array(length);
1027 if (!IsConstructor(C)) {
1028 ThrowTypeError(JSMSG_NOT_CONSTRUCTOR, "constructor property");
1032 return constructContentFunction(C, C, length);
1035 // ES2020 draft rev dc1e21c454bd316810be1c0e7af0131a2d7f38e9
1036 // 22.1.3.11 Array.prototype.flatMap ( mapperFunction [ , thisArg ] )
1037 function ArrayFlatMap(mapperFunction /*, thisArg*/) {
1039 var O = ToObject(this);
1042 var sourceLen = ToLength(O.length);
1045 if (!IsCallable(mapperFunction)) {
1046 ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, mapperFunction));
1050 var T = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
1053 var A = ArraySpeciesCreate(O, 0);
1056 FlattenIntoArray(A, O, sourceLen, 0, 1, mapperFunction, T);
1062 // ES2020 draft rev dc1e21c454bd316810be1c0e7af0131a2d7f38e9
1063 // 22.1.3.10 Array.prototype.flat ( [ depth ] )
1064 function ArrayFlat(/* depth */) {
1066 var O = ToObject(this);
1069 var sourceLen = ToLength(O.length);
1075 if (ArgumentsLength() && GetArgument(0) !== undefined) {
1076 depthNum = ToInteger(GetArgument(0));
1080 var A = ArraySpeciesCreate(O, 0);
1083 FlattenIntoArray(A, O, sourceLen, 0, depthNum);
1089 // ES2020 draft rev dc1e21c454bd316810be1c0e7af0131a2d7f38e9
1090 // 22.1.3.10.1 FlattenIntoArray ( target, source, sourceLen, start, depth [ , mapperFunction, thisArg ] )
1091 function FlattenIntoArray(
1101 var targetIndex = start;
1104 for (var sourceIndex = 0; sourceIndex < sourceLen; sourceIndex++) {
1106 if (sourceIndex in source) {
1108 var element = source[sourceIndex];
1110 if (mapperFunction) {
1112 assert(ArgumentsLength() === 7, "thisArg is present");
1115 element = callContentFunction(
1125 var shouldFlatten = false;
1130 shouldFlatten = IsArray(element);
1134 if (shouldFlatten) {
1136 var elementLen = ToLength(element.length);
1139 targetIndex = FlattenIntoArray(
1148 if (targetIndex >= MAX_NUMERIC_INDEX) {
1149 ThrowTypeError(JSMSG_TOO_LONG_ARRAY);
1153 DefineDataProperty(target, targetIndex, element);
1165 // https://github.com/tc39/proposal-relative-indexing-method
1166 // Array.prototype.at ( index )
1167 function ArrayAt(index) {
1169 var O = ToObject(this);
1172 var len = ToLength(O.length);
1175 var relativeIndex = ToInteger(index);
1179 if (relativeIndex >= 0) {
1182 k = len + relativeIndex;
1186 if (k < 0 || k >= len) {
1193 // This function is only barely too long for normal inlining.
1194 SetIsInlinableLargeFunction(ArrayAt);
1196 // https://github.com/tc39/proposal-change-array-by-copy
1197 // Array.prototype.toReversed()
1198 function ArrayToReversed() {
1199 // Step 1. Let O be ? ToObject(this value).
1200 var O = ToObject(this);
1202 // Step 2. Let len be ? LengthOfArrayLike(O).
1203 var len = ToLength(O.length);
1205 // Step 3. Let A be ArrayCreate(𝔽(len)).
1206 var A = std_Array(len);
1208 // Step 4. Let k be 0.
1209 // Step 5. Repeat, while k < len,
1210 for (var k = 0; k < len; k++) {
1211 // Step 5.a. Let from be ! ToString(𝔽(len - k - 1)).
1212 var from = len - k - 1;
1214 // Skip Step 5.b. Let Pk be ToString(𝔽(k)).
1215 // k is coerced into a string through the property access.
1217 // Step 5.c. Let fromValue be ? Get(O, from).
1218 var fromValue = O[from];
1220 // Step 5.d. Perform ! CreateDataPropertyOrThrow(A, 𝔽(k), fromValue).
1221 DefineDataProperty(A, k, fromValue);
1224 // Step 6. Return A.
1228 // https://github.com/tc39/proposal-change-array-by-copy
1229 // Array.prototype.toSorted()
1230 function ArrayToSorted(comparefn) {
1231 // Step 1. If comparefn is not undefined and IsCallable(comparefn) is
1232 // false, throw a TypeError exception.
1233 if (comparefn !== undefined && !IsCallable(comparefn)) {
1234 ThrowTypeError(JSMSG_BAD_TOSORTED_ARG);
1237 // Step 2. Let O be ? ToObject(this value).
1238 var O = ToObject(this);
1240 // Step 3. Let len be ? LengthOfArrayLike(O).
1241 var len = ToLength(O.length);
1243 // Step 4. Let A be ? ArrayCreate(𝔽(len)).
1244 var items = std_Array(len);
1246 // We depart from steps 5-8 of the spec for performance reasons, as
1247 // following the spec would require copying the input array twice.
1248 // Instead, we create a new array that replaces holes with undefined,
1249 // and sort this array.
1250 for (var k = 0; k < len; k++) {
1251 DefineDataProperty(items, k, O[k]);
1254 // Arrays with less than two elements remain unchanged when sorted.
1260 return callFunction(std_Array_sort, items, comparefn);
1263 // https://github.com/tc39/proposal-array-find-from-last
1264 // Array.prototype.findLast ( predicate, thisArg )
1265 function ArrayFindLast(predicate /*, thisArg*/) {
1267 var O = ToObject(this);
1270 var len = ToLength(O.length);
1273 if (ArgumentsLength() === 0) {
1274 ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.findLast");
1276 if (!IsCallable(predicate)) {
1277 ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate));
1280 var thisArg = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
1283 for (var k = len - 1; k >= 0; k--) {
1288 if (callContentFunction(predicate, thisArg, kValue, k, O)) {
1296 // Inlining this enables inlining of the callback function.
1297 SetIsInlinableLargeFunction(ArrayFindLast);
1299 // https://github.com/tc39/proposal-array-find-from-last
1300 // Array.prototype.findLastIndex ( predicate, thisArg )
1301 function ArrayFindLastIndex(predicate /*, thisArg*/) {
1303 var O = ToObject(this);
1306 var len = ToLength(O.length);
1309 if (ArgumentsLength() === 0) {
1310 ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "Array.prototype.findLastIndex");
1312 if (!IsCallable(predicate)) {
1313 ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate));
1316 var thisArg = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
1319 for (var k = len - 1; k >= 0; k--) {
1321 if (callContentFunction(predicate, thisArg, O[k], k, O)) {
1329 // Inlining this enables inlining of the callback function.
1330 SetIsInlinableLargeFunction(ArrayFindLastIndex);