mirror of
https://github.com/classilla/tenfourfox.git
synced 2024-06-10 02:29:43 +00:00
1192 lines
33 KiB
JavaScript
1192 lines
33 KiB
JavaScript
/* 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"
|
|
|
|
// 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");
|
|
}
|
|
|
|
// Bug 1101256: detachment checks mandated by ValidateTypedArray
|
|
|
|
// 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
|
|
// typed array is neutered, so the intrinsic below checks for neutering.
|
|
// 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;
|
|
|
|
// Step 2-3.
|
|
if (!IsObject(O) || !IsTypedArray(O)) {
|
|
return callFunction(CallTypedArrayMethodIfWrapped, O, "TypedArrayEntries");
|
|
}
|
|
|
|
// Step 4-6. Bug 1101256: detachment checks
|
|
|
|
// 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 = undefined) {
|
|
// This function is not generic.
|
|
if (!IsObject(this) || !IsTypedArray(this)) {
|
|
return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, thisArg,
|
|
"TypedArrayEvery");
|
|
}
|
|
|
|
// Steps 1-2.
|
|
var O = this;
|
|
|
|
// Steps 3-5.
|
|
var len = TypedArrayLength(O);
|
|
|
|
// 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 = thisArg;
|
|
|
|
// 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 = callFunction(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");
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|
|
// ES6 draft 32 (2015-02-02) 22.2.3.9 %TypedArray%.prototype.filter(callbackfn[, thisArg])
|
|
function TypedArrayFilter(callbackfn, thisArg = undefined) {
|
|
// Step 1.
|
|
var O = this;
|
|
|
|
// Steps 2-3.
|
|
// This function is not generic.
|
|
if (!IsObject(O) || !IsTypedArray(O)) {
|
|
return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, thisArg,
|
|
"TypedArrayFilter");
|
|
}
|
|
|
|
// Step 4.
|
|
var len = TypedArrayLength(O);
|
|
|
|
// Step 5.
|
|
if (arguments.length === 0)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.filter");
|
|
if (!IsCallable(callbackfn))
|
|
ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
|
|
|
|
// Step 6.
|
|
var T = thisArg;
|
|
|
|
// Step 7.
|
|
var defaultConstructor = _ConstructorForTypedArray(O);
|
|
|
|
// Steps 8-9.
|
|
var C = SpeciesConstructor(O, defaultConstructor);
|
|
|
|
// Step 10.
|
|
var kept = new List();
|
|
|
|
// Step 12.
|
|
var captured = 0;
|
|
|
|
// Steps 11, 13 and 13.g.
|
|
for (var k = 0; k < len; k++) {
|
|
// Steps 13.b-c.
|
|
var kValue = O[k];
|
|
// Steps 13.d-e.
|
|
var selected = ToBoolean(callFunction(callbackfn, T, kValue, k, O));
|
|
// Step 13.f.
|
|
if (selected) {
|
|
// Step 13.f.i.
|
|
callFunction(std_Array_push, kept, kValue);
|
|
// Step 13.f.ii.
|
|
captured++;
|
|
}
|
|
}
|
|
|
|
// Steps 14-15.
|
|
var A = new C(captured);
|
|
|
|
// Steps 16 and 17.c.
|
|
for (var n = 0; n < captured; n++) {
|
|
// Steps 17.a-b.
|
|
A[n] = kept[n];
|
|
}
|
|
|
|
// Step 18.
|
|
return A;
|
|
}
|
|
|
|
// ES6 draft rev28 (2014/10/14) 22.2.3.10 %TypedArray%.prototype.find(predicate[, thisArg]).
|
|
function TypedArrayFind(predicate, thisArg = undefined) {
|
|
// This function is not generic.
|
|
if (!IsObject(this) || !IsTypedArray(this)) {
|
|
return callFunction(CallTypedArrayMethodIfWrapped, this, predicate, thisArg,
|
|
"TypedArrayFind");
|
|
}
|
|
|
|
// Steps 1-2.
|
|
var O = this;
|
|
|
|
// Steps 3-5.
|
|
var len = TypedArrayLength(O);
|
|
|
|
// 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 = thisArg;
|
|
|
|
// 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 (callFunction(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 = undefined) {
|
|
// This function is not generic.
|
|
if (!IsObject(this) || !IsTypedArray(this)) {
|
|
return callFunction(CallTypedArrayMethodIfWrapped, this, predicate, thisArg,
|
|
"TypedArrayFindIndex");
|
|
}
|
|
|
|
// Steps 1-2.
|
|
var O = this;
|
|
|
|
// Steps 3-5.
|
|
var len = TypedArrayLength(O);
|
|
|
|
// 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 = thisArg;
|
|
|
|
// Steps 8-9.
|
|
// Steps a (implicit), and g.
|
|
for (var k = 0; k < len; k++) {
|
|
// Steps a-f.
|
|
if (callFunction(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 = undefined) {
|
|
// This function is not generic.
|
|
if (!IsObject(this) || !IsTypedArray(this)) {
|
|
return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, thisArg,
|
|
"TypedArrayForEach");
|
|
}
|
|
|
|
// Step 1-2.
|
|
var O = this;
|
|
|
|
// Step 3-4.
|
|
var len = TypedArrayLength(O);
|
|
|
|
// 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 = thisArg;
|
|
|
|
// 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.
|
|
callFunction(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");
|
|
}
|
|
|
|
// Steps 1-2.
|
|
var O = this;
|
|
|
|
// Steps 3-5.
|
|
var len = TypedArrayLength(O);
|
|
|
|
// Step 6.
|
|
if (len === 0)
|
|
return -1;
|
|
|
|
// Steps 7-8.
|
|
var n = ToInteger(fromIndex);
|
|
|
|
// 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");
|
|
}
|
|
|
|
// 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 not 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 not have undefined or null elements.
|
|
var next = ToString(element);
|
|
|
|
// Step 13.e.
|
|
R = S + next;
|
|
}
|
|
|
|
// Step 14.
|
|
return R;
|
|
}
|
|
|
|
// ES6 draft rev30 (2014/12/24) 22.2.3.15 %TypedArray%.prototype.keys()
|
|
function TypedArrayKeys() {
|
|
// Step 1.
|
|
var O = this;
|
|
|
|
// Step 2-3.
|
|
if (!IsObject(O) || !IsTypedArray(O)) {
|
|
return callFunction(CallTypedArrayMethodIfWrapped, O, "TypedArrayKeys");
|
|
}
|
|
|
|
// Step 4-6. Bug 1101256: detachment checks
|
|
|
|
// Step 7.
|
|
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");
|
|
}
|
|
|
|
// Steps 1-2.
|
|
var O = this;
|
|
|
|
// Steps 3-5.
|
|
var len = TypedArrayLength(O);
|
|
|
|
// Step 6.
|
|
if (len === 0)
|
|
return -1;
|
|
|
|
// Steps 7-8.
|
|
var n = fromIndex === undefined ? len - 1 : ToInteger(fromIndex);
|
|
|
|
// 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;
|
|
}
|
|
|
|
// ES6 draft rev32 (2015-02-02) 22.2.3.18 %TypedArray%.prototype.map(callbackfn [, thisArg]).
|
|
function TypedArrayMap(callbackfn, thisArg = undefined) {
|
|
// Step 1.
|
|
var O = this;
|
|
|
|
// Steps 2-3.
|
|
// This function is not generic.
|
|
if (!IsObject(O) || !IsTypedArray(O)) {
|
|
return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, thisArg,
|
|
"TypedArrayMap");
|
|
}
|
|
|
|
// Step 4.
|
|
var len = TypedArrayLength(O);
|
|
|
|
// Step 5.
|
|
if (arguments.length === 0)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, '%TypedArray%.prototype.map');
|
|
if (!IsCallable(callbackfn))
|
|
ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn));
|
|
|
|
// Step 6.
|
|
var T = thisArg;
|
|
|
|
// Step 7.
|
|
var defaultConstructor = _ConstructorForTypedArray(O);
|
|
|
|
// Steps 8-9.
|
|
var C = SpeciesConstructor(O, defaultConstructor);
|
|
|
|
// Steps 10-11.
|
|
var A = new C(len);
|
|
|
|
// Steps 12, 13.a (implicit) and 13.h.
|
|
for (var k = 0; k < len; k++) {
|
|
// Steps 13.d-e.
|
|
var mappedValue = callFunction(callbackfn, T, O[k], k, O);
|
|
// Steps 13.f-g.
|
|
A[k] = mappedValue;
|
|
}
|
|
|
|
// Step 14.
|
|
return A;
|
|
}
|
|
|
|
// ES6 draft rev30 (2014/12/24) 22.2.3.19 %TypedArray%.prototype.reduce(callbackfn[, initialValue]).
|
|
function TypedArrayReduce(callbackfn/*, initialValue*/) {
|
|
// This function is not generic.
|
|
if (!IsObject(this) || !IsTypedArray(this))
|
|
return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, "TypedArrayReduce");
|
|
|
|
// Steps 1-2.
|
|
var O = this;
|
|
|
|
// Steps 3-5.
|
|
var len = TypedArrayLength(O);
|
|
|
|
// 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 = callFunction(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*/) {
|
|
// This function is not generic.
|
|
if (!IsObject(this) || !IsTypedArray(this))
|
|
return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, "TypedArrayReduceRight");
|
|
|
|
// Steps 1-2.
|
|
var O = this;
|
|
|
|
// Steps 3-5.
|
|
var len = TypedArrayLength(O);
|
|
|
|
// 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 = callFunction(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");
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|
|
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) {
|
|
// Typed arrays whose buffers are null use inline storage and can't have
|
|
// been neutered.
|
|
if (buffer === null)
|
|
return false;
|
|
|
|
assert(IsArrayBuffer(buffer) || IsSharedArrayBuffer(buffer),
|
|
"non-ArrayBuffer passed to IsDetachedBuffer");
|
|
|
|
// Typed arrays whose buffers map shared memory can't have been neutered.
|
|
//
|
|
// 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_NEUTERED_FLAG) !== 0;
|
|
}
|
|
|
|
// 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) {
|
|
// 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 = ViewedArrayBufferIfReified(target);
|
|
if (IsDetachedBuffer(targetBuffer))
|
|
ThrowTypeError(JSMSG_TYPED_ARRAY_DETACHED);
|
|
|
|
// 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);
|
|
}
|
|
|
|
// ES6 draft rev32 (2015-02-02) 22.2.3.23 %TypedArray%.prototype.slice(start, end).
|
|
function TypedArraySlice(start, end) {
|
|
|
|
// Step 1.
|
|
var O = this;
|
|
|
|
// Step 2-3.
|
|
if (!IsObject(O) || !IsTypedArray(O)) {
|
|
return callFunction(CallTypedArrayMethodIfWrapped, O, start, end, "TypedArraySlice");
|
|
}
|
|
|
|
// Step 4.
|
|
var len = TypedArrayLength(O);
|
|
|
|
// Steps 5-6.
|
|
var relativeStart = ToInteger(start);
|
|
|
|
// Step 7.
|
|
var k = relativeStart < 0
|
|
? std_Math_max(len + relativeStart, 0)
|
|
: std_Math_min(relativeStart, len);
|
|
|
|
// Steps 8-9.
|
|
var relativeEnd = end === undefined ? len : ToInteger(end);
|
|
|
|
// Step 10.
|
|
var final = relativeEnd < 0
|
|
? std_Math_max(len + relativeEnd, 0)
|
|
: std_Math_min(relativeEnd, len);
|
|
|
|
// Step 11.
|
|
var count = std_Math_max(final - k, 0);
|
|
|
|
// Step 12.
|
|
var defaultConstructor = _ConstructorForTypedArray(O);
|
|
|
|
// Steps 13-14.
|
|
var C = SpeciesConstructor(O, defaultConstructor);
|
|
|
|
// Steps 15-16.
|
|
var A = new C(count);
|
|
|
|
// Step 17.
|
|
var n = 0;
|
|
|
|
// Step 18.
|
|
while (k < final) {
|
|
// Steps 18.a-e.
|
|
A[n] = O[k];
|
|
// Step 18f.
|
|
k++;
|
|
// Step 18g.
|
|
n++;
|
|
}
|
|
|
|
// Step 19.
|
|
return A;
|
|
}
|
|
|
|
// ES6 draft rev30 (2014/12/24) 22.2.3.25 %TypedArray%.prototype.some(callbackfn[, thisArg]).
|
|
function TypedArraySome(callbackfn, thisArg = undefined) {
|
|
// This function is not generic.
|
|
if (!IsObject(this) || !IsTypedArray(this)) {
|
|
return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, thisArg,
|
|
"TypedArraySome");
|
|
}
|
|
|
|
// Steps 1-2.
|
|
var O = this;
|
|
|
|
// Steps 3-5.
|
|
var len = TypedArrayLength(O);
|
|
|
|
// 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 = thisArg;
|
|
|
|
// 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 = callFunction(callbackfn, T, kValue, k, O);
|
|
|
|
// Step 9.d.v.
|
|
if (testResult)
|
|
return true;
|
|
}
|
|
|
|
// Step 10.
|
|
return false;
|
|
}
|
|
|
|
// ES6 draft 20150304 %TypedArray%.prototype.subarray
|
|
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);
|
|
|
|
// Steps 7-9.
|
|
var relativeBegin = ToInteger(begin);
|
|
var beginIndex = relativeBegin < 0 ? std_Math_max(srcLength + relativeBegin, 0)
|
|
: std_Math_min(relativeBegin, srcLength);
|
|
|
|
// Steps 10-12.
|
|
var relativeEnd = end === undefined ? srcLength : ToInteger(end);
|
|
var endIndex = relativeEnd < 0 ? std_Math_max(srcLength + relativeEnd, 0)
|
|
: std_Math_min(relativeEnd, srcLength);
|
|
|
|
// Step 13.
|
|
var newLength = std_Math_max(endIndex - beginIndex, 0);
|
|
|
|
// Steps 14-15, altered to use a shift instead of a size for performance.
|
|
var elementShift = TypedArrayElementShift(obj);
|
|
|
|
// Step 16.
|
|
var srcByteOffset = TypedArrayByteOffset(obj);
|
|
|
|
// Step 17.
|
|
var beginByteOffset = srcByteOffset + (beginIndex << elementShift);
|
|
|
|
// Steps 18-20.
|
|
var defaultConstructor = _ConstructorForTypedArray(obj);
|
|
var constructor = SpeciesConstructor(obj, defaultConstructor);
|
|
|
|
// Steps 21-22.
|
|
return new constructor(buffer, beginByteOffset, newLength);
|
|
}
|
|
|
|
// ES6 draft rev30 (2014/12/24) 22.2.3.30 %TypedArray%.prototype.values()
|
|
function TypedArrayValues() {
|
|
// Step 1.
|
|
var O = this;
|
|
|
|
// Step 2-3.
|
|
if (!IsObject(O) || !IsTypedArray(O)) {
|
|
return callFunction(CallTypedArrayMethodIfWrapped, O, "TypedArrayValues");
|
|
}
|
|
|
|
// Step 4-6. Bug 1101256: detachment checks
|
|
|
|
// 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");
|
|
}
|
|
|
|
// 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;
|
|
}
|
|
|
|
// ES6 draft rev30 (2014/12/24) 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, DecompileArg(1, C));
|
|
|
|
// Step 3.
|
|
var f = mapfn;
|
|
|
|
// Step 4.
|
|
if (f !== undefined && !IsCallable(f))
|
|
ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(1, f));
|
|
|
|
// Steps 5-6.
|
|
return TypedArrayFrom(C, undefined, source, f, thisArg);
|
|
}
|
|
|
|
// ES6 draft rev30 (2014/12/24) 22.2.2.1.1 TypedArrayFrom().
|
|
function TypedArrayFrom(constructor, target, items, mapfn, thisArg) {
|
|
// Step 1.
|
|
var C = constructor;
|
|
|
|
// Step 2.
|
|
assert(C === undefined || target === undefined,
|
|
"Neither of 'constructor' and 'target' is undefined");
|
|
|
|
// Step 3.
|
|
assert(IsConstructor(C) || C === undefined,
|
|
"'constructor' is neither an constructor nor undefined");
|
|
|
|
// Step 4.
|
|
assert(target === undefined || IsTypedArray(target),
|
|
"'target' is neither a typed array nor undefined");
|
|
|
|
// Step 5.
|
|
assert(IsCallable(mapfn) || mapfn === undefined,
|
|
"'target' is neither a function nor undefined");
|
|
|
|
// Steps 6-7.
|
|
var mapping = mapfn !== undefined;
|
|
var T = thisArg;
|
|
|
|
// Steps 8-9.
|
|
var usingIterator = GetMethod(items, std_iterator);
|
|
|
|
// Step 10.
|
|
if (usingIterator !== undefined) {
|
|
// Steps 10.a-b.
|
|
var iterator = GetIterator(items, usingIterator);
|
|
|
|
// Step 10.c.
|
|
var values = new List();
|
|
|
|
// Steps 10.d-e.
|
|
while (true) {
|
|
// Steps 10.e.i-ii.
|
|
var next = callFunction(iterator.next, iterator);
|
|
if (!IsObject(next))
|
|
ThrowTypeError(JSMSG_NEXT_RETURNED_PRIMITIVE);
|
|
|
|
// Steps 10.e.iii-vi.
|
|
if (next.done)
|
|
break;
|
|
callFunction(std_Array_push, values, next.value);
|
|
}
|
|
|
|
// Step 10.f.
|
|
var len = values.length;
|
|
|
|
// Steps 10.g-h.
|
|
// There is no need to implement the 22.2.2.1.2 - TypedArrayAllocOrInit() method,
|
|
// since `%TypedArray%(object)` currently doesn't call this self-hosted TypedArrayFrom().
|
|
var targetObj = new C(len);
|
|
|
|
// Steps 10.i-j.
|
|
for (var k = 0; k < len; k++) {
|
|
// Steps 10.j.i-ii.
|
|
var kValue = values[k];
|
|
|
|
// Steps 10.j.iii-iv.
|
|
var mappedValue = mapping ? callFunction(mapfn, T, kValue, k) : kValue;
|
|
|
|
// Steps 10.j.v-vi.
|
|
targetObj[k] = mappedValue;
|
|
}
|
|
|
|
// Step 10.k.
|
|
// 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 10.l.
|
|
return targetObj;
|
|
}
|
|
|
|
// Step 11 is an assertion: items is not an Iterator. Testing this is
|
|
// literally the very last thing we did, so we don't assert here.
|
|
|
|
// Steps 12-13.
|
|
var arrayLike = ToObject(items);
|
|
|
|
// Steps 14-16.
|
|
var len = ToLength(arrayLike.length);
|
|
|
|
// Steps 17-18.
|
|
// See comment for steps 10.g-h.
|
|
var targetObj = new C(len);
|
|
|
|
// Steps 19-20.
|
|
for (var k = 0; k < len; k++) {
|
|
// Steps 20.a-c.
|
|
var kValue = arrayLike[k];
|
|
|
|
// Steps 20.d-e.
|
|
var mappedValue = mapping ? callFunction(mapfn, T, kValue, k) : kValue;
|
|
|
|
// Steps 20.f-g.
|
|
targetObj[k] = mappedValue;
|
|
}
|
|
|
|
// Step 21.
|
|
return targetObj;
|
|
}
|
|
|
|
// ES6 draft rev30 (2014/12/24) 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;
|
|
|
|
// Steps 4-5.
|
|
if (!IsConstructor(C))
|
|
ThrowTypeError(JSMSG_NOT_CONSTRUCTOR, typeof C);
|
|
|
|
var newObj = new 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;
|
|
}
|
|
|
|
// 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]");
|
|
|