summaryrefslogtreecommitdiffstats
path: root/js/src/builtin/TypedArray.js
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /js/src/builtin/TypedArray.js
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'js/src/builtin/TypedArray.js')
-rw-r--r--js/src/builtin/TypedArray.js1735
1 files changed, 1735 insertions, 0 deletions
diff --git a/js/src/builtin/TypedArray.js b/js/src/builtin/TypedArray.js
new file mode 100644
index 000000000..4d2d6488f
--- /dev/null
+++ b/js/src/builtin/TypedArray.js
@@ -0,0 +1,1735 @@
+/* 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/. */
+
+#include "TypedObjectConstants.h"
+
+function ViewedArrayBufferIfReified(tarray) {
+ assert(IsTypedArray(tarray), "non-typed array asked for its buffer");
+
+ var buf = UnsafeGetReservedSlot(tarray, JS_TYPEDARRAYLAYOUT_BUFFER_SLOT);
+ assert(buf === null || (IsObject(buf) && (IsArrayBuffer(buf) || IsSharedArrayBuffer(buf))),
+ "unexpected value in buffer slot");
+ return buf;
+}
+
+function IsDetachedBuffer(buffer) {
+ // A typed array with a null buffer has never had its buffer exposed to
+ // become detached.
+ if (buffer === null)
+ return false;
+
+ assert(IsArrayBuffer(buffer) || IsSharedArrayBuffer(buffer),
+ "non-ArrayBuffer passed to IsDetachedBuffer");
+
+ // Shared array buffers are not detachable.
+ //
+ // This check is more expensive than desirable, but IsDetachedBuffer is
+ // only hot for non-shared memory in SetFromNonTypedArray, so there is an
+ // optimization in place there to avoid incurring the cost here. An
+ // alternative is to give SharedArrayBuffer the same layout as ArrayBuffer.
+ if (IsSharedArrayBuffer(buffer))
+ return false;
+
+ var flags = UnsafeGetInt32FromReservedSlot(buffer, JS_ARRAYBUFFER_FLAGS_SLOT);
+ return (flags & JS_ARRAYBUFFER_DETACHED_FLAG) !== 0;
+}
+
+function GetAttachedArrayBuffer(tarray) {
+ var buffer = ViewedArrayBufferIfReified(tarray);
+ if (IsDetachedBuffer(buffer))
+ ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
+ return buffer;
+}
+
+// A function which ensures that the argument is either a typed array or a
+// cross-compartment wrapper for a typed array and that the typed array involved
+// has an attached array buffer. If one of those conditions doesn't hold (wrong
+// kind of argument, or detached array buffer), an exception is thrown. The
+// return value is `true` if the argument is a typed array, `false` if it's a
+// cross-compartment wrapper for a typed array.
+function IsTypedArrayEnsuringArrayBuffer(arg) {
+ if (IsObject(arg) && IsTypedArray(arg)) {
+ GetAttachedArrayBuffer(arg);
+ return true;
+ }
+
+ // This is a bit hacky but gets the job done: the first `arg` is used to
+ // test for a wrapped typed array, the second as an argument to
+ // GetAttachedArrayBuffer.
+ callFunction(CallTypedArrayMethodIfWrapped, arg, arg, "GetAttachedArrayBuffer");
+ return false;
+}
+
+// ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
+// 22.2.3.5.1 Runtime Semantics: ValidateTypedArray ( O )
+function ValidateTypedArray(obj, error) {
+ if (IsObject(obj)) {
+ /* Steps 3-5 (non-wrapped typed arrays). */
+ if (IsTypedArray(obj)) {
+ // GetAttachedArrayBuffer throws for detached array buffers.
+ GetAttachedArrayBuffer(obj);
+ return true;
+ }
+
+ /* Steps 3-5 (wrapped typed arrays). */
+ if (IsPossiblyWrappedTypedArray(obj)) {
+ if (PossiblyWrappedTypedArrayHasDetachedBuffer(obj))
+ ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
+ return false;
+ }
+ }
+
+ /* Steps 1-2. */
+ ThrowTypeError(error);
+}
+
+// ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
+// 22.2.4.6 TypedArrayCreate ( constructor, argumentList )
+function TypedArrayCreateWithLength(constructor, length) {
+ // Step 1.
+ var newTypedArray = new constructor(length);
+
+ // Step 2.
+ var isTypedArray = ValidateTypedArray(newTypedArray, JSMSG_NON_TYPED_ARRAY_RETURNED);
+
+ // Step 3.
+ var len;
+ if (isTypedArray) {
+ len = TypedArrayLength(newTypedArray);
+ } else {
+ len = callFunction(CallTypedArrayMethodIfWrapped, newTypedArray, newTypedArray,
+ "TypedArrayLength");
+ }
+
+ if (len < length)
+ ThrowTypeError(JSMSG_SHORT_TYPED_ARRAY_RETURNED, length, len);
+
+ // Step 4.
+ return newTypedArray;
+}
+
+// ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
+// 22.2.4.6 TypedArrayCreate ( constructor, argumentList )
+function TypedArrayCreateWithBuffer(constructor, buffer, byteOffset, length) {
+ // Step 1.
+ var newTypedArray = new constructor(buffer, byteOffset, length);
+
+ // Step 2.
+ ValidateTypedArray(newTypedArray, JSMSG_NON_TYPED_ARRAY_RETURNED);
+
+ // Step 3 (not applicable).
+
+ // Step 4.
+ return newTypedArray;
+}
+
+// ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
+// 22.2.4.7 TypedArraySpeciesCreate ( exemplar, argumentList )
+function TypedArraySpeciesCreateWithLength(exemplar, length) {
+ // Step 1 (omitted).
+
+ // Step 2.
+ var defaultConstructor = _ConstructorForTypedArray(exemplar);
+
+ // Step 3.
+ var C = SpeciesConstructor(exemplar, defaultConstructor);
+
+ // Step 4.
+ return TypedArrayCreateWithLength(C, length);
+}
+
+// ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
+// 22.2.4.7 TypedArraySpeciesCreate ( exemplar, argumentList )
+function TypedArraySpeciesCreateWithBuffer(exemplar, buffer, byteOffset, length) {
+ // Step 1 (omitted).
+
+ // Step 2.
+ var defaultConstructor = _ConstructorForTypedArray(exemplar);
+
+ // Step 3.
+ var C = SpeciesConstructor(exemplar, defaultConstructor);
+
+ // Step 4.
+ return TypedArrayCreateWithBuffer(C, buffer, byteOffset, length);
+}
+
+// ES6 draft 20150304 %TypedArray%.prototype.copyWithin
+function TypedArrayCopyWithin(target, start, end = undefined) {
+ // This function is not generic.
+ if (!IsObject(this) || !IsTypedArray(this)) {
+ return callFunction(CallTypedArrayMethodIfWrapped, this, target, start, end,
+ "TypedArrayCopyWithin");
+ }
+
+ GetAttachedArrayBuffer(this);
+
+ // Steps 1-2.
+ var obj = this;
+
+ // Steps 3-4, modified for the typed array case.
+ var len = TypedArrayLength(obj);
+
+ assert(0 <= len && len <= 0x7FFFFFFF,
+ "assumed by some of the math below, see also the other assertions");
+
+ // Steps 5-7.
+ var relativeTarget = ToInteger(target);
+
+ var to = relativeTarget < 0 ? std_Math_max(len + relativeTarget, 0)
+ : std_Math_min(relativeTarget, len);
+
+ // Steps 8-10.
+ var relativeStart = ToInteger(start);
+
+ var from = relativeStart < 0 ? std_Math_max(len + relativeStart, 0)
+ : std_Math_min(relativeStart, len);
+
+ // Steps 11-13.
+ var relativeEnd = end === undefined ? len
+ : ToInteger(end);
+
+ var final = relativeEnd < 0 ? std_Math_max(len + relativeEnd, 0)
+ : std_Math_min(relativeEnd, len);
+
+ // Step 14.
+ var count = std_Math_min(final - from, len - to);
+
+ assert(0 <= to && to <= 0x7FFFFFFF,
+ "typed array |to| index assumed int32_t");
+ assert(0 <= from && from <= 0x7FFFFFFF,
+ "typed array |from| index assumed int32_t");
+
+ // Negative counts are possible for cases like tarray.copyWithin(0, 3, 0)
+ // where |count === final - from|. As |to| is within the [0, len] range,
+ // only |final - from| may underflow; with |final| in the range [0, len]
+ // and |from| in the range [0, len] the overall subtraction range is
+ // [-len, len] for |count| -- and with |len| bounded by implementation
+ // limits to 2**31 - 1, there can be no exceeding int32_t.
+ assert(-0x7FFFFFFF - 1 <= count && count <= 0x7FFFFFFF,
+ "typed array element count assumed int32_t");
+
+ // Steps 15-17.
+ //
+ // Note that getting or setting a typed array element must throw if the
+ // underlying buffer is detached, so the intrinsic below checks for
+ // detachment. This happens *only* if a get/set occurs, i.e. when
+ // |count > 0|.
+ //
+ // Also note that this copies elements effectively by memmove, *not* in
+ // step 17's specified order. This is unobservable, but it would be if we
+ // used this method to implement shared typed arrays' copyWithin.
+ if (count > 0)
+ MoveTypedArrayElements(obj, to | 0, from | 0, count | 0);
+
+ // Step 18.
+ return obj;
+}
+
+// ES6 draft rev30 (2014/12/24) 22.2.3.6 %TypedArray%.prototype.entries()
+function TypedArrayEntries() {
+ // Step 1.
+ var O = this;
+
+ // We need to be a bit careful here, because in the Xray case we want to
+ // create the iterator in our current compartment.
+ //
+ // Before doing that, though, we want to check that we have a typed array
+ // and it does not have a detached array buffer. We do the latter by just
+ // calling GetAttachedArrayBuffer() and letting it throw if there isn't one.
+ // In the case when we're not sure we have a typed array (e.g. we might have
+ // a cross-compartment wrapper for one), we can go ahead and call
+ // GetAttachedArrayBuffer via IsTypedArrayEnsuringArrayBuffer; that will
+ // throw if we're not actually a wrapped typed array, or if we have a
+ // detached array buffer.
+
+ // Step 2-6.
+ IsTypedArrayEnsuringArrayBuffer(O);
+
+ // Step 7.
+ return CreateArrayIterator(O, ITEM_KIND_KEY_AND_VALUE);
+}
+
+// ES6 draft rev30 (2014/12/24) 22.2.3.7 %TypedArray%.prototype.every(callbackfn[, thisArg]).
+function TypedArrayEvery(callbackfn/*, thisArg*/) {
+ // Steps 1-2.
+ var O = this;
+
+ // This function is not generic.
+ // We want to make sure that we have an attached buffer, per spec prose.
+ var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+
+ // If we got here, `this` is either a typed array or a cross-compartment
+ // wrapper for one.
+
+ // Steps 3-5.
+ var len;
+ if (isTypedArray)
+ len = TypedArrayLength(O);
+ else
+ len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
+
+ // Step 6.
+ if (arguments.length === 0)
+ ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.every");
+ if (!IsCallable(callbackfn))
+ ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
+
+ // Step 7.
+ var T = arguments.length > 1 ? arguments[1] : void 0;
+
+ // Steps 8-9.
+ // Omit steps 9.a-9.c and the 'if' clause in step 9.d, since there are no holes in typed arrays.
+ for (var k = 0; k < len; k++) {
+ // Steps 9.d.i-9.d.ii.
+ var kValue = O[k];
+
+ // Steps 9.d.iii-9.d.iv.
+ var testResult = callContentFunction(callbackfn, T, kValue, k, O);
+
+ // Step 9.d.v.
+ if (!testResult)
+ return false;
+ }
+
+ // Step 10.
+ return true;
+}
+
+// ES6 draft rev29 (2014/12/06) 22.2.3.8 %TypedArray%.prototype.fill(value [, start [, end ]])
+function TypedArrayFill(value, start = 0, end = undefined) {
+ // This function is not generic.
+ if (!IsObject(this) || !IsTypedArray(this)) {
+ return callFunction(CallTypedArrayMethodIfWrapped, this, value, start, end,
+ "TypedArrayFill");
+ }
+
+ GetAttachedArrayBuffer(this);
+
+ // Steps 1-2.
+ var O = this;
+
+ // Steps 3-5.
+ var len = TypedArrayLength(O);
+
+ // 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;
+}
+
+// ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
+// %TypedArray%.prototype.filter ( callbackfn [ , thisArg ] )
+function TypedArrayFilter(callbackfn/*, thisArg*/) {
+ // Step 1.
+ var O = this;
+
+ // Step 2.
+ // This function is not generic.
+ // We want to make sure that we have an attached buffer, per spec prose.
+ var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+
+ // If we got here, `this` is either a typed array or a cross-compartment
+ // wrapper for one.
+
+ // Step 3.
+ var len;
+ if (isTypedArray)
+ len = TypedArrayLength(O);
+ else
+ len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
+
+ // Step 4.
+ if (arguments.length === 0)
+ ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.filter");
+ if (!IsCallable(callbackfn))
+ ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
+
+ // Step 5.
+ var T = arguments.length > 1 ? arguments[1] : void 0;
+
+ // Step 6.
+ var kept = new List();
+
+ // Step 8.
+ var captured = 0;
+
+ // Steps 7 and 9.e.
+ for (var k = 0; k < len; k++) {
+ // Steps 9.a-b.
+ var kValue = O[k];
+
+ // Step 9.c.
+ var selected = ToBoolean(callContentFunction(callbackfn, T, kValue, k, O));
+
+ // Step 9.d.
+ if (selected) {
+ // Steps 9.d.i-ii.
+ kept[captured++] = kValue;
+ }
+ }
+
+ // Step 10.
+ var A = TypedArraySpeciesCreateWithLength(O, captured);
+
+ // Steps 11 and 12.b.
+ for (var n = 0; n < captured; n++) {
+ // Step 12.a.
+ A[n] = kept[n];
+ }
+
+ // Step 13.
+ return A;
+}
+
+// ES6 draft rev28 (2014/10/14) 22.2.3.10 %TypedArray%.prototype.find(predicate[, thisArg]).
+function TypedArrayFind(predicate/*, thisArg*/) {
+ // Steps 1-2.
+ var O = this;
+
+ // This function is not generic.
+ // We want to make sure that we have an attached buffer, per spec prose.
+ var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+
+ // If we got here, `this` is either a typed array or a cross-compartment
+ // wrapper for one.
+
+ // Steps 3-5.
+ var len;
+ if (isTypedArray)
+ len = TypedArrayLength(O);
+ else
+ len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
+
+ // Step 6.
+ if (arguments.length === 0)
+ ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.find");
+ if (!IsCallable(predicate))
+ ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate));
+
+ // Step 7.
+ var T = arguments.length > 1 ? arguments[1] : void 0;
+
+ // 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 rev28 (2014/10/14) 22.2.3.11 %TypedArray%.prototype.findIndex(predicate[, thisArg]).
+function TypedArrayFindIndex(predicate/*, thisArg*/) {
+ // Steps 1-2.
+ var O = this;
+
+ // This function is not generic.
+ // We want to make sure that we have an attached buffer, per spec prose.
+ var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+
+ // If we got here, `this` is either a typed array or a cross-compartment
+ // wrapper for one.
+
+ // Steps 3-5.
+ var len;
+ if (isTypedArray)
+ len = TypedArrayLength(O);
+ else
+ len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
+
+ // Step 6.
+ if (arguments.length === 0)
+ ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.findIndex");
+ if (!IsCallable(predicate))
+ ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, predicate));
+
+ // Step 7.
+ var T = arguments.length > 1 ? arguments[1] : void 0;
+
+ // 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 rev31 (2015-01-15) 22.1.3.10 %TypedArray%.prototype.forEach(callbackfn[,thisArg])
+function TypedArrayForEach(callbackfn/*, thisArg*/) {
+ // Step 1-2.
+ var O = this;
+
+ // This function is not generic.
+ // We want to make sure that we have an attached buffer, per spec prose.
+ var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+
+ // If we got here, `this` is either a typed array or a cross-compartment
+ // wrapper for one.
+
+ // Step 3-4.
+ var len;
+ if (isTypedArray)
+ len = TypedArrayLength(O);
+ else
+ len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
+
+ // Step 5.
+ if (arguments.length === 0)
+ ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'TypedArray.prototype.forEach');
+ if (!IsCallable(callbackfn))
+ ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
+
+ // Step 6.
+ var T = arguments.length > 1 ? arguments[1] : void 0;
+
+ // Step 7-8.
+ // Step 7, 8a (implicit) and 8e.
+ for (var k = 0; k < len; k++) {
+ // Step 8b-8c are unnecessary since the condition always holds true for TypedArray.
+ // Step 8d.
+ callContentFunction(callbackfn, T, O[k], k, O);
+ }
+
+ // Step 9.
+ return undefined;
+}
+
+// ES6 draft rev29 (2014/12/06) 22.2.3.13 %TypedArray%.prototype.indexOf(searchElement[, fromIndex]).
+function TypedArrayIndexOf(searchElement, fromIndex = 0) {
+ // This function is not generic.
+ if (!IsObject(this) || !IsTypedArray(this)) {
+ return callFunction(CallTypedArrayMethodIfWrapped, this, searchElement, fromIndex,
+ "TypedArrayIndexOf");
+ }
+
+ GetAttachedArrayBuffer(this);
+
+ // Steps 1-2.
+ var O = this;
+
+ // Steps 3-5.
+ var len = TypedArrayLength(O);
+
+ // Step 6.
+ if (len === 0)
+ return -1;
+
+ // Steps 7-8. Add zero to convert -0 to +0, per ES6 5.2.
+ var n = ToInteger(fromIndex) + 0;
+
+ // Step 9.
+ if (n >= len)
+ return -1;
+
+ var k;
+ // Step 10.
+ if (n >= 0) {
+ k = n;
+ }
+ // Step 11.
+ else {
+ // Step a.
+ k = len + n;
+ // Step b.
+ if (k < 0)
+ k = 0;
+ }
+
+ // Step 12.
+ // Omit steps a-b, since there are no holes in typed arrays.
+ for (; k < len; k++) {
+ if (O[k] === searchElement)
+ return k;
+ }
+
+ // Step 13.
+ return -1;
+}
+
+// ES6 draft rev30 (2014/12/24) 22.2.3.14 %TypedArray%.prototype.join(separator).
+function TypedArrayJoin(separator) {
+ // This function is not generic.
+ if (!IsObject(this) || !IsTypedArray(this)) {
+ return callFunction(CallTypedArrayMethodIfWrapped, this, separator, "TypedArrayJoin");
+ }
+
+ GetAttachedArrayBuffer(this);
+
+ // Steps 1-2.
+ var O = this;
+
+ // Steps 3-5.
+ var len = TypedArrayLength(O);
+
+ // Steps 6-7.
+ var sep = separator === undefined ? "," : ToString(separator);
+
+ // Step 8.
+ if (len === 0)
+ return "";
+
+ // Step 9.
+ var element0 = O[0];
+
+ // Steps 10-11.
+ // Omit the 'if' clause in step 10, since typed arrays can't have undefined or null elements.
+ var R = ToString(element0);
+
+ // Steps 12-13.
+ for (var k = 1; k < len; k++) {
+ // Step 13.a.
+ var S = R + sep;
+
+ // Step 13.b.
+ var element = O[k];
+
+ // Steps 13.c-13.d.
+ // Omit the 'if' clause in step 13.c, since typed arrays can't have undefined or null elements.
+ var next = ToString(element);
+
+ // Step 13.e.
+ R = S + next;
+ }
+
+ // Step 14.
+ return R;
+}
+
+// ES6 draft (2016/1/11) 22.2.3.15 %TypedArray%.prototype.keys()
+function TypedArrayKeys() {
+ // Step 1.
+ var O = this;
+
+ // See the big comment in TypedArrayEntries for what we're doing here.
+
+ // Step 2.
+ IsTypedArrayEnsuringArrayBuffer(O);
+
+ // Step 3.
+ return CreateArrayIterator(O, ITEM_KIND_KEY);
+}
+
+// ES6 draft rev29 (2014/12/06) 22.2.3.16 %TypedArray%.prototype.lastIndexOf(searchElement [,fromIndex]).
+function TypedArrayLastIndexOf(searchElement, fromIndex = undefined) {
+ // This function is not generic.
+ if (!IsObject(this) || !IsTypedArray(this)) {
+ return callFunction(CallTypedArrayMethodIfWrapped, this, searchElement, fromIndex,
+ "TypedArrayLastIndexOf");
+ }
+
+ GetAttachedArrayBuffer(this);
+
+ // Steps 1-2.
+ var O = this;
+
+ // Steps 3-5.
+ var len = TypedArrayLength(O);
+
+ // Step 6.
+ if (len === 0)
+ return -1;
+
+ // Steps 7-8. Add zero to convert -0 to +0, per ES6 5.2.
+ var n = fromIndex === undefined ? len - 1 : ToInteger(fromIndex) + 0;
+
+ // Steps 9-10.
+ var k = n >= 0 ? std_Math_min(n, len - 1) : len + n;
+
+ // Step 11.
+ // Omit steps a-b, since there are no holes in typed arrays.
+ for (; k >= 0; k--) {
+ if (O[k] === searchElement)
+ return k;
+ }
+
+ // Step 12.
+ return -1;
+}
+
+// ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
+// 22.2.3.19 %TypedArray%.prototype.map ( callbackfn [ , thisArg ] )
+function TypedArrayMap(callbackfn/*, thisArg*/) {
+ // Step 1.
+ var O = this;
+
+ // Step 2.
+ // This function is not generic.
+ // We want to make sure that we have an attached buffer, per spec prose.
+ var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+
+ // If we got here, `this` is either a typed array or a cross-compartment
+ // wrapper for one.
+
+ // Step 3.
+ var len;
+ if (isTypedArray)
+ len = TypedArrayLength(O);
+ else
+ len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
+
+ // Step 4.
+ if (arguments.length === 0)
+ ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, '%TypedArray%.prototype.map');
+ if (!IsCallable(callbackfn))
+ ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
+
+ // Step 5.
+ var T = arguments.length > 1 ? arguments[1] : void 0;
+
+ // Step 6.
+ var A = TypedArraySpeciesCreateWithLength(O, len);
+
+ // Steps 7, 8.a (implicit) and 8.e.
+ for (var k = 0; k < len; k++) {
+ // Steps 8.b-c.
+ var mappedValue = callContentFunction(callbackfn, T, O[k], k, O);
+
+ // Steps 8.d.
+ A[k] = mappedValue;
+ }
+
+ // Step 9.
+ return A;
+}
+
+// ES6 draft rev30 (2014/12/24) 22.2.3.19 %TypedArray%.prototype.reduce(callbackfn[, initialValue]).
+function TypedArrayReduce(callbackfn/*, initialValue*/) {
+ // Steps 1-2.
+ var O = this;
+
+ // This function is not generic.
+ // We want to make sure that we have an attached buffer, per spec prose.
+ var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+
+ // If we got here, `this` is either a typed array or a cross-compartment
+ // wrapper for one.
+
+ // Steps 3-5.
+ var len;
+ if (isTypedArray)
+ len = TypedArrayLength(O);
+ else
+ len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
+
+ // Step 6.
+ if (arguments.length === 0)
+ ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.reduce");
+ if (!IsCallable(callbackfn))
+ ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
+
+ // Step 7.
+ if (len === 0 && arguments.length === 1)
+ ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE);
+
+ // Step 8.
+ var k = 0;
+
+ // Steps 9-10.
+ // Omit some steps, since 'accumulator' should always be O[0] in step 10 for typed arrays.
+ var accumulator = arguments.length > 1 ? arguments[1] : O[k++];
+
+ // Step 11.
+ // Omit steps 11.b-11.c and the 'if' clause in step 11.d, since there are no holes in typed arrays.
+ for (; k < len; k++) {
+ accumulator = callContentFunction(callbackfn, undefined, accumulator, O[k], k, O);
+ }
+
+ // Step 12.
+ return accumulator;
+}
+
+// ES6 draft rev30 (2014/12/24) 22.2.3.20 %TypedArray%.prototype.reduceRight(callbackfn[, initialValue]).
+function TypedArrayReduceRight(callbackfn/*, initialValue*/) {
+ // Steps 1-2.
+ var O = this;
+
+ // This function is not generic.
+ // We want to make sure that we have an attached buffer, per spec prose.
+ var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+
+ // If we got here, `this` is either a typed array or a cross-compartment
+ // wrapper for one.
+
+ // Steps 3-5.
+ var len;
+ if (isTypedArray)
+ len = TypedArrayLength(O);
+ else
+ len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
+
+ // Step 6.
+ if (arguments.length === 0)
+ ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.reduceRight");
+ if (!IsCallable(callbackfn))
+ ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
+
+ // Step 7.
+ if (len === 0 && arguments.length === 1)
+ ThrowTypeError(JSMSG_EMPTY_ARRAY_REDUCE);
+
+ // Step 8.
+ var k = len - 1;
+
+ // Steps 9-10.
+ // Omit some steps, since 'accumulator' should always be O[len-1] in step 10 for typed arrays.
+ var accumulator = arguments.length > 1 ? arguments[1] : O[k--];
+
+ // Step 11.
+ // Omit steps 11.b-11.c and the 'if' clause in step 11.d, since there are no holes in typed arrays.
+ for (; k >= 0; k--) {
+ accumulator = callContentFunction(callbackfn, undefined, accumulator, O[k], k, O);
+ }
+
+ // Step 12.
+ return accumulator;
+}
+
+// ES6 draft rev29 (2014/12/06) 22.2.3.21 %TypedArray%.prototype.reverse().
+function TypedArrayReverse() {
+ // This function is not generic.
+ if (!IsObject(this) || !IsTypedArray(this)) {
+ return callFunction(CallTypedArrayMethodIfWrapped, this, "TypedArrayReverse");
+ }
+
+ GetAttachedArrayBuffer(this);
+
+ // Steps 1-2.
+ var O = this;
+
+ // Steps 3-5.
+ var len = TypedArrayLength(O);
+
+ // Step 6.
+ var middle = std_Math_floor(len / 2);
+
+ // Steps 7-8.
+ // Omit some steps, since there are no holes in typed arrays.
+ // Especially all the HasProperty/*exists checks always succeed.
+ for (var lower = 0; lower !== middle; lower++) {
+ // Step 8.a.
+ var upper = len - lower - 1;
+
+ // Step 8.f.i.
+ var lowerValue = O[lower];
+
+ // Step 8.i.i.
+ var upperValue = O[upper];
+
+ // We always end up in the step 8.j. case.
+ O[lower] = upperValue;
+ O[upper] = lowerValue;
+ }
+
+ // Step 9.
+ return O;
+}
+
+// ES6 draft 20150220 22.2.3.22.1 %TypedArray%.prototype.set(array [, offset])
+function SetFromNonTypedArray(target, array, targetOffset, targetLength, targetBuffer) {
+ assert(!IsPossiblyWrappedTypedArray(array),
+ "typed arrays must be passed to SetFromTypedArray");
+
+ // Steps 1-11 provided by caller.
+
+ // Steps 16-17.
+ var src = ToObject(array);
+
+ // Steps 18-19.
+ var srcLength = ToLength(src.length);
+
+ // Step 20.
+ var limitOffset = targetOffset + srcLength;
+ if (limitOffset > targetLength)
+ ThrowRangeError(JSMSG_BAD_INDEX);
+
+ // Step 22.
+ var k = 0;
+
+ // Optimization: if the buffer is shared then it is not detachable
+ // and also not inline, so avoid checking overhead inside the loop in
+ // that case.
+ var isShared = targetBuffer !== null && IsSharedArrayBuffer(targetBuffer);
+
+ // Steps 12-15, 21, 23-24.
+ while (targetOffset < limitOffset) {
+ // Steps 24a-c.
+ var kNumber = ToNumber(src[k]);
+
+ // Step 24d. This explicit check will be unnecessary when we implement
+ // throw-on-getting/setting-element-in-detached-buffer semantics.
+ if (!isShared) {
+ if (targetBuffer === null) {
+ // A typed array previously using inline storage may acquire a
+ // buffer, so we must check with the source.
+ targetBuffer = ViewedArrayBufferIfReified(target);
+ }
+ if (IsDetachedBuffer(targetBuffer))
+ ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
+ }
+
+ // Step 24e.
+ target[targetOffset] = kNumber;
+
+ // Steps 24f-g.
+ k++;
+ targetOffset++;
+ }
+
+ // Step 25.
+ return undefined;
+}
+
+// ES6 draft 20150220 22.2.3.22.2 %TypedArray%.prototype.set(typedArray [, offset])
+function SetFromTypedArray(target, typedArray, targetOffset, targetLength) {
+ assert(IsPossiblyWrappedTypedArray(typedArray),
+ "only typed arrays may be passed to this method");
+
+ // Steps 1-11 provided by caller.
+
+ // Steps 12-24.
+ var res = SetFromTypedArrayApproach(target, typedArray, targetOffset,
+ targetLength | 0);
+ assert(res === JS_SETTYPEDARRAY_SAME_TYPE ||
+ res === JS_SETTYPEDARRAY_OVERLAPPING ||
+ res === JS_SETTYPEDARRAY_DISJOINT,
+ "intrinsic didn't return one of its enumerated return values");
+
+ // If the elements had the same type, then SetFromTypedArrayApproach also
+ // performed step 29.
+ if (res == JS_SETTYPEDARRAY_SAME_TYPE)
+ return undefined; // Step 25: done.
+
+ // Otherwise, all checks and side effects except the actual element-writing
+ // happened. Either we're assigning from one range to a non-overlapping
+ // second range, or we're not.
+
+ if (res === JS_SETTYPEDARRAY_DISJOINT) {
+ SetDisjointTypedElements(target, targetOffset | 0, typedArray);
+ return undefined; // Step 25: done.
+ }
+
+ // Now the hard case: overlapping memory ranges. Delegate to yet another
+ // intrinsic.
+ SetOverlappingTypedElements(target, targetOffset | 0, typedArray);
+
+ // Step 25.
+ return undefined;
+}
+
+// ES6 draft 20150304 %TypedArray%.prototype.set
+function TypedArraySet(overloaded, offset = 0) {
+ // Steps 2-5, either algorithm.
+ var target = this;
+ if (!IsObject(target) || !IsTypedArray(target)) {
+ return callFunction(CallTypedArrayMethodIfWrapped,
+ target, overloaded, offset, "TypedArraySet");
+ }
+
+ // Steps 6-8, either algorithm.
+ var targetOffset = ToInteger(offset);
+ if (targetOffset < 0)
+ ThrowRangeError(JSMSG_TYPED_ARRAY_NEGATIVE_ARG, "2");
+
+ // Steps 9-10.
+ var targetBuffer = GetAttachedArrayBuffer(target);
+
+ // Step 11.
+ var targetLength = TypedArrayLength(target);
+
+ // Steps 12 et seq.
+ if (IsPossiblyWrappedTypedArray(overloaded))
+ return SetFromTypedArray(target, overloaded, targetOffset, targetLength);
+
+ return SetFromNonTypedArray(target, overloaded, targetOffset, targetLength, targetBuffer);
+}
+
+// ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
+// 22.2.3.24 %TypedArray%.prototype.slice ( start, end )
+function TypedArraySlice(start, end) {
+ // Step 1.
+ var O = this;
+
+ // Step 2.
+ if (!IsObject(O) || !IsTypedArray(O)) {
+ return callFunction(CallTypedArrayMethodIfWrapped, O, start, end, "TypedArraySlice");
+ }
+
+ GetAttachedArrayBuffer(O);
+
+ // Step 3.
+ var len = TypedArrayLength(O);
+
+ // Step 4.
+ var relativeStart = ToInteger(start);
+
+ // Step 5.
+ var k = relativeStart < 0
+ ? std_Math_max(len + relativeStart, 0)
+ : std_Math_min(relativeStart, len);
+
+ // Step 6.
+ var relativeEnd = end === undefined ? len : ToInteger(end);
+
+ // Step 7.
+ var final = relativeEnd < 0
+ ? std_Math_max(len + relativeEnd, 0)
+ : std_Math_min(relativeEnd, len);
+
+ // Step 8.
+ var count = std_Math_max(final - k, 0);
+
+ // Step 9.
+ var A = TypedArraySpeciesCreateWithLength(O, count);
+
+ // Step 14.a.
+ var n = 0;
+
+ // Step 14.b.
+ while (k < final) {
+ // Steps 14.b.i-v.
+ A[n++] = O[k++];
+ }
+
+ // FIXME: Implement step 15 (bug 1140152).
+
+ // Step 16.
+ return A;
+}
+
+// ES6 draft rev30 (2014/12/24) 22.2.3.25 %TypedArray%.prototype.some(callbackfn[, thisArg]).
+function TypedArraySome(callbackfn/*, thisArg*/) {
+ // Steps 1-2.
+ var O = this;
+
+ // This function is not generic.
+ // We want to make sure that we have an attached buffer, per spec prose.
+ var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
+
+ // If we got here, `this` is either a typed array or a cross-compartment
+ // wrapper for one.
+
+ // Steps 3-5.
+ var len;
+ if (isTypedArray)
+ len = TypedArrayLength(O);
+ else
+ len = callFunction(CallTypedArrayMethodIfWrapped, O, O, "TypedArrayLength");
+
+ // Step 6.
+ if (arguments.length === 0)
+ ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.some");
+ if (!IsCallable(callbackfn))
+ ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
+
+ // Step 7.
+ var T = arguments.length > 1 ? arguments[1] : void 0;
+
+ // Steps 8-9.
+ // Omit steps 9.a-9.c and the 'if' clause in step 9.d, since there are no holes in typed arrays.
+ for (var k = 0; k < len; k++) {
+ // Steps 9.d.i-9.d.ii.
+ var kValue = O[k];
+
+ // Steps 9.d.iii-9.d.iv.
+ var testResult = callContentFunction(callbackfn, T, kValue, k, O);
+
+ // Step 9.d.v.
+ if (testResult)
+ return true;
+ }
+
+ // Step 10.
+ return false;
+}
+
+// ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
+// 22.2.3.26 TypedArray SortCompare abstract operation
+// Cases are ordered according to likelihood of occurrence
+// as opposed to the ordering in the spec.
+function TypedArrayCompare(x, y) {
+ // Step 1.
+ assert(typeof x === "number" && typeof y === "number",
+ "x and y are not numbers.");
+
+ // Step 2 (Implemented in TypedArraySort).
+
+ // Step 6.
+ if (x < y)
+ return -1;
+
+ // Step 7.
+ if (x > y)
+ return 1;
+
+ // Steps 8-9.
+ if (x === 0 && y === 0)
+ return (1/x > 0 ? 1 : 0) - (1/y > 0 ? 1 : 0);
+
+ // Steps 3-4.
+ if (Number_isNaN(x))
+ return Number_isNaN(y) ? 0 : 1;
+
+ // Steps 5, 10.
+ return Number_isNaN(y) ? -1 : 0;
+}
+
+// TypedArray SortCompare specialization for integer values.
+function TypedArrayCompareInt(x, y) {
+ // Step 1.
+ assert(typeof x === "number" && typeof y === "number",
+ "x and y are not numbers.");
+ assert((x === (x|0) || x === (x>>>0)) && (y === (y|0) || y === (y>>>0)),
+ "x and y are not int32/uint32 numbers.");
+
+ // Step 2 (Implemented in TypedArraySort).
+
+ // Steps 6-7.
+ var diff = x - y;
+ if (diff)
+ return diff;
+
+ // Steps 3-5, 8-9 (Not applicable when sorting integer values).
+
+ // Step 10.
+ return 0;
+}
+
+// ES6 draft 20151210 22.2.3.26 %TypedArray%.prototype.sort ( comparefn ).
+function TypedArraySort(comparefn) {
+ // This function is not generic.
+
+ // Step 1.
+ var obj = this;
+
+ // Step 2.
+ var isTypedArray = IsObject(obj) && IsTypedArray(obj);
+
+ var buffer;
+ if (isTypedArray) {
+ buffer = GetAttachedArrayBuffer(obj);
+ } else {
+ buffer = callFunction(CallTypedArrayMethodIfWrapped, obj, obj, "GetAttachedArrayBuffer");
+ }
+
+ // Step 3.
+ var len;
+ if (isTypedArray) {
+ len = TypedArrayLength(obj);
+ } else {
+ len = callFunction(CallTypedArrayMethodIfWrapped, obj, obj, "TypedArrayLength");
+ }
+
+ if (comparefn === undefined) {
+ // CountingSort doesn't invoke the comparator function.
+ if (IsUint8TypedArray(obj)) {
+ return CountingSort(obj, len, false /* signed */);
+ } else if (IsInt8TypedArray(obj)) {
+ return CountingSort(obj, len, true /* signed */);
+ } else if (IsUint16TypedArray(obj)) {
+ return RadixSort(obj, len, buffer, 2 /* nbytes */, false /* signed */, false /* floating */, TypedArrayCompareInt);
+ } else if (IsInt16TypedArray(obj)) {
+ return RadixSort(obj, len, buffer, 2 /* nbytes */, true /* signed */, false /* floating */, TypedArrayCompareInt);
+ } else if (IsUint32TypedArray(obj)) {
+ return RadixSort(obj, len, buffer, 4 /* nbytes */, false /* signed */, false /* floating */, TypedArrayCompareInt);
+ } else if (IsInt32TypedArray(obj)) {
+ return RadixSort(obj, len, buffer, 4 /* nbytes */, true /* signed */, false /* floating */, TypedArrayCompareInt);
+ } else if (IsFloat32TypedArray(obj)) {
+ return RadixSort(obj, len, buffer, 4 /* nbytes */, true /* signed */, true /* floating */, TypedArrayCompare);
+ }
+ return QuickSort(obj, len, TypedArrayCompare);
+ }
+
+ // To satisfy step 2 from TypedArray SortCompare described in 22.2.3.26
+ // the user supplied comparefn is wrapped.
+ var wrappedCompareFn = comparefn;
+ comparefn = function(x, y) {
+ // Step a.
+ var v = wrappedCompareFn(x, y);
+ // Step b.
+ if (buffer === null) {
+ // A typed array previously using inline storage may acquire a
+ // buffer, so we must check with the source.
+ if (isTypedArray) {
+ buffer = GetAttachedArrayBuffer(obj);
+ } else {
+ buffer = callFunction(CallTypedArrayMethodIfWrapped, obj, obj,
+ "GetAttachedArrayBuffer");
+ }
+ }
+ var bufferDetached;
+ if (isTypedArray) {
+ bufferDetached = IsDetachedBuffer(buffer);
+ } else {
+ // This is totally cheating and only works because we know `obj`
+ // and `buffer` are same-compartment".
+ bufferDetached = callFunction(CallTypedArrayMethodIfWrapped, obj,
+ buffer, "IsDetachedBuffer");
+ }
+ if (bufferDetached)
+ ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
+ // Step c. is redundant, see:
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1121937#c36
+ // Step d.
+ return v;
+ }
+
+ return QuickSort(obj, len, comparefn);
+}
+
+// ES2017 draft rev f8a9be8ea4bd97237d176907a1e3080dce20c68f
+// 22.2.3.28 %TypedArray%.prototype.toLocaleString ([ reserved1 [ , reserved2 ] ])
+// ES2017 Intl draft rev 78bbe7d1095f5ff3760ac4017ed366026e4cb276
+// 13.4.1 Array.prototype.toLocaleString ([ locales [ , options ]])
+function TypedArrayToLocaleString(locales = undefined, options = undefined) {
+ // ValidateTypedArray, then step 1.
+ var array = this;
+
+ // This function is not generic.
+ // We want to make sure that we have an attached buffer, per spec prose.
+ var isTypedArray = IsTypedArrayEnsuringArrayBuffer(array);
+
+ // If we got here, `this` is either a typed array or a cross-compartment
+ // wrapper for one.
+
+ // Step 2.
+ var len;
+ if (isTypedArray)
+ len = TypedArrayLength(array);
+ else
+ len = callFunction(CallTypedArrayMethodIfWrapped, array, array, "TypedArrayLength");
+
+ // Step 4.
+ if (len === 0)
+ return "";
+
+ // Step 5.
+ var firstElement = array[0];
+
+ // Steps 6-7.
+ // Omit the 'if' clause in step 6, since typed arrays can't have undefined
+ // or null elements.
+#if EXPOSE_INTL_API
+ var R = ToString(callContentFunction(firstElement.toLocaleString, firstElement, locales, options));
+#else
+ var R = ToString(callContentFunction(firstElement.toLocaleString, firstElement));
+#endif
+
+ // 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.a.
+ var S = R + separator;
+
+ // Step 9.b.
+ var nextElement = array[k];
+
+ // Step 9.c *should* be unreachable: typed array elements are numbers.
+ // But bug 1079853 means |nextElement| *could* be |undefined|, if the
+ // previous iteration's step 9.d or step 7 detached |array|'s buffer.
+ // Conveniently, if this happens, evaluating |nextElement.toLocaleString|
+ // throws the required TypeError, and the only observable difference is
+ // the error message. So despite bug 1079853, we can skip step 9.c.
+
+ // Step 9.d.
+#if EXPOSE_INTL_API
+ R = ToString(callContentFunction(nextElement.toLocaleString, nextElement, locales, options));
+#else
+ R = ToString(callContentFunction(nextElement.toLocaleString, nextElement));
+#endif
+
+ // Step 9.e.
+ R = S + R;
+ }
+
+ // Step 10.
+ return R;
+}
+
+// ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
+// 22.2.3.27 %TypedArray%.prototype.subarray( begin, end )
+function TypedArraySubarray(begin, end) {
+ // Step 1.
+ var obj = this;
+
+ // Steps 2-3.
+ // This function is not generic.
+ if (!IsObject(obj) || !IsTypedArray(obj)) {
+ return callFunction(CallTypedArrayMethodIfWrapped, this, begin, end,
+ "TypedArraySubarray");
+ }
+
+ // Steps 4-6.
+ var buffer = TypedArrayBuffer(obj);
+ var srcLength = TypedArrayLength(obj);
+
+ // Step 14 (Reordered because otherwise it'd be observable that we reset
+ // the byteOffset to zero when the underlying array buffer gets detached).
+ var srcByteOffset = TypedArrayByteOffset(obj);
+
+ // Steps 7-8.
+ var relativeBegin = ToInteger(begin);
+ var beginIndex = relativeBegin < 0 ? std_Math_max(srcLength + relativeBegin, 0)
+ : std_Math_min(relativeBegin, srcLength);
+
+ // Steps 9-10.
+ var relativeEnd = end === undefined ? srcLength : ToInteger(end);
+ var endIndex = relativeEnd < 0 ? std_Math_max(srcLength + relativeEnd, 0)
+ : std_Math_min(relativeEnd, srcLength);
+
+ // Step 11.
+ var newLength = std_Math_max(endIndex - beginIndex, 0);
+
+ // Steps 12-13, altered to use a shift instead of a size for performance.
+ var elementShift = TypedArrayElementShift(obj);
+
+ // Step 15.
+ var beginByteOffset = srcByteOffset + (beginIndex << elementShift);
+
+ // Steps 16-17.
+ return TypedArraySpeciesCreateWithBuffer(obj, buffer, beginByteOffset, newLength);
+}
+
+// ES6 draft rev30 (2014/12/24) 22.2.3.30 %TypedArray%.prototype.values()
+function TypedArrayValues() {
+ // Step 1.
+ var O = this;
+
+ // See the big comment in TypedArrayEntries for what we're doing here.
+ IsTypedArrayEnsuringArrayBuffer(O);
+
+ // Step 7.
+ return CreateArrayIterator(O, ITEM_KIND_VALUE);
+}
+_SetCanonicalName(TypedArrayValues, "values");
+
+// Proposed for ES7:
+// https://github.com/tc39/Array.prototype.includes/blob/7c023c19a0/spec.md
+function TypedArrayIncludes(searchElement, fromIndex = 0) {
+ // This function is not generic.
+ if (!IsObject(this) || !IsTypedArray(this)) {
+ return callFunction(CallTypedArrayMethodIfWrapped, this, searchElement,
+ fromIndex, "TypedArrayIncludes");
+ }
+
+ GetAttachedArrayBuffer(this);
+
+ // Steps 1-2.
+ var O = this;
+
+ // Steps 3-4.
+ var len = TypedArrayLength(O);
+
+ // Step 5.
+ if (len === 0)
+ return false;
+
+ // Steps 6-7.
+ var n = ToInteger(fromIndex);
+
+ var k;
+ // Step 8.
+ 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;
+}
+
+// ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
+// 22.2.2.1 %TypedArray%.from ( source [ , mapfn [ , thisArg ] ] )
+function TypedArrayStaticFrom(source, mapfn = undefined, thisArg = undefined) {
+ // Step 1.
+ var C = this;
+
+ // Step 2.
+ if (!IsConstructor(C))
+ ThrowTypeError(JSMSG_NOT_CONSTRUCTOR, typeof C);
+
+ // Step 3.
+ var mapping;
+ if (mapfn !== undefined) {
+ // Step 3.a.
+ if (!IsCallable(mapfn))
+ ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, mapfn));
+
+ // Step 3.b.
+ mapping = true;
+ } else {
+ // Step 4.
+ mapping = false;
+ }
+
+ // Step 5.
+ var T = thisArg;
+
+ // Step 6.
+ var usingIterator = GetMethod(source, std_iterator);
+
+ // Step 7.
+ if (usingIterator !== undefined) {
+ // Step 7.a.
+ // Inlined: 22.2.2.1.1 Runtime Semantics: IterableToList( items, method ).
+
+ // 22.2.2.1.1 IterableToList, step 1.
+ var iterator = GetIterator(source, usingIterator);
+
+ // 22.2.2.1.1 IterableToList, step 2.
+ var values = new List();
+
+ // 22.2.2.1.1 IterableToList, steps 3-4.
+ var i = 0;
+ while (true) {
+ // 22.2.2.1.1 IterableToList, step 4.a.
+ var next = callContentFunction(iterator.next, iterator);
+ if (!IsObject(next))
+ ThrowTypeError(JSMSG_NEXT_RETURNED_PRIMITIVE);
+
+ // 22.2.2.1.1 IterableToList, step 4.b.
+ if (next.done)
+ break;
+ values[i++] = next.value;
+ }
+
+ // Step 7.b.
+ var len = i;
+
+ // Step 7.c.
+ var targetObj = TypedArrayCreateWithLength(C, len);
+
+ // Steps 7.d-e.
+ for (var k = 0; k < len; k++) {
+ // Step 7.e.ii.
+ var kValue = values[k];
+
+ // Steps 7.e.iii-iv.
+ var mappedValue = mapping ? callContentFunction(mapfn, T, kValue, k) : kValue;
+
+ // Step 7.e.v.
+ targetObj[k] = mappedValue;
+ }
+
+ // Step 7.f.
+ // Asserting that `values` is empty here would require removing them one by one from
+ // the list's start in the loop above. That would introduce unacceptable overhead.
+ // Additionally, the loop's logic is simple enough not to require the assert.
+
+ // Step 7.g.
+ return targetObj;
+ }
+
+ // Step 8 is an assertion: items is not an Iterator. Testing this is
+ // literally the very last thing we did, so we don't assert here.
+
+ // Step 9.
+ var arrayLike = ToObject(source);
+
+ // Step 10.
+ var len = ToLength(arrayLike.length);
+
+ // Step 11.
+ var targetObj = TypedArrayCreateWithLength(C, len);
+
+ // Steps 12-13.
+ for (var k = 0; k < len; k++) {
+ // Steps 13.a-b.
+ var kValue = arrayLike[k];
+
+ // Steps 13.c-d.
+ var mappedValue = mapping ? callContentFunction(mapfn, T, kValue, k) : kValue;
+
+ // Step 13.e.
+ targetObj[k] = mappedValue;
+ }
+
+ // Step 14.
+ return targetObj;
+}
+
+// ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
+// 22.2.2.2 %TypedArray%.of ( ...items )
+function TypedArrayStaticOf(/*...items*/) {
+ // Step 1.
+ var len = arguments.length;
+
+ // Step 2.
+ var items = arguments;
+
+ // Step 3.
+ var C = this;
+
+ // Step 4.
+ if (!IsConstructor(C))
+ ThrowTypeError(JSMSG_NOT_CONSTRUCTOR, typeof C);
+
+ // Step 5.
+ var newObj = TypedArrayCreateWithLength(C, len);
+
+ // Steps 6-7.
+ for (var k = 0; k < len; k++)
+ newObj[k] = items[k]
+
+ // Step 8.
+ return newObj;
+}
+
+// ES 2016 draft Mar 25, 2016 22.2.2.4.
+function TypedArraySpecies() {
+ // Step 1.
+ return this;
+}
+_SetCanonicalName(TypedArraySpecies, "get [Symbol.species]");
+
+// ES 2017 draft June 2, 2016 22.2.3.32
+function TypedArrayToStringTag() {
+ // Step 1.
+ var O = this;
+
+ // Steps 2-3.
+ if (!IsObject(O) || !IsTypedArray(O))
+ return undefined;
+
+ // Steps 4-6.
+ // Modified to retrieve the [[TypedArrayName]] from the constructor.
+ return _NameForTypedArray(O);
+}
+_SetCanonicalName(TypedArrayToStringTag, "get [Symbol.toStringTag]");
+
+// ES2017 draft rev 6859bb9ccaea9c6ede81d71e5320e3833b92cb3e
+// 22.2.2.1.1 Runtime Semantics: IterableToList( items, method )
+function IterableToList(items, method) {
+ // Step 1.
+ var iterator = GetIterator(items, method);
+
+ // Step 2.
+ var values = [];
+
+ // Steps 3-4.
+ var i = 0;
+ while (true) {
+ // Step 4.a.
+ var next = callContentFunction(iterator.next, iterator);
+ if (!IsObject(next))
+ ThrowTypeError(JSMSG_NEXT_RETURNED_PRIMITIVE);
+
+ // Step 4.b.
+ if (next.done)
+ break;
+ _DefineDataProperty(values, i++, next.value);
+ }
+
+ // Step 5.
+ return values;
+}
+
+// ES 2016 draft Mar 25, 2016 24.1.4.3.
+function ArrayBufferSlice(start, end) {
+ // Step 1.
+ var O = this;
+
+ // Steps 2-3,
+ // This function is not generic.
+ if (!IsObject(O) || !IsArrayBuffer(O)) {
+ return callFunction(CallArrayBufferMethodIfWrapped, O, start, end,
+ "ArrayBufferSlice");
+ }
+
+ // Step 4.
+ if (IsDetachedBuffer(O))
+ ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
+
+ // Step 5.
+ var len = ArrayBufferByteLength(O);
+
+ // Step 6.
+ var relativeStart = ToInteger(start);
+
+ // Step 7.
+ var first = relativeStart < 0 ? std_Math_max(len + relativeStart, 0)
+ : std_Math_min(relativeStart, len);
+
+ // Step 8.
+ var relativeEnd = end === undefined ? len
+ : ToInteger(end);
+
+ // Step 9.
+ var final = relativeEnd < 0 ? std_Math_max(len + relativeEnd, 0)
+ : std_Math_min(relativeEnd, len);
+
+ // Step 10.
+ var newLen = std_Math_max(final - first, 0);
+
+ // Step 11
+ var ctor = SpeciesConstructor(O, GetBuiltinConstructor("ArrayBuffer"));
+
+ // Step 12.
+ var new_ = new ctor(newLen);
+
+ var isWrapped = false;
+ if (IsArrayBuffer(new_)) {
+ // Step 14.
+ if (IsDetachedBuffer(new_))
+ ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
+ } else {
+ // Step 13.
+ if (!IsWrappedArrayBuffer(new_))
+ ThrowTypeError(JSMSG_NON_ARRAY_BUFFER_RETURNED);
+
+ isWrapped = true;
+
+ // Step 14.
+ if (callFunction(CallArrayBufferMethodIfWrapped, new_, "IsDetachedBufferThis"))
+ ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
+ }
+
+ // Step 15.
+ if (new_ === O)
+ ThrowTypeError(JSMSG_SAME_ARRAY_BUFFER_RETURNED);
+
+ // Step 16.
+ var actualLen = PossiblyWrappedArrayBufferByteLength(new_);
+ if (actualLen < newLen)
+ ThrowTypeError(JSMSG_SHORT_ARRAY_BUFFER_RETURNED, newLen, actualLen);
+
+ // Step 18.
+ if (IsDetachedBuffer(O))
+ ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
+
+ // Steps 19-21.
+ ArrayBufferCopyData(new_, O, first | 0, newLen | 0, isWrapped);
+
+ // Step 22.
+ return new_;
+}
+
+function IsDetachedBufferThis() {
+ return IsDetachedBuffer(this);
+}
+
+// ES 2016 draft Mar 25, 2016 24.1.3.3.
+function ArrayBufferSpecies() {
+ // Step 1.
+ return this;
+}
+_SetCanonicalName(ArrayBufferSpecies, "get [Symbol.species]");
+
+// Shared memory and atomics proposal (30 Oct 2016)
+function SharedArrayBufferSpecies() {
+ // Step 1.
+ return this;
+}
+_SetCanonicalName(SharedArrayBufferSpecies, "get [Symbol.species]");
+
+// Shared memory and atomics proposal 6.2.1.5.3 (30 Oct 2016)
+// http://tc39.github.io/ecmascript_sharedmem/shmem.html
+function SharedArrayBufferSlice(start, end) {
+ // Step 1.
+ var O = this;
+
+ // Steps 2-4,
+ // This function is not generic.
+ if (!IsObject(O) || !IsSharedArrayBuffer(O)) {
+ return callFunction(CallSharedArrayBufferMethodIfWrapped, O, start, end,
+ "SharedArrayBufferSlice");
+ }
+
+ // Step 5.
+ var len = SharedArrayBufferByteLength(O);
+
+ // Step 6.
+ var relativeStart = ToInteger(start);
+
+ // Step 7.
+ var first = relativeStart < 0 ? std_Math_max(len + relativeStart, 0)
+ : std_Math_min(relativeStart, len);
+
+ // Step 8.
+ var relativeEnd = end === undefined ? len
+ : ToInteger(end);
+
+ // Step 9.
+ var final = relativeEnd < 0 ? std_Math_max(len + relativeEnd, 0)
+ : std_Math_min(relativeEnd, len);
+
+ // Step 10.
+ var newLen = std_Math_max(final - first, 0);
+
+ // Step 11
+ var ctor = SpeciesConstructor(O, GetBuiltinConstructor("SharedArrayBuffer"));
+
+ // Step 12.
+ var new_ = new ctor(newLen);
+
+ // Step 13.
+ var isWrapped = false;
+ if (!IsSharedArrayBuffer(new_)) {
+ if (!IsWrappedSharedArrayBuffer(new_))
+ ThrowTypeError(JSMSG_NON_SHARED_ARRAY_BUFFER_RETURNED);
+ isWrapped = true;
+ }
+
+ // Step 14.
+ if (new_ === O)
+ ThrowTypeError(JSMSG_SAME_SHARED_ARRAY_BUFFER_RETURNED);
+
+ // Step 15.
+ var actualLen = PossiblyWrappedSharedArrayBufferByteLength(new_);
+ if (actualLen < newLen)
+ ThrowTypeError(JSMSG_SHORT_SHARED_ARRAY_BUFFER_RETURNED, newLen, actualLen);
+
+ // Steps 16-18.
+ SharedArrayBufferCopyData(new_, O, first | 0, newLen | 0, isWrapped);
+
+ // Step 19.
+ return new_;
+}