Bug 1877642 - Disable browser_fullscreen-tab-close-race.js on apple_silicon !debug...
[gecko.git] / js / src / builtin / TypedArray.js
blob4d5474f6a785f98eef138bf4641d605ea1226424
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/. */
5 #include "TypedArrayConstants.h"
7 function ViewedArrayBufferIfReified(tarray) {
8   assert(IsTypedArray(tarray), "non-typed array asked for its buffer");
10   var buf = UnsafeGetReservedSlot(tarray, JS_TYPEDARRAYLAYOUT_BUFFER_SLOT);
11   assert(
12     buf === false ||
13       buf === true ||
14       (IsObject(buf) &&
15         (GuardToArrayBuffer(buf) !== null ||
16           GuardToSharedArrayBuffer(buf) !== null)),
17     "unexpected value in buffer slot"
18   );
19   return IsObject(buf) ? buf : null;
22 function IsDetachedBuffer(buffer) {
23   // A typed array with a null buffer has never had its buffer exposed,
24   // and so cannot have become detached.
25   if (buffer === null) {
26     return false;
27   }
29   assert(
30     GuardToArrayBuffer(buffer) !== null ||
31       GuardToSharedArrayBuffer(buffer) !== null,
32     "non-ArrayBuffer passed to IsDetachedBuffer"
33   );
35   // Shared array buffers are not detachable.
36   if ((buffer = GuardToArrayBuffer(buffer)) === null) {
37     return false;
38   }
40   var flags = UnsafeGetInt32FromReservedSlot(buffer, JS_ARRAYBUFFER_FLAGS_SLOT);
41   return (flags & JS_ARRAYBUFFER_DETACHED_FLAG) !== 0;
44 function GetAttachedArrayBuffer(tarray) {
45   var buffer = ViewedArrayBufferIfReified(tarray);
46   if (IsDetachedBuffer(buffer)) {
47     ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
48   }
49   return buffer;
52 function GetAttachedArrayBufferMethod() {
53   return GetAttachedArrayBuffer(this);
56 // A function which ensures that the argument is either a typed array or a
57 // cross-compartment wrapper for a typed array and that the typed array involved
58 // has an attached array buffer.  If one of those conditions doesn't hold (wrong
59 // kind of argument, or detached array buffer), an exception is thrown.
60 function EnsureTypedArrayWithArrayBuffer(arg) {
61   if (IsObject(arg) && IsTypedArray(arg)) {
62     GetAttachedArrayBuffer(arg);
63     return;
64   }
66   callFunction(
67     CallTypedArrayMethodIfWrapped,
68     arg,
69     "GetAttachedArrayBufferMethod"
70   );
73 // ES2019 draft rev 85ce767c86a1a8ed719fe97e978028bff819d1f2
74 // 7.3.20 SpeciesConstructor ( O, defaultConstructor )
76 // SpeciesConstructor function optimized for TypedArrays to avoid calling
77 // ConstructorForTypedArray, a non-inlineable runtime function, in the normal
78 // case.
79 function TypedArraySpeciesConstructor(obj) {
80   // Step 1.
81   assert(IsObject(obj), "not passed an object");
83   // Step 2.
84   var ctor = obj.constructor;
86   // Step 3.
87   if (ctor === undefined) {
88     return ConstructorForTypedArray(obj);
89   }
91   // Step 4.
92   if (!IsObject(ctor)) {
93     ThrowTypeError(JSMSG_OBJECT_REQUIRED, "object's 'constructor' property");
94   }
96   // Steps 5.
97   var s = ctor[GetBuiltinSymbol("species")];
99   // Step 6.
100   if (IsNullOrUndefined(s)) {
101     return ConstructorForTypedArray(obj);
102   }
104   // Step 7.
105   if (IsConstructor(s)) {
106     return s;
107   }
109   // Step 8.
110   ThrowTypeError(
111     JSMSG_NOT_CONSTRUCTOR,
112     "@@species property of object's constructor"
113   );
116 // ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
117 // 22.2.3.5.1 Runtime Semantics: ValidateTypedArray ( O )
118 function ValidateTypedArray(obj) {
119   if (IsObject(obj)) {
120     /* Steps 3-5 (non-wrapped typed arrays). */
121     if (IsTypedArray(obj)) {
122       // GetAttachedArrayBuffer throws for detached array buffers.
123       GetAttachedArrayBuffer(obj);
124       return;
125     }
127     /* Steps 3-5 (wrapped typed arrays). */
128     if (IsPossiblyWrappedTypedArray(obj)) {
129       if (PossiblyWrappedTypedArrayHasDetachedBuffer(obj)) {
130         ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
131       }
132       return;
133     }
134   }
136   /* Steps 1-2. */
137   ThrowTypeError(JSMSG_NON_TYPED_ARRAY_RETURNED);
140 // ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
141 // 22.2.4.6 TypedArrayCreate ( constructor, argumentList )
142 function TypedArrayCreateWithLength(constructor, length) {
143   // Step 1.
144   var newTypedArray = constructContentFunction(
145     constructor,
146     constructor,
147     length
148   );
150   // Step 2.
151   ValidateTypedArray(newTypedArray);
153   // Step 3.
154   var len = PossiblyWrappedTypedArrayLength(newTypedArray);
156   if (len < length) {
157     ThrowTypeError(JSMSG_SHORT_TYPED_ARRAY_RETURNED, length, len);
158   }
160   // Step 4.
161   return newTypedArray;
164 // ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
165 // 22.2.4.6 TypedArrayCreate ( constructor, argumentList )
166 function TypedArrayCreateWithBuffer(constructor, buffer, byteOffset, length) {
167   // Step 1.
168   var newTypedArray = constructContentFunction(
169     constructor,
170     constructor,
171     buffer,
172     byteOffset,
173     length
174   );
176   // Step 2.
177   ValidateTypedArray(newTypedArray);
179   // We also need to make sure the length is in-bounds. This is checked by
180   // calling PossiblyWrappedTypedArrayLength, which throws for out-of-bounds.
181   PossiblyWrappedTypedArrayLength(newTypedArray);
183   // Step 3 (not applicable).
185   // Step 4.
186   return newTypedArray;
189 // ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
190 // 22.2.4.6 TypedArrayCreate ( constructor, argumentList )
191 function TypedArrayCreateWithResizableBuffer(constructor, buffer, byteOffset) {
192   // Step 1.
193   var newTypedArray = constructContentFunction(
194     constructor,
195     constructor,
196     buffer,
197     byteOffset
198   );
200   // Step 2.
201   ValidateTypedArray(newTypedArray);
203   // We also need to make sure the length is in-bounds. This is checked by
204   // calling PossiblyWrappedTypedArrayLength, which throws for out-of-bounds.
205   PossiblyWrappedTypedArrayLength(newTypedArray);
207   // Step 3 (not applicable).
209   // Step 4.
210   return newTypedArray;
213 // ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
214 // 22.2.4.7 TypedArraySpeciesCreate ( exemplar, argumentList )
215 function TypedArraySpeciesCreateWithLength(exemplar, length) {
216   // Step 1 (omitted).
218   // Steps 2-3.
219   var C = TypedArraySpeciesConstructor(exemplar);
221   // Step 4.
222   return TypedArrayCreateWithLength(C, length);
225 // ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
226 // 22.2.4.7 TypedArraySpeciesCreate ( exemplar, argumentList )
227 function TypedArraySpeciesCreateWithBuffer(
228   exemplar,
229   buffer,
230   byteOffset,
231   length
232 ) {
233   // Step 1 (omitted).
235   // Steps 2-3.
236   var C = TypedArraySpeciesConstructor(exemplar);
238   // Step 4.
239   return TypedArrayCreateWithBuffer(C, buffer, byteOffset, length);
242 // ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
243 // 22.2.4.7 TypedArraySpeciesCreate ( exemplar, argumentList )
244 function TypedArraySpeciesCreateWithResizableBuffer(
245   exemplar,
246   buffer,
247   byteOffset
248 ) {
249   // Step 1 (omitted).
251   // Steps 2-3.
252   var C = TypedArraySpeciesConstructor(exemplar);
254   // Step 4.
255   return TypedArrayCreateWithResizableBuffer(C, buffer, byteOffset);
258 // ES6 draft rev30 (2014/12/24) 22.2.3.6 %TypedArray%.prototype.entries()
259 function TypedArrayEntries() {
260   // Step 1.
261   var O = this;
263   // We need to be a bit careful here, because in the Xray case we want to
264   // create the iterator in our current compartment.
265   //
266   // Before doing that, though, we want to check that we have a typed array
267   // and it does not have a detached array buffer.  We do the latter by just
268   // calling GetAttachedArrayBuffer() and letting it throw if there isn't one.
269   // In the case when we're not sure we have a typed array (e.g. we might have
270   // a cross-compartment wrapper for one), we can go ahead and call
271   // GetAttachedArrayBuffer via EnsureTypedArrayWithArrayBuffer; that will
272   // throw if we're not actually a wrapped typed array, or if we have a
273   // detached array buffer.
275   // Step 2-6.
276   EnsureTypedArrayWithArrayBuffer(O);
278   // We also need to make sure the length is in-bounds. This is checked by
279   // calling PossiblyWrappedTypedArrayLength, which throws for out-of-bounds.
280   PossiblyWrappedTypedArrayLength(O);
282   // Step 7.
283   return CreateArrayIterator(O, ITEM_KIND_KEY_AND_VALUE);
286 // ES2021 draft rev 190d474c3d8728653fbf8a5a37db1de34b9c1472
287 // Plus <https://github.com/tc39/ecma262/pull/2221>
288 // 22.2.3.7 %TypedArray%.prototype.every ( callbackfn [ , thisArg ] )
289 function TypedArrayEvery(callbackfn /*, thisArg*/) {
290   // Step 1.
291   var O = this;
293   // Step 2.
294   EnsureTypedArrayWithArrayBuffer(O);
296   // If we got here, `this` is either a typed array or a wrapper for one.
298   // Step 3.
299   var len = PossiblyWrappedTypedArrayLength(O);
301   // Step 4.
302   if (ArgumentsLength() === 0) {
303     ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.every");
304   }
305   if (!IsCallable(callbackfn)) {
306     ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
307   }
309   var thisArg = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
311   // Steps 5-6.
312   for (var k = 0; k < len; k++) {
313     // Steps 6.b-d.
314     var kValue = O[k];
316     // Step 6.c.
317     var testResult = callContentFunction(callbackfn, thisArg, kValue, k, O);
319     // Step 6.d.
320     if (!testResult) {
321       return false;
322     }
323   }
325   // Step 7.
326   return true;
328 // Inlining this enables inlining of the callback function.
329 SetIsInlinableLargeFunction(TypedArrayEvery);
331 // ES2024 draft rev b643e1d9bdc0e98d238a72f9988c01265306d09f
332 // Including the changes from <https://github.com/tc39/ecma262/pull/3116>.
334 // 23.2.3.9 %TypedArray%.prototype.fill ( value [ , start [ , end ] ] )
335 function TypedArrayFill(value, start = 0, end = undefined) {
336   // This function is not generic.
337   if (!IsObject(this) || !IsTypedArray(this)) {
338     return callFunction(
339       CallTypedArrayMethodIfWrapped,
340       this,
341       value,
342       start,
343       end,
344       "TypedArrayFill"
345     );
346   }
348   // Step 1.
349   var O = this;
351   // Step 2.
352   var buffer = GetAttachedArrayBuffer(this);
354   // Step 3.
355   var len = TypedArrayLength(O);
357   // Steps 4-5.
358   var kind = GetTypedArrayKind(O);
359   if (kind === TYPEDARRAY_KIND_BIGINT64 || kind === TYPEDARRAY_KIND_BIGUINT64) {
360     value = ToBigInt(value);
361   } else {
362     value = ToNumber(value);
363   }
365   // Step 6.
366   var relativeStart = ToInteger(start);
368   // Steps 7-9.
369   var k =
370     relativeStart < 0
371       ? std_Math_max(len + relativeStart, 0)
372       : std_Math_min(relativeStart, len);
374   // Step 10.
375   var relativeEnd = end === undefined ? len : ToInteger(end);
377   // Steps 11-13.
378   var final =
379     relativeEnd < 0
380       ? std_Math_max(len + relativeEnd, 0)
381       : std_Math_min(relativeEnd, len);
383   // Steps 14-16.
384   if (buffer === null) {
385     // A typed array previously using inline storage may acquire a
386     // buffer, so we must check with the source.
387     buffer = ViewedArrayBufferIfReified(O);
388   }
390   if (IsDetachedBuffer(buffer)) {
391     ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
392   }
394   len = TypedArrayLength(O);
396   // Step 17.
397   final = std_Math_min(final, len);
399   // Step 18.
400   for (; k < final; k++) {
401     O[k] = value;
402   }
404   // Step 19.
405   return O;
408 // ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
409 // %TypedArray%.prototype.filter ( callbackfn [ , thisArg ] )
410 function TypedArrayFilter(callbackfn /*, thisArg*/) {
411   // Step 1.
412   var O = this;
414   // Step 2.
415   // This function is not generic.
416   // We want to make sure that we have an attached buffer, per spec prose.
417   EnsureTypedArrayWithArrayBuffer(O);
419   // If we got here, `this` is either a typed array or a wrapper for one.
421   // Step 3.
422   var len = PossiblyWrappedTypedArrayLength(O);
424   // Step 4.
425   if (ArgumentsLength() === 0) {
426     ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.filter");
427   }
428   if (!IsCallable(callbackfn)) {
429     ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
430   }
432   // Step 5.
433   var T = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
435   // Step 6.
436   var kept = new_List();
438   // Step 8.
439   var captured = 0;
441   // Steps 7 and 9.e.
442   for (var k = 0; k < len; k++) {
443     // Steps 9.a-b.
444     var kValue = O[k];
446     // Steps 9.c-d.
447     if (callContentFunction(callbackfn, T, kValue, k, O)) {
448       // Steps 9.d.i-ii.
449       kept[captured++] = kValue;
450     }
451   }
453   // Step 10.
454   var A = TypedArraySpeciesCreateWithLength(O, captured);
456   // Steps 11 and 12.b.
457   for (var n = 0; n < captured; n++) {
458     // Step 12.a.
459     A[n] = kept[n];
460   }
462   // Step 13.
463   return A;
465 // Inlining this enables inlining of the callback function.
466 SetIsInlinableLargeFunction(TypedArrayFilter);
468 // ES2021 draft rev 190d474c3d8728653fbf8a5a37db1de34b9c1472
469 // Plus <https://github.com/tc39/ecma262/pull/2221>
470 // 22.2.3.10 %TypedArray%.prototype.find ( predicate [ , thisArg ] )
471 function TypedArrayFind(predicate /*, thisArg*/) {
472   // Step 1.
473   var O = this;
475   // Step 2.
476   EnsureTypedArrayWithArrayBuffer(O);
478   // If we got here, `this` is either a typed array or a wrapper for one.
480   // Step 3.
481   var len = PossiblyWrappedTypedArrayLength(O);
483   // Step 4.
484   if (ArgumentsLength() === 0) {
485     ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.find");
486   }
487   if (!IsCallable(predicate)) {
488     ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate));
489   }
491   var thisArg = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
493   // Steps 5-6.
494   for (var k = 0; k < len; k++) {
495     // Steps 6.a-b.
496     var kValue = O[k];
498     // Steps 6.c-d.
499     if (callContentFunction(predicate, thisArg, kValue, k, O)) {
500       return kValue;
501     }
502   }
504   // Step 7.
505   return undefined;
507 // Inlining this enables inlining of the callback function.
508 SetIsInlinableLargeFunction(TypedArrayFind);
510 // ES2021 draft rev 190d474c3d8728653fbf8a5a37db1de34b9c1472
511 // Plus <https://github.com/tc39/ecma262/pull/2221>
512 // 22.2.3.11 %TypedArray%.prototype.findIndex ( predicate [ , thisArg ] )
513 function TypedArrayFindIndex(predicate /*, thisArg*/) {
514   // Step 1.
515   var O = this;
517   // Step 2.
518   EnsureTypedArrayWithArrayBuffer(O);
520   // If we got here, `this` is either a typed array or a wrapper for one.
522   // Step 3.
523   var len = PossiblyWrappedTypedArrayLength(O);
525   // Step 4.
526   if (ArgumentsLength() === 0) {
527     ThrowTypeError(
528       JSMSG_MISSING_FUN_ARG,
529       0,
530       "%TypedArray%.prototype.findIndex"
531     );
532   }
533   if (!IsCallable(predicate)) {
534     ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate));
535   }
537   var thisArg = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
539   // Steps 5-6.
540   for (var k = 0; k < len; k++) {
541     // Steps 6.a-f.
542     if (callContentFunction(predicate, thisArg, O[k], k, O)) {
543       return k;
544     }
545   }
547   // Step 7.
548   return -1;
550 // Inlining this enables inlining of the callback function.
551 SetIsInlinableLargeFunction(TypedArrayFindIndex);
553 // ES2021 draft rev 190d474c3d8728653fbf8a5a37db1de34b9c1472
554 // Plus <https://github.com/tc39/ecma262/pull/2221>
555 // 22.2.3.12 %TypedArray%.prototype.forEach ( callbackfn [ , thisArg ] )
556 function TypedArrayForEach(callbackfn /*, thisArg*/) {
557   // Step 1.
558   var O = this;
560   // Step 2.
561   EnsureTypedArrayWithArrayBuffer(O);
563   // If we got here, `this` is either a typed array or a wrapper for one.
565   // Step 3.
566   var len = PossiblyWrappedTypedArrayLength(O);
568   // Step 4.
569   if (ArgumentsLength() === 0) {
570     ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "TypedArray.prototype.forEach");
571   }
572   if (!IsCallable(callbackfn)) {
573     ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
574   }
576   var thisArg = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
578   // Steps 5-6.
579   for (var k = 0; k < len; k++) {
580     // Steps 6.a-c.
581     callContentFunction(callbackfn, thisArg, O[k], k, O);
582   }
584   // Step 7.
585   return undefined;
587 // Inlining this enables inlining of the callback function.
588 SetIsInlinableLargeFunction(TypedArrayForEach);
590 // ES2021 draft rev 190d474c3d8728653fbf8a5a37db1de34b9c1472
591 // Plus <https://github.com/tc39/ecma262/pull/2221>
592 // 22.2.3.14 %TypedArray%.prototype.indexOf ( searchElement [ , fromIndex ] )
593 function TypedArrayIndexOf(searchElement, fromIndex = 0) {
594   // Step 2.
595   if (!IsObject(this) || !IsTypedArray(this)) {
596     return callFunction(
597       CallTypedArrayMethodIfWrapped,
598       this,
599       searchElement,
600       fromIndex,
601       "TypedArrayIndexOf"
602     );
603   }
605   GetAttachedArrayBuffer(this);
607   // Step 1.
608   var O = this;
610   // Step 3.
611   var len = TypedArrayLength(O);
613   // Step 4.
614   if (len === 0) {
615     return -1;
616   }
618   // Step 5.
619   var n = ToInteger(fromIndex);
621   // Step 6.
622   assert(fromIndex !== undefined || n === 0, "ToInteger(undefined) is zero");
624   // Reload O.[[ArrayLength]] in case ToInteger() detached or resized the ArrayBuffer.
625   // This lets us avoid executing the HasProperty operation in step 11.a.
626   len = std_Math_min(len, TypedArrayLengthZeroOnOutOfBounds(O));
628   assert(
629     len === 0 || !IsDetachedBuffer(ViewedArrayBufferIfReified(O)),
630     "TypedArrays with detached buffers have a length of zero"
631   );
633   // Step 7.
634   if (n >= len) {
635     return -1;
636   }
638   // Steps 7-10.
639   // Steps 7-8 are handled implicitly.
640   var k;
641   if (n >= 0) {
642     // Step 9.a.
643     k = n;
644   } else {
645     // Step 10.a.
646     k = len + n;
648     // Step 10.b.
649     if (k < 0) {
650       k = 0;
651     }
652   }
654   // Step 11.
655   for (; k < len; k++) {
656     // Step 11.a (not necessary in our implementation).
657     assert(k in O, "unexpected missing element");
659     // Steps 11.b.i-iii.
660     if (O[k] === searchElement) {
661       return k;
662     }
663   }
665   // Step 12.
666   return -1;
669 // ES2021 draft rev 190d474c3d8728653fbf8a5a37db1de34b9c1472
670 // Plus <https://github.com/tc39/ecma262/pull/2221>
671 // 22.2.3.15 %TypedArray%.prototype.join ( separator )
672 function TypedArrayJoin(separator) {
673   // Step 2.
674   if (!IsObject(this) || !IsTypedArray(this)) {
675     return callFunction(
676       CallTypedArrayMethodIfWrapped,
677       this,
678       separator,
679       "TypedArrayJoin"
680     );
681   }
683   GetAttachedArrayBuffer(this);
685   // Step 1.
686   var O = this;
688   // Step 3.
689   var len = TypedArrayLength(O);
691   // Steps 4-5.
692   var sep = separator === undefined ? "," : ToString(separator);
694   // Steps 6 and 9.
695   if (len === 0) {
696     return "";
697   }
699   var limit = std_Math_min(len, TypedArrayLengthZeroOnOutOfBounds(O));
701   // ToString() might have detached or resized the underlying ArrayBuffer. To avoid
702   // checking for this condition when looping in step 8.c, do it once here.
703   if (limit === 0) {
704     return callFunction(String_repeat, sep, len - 1);
705   }
707   assert(
708     !IsDetachedBuffer(ViewedArrayBufferIfReified(O)),
709     "TypedArrays with detached buffers have a length of zero"
710   );
712   var element0 = O[0];
714   // Omit the 'if' clause in step 8.c, since typed arrays can't have undefined or null elements.
715   assert(element0 !== undefined, "unexpected undefined element");
717   // Step 6.
718   var R = ToString(element0);
720   // Steps 7-8.
721   for (var k = 1; k < limit; k++) {
722     // Step 8.b.
723     var element = O[k];
725     // Omit the 'if' clause in step 8.c, since typed arrays can't have undefined or null elements.
726     assert(element !== undefined, "unexpected undefined element");
728     // Steps 8.a and 8.c-d.
729     R += sep + ToString(element);
730   }
732   if (limit < len) {
733     R += callFunction(String_repeat, sep, len - limit);
734   }
736   // Step 9.
737   return R;
740 // ES6 draft (2016/1/11) 22.2.3.15 %TypedArray%.prototype.keys()
741 function TypedArrayKeys() {
742   // Step 1.
743   var O = this;
745   // See the big comment in TypedArrayEntries for what we're doing here.
747   // Step 2.
748   EnsureTypedArrayWithArrayBuffer(O);
749   PossiblyWrappedTypedArrayLength(O);
751   // Step 3.
752   return CreateArrayIterator(O, ITEM_KIND_KEY);
755 // ES2021 draft rev 190d474c3d8728653fbf8a5a37db1de34b9c1472
756 // Plus <https://github.com/tc39/ecma262/pull/2221>
757 // 22.2.3.17 %TypedArray%.prototype.lastIndexOf ( searchElement [ , fromIndex ] )
758 function TypedArrayLastIndexOf(searchElement /*, fromIndex*/) {
759   // Step 2.
760   if (!IsObject(this) || !IsTypedArray(this)) {
761     if (ArgumentsLength() > 1) {
762       return callFunction(
763         CallTypedArrayMethodIfWrapped,
764         this,
765         searchElement,
766         GetArgument(1),
767         "TypedArrayLastIndexOf"
768       );
769     }
770     return callFunction(
771       CallTypedArrayMethodIfWrapped,
772       this,
773       searchElement,
774       "TypedArrayLastIndexOf"
775     );
776   }
778   GetAttachedArrayBuffer(this);
780   // Step 1.
781   var O = this;
783   // Step 3.
784   var len = TypedArrayLength(O);
786   // Step 4.
787   if (len === 0) {
788     return -1;
789   }
791   // Step 5.
792   var n = ArgumentsLength() > 1 ? ToInteger(GetArgument(1)) : len - 1;
794   // Reload O.[[ArrayLength]] in case ToInteger() detached or resized the ArrayBuffer.
795   // This lets us avoid executing the HasProperty operation in step 9.a.
796   len = std_Math_min(len, TypedArrayLengthZeroOnOutOfBounds(O));
798   assert(
799     len === 0 || !IsDetachedBuffer(ViewedArrayBufferIfReified(O)),
800     "TypedArrays with detached buffers have a length of zero"
801   );
803   // Steps 6-8.
804   var k = n >= 0 ? std_Math_min(n, len - 1) : len + n;
806   // Step 9.
807   for (; k >= 0; k--) {
808     // Step 9.a (not necessary in our implementation).
809     assert(k in O, "unexpected missing element");
811     // Steps 9.b.i-iii.
812     if (O[k] === searchElement) {
813       return k;
814     }
815   }
817   // Step 10.
818   return -1;
821 // ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
822 // 22.2.3.19 %TypedArray%.prototype.map ( callbackfn [ , thisArg ] )
823 function TypedArrayMap(callbackfn /*, thisArg*/) {
824   // Step 1.
825   var O = this;
827   // Step 2.
828   // This function is not generic.
829   // We want to make sure that we have an attached buffer, per spec prose.
830   EnsureTypedArrayWithArrayBuffer(O);
832   // If we got here, `this` is either a typed array or a wrapper for one.
834   // Step 3.
835   var len = PossiblyWrappedTypedArrayLength(O);
837   // Step 4.
838   if (ArgumentsLength() === 0) {
839     ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.map");
840   }
841   if (!IsCallable(callbackfn)) {
842     ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
843   }
845   // Step 5.
846   var T = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
848   // Step 6.
849   var A = TypedArraySpeciesCreateWithLength(O, len);
851   // Steps 7, 8.a (implicit) and 8.e.
852   for (var k = 0; k < len; k++) {
853     // Steps 8.b-c.
854     var mappedValue = callContentFunction(callbackfn, T, O[k], k, O);
856     // Steps 8.d.
857     A[k] = mappedValue;
858   }
860   // Step 9.
861   return A;
863 // Inlining this enables inlining of the callback function.
864 SetIsInlinableLargeFunction(TypedArrayMap);
866 // ES2021 draft rev 190d474c3d8728653fbf8a5a37db1de34b9c1472
867 // Plus <https://github.com/tc39/ecma262/pull/2221>
868 // 22.2.3.20 %TypedArray%.prototype.reduce ( callbackfn [ , initialValue ] )
869 function TypedArrayReduce(callbackfn /*, initialValue*/) {
870   // Step 1.
871   var O = this;
873   // Step 2.
874   EnsureTypedArrayWithArrayBuffer(O);
876   // If we got here, `this` is either a typed array or a wrapper for one.
878   // Step 3.
879   var len = PossiblyWrappedTypedArrayLength(O);
881   // Step 4.
882   if (ArgumentsLength() === 0) {
883     ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.reduce");
884   }
885   if (!IsCallable(callbackfn)) {
886     ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
887   }
889   // Step 5.
890   if (len === 0 && ArgumentsLength() === 1) {
891     ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE);
892   }
894   // Step 6.
895   var k = 0;
897   // Steps 7-9.
898   var accumulator = ArgumentsLength() > 1 ? GetArgument(1) : O[k++];
900   // Step 10.
901   for (; k < len; k++) {
902     accumulator = callContentFunction(
903       callbackfn,
904       undefined,
905       accumulator,
906       O[k],
907       k,
908       O
909     );
910   }
912   // Step 11.
913   return accumulator;
916 // ES2021 draft rev 190d474c3d8728653fbf8a5a37db1de34b9c1472
917 // Plus <https://github.com/tc39/ecma262/pull/2221>
918 // 22.2.3.21 %TypedArray%.prototype.reduceRight ( callbackfn [ , initialValue ] )
919 function TypedArrayReduceRight(callbackfn /*, initialValue*/) {
920   // Step 1.
921   var O = this;
923   // Step 2.
924   EnsureTypedArrayWithArrayBuffer(O);
926   // If we got here, `this` is either a typed array or a wrapper for one.
928   // Step 3.
929   var len = PossiblyWrappedTypedArrayLength(O);
931   // Step 4.
932   if (ArgumentsLength() === 0) {
933     ThrowTypeError(
934       JSMSG_MISSING_FUN_ARG,
935       0,
936       "%TypedArray%.prototype.reduceRight"
937     );
938   }
939   if (!IsCallable(callbackfn)) {
940     ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
941   }
943   // Step 5.
944   if (len === 0 && ArgumentsLength() === 1) {
945     ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE);
946   }
948   // Step 6.
949   var k = len - 1;
951   // Steps 7-9.
952   var accumulator = ArgumentsLength() > 1 ? GetArgument(1) : O[k--];
954   // Step 10.
955   for (; k >= 0; k--) {
956     accumulator = callContentFunction(
957       callbackfn,
958       undefined,
959       accumulator,
960       O[k],
961       k,
962       O
963     );
964   }
966   // Step 11.
967   return accumulator;
970 // ES2021 draft rev 190d474c3d8728653fbf8a5a37db1de34b9c1472
971 // Plus <https://github.com/tc39/ecma262/pull/2221>
972 // 22.2.3.22 %TypedArray%.prototype.reverse ( )
973 function TypedArrayReverse() {
974   // Step 2.
975   if (!IsObject(this) || !IsTypedArray(this)) {
976     return callFunction(
977       CallTypedArrayMethodIfWrapped,
978       this,
979       "TypedArrayReverse"
980     );
981   }
983   GetAttachedArrayBuffer(this);
985   // Step 1.
986   var O = this;
988   // Step 3.
989   var len = TypedArrayLength(O);
991   // Step 4.
992   var middle = std_Math_floor(len / 2);
994   // Steps 5-6.
995   for (var lower = 0; lower !== middle; lower++) {
996     // Step 6.a.
997     var upper = len - lower - 1;
999     // Step 6.d.
1000     var lowerValue = O[lower];
1002     // Step 6.e.
1003     var upperValue = O[upper];
1005     // Steps 6.f-g.
1006     O[lower] = upperValue;
1007     O[upper] = lowerValue;
1008   }
1010   // Step 7.
1011   return O;
1014 // ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
1015 // 22.2.3.24 %TypedArray%.prototype.slice ( start, end )
1016 function TypedArraySlice(start, end) {
1017   // Step 1.
1018   var O = this;
1020   // Step 2.
1021   if (!IsObject(O) || !IsTypedArray(O)) {
1022     return callFunction(
1023       CallTypedArrayMethodIfWrapped,
1024       O,
1025       start,
1026       end,
1027       "TypedArraySlice"
1028     );
1029   }
1031   GetAttachedArrayBuffer(O);
1033   // Step 3.
1034   var len = TypedArrayLength(O);
1036   // Step 4.
1037   var relativeStart = ToInteger(start);
1039   // Step 5.
1040   var k =
1041     relativeStart < 0
1042       ? std_Math_max(len + relativeStart, 0)
1043       : std_Math_min(relativeStart, len);
1045   // Step 6.
1046   var relativeEnd = end === undefined ? len : ToInteger(end);
1048   // Step 7.
1049   var final =
1050     relativeEnd < 0
1051       ? std_Math_max(len + relativeEnd, 0)
1052       : std_Math_min(relativeEnd, len);
1054   // Step 8.
1055   var count = std_Math_max(final - k, 0);
1057   // Step 9.
1058   var A = TypedArraySpeciesCreateWithLength(O, count);
1060   // Steps 14-15.
1061   if (count > 0) {
1062     // Steps 10-13, 15.
1063     var sliced = TypedArrayBitwiseSlice(O, A, k, count);
1065     // Step 14.
1066     if (!sliced) {
1067       // Adjust |final| in case |O| has been resized.
1068       //
1069       // https://tc39.es/proposal-resizablearraybuffer/#sec-%typedarray%.prototype.slice
1070       final = std_Math_min(final, TypedArrayLength(O));
1072       // Step 14.a.
1073       var n = 0;
1075       // Step 14.b.
1076       while (k < final) {
1077         // Steps 14.b.i-v.
1078         A[n++] = O[k++];
1079       }
1080     }
1081   }
1083   // Step 16.
1084   return A;
1087 // ES2021 draft rev 190d474c3d8728653fbf8a5a37db1de34b9c1472
1088 // Plus <https://github.com/tc39/ecma262/pull/2221>
1089 // 22.2.3.25 %TypedArray%.prototype.some ( callbackfn [ , thisArg ] )
1090 function TypedArraySome(callbackfn /*, thisArg*/) {
1091   // Step 1.
1092   var O = this;
1094   // Step 2.
1095   EnsureTypedArrayWithArrayBuffer(O);
1097   // If we got here, `this` is either a typed array or a wrapper for one.
1099   // Step 3.
1100   var len = PossiblyWrappedTypedArrayLength(O);
1102   // Step 4.
1103   if (ArgumentsLength() === 0) {
1104     ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.some");
1105   }
1106   if (!IsCallable(callbackfn)) {
1107     ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
1108   }
1110   var thisArg = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
1112   // Steps 5-6.
1113   for (var k = 0; k < len; k++) {
1114     // Steps 6.a-b.
1115     var kValue = O[k];
1117     // Step 6.c.
1118     var testResult = callContentFunction(callbackfn, thisArg, kValue, k, O);
1120     // Step 6.d.
1121     if (testResult) {
1122       return true;
1123     }
1124   }
1126   // Step 7.
1127   return false;
1129 // Inlining this enables inlining of the callback function.
1130 SetIsInlinableLargeFunction(TypedArraySome);
1132 // To satisfy step 6.b from TypedArray SortCompare described in 23.2.3.29 the
1133 // user supplied comparefn is wrapped.
1134 function TypedArraySortCompare(comparefn) {
1135   return function(x, y) {
1136     // Step 6.b.i.
1137     var v = +callContentFunction(comparefn, undefined, x, y);
1139     // Step 6.b.ii.
1140     if (v !== v) {
1141       return 0;
1142     }
1144     // Step 6.b.iii.
1145     return v;
1146   };
1149 // ES2019 draft rev 8a16cb8d18660a1106faae693f0f39b9f1a30748
1150 // 22.2.3.26 %TypedArray%.prototype.sort ( comparefn )
1151 function TypedArraySort(comparefn) {
1152   // This function is not generic.
1154   // Step 1.
1155   if (comparefn !== undefined) {
1156     if (!IsCallable(comparefn)) {
1157       ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, comparefn));
1158     }
1159   }
1161   // Step 2.
1162   var obj = this;
1164   // Step 3.
1165   EnsureTypedArrayWithArrayBuffer(obj);
1167   // Step 4.
1168   var len = PossiblyWrappedTypedArrayLength(obj);
1170   // Arrays with less than two elements remain unchanged when sorted.
1171   if (len <= 1) {
1172     return obj;
1173   }
1175   if (comparefn === undefined) {
1176     return TypedArrayNativeSort(obj);
1177   }
1179   // Steps 5-6.
1180   var wrappedCompareFn = TypedArraySortCompare(comparefn);
1182   // Step 7.
1183   var sorted = MergeSortTypedArray(obj, len, wrappedCompareFn);
1185   // Move the sorted elements into the array.
1186   for (var i = 0; i < len; i++) {
1187     obj[i] = sorted[i];
1188   }
1190   return obj;
1193 // ES2017 draft rev f8a9be8ea4bd97237d176907a1e3080dce20c68f
1194 //   22.2.3.28 %TypedArray%.prototype.toLocaleString ([ reserved1 [ , reserved2 ] ])
1195 // ES2017 Intl draft rev 78bbe7d1095f5ff3760ac4017ed366026e4cb276
1196 //   13.4.1 Array.prototype.toLocaleString ([ locales [ , options ]])
1197 function TypedArrayToLocaleString(locales = undefined, options = undefined) {
1198   // ValidateTypedArray, then step 1.
1199   var array = this;
1201   // This function is not generic.
1202   // We want to make sure that we have an attached buffer, per spec prose.
1203   EnsureTypedArrayWithArrayBuffer(array);
1205   // If we got here, `this` is either a typed array or a wrapper for one.
1207   // Step 2.
1208   var len = PossiblyWrappedTypedArrayLength(array);
1210   // Step 4.
1211   if (len === 0) {
1212     return "";
1213   }
1215   // Step 5.
1216   var firstElement = array[0];
1217   assert(
1218     typeof firstElement === "number" || typeof firstElement === "bigint",
1219     "TypedArray elements are either Numbers or BigInts"
1220   );
1222   // Steps 6-7.
1223   // Omit the 'if' clause in step 6, since non-empty typed arrays can't have
1224   // undefined or null elements.
1225 #if JS_HAS_INTL_API
1226   var R = ToString(
1227     callContentFunction(
1228       firstElement.toLocaleString,
1229       firstElement,
1230       locales,
1231       options
1232     )
1233   );
1234 #else
1235   var R = ToString(
1236     callContentFunction(firstElement.toLocaleString, firstElement)
1237   );
1238 #endif
1240   // Step 3 (reordered).
1241   // We don't (yet?) implement locale-dependent separators.
1242   var separator = ",";
1244   // Steps 8-9.
1245   for (var k = 1; k < len; k++) {
1246     // Step 9.a.
1247     R += separator;
1249     // Step 9.b.
1250     var nextElement = array[k];
1252     // Step 9.c.
1253     if (nextElement === undefined) {
1254       continue;
1255     }
1256     assert(
1257       typeof nextElement === "number" || typeof nextElement === "bigint",
1258       "TypedArray elements are either Numbers or BigInts"
1259     );
1261     // Steps 9.d-e.
1262 #if JS_HAS_INTL_API
1263     R += ToString(
1264       callContentFunction(
1265         nextElement.toLocaleString,
1266         nextElement,
1267         locales,
1268         options
1269       )
1270     );
1271 #else
1272     R += ToString(callContentFunction(nextElement.toLocaleString, nextElement));
1273 #endif
1274   }
1276   // Step 10.
1277   return R;
1280 // ES2020 draft rev dc1e21c454bd316810be1c0e7af0131a2d7f38e9
1281 // 22.2.3.27 %TypedArray%.prototype.subarray ( begin, end )
1282 function TypedArraySubarray(begin, end) {
1283   // Step 1.
1284   var obj = this;
1286   // Steps 2-3.
1287   // This function is not generic.
1288   if (!IsObject(obj) || !IsTypedArray(obj)) {
1289     return callFunction(
1290       CallTypedArrayMethodIfWrapped,
1291       this,
1292       begin,
1293       end,
1294       "TypedArraySubarray"
1295     );
1296   }
1298   // Step 4.
1299   var buffer = ViewedArrayBufferIfReified(obj);
1300   if (buffer === null) {
1301     buffer = TypedArrayBuffer(obj);
1302   }
1304   // Step 5.
1305   var srcLength = TypedArrayLengthZeroOnOutOfBounds(obj);
1307   // Step 13 (Reordered because otherwise it'd be observable that we reset
1308   // the byteOffset to zero when the underlying array buffer gets detached).
1309   var srcByteOffset = TypedArrayByteOffset(obj);
1311   // Step 6.
1312   var relativeBegin = ToInteger(begin);
1314   // Step 7.
1315   var beginIndex =
1316     relativeBegin < 0
1317       ? std_Math_max(srcLength + relativeBegin, 0)
1318       : std_Math_min(relativeBegin, srcLength);
1320   // Steps 11-12. (Reordered)
1321   var elementSize = TypedArrayElementSize(obj);
1323   // Step 14. (Reordered)
1324   var beginByteOffset = srcByteOffset + beginIndex * elementSize;
1326   if (end === undefined && TypedArrayIsAutoLength(obj)) {
1327     return TypedArraySpeciesCreateWithResizableBuffer(
1328       obj,
1329       buffer,
1330       beginByteOffset
1331     );
1332   }
1334   // Step 8.
1335   var relativeEnd = end === undefined ? srcLength : ToInteger(end);
1337   // Step 9.
1338   var endIndex =
1339     relativeEnd < 0
1340       ? std_Math_max(srcLength + relativeEnd, 0)
1341       : std_Math_min(relativeEnd, srcLength);
1343   // Step 10.
1344   var newLength = std_Math_max(endIndex - beginIndex, 0);
1346   // Steps 15-16.
1347   return TypedArraySpeciesCreateWithBuffer(
1348     obj,
1349     buffer,
1350     beginByteOffset,
1351     newLength
1352   );
1355 // https://tc39.es/proposal-relative-indexing-method
1356 // %TypedArray%.prototype.at ( index )
1357 function TypedArrayAt(index) {
1358   // Step 1.
1359   var obj = this;
1361   // Step 2.
1362   // This function is not generic.
1363   if (!IsObject(obj) || !IsTypedArray(obj)) {
1364     return callFunction(
1365       CallTypedArrayMethodIfWrapped,
1366       obj,
1367       index,
1368       "TypedArrayAt"
1369     );
1370   }
1371   GetAttachedArrayBuffer(obj);
1373   // Step 3.
1374   var len = TypedArrayLength(obj);
1376   // Step 4.
1377   var relativeIndex = ToInteger(index);
1379   // Steps 5-6.
1380   var k;
1381   if (relativeIndex >= 0) {
1382     k = relativeIndex;
1383   } else {
1384     k = len + relativeIndex;
1385   }
1387   // Step 7.
1388   if (k < 0 || k >= len) {
1389     return undefined;
1390   }
1392   // Step 8.
1393   return obj[k];
1395 // This function is only barely too long for normal inlining.
1396 SetIsInlinableLargeFunction(TypedArrayAt);
1398 // https://github.com/tc39/proposal-array-find-from-last
1399 // %TypedArray%.prototype.findLast ( predicate, thisArg )
1400 function TypedArrayFindLast(predicate /*, thisArg*/) {
1401   // Step 1.
1402   var O = this;
1404   // Step 2.
1405   EnsureTypedArrayWithArrayBuffer(O);
1407   // If we got here, `this` is either a typed array or a wrapper for one.
1409   // Step 3.
1410   var len = PossiblyWrappedTypedArrayLength(O);
1412   // Step 4.
1413   if (ArgumentsLength() === 0) {
1414     ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.findLast");
1415   }
1416   if (!IsCallable(predicate)) {
1417     ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate));
1418   }
1420   var thisArg = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
1422   // Steps 5-6.
1423   for (var k = len - 1; k >= 0; k--) {
1424     // Steps 6.a-b.
1425     var kValue = O[k];
1427     // Steps 6.c-d.
1428     if (callContentFunction(predicate, thisArg, kValue, k, O)) {
1429       return kValue;
1430     }
1431   }
1433   // Step 7.
1434   return undefined;
1436 // Inlining this enables inlining of the callback function.
1437 SetIsInlinableLargeFunction(TypedArrayFindLast);
1439 // https://github.com/tc39/proposal-array-find-from-last
1440 // %TypedArray%.prototype.findLastIndex ( predicate, thisArg )
1441 function TypedArrayFindLastIndex(predicate /*, thisArg*/) {
1442   // Step 1.
1443   var O = this;
1445   // Step 2.
1446   EnsureTypedArrayWithArrayBuffer(O);
1448   // If we got here, `this` is either a typed array or a wrapper for one.
1450   // Step 3.
1451   var len = PossiblyWrappedTypedArrayLength(O);
1453   // Step 4.
1454   if (ArgumentsLength() === 0) {
1455     ThrowTypeError(
1456       JSMSG_MISSING_FUN_ARG,
1457       0,
1458       "%TypedArray%.prototype.findLastIndex"
1459     );
1460   }
1461   if (!IsCallable(predicate)) {
1462     ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate));
1463   }
1465   var thisArg = ArgumentsLength() > 1 ? GetArgument(1) : undefined;
1467   // Steps 5-6.
1468   for (var k = len - 1; k >= 0; k--) {
1469     // Steps 6.a-f.
1470     if (callContentFunction(predicate, thisArg, O[k], k, O)) {
1471       return k;
1472     }
1473   }
1475   // Step 7.
1476   return -1;
1478 // Inlining this enables inlining of the callback function.
1479 SetIsInlinableLargeFunction(TypedArrayFindLastIndex);
1481 // ES6 draft rev30 (2014/12/24) 22.2.3.30 %TypedArray%.prototype.values()
1483 // Uncloned functions with `$` prefix are allocated as extended function
1484 // to store the original name in `SetCanonicalName`.
1485 function $TypedArrayValues() {
1486   // Step 1.
1487   var O = this;
1489   // See the big comment in TypedArrayEntries for what we're doing here.
1490   EnsureTypedArrayWithArrayBuffer(O);
1491   PossiblyWrappedTypedArrayLength(O);
1493   // Step 7.
1494   return CreateArrayIterator(O, ITEM_KIND_VALUE);
1496 SetCanonicalName($TypedArrayValues, "values");
1498 // ES2021 draft rev 190d474c3d8728653fbf8a5a37db1de34b9c1472
1499 // Plus <https://github.com/tc39/ecma262/pull/2221>
1500 // 22.2.3.13 %TypedArray%.prototype.includes ( searchElement [ , fromIndex ] )
1501 function TypedArrayIncludes(searchElement, fromIndex = 0) {
1502   // Step 2.
1503   if (!IsObject(this) || !IsTypedArray(this)) {
1504     return callFunction(
1505       CallTypedArrayMethodIfWrapped,
1506       this,
1507       searchElement,
1508       fromIndex,
1509       "TypedArrayIncludes"
1510     );
1511   }
1513   GetAttachedArrayBuffer(this);
1515   // Step 1.
1516   var O = this;
1518   // Step 3.
1519   var len = TypedArrayLength(O);
1521   // Step 4.
1522   if (len === 0) {
1523     return false;
1524   }
1526   // Step 5.
1527   var n = ToInteger(fromIndex);
1529   // Step 6.
1530   assert(fromIndex !== undefined || n === 0, "ToInteger(undefined) is zero");
1532   // Steps 7-10.
1533   // Steps 7-8 are handled implicitly.
1534   var k;
1535   if (n >= 0) {
1536     // Step 9.a
1537     k = n;
1538   } else {
1539     // Step 10.a.
1540     k = len + n;
1542     // Step 10.b.
1543     if (k < 0) {
1544       k = 0;
1545     }
1546   }
1548   // Step 11.
1549   while (k < len) {
1550     // Steps 11.a-b.
1551     if (SameValueZero(searchElement, O[k])) {
1552       return true;
1553     }
1555     // Step 11.c.
1556     k++;
1557   }
1559   // Step 12.
1560   return false;
1563 // ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
1564 // 22.2.2.1 %TypedArray%.from ( source [ , mapfn [ , thisArg ] ] )
1565 function TypedArrayStaticFrom(source, mapfn = undefined, thisArg = undefined) {
1566   // Step 1.
1567   var C = this;
1569   // Step 2.
1570   if (!IsConstructor(C)) {
1571     ThrowTypeError(JSMSG_NOT_CONSTRUCTOR, typeof C);
1572   }
1574   // Step 3.
1575   var mapping;
1576   if (mapfn !== undefined) {
1577     // Step 3.a.
1578     if (!IsCallable(mapfn)) {
1579       ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, mapfn));
1580     }
1582     // Step 3.b.
1583     mapping = true;
1584   } else {
1585     // Step 4.
1586     mapping = false;
1587   }
1589   // Step 5.
1590   var T = thisArg;
1592   // Step 6.
1593   // Inlined: GetMethod, steps 1-2.
1594   var usingIterator = source[GetBuiltinSymbol("iterator")];
1596   // Step 7.
1597   // Inlined: GetMethod, step 3.
1598   if (usingIterator !== undefined && usingIterator !== null) {
1599     // Inlined: GetMethod, step 4.
1600     if (!IsCallable(usingIterator)) {
1601       ThrowTypeError(JSMSG_NOT_ITERABLE, DecompileArg(0, source));
1602     }
1604     // Try to take a fast path when there's no mapper function and the
1605     // constructor is a built-in TypedArray constructor.
1606     if (!mapping && IsTypedArrayConstructor(C) && IsObject(source)) {
1607       // The source is a TypedArray using the default iterator.
1608       if (
1609         usingIterator === $TypedArrayValues &&
1610         IsTypedArray(source) &&
1611         ArrayIteratorPrototypeOptimizable()
1612       ) {
1613         // Step 7.a.
1614         // Omitted but we still need to throw if |source| was detached.
1615         GetAttachedArrayBuffer(source);
1617         // Step 7.b.
1618         var len = TypedArrayLength(source);
1620         // Step 7.c.
1621         var targetObj = constructContentFunction(C, C, len);
1623         // Steps 7.d-f.
1624         for (var k = 0; k < len; k++) {
1625           targetObj[k] = source[k];
1626         }
1628         // Step 7.g.
1629         return targetObj;
1630       }
1632       // The source is a packed array using the default iterator.
1633       if (
1634         usingIterator === $ArrayValues &&
1635         IsPackedArray(source) &&
1636         ArrayIteratorPrototypeOptimizable()
1637       ) {
1638         // Steps 7.b-c.
1639         var targetObj = constructContentFunction(C, C, source.length);
1641         // Steps 7.a, 7.d-f.
1642         TypedArrayInitFromPackedArray(targetObj, source);
1644         // Step 7.g.
1645         return targetObj;
1646       }
1647     }
1649     // Step 7.a.
1650     var values = IterableToList(source, usingIterator);
1652     // Step 7.b.
1653     var len = values.length;
1655     // Step 7.c.
1656     var targetObj = TypedArrayCreateWithLength(C, len);
1658     // Steps 7.d-e.
1659     for (var k = 0; k < len; k++) {
1660       // Step 7.e.ii.
1661       var kValue = values[k];
1663       // Steps 7.e.iii-iv.
1664       var mappedValue = mapping
1665         ? callContentFunction(mapfn, T, kValue, k)
1666         : kValue;
1668       // Step 7.e.v.
1669       targetObj[k] = mappedValue;
1670     }
1672     // Step 7.f.
1673     // Asserting that `values` is empty here would require removing them one by one from
1674     // the list's start in the loop above. That would introduce unacceptable overhead.
1675     // Additionally, the loop's logic is simple enough not to require the assert.
1677     // Step 7.g.
1678     return targetObj;
1679   }
1681   // Step 8 is an assertion: items is not an Iterator. Testing this is
1682   // literally the very last thing we did, so we don't assert here.
1684   // Step 9.
1685   var arrayLike = ToObject(source);
1687   // Step 10.
1688   var len = ToLength(arrayLike.length);
1690   // Step 11.
1691   var targetObj = TypedArrayCreateWithLength(C, len);
1693   // Steps 12-13.
1694   for (var k = 0; k < len; k++) {
1695     // Steps 13.a-b.
1696     var kValue = arrayLike[k];
1698     // Steps 13.c-d.
1699     var mappedValue = mapping
1700       ? callContentFunction(mapfn, T, kValue, k)
1701       : kValue;
1703     // Step 13.e.
1704     targetObj[k] = mappedValue;
1705   }
1707   // Step 14.
1708   return targetObj;
1711 // ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
1712 // 22.2.2.2 %TypedArray%.of ( ...items )
1713 function TypedArrayStaticOf(/*...items*/) {
1714   // Step 1.
1715   var len = ArgumentsLength();
1717   // Step 2 (implicit).
1719   // Step 3.
1720   var C = this;
1722   // Step 4.
1723   if (!IsConstructor(C)) {
1724     ThrowTypeError(JSMSG_NOT_CONSTRUCTOR, typeof C);
1725   }
1727   // Step 5.
1728   var newObj = TypedArrayCreateWithLength(C, len);
1730   // Steps 6-7.
1731   for (var k = 0; k < len; k++) {
1732     newObj[k] = GetArgument(k);
1733   }
1735   // Step 8.
1736   return newObj;
1739 // ES 2016 draft Mar 25, 2016 22.2.2.4.
1740 function $TypedArraySpecies() {
1741   // Step 1.
1742   return this;
1744 SetCanonicalName($TypedArraySpecies, "get [Symbol.species]");
1746 // ES2018 draft rev 0525bb33861c7f4e9850f8a222c89642947c4b9c
1747 // 22.2.2.1.1 Runtime Semantics: IterableToList( items, method )
1748 function IterableToList(items, method) {
1749   // Step 1 (Inlined GetIterator).
1751   // 7.4.1 GetIterator, step 1.
1752   assert(IsCallable(method), "method argument is a function");
1754   // 7.4.1 GetIterator, step 2.
1755   var iterator = callContentFunction(method, items);
1757   // 7.4.1 GetIterator, step 3.
1758   if (!IsObject(iterator)) {
1759     ThrowTypeError(JSMSG_GET_ITER_RETURNED_PRIMITIVE);
1760   }
1762   // 7.4.1 GetIterator, step 4.
1763   var nextMethod = iterator.next;
1765   // Step 2.
1766   var values = [];
1768   // Steps 3-4.
1769   var i = 0;
1770   while (true) {
1771     // Step 4.a.
1772     var next = callContentFunction(nextMethod, iterator);
1773     if (!IsObject(next)) {
1774       ThrowTypeError(JSMSG_ITER_METHOD_RETURNED_PRIMITIVE, "next");
1775     }
1777     // Step 4.b.
1778     if (next.done) {
1779       break;
1780     }
1781     DefineDataProperty(values, i++, next.value);
1782   }
1784   // Step 5.
1785   return values;
1788 // ES2020 draft rev dc1e21c454bd316810be1c0e7af0131a2d7f38e9
1789 // 24.1.4.3 ArrayBuffer.prototype.slice ( start, end )
1790 function ArrayBufferSlice(start, end) {
1791   // Step 1.
1792   var O = this;
1794   // Steps 2-3,
1795   // This function is not generic.
1796   if (!IsObject(O) || (O = GuardToArrayBuffer(O)) === null) {
1797     return callFunction(
1798       CallArrayBufferMethodIfWrapped,
1799       this,
1800       start,
1801       end,
1802       "ArrayBufferSlice"
1803     );
1804   }
1806   // Step 4.
1807   if (IsDetachedBuffer(O)) {
1808     ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
1809   }
1811   // Step 5.
1812   var len = ArrayBufferByteLength(O);
1814   // Step 6.
1815   var relativeStart = ToInteger(start);
1817   // Step 7.
1818   var first =
1819     relativeStart < 0
1820       ? std_Math_max(len + relativeStart, 0)
1821       : std_Math_min(relativeStart, len);
1823   // Step 8.
1824   var relativeEnd = end === undefined ? len : ToInteger(end);
1826   // Step 9.
1827   var final =
1828     relativeEnd < 0
1829       ? std_Math_max(len + relativeEnd, 0)
1830       : std_Math_min(relativeEnd, len);
1832   // Step 10.
1833   var newLen = std_Math_max(final - first, 0);
1835   // Step 11
1836   var ctor = SpeciesConstructor(O, GetBuiltinConstructor("ArrayBuffer"));
1838   // Step 12.
1839   var new_ = constructContentFunction(ctor, ctor, newLen);
1841   // Steps 13-15.
1842   var isWrapped = false;
1843   var newBuffer;
1844   if ((newBuffer = GuardToArrayBuffer(new_)) !== null) {
1845     // Step 15.
1846     if (IsDetachedBuffer(newBuffer)) {
1847       ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
1848     }
1849   } else {
1850     newBuffer = new_;
1852     // Steps 13-14.
1853     if (!IsWrappedArrayBuffer(newBuffer)) {
1854       ThrowTypeError(JSMSG_NON_ARRAY_BUFFER_RETURNED);
1855     }
1857     isWrapped = true;
1859     // Step 15.
1860     if (
1861       callFunction(
1862         CallArrayBufferMethodIfWrapped,
1863         newBuffer,
1864         "IsDetachedBufferThis"
1865       )
1866     ) {
1867       ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
1868     }
1869   }
1871   // Step 16.
1872   if (newBuffer === O) {
1873     ThrowTypeError(JSMSG_SAME_ARRAY_BUFFER_RETURNED);
1874   }
1876   // Step 17.
1877   var actualLen = PossiblyWrappedArrayBufferByteLength(newBuffer);
1878   if (actualLen < newLen) {
1879     ThrowTypeError(JSMSG_SHORT_ARRAY_BUFFER_RETURNED, newLen, actualLen);
1880   }
1882   // Steps 18-19.
1883   if (IsDetachedBuffer(O)) {
1884     ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
1885   }
1887   // Steps 20-22.
1888   //
1889   // Reacquire the length in case the buffer has been resized.
1890   var currentLen = ArrayBufferByteLength(O);
1892   if (first < currentLen) {
1893     var count = std_Math_min(newLen, currentLen - first);
1894     ArrayBufferCopyData(newBuffer, 0, O, first, count, isWrapped);
1895   }
1897   // Step 23.
1898   return newBuffer;
1901 function IsDetachedBufferThis() {
1902   return IsDetachedBuffer(this);
1905 // ES 2016 draft Mar 25, 2016 24.1.3.3.
1906 function $ArrayBufferSpecies() {
1907   // Step 1.
1908   return this;
1910 SetCanonicalName($ArrayBufferSpecies, "get [Symbol.species]");
1912 // Shared memory and atomics proposal (30 Oct 2016)
1913 function $SharedArrayBufferSpecies() {
1914   // Step 1.
1915   return this;
1917 SetCanonicalName($SharedArrayBufferSpecies, "get [Symbol.species]");
1919 // ES2020 draft rev dc1e21c454bd316810be1c0e7af0131a2d7f38e9
1920 // 24.2.4.3 SharedArrayBuffer.prototype.slice ( start, end )
1921 function SharedArrayBufferSlice(start, end) {
1922   // Step 1.
1923   var O = this;
1925   // Steps 2-3.
1926   // This function is not generic.
1927   if (!IsObject(O) || (O = GuardToSharedArrayBuffer(O)) === null) {
1928     return callFunction(
1929       CallSharedArrayBufferMethodIfWrapped,
1930       this,
1931       start,
1932       end,
1933       "SharedArrayBufferSlice"
1934     );
1935   }
1937   // Step 4.
1938   var len = SharedArrayBufferByteLength(O);
1940   // Step 5.
1941   var relativeStart = ToInteger(start);
1943   // Step 6.
1944   var first =
1945     relativeStart < 0
1946       ? std_Math_max(len + relativeStart, 0)
1947       : std_Math_min(relativeStart, len);
1949   // Step 7.
1950   var relativeEnd = end === undefined ? len : ToInteger(end);
1952   // Step 8.
1953   var final =
1954     relativeEnd < 0
1955       ? std_Math_max(len + relativeEnd, 0)
1956       : std_Math_min(relativeEnd, len);
1958   // Step 9.
1959   var newLen = std_Math_max(final - first, 0);
1961   // Step 10
1962   var ctor = SpeciesConstructor(O, GetBuiltinConstructor("SharedArrayBuffer"));
1964   // Step 11.
1965   var new_ = constructContentFunction(ctor, ctor, newLen);
1967   // Steps 12-13.
1968   var isWrapped = false;
1969   var newObj;
1970   if ((newObj = GuardToSharedArrayBuffer(new_)) === null) {
1971     if (!IsWrappedSharedArrayBuffer(new_)) {
1972       ThrowTypeError(JSMSG_NON_SHARED_ARRAY_BUFFER_RETURNED);
1973     }
1974     isWrapped = true;
1975     newObj = new_;
1976   }
1978   // Step 14.
1979   if (newObj === O || SharedArrayBuffersMemorySame(newObj, O)) {
1980     ThrowTypeError(JSMSG_SAME_SHARED_ARRAY_BUFFER_RETURNED);
1981   }
1983   // Step 15.
1984   var actualLen = PossiblyWrappedSharedArrayBufferByteLength(newObj);
1985   if (actualLen < newLen) {
1986     ThrowTypeError(JSMSG_SHORT_SHARED_ARRAY_BUFFER_RETURNED, newLen, actualLen);
1987   }
1989   // Steps 16-18.
1990   SharedArrayBufferCopyData(newObj, 0, O, first, newLen, isWrapped);
1992   // Step 19.
1993   return newObj;
1996 // https://github.com/tc39/proposal-change-array-by-copy
1997 function TypedArrayCreateSameType(exemplar, length) {
1998   // Step 1. Assert: exemplar is an Object that has [[TypedArrayName]] and [[ContentType]] internal slots.
1999   assert(
2000     IsPossiblyWrappedTypedArray(exemplar),
2001     "in TypedArrayCreateSameType, exemplar does not have a [[ContentType]] internal slot"
2002   );
2004   // Step 2. Let constructor be the intrinsic object listed in column one of Table 63 for exemplar.[[TypedArrayName]].
2005   var constructor = ConstructorForTypedArray(exemplar);
2007   // Step 4 omitted. Assert: result has [[TypedArrayName]] and [[ContentType]] internal slots. - guaranteed by the TypedArray implementation
2008   // Step 5 omitted. Assert: result.[[ContentType]] is exemplar.[[ContentType]]. - guaranteed by the typed array implementation
2010   // Step 3. Let result be ? TypedArrayCreate(constructor, argumentList).
2011   // Step 6. Return result.
2012   return TypedArrayCreateWithLength(constructor, length);
2015 // https://github.com/tc39/proposal-change-array-by-copy
2016 // TypedArray.prototype.toReversed()
2017 function TypedArrayToReversed() {
2018   // Step 2. Perform ? ValidateTypedArray(O).
2019   if (!IsObject(this) || !IsTypedArray(this)) {
2020     return callFunction(
2021       CallTypedArrayMethodIfWrapped,
2022       this,
2023       "TypedArrayToReversed"
2024     );
2025   }
2027   GetAttachedArrayBuffer(this);
2029   // Step 1. Let O be the this value.
2030   var O = this;
2032   // Step 3. Let length be O.[[ArrayLength]].
2033   var len = TypedArrayLength(O);
2035   // Step 4. Let A be ? TypedArrayCreateSameType(O, « 𝔽(length) »).
2036   var A = TypedArrayCreateSameType(O, len);
2038   // Step 5. Let k be 0.
2039   // Step 6. Repeat, while k < length,
2040   for (var k = 0; k < len; k++) {
2041     // Step 5.a. Let from be ! ToString(𝔽(length - k - 1)).
2042     var from = len - k - 1;
2043     // Step 5.b. omitted - Let Pk be ! ToString(𝔽(k)).
2044     // k coerced to String by property access
2045     // Step 5.c. Let fromValue be ! Get(O, from).
2046     var fromValue = O[from];
2047     // Step 5.d. Perform ! Set(A, k, kValue, true).
2048     A[k] = fromValue;
2049   }
2051   // Step 7. Return A.
2052   return A;
2055 // https://github.com/tc39/proposal-change-array-by-copy
2056 // TypedArray.prototype.with()
2057 function TypedArrayWith(index, value) {
2058   // Step 2. Perform ? ValidateTypedArray(O).
2059   if (!IsObject(this) || !IsTypedArray(this)) {
2060     return callFunction(
2061       CallTypedArrayMethodIfWrapped,
2062       this,
2063       index,
2064       value,
2065       "TypedArrayWith"
2066     );
2067   }
2069   GetAttachedArrayBuffer(this);
2071   // Step 1. Let O be the this value.
2072   var O = this;
2074   // Step 3. Let len be O.[[ArrayLength]].
2075   var len = TypedArrayLength(O);
2077   // Step 4. Let relativeIndex be ? ToIntegerOrInfinity(index).
2078   var relativeIndex = ToInteger(index);
2080   var actualIndex;
2081   if (relativeIndex >= 0) {
2082     // Step 5. If relativeIndex ≥ 0, let actualIndex be relativeIndex.
2083     actualIndex = relativeIndex;
2084   } else {
2085     // Step 6. Else, let actualIndex be len + relativeIndex.
2086     actualIndex = len + relativeIndex;
2087   }
2089   var kind = GetTypedArrayKind(O);
2090   if (kind === TYPEDARRAY_KIND_BIGINT64 || kind === TYPEDARRAY_KIND_BIGUINT64) {
2091     // Step 7. If O.[[ContentType]] is BigInt, set value to ? ToBigInt(value).
2092     value = ToBigInt(value);
2093   } else {
2094     // Step 8. Else, set value to ? ToNumber(value).
2095     value = ToNumber(value);
2096   }
2098   // Reload the array length in case the underlying buffer has been detached or resized.
2099   var currentLen = TypedArrayLengthZeroOnOutOfBounds(O);
2100   assert(
2101     !IsDetachedBuffer(ViewedArrayBufferIfReified(O)) || currentLen === 0,
2102     "length is set to zero when the buffer has been detached"
2103   );
2105   // Step 9. If ! IsValidIntegerIndex(O, 𝔽(actualIndex)) is false, throw a RangeError exception.
2106   // This check is an inlined version of the IsValidIntegerIndex abstract operation.
2107   if (actualIndex < 0 || actualIndex >= currentLen) {
2108     ThrowRangeError(JSMSG_BAD_INDEX);
2109   }
2111   // Step 10. Let A be ? TypedArrayCreateSameType(O, « 𝔽(len) »).
2112   var A = TypedArrayCreateSameType(O, len);
2114   // Step 11. Let k be 0.
2115   // Step 12. Repeat, while k < len,
2116   for (var k = 0; k < len; k++) {
2117     // Step 12.a. omitted - Let Pk be ! ToString(𝔽(k)).
2118     // k coerced to String by property access
2120     // Step 12.b. If k is actualIndex, let fromValue be value.
2121     // Step 12.c. Else, let fromValue be ! Get(O, Pk).
2122     var fromValue = k === actualIndex ? value : O[k];
2124     // Step 12.d. Perform ! Set(A, Pk, fromValue, true).
2125     A[k] = fromValue;
2126   }
2128   // Step 13.
2129   return A;
2132 // https://github.com/tc39/proposal-change-array-by-copy
2133 // TypedArray.prototype.toSorted()
2134 function TypedArrayToSorted(comparefn) {
2135   // Step 1. If comparefn is not undefined and IsCallable(comparefn) is false, throw a TypeError exception.
2136   if (comparefn !== undefined) {
2137     if (!IsCallable(comparefn)) {
2138       ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, comparefn));
2139     }
2140   }
2142   // Step 2. Let O be the this value.
2143   var O = this;
2145   // Step 3. Perform ? ValidateTypedArray(this).
2146   EnsureTypedArrayWithArrayBuffer(O);
2148   // Step 4. omitted.  Let buffer be obj.[[ViewedArrayBuffer]].
2149   // FIXME: Draft spec not synched with https://github.com/tc39/ecma262/pull/2723
2151   // Step 5. Let len be O.[[ArrayLength]].
2152   var len = PossiblyWrappedTypedArrayLength(O);
2154   // Arrays with less than two elements remain unchanged when sorted.
2155   if (len <= 1) {
2156     // Step 6. Let A be ? TypedArrayCreateSameType(O, « 𝔽(len) »).
2157     var A = TypedArrayCreateSameType(O, len);
2159     // Steps 7-11.
2160     if (len > 0) {
2161       A[0] = O[0];
2162     }
2164     // Step 12.
2165     return A;
2166   }
2168   if (comparefn === undefined) {
2169     // Step 6. Let A be ? TypedArrayCreateSameType(O, « 𝔽(len) »).
2170     var A = TypedArrayCreateSameType(O, len);
2172     // Steps 7-11 not followed exactly; this implementation copies the list and then
2173     // sorts the copy, rather than calling a sort method that copies the list and then
2174     // copying the result again.
2176     // Equivalent to steps 10-11.
2177     for (var k = 0; k < len; k++) {
2178       A[k] = O[k];
2179     }
2181     // Equivalent to steps 7-9 and 12.
2182     return TypedArrayNativeSort(A);
2183   }
2185   // Steps 7-8.
2186   var wrappedCompareFn = TypedArraySortCompare(comparefn);
2188   // Steps 6 and 9-12.
2189   //
2190   // MergeSortTypedArray returns a sorted copy - exactly what we need to return.
2191   return MergeSortTypedArray(O, len, wrappedCompareFn);