Upgrade V8 to version 4.9.385.28
https://chromium.googlesource.com/v8/v8/+/4.9.385.28
FPIIM-449
Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/js/typedarray.js b/src/js/typedarray.js
new file mode 100644
index 0000000..fd668a5
--- /dev/null
+++ b/src/js/typedarray.js
@@ -0,0 +1,980 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+(function(global, utils) {
+
+"use strict";
+
+%CheckIsBootstrapping();
+
+// -------------------------------------------------------------------
+// Imports
+
+var ArrayFrom;
+var ArrayToString;
+var ArrayValues;
+var GlobalArray = global.Array;
+var GlobalArrayBuffer = global.ArrayBuffer;
+var GlobalDataView = global.DataView;
+var GlobalObject = global.Object;
+var InternalArray = utils.InternalArray;
+var InnerArrayCopyWithin;
+var InnerArrayEvery;
+var InnerArrayFill;
+var InnerArrayFilter;
+var InnerArrayFind;
+var InnerArrayFindIndex;
+var InnerArrayForEach;
+var InnerArrayIncludes;
+var InnerArrayIndexOf;
+var InnerArrayJoin;
+var InnerArrayLastIndexOf;
+var InnerArrayReduce;
+var InnerArrayReduceRight;
+var InnerArraySome;
+var InnerArraySort;
+var InnerArrayToLocaleString;
+var InternalArray = utils.InternalArray;
+var IsNaN;
+var MakeRangeError;
+var MakeTypeError;
+var MaxSimple;
+var MinSimple;
+var PackedArrayReverse;
+var SpeciesConstructor;
+var ToPositiveInteger;
+var iteratorSymbol = utils.ImportNow("iterator_symbol");
+var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
+
+macro TYPED_ARRAYS(FUNCTION)
+// arrayIds below should be synchronized with Runtime_TypedArrayInitialize.
+FUNCTION(1, Uint8Array, 1)
+FUNCTION(2, Int8Array, 1)
+FUNCTION(3, Uint16Array, 2)
+FUNCTION(4, Int16Array, 2)
+FUNCTION(5, Uint32Array, 4)
+FUNCTION(6, Int32Array, 4)
+FUNCTION(7, Float32Array, 4)
+FUNCTION(8, Float64Array, 8)
+FUNCTION(9, Uint8ClampedArray, 1)
+endmacro
+
+macro DECLARE_GLOBALS(INDEX, NAME, SIZE)
+var GlobalNAME = global.NAME;
+endmacro
+
+TYPED_ARRAYS(DECLARE_GLOBALS)
+
+utils.Import(function(from) {
+ ArrayFrom = from.ArrayFrom;
+ ArrayToString = from.ArrayToString;
+ ArrayValues = from.ArrayValues;
+ InnerArrayCopyWithin = from.InnerArrayCopyWithin;
+ InnerArrayEvery = from.InnerArrayEvery;
+ InnerArrayFill = from.InnerArrayFill;
+ InnerArrayFilter = from.InnerArrayFilter;
+ InnerArrayFind = from.InnerArrayFind;
+ InnerArrayFindIndex = from.InnerArrayFindIndex;
+ InnerArrayForEach = from.InnerArrayForEach;
+ InnerArrayIncludes = from.InnerArrayIncludes;
+ InnerArrayIndexOf = from.InnerArrayIndexOf;
+ InnerArrayJoin = from.InnerArrayJoin;
+ InnerArrayLastIndexOf = from.InnerArrayLastIndexOf;
+ InnerArrayReduce = from.InnerArrayReduce;
+ InnerArrayReduceRight = from.InnerArrayReduceRight;
+ InnerArraySome = from.InnerArraySome;
+ InnerArraySort = from.InnerArraySort;
+ InnerArrayToLocaleString = from.InnerArrayToLocaleString;
+ IsNaN = from.IsNaN;
+ MakeRangeError = from.MakeRangeError;
+ MakeTypeError = from.MakeTypeError;
+ MaxSimple = from.MaxSimple;
+ MinSimple = from.MinSimple;
+ PackedArrayReverse = from.PackedArrayReverse;
+ SpeciesConstructor = from.SpeciesConstructor;
+ ToPositiveInteger = from.ToPositiveInteger;
+});
+
+// --------------- Typed Arrays ---------------------
+
+function TypedArrayDefaultConstructor(typedArray) {
+ switch (%_ClassOf(typedArray)) {
+macro TYPED_ARRAY_CONSTRUCTOR_CASE(ARRAY_ID, NAME, ELEMENT_SIZE)
+ case "NAME":
+ return GlobalNAME;
+endmacro
+TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTOR_CASE)
+ }
+ // The TypeError should not be generated since all callers should
+ // have already called ValidateTypedArray.
+ throw MakeTypeError(kIncompatibleMethodReceiver,
+ "TypedArrayDefaultConstructor", this);
+}
+
+function TypedArrayCreate(constructor, arg0, arg1, arg2) {
+ if (IS_UNDEFINED(arg1)) {
+ var newTypedArray = new constructor(arg0);
+ } else {
+ var newTypedArray = new constructor(arg0, arg1, arg2);
+ }
+ if (!%_IsTypedArray(newTypedArray)) throw MakeTypeError(kNotTypedArray);
+ // TODO(littledan): Check for being detached, here and elsewhere
+ // All callers where the first argument is a Number have no additional
+ // arguments.
+ if (IS_NUMBER(arg0) && %_TypedArrayGetLength(newTypedArray) < arg0) {
+ throw MakeTypeError(kTypedArrayTooShort);
+ }
+ return newTypedArray;
+}
+
+function TypedArraySpeciesCreate(exemplar, arg0, arg1, arg2, conservative) {
+ var defaultConstructor = TypedArrayDefaultConstructor(exemplar);
+ var constructor = SpeciesConstructor(exemplar, defaultConstructor,
+ conservative);
+ return TypedArrayCreate(constructor, arg0, arg1, arg2);
+}
+
+macro TYPED_ARRAY_CONSTRUCTOR(ARRAY_ID, NAME, ELEMENT_SIZE)
+function NAMEConstructByArrayBuffer(obj, buffer, byteOffset, length) {
+ if (!IS_UNDEFINED(byteOffset)) {
+ byteOffset = ToPositiveInteger(byteOffset, kInvalidTypedArrayLength);
+ }
+ if (!IS_UNDEFINED(length)) {
+ length = ToPositiveInteger(length, kInvalidTypedArrayLength);
+ }
+
+ var bufferByteLength = %_ArrayBufferGetByteLength(buffer);
+ var offset;
+ if (IS_UNDEFINED(byteOffset)) {
+ offset = 0;
+ } else {
+ offset = byteOffset;
+
+ if (offset % ELEMENT_SIZE !== 0) {
+ throw MakeRangeError(kInvalidTypedArrayAlignment,
+ "start offset", "NAME", ELEMENT_SIZE);
+ }
+ if (offset > bufferByteLength) {
+ throw MakeRangeError(kInvalidTypedArrayOffset);
+ }
+ }
+
+ var newByteLength;
+ var newLength;
+ if (IS_UNDEFINED(length)) {
+ if (bufferByteLength % ELEMENT_SIZE !== 0) {
+ throw MakeRangeError(kInvalidTypedArrayAlignment,
+ "byte length", "NAME", ELEMENT_SIZE);
+ }
+ newByteLength = bufferByteLength - offset;
+ newLength = newByteLength / ELEMENT_SIZE;
+ } else {
+ var newLength = length;
+ newByteLength = newLength * ELEMENT_SIZE;
+ }
+ if ((offset + newByteLength > bufferByteLength)
+ || (newLength > %_MaxSmi())) {
+ throw MakeRangeError(kInvalidTypedArrayLength);
+ }
+ %_TypedArrayInitialize(obj, ARRAY_ID, buffer, offset, newByteLength, true);
+}
+
+function NAMEConstructByLength(obj, length) {
+ var l = IS_UNDEFINED(length) ?
+ 0 : ToPositiveInteger(length, kInvalidTypedArrayLength);
+ if (l > %_MaxSmi()) {
+ throw MakeRangeError(kInvalidTypedArrayLength);
+ }
+ var byteLength = l * ELEMENT_SIZE;
+ if (byteLength > %_TypedArrayMaxSizeInHeap()) {
+ var buffer = new GlobalArrayBuffer(byteLength);
+ %_TypedArrayInitialize(obj, ARRAY_ID, buffer, 0, byteLength, true);
+ } else {
+ %_TypedArrayInitialize(obj, ARRAY_ID, null, 0, byteLength, true);
+ }
+}
+
+function NAMEConstructByArrayLike(obj, arrayLike) {
+ var length = arrayLike.length;
+ var l = ToPositiveInteger(length, kInvalidTypedArrayLength);
+
+ if (l > %_MaxSmi()) {
+ throw MakeRangeError(kInvalidTypedArrayLength);
+ }
+ var initialized = false;
+ var byteLength = l * ELEMENT_SIZE;
+ if (byteLength <= %_TypedArrayMaxSizeInHeap()) {
+ %_TypedArrayInitialize(obj, ARRAY_ID, null, 0, byteLength, false);
+ } else {
+ initialized =
+ %TypedArrayInitializeFromArrayLike(obj, ARRAY_ID, arrayLike, l);
+ }
+ if (!initialized) {
+ for (var i = 0; i < l; i++) {
+ // It is crucial that we let any execptions from arrayLike[i]
+ // propagate outside the function.
+ obj[i] = arrayLike[i];
+ }
+ }
+}
+
+function NAMEConstructByIterable(obj, iterable, iteratorFn) {
+ var list = new InternalArray();
+ // Reading the Symbol.iterator property of iterable twice would be
+ // observable with getters, so instead, we call the function which
+ // was already looked up, and wrap it in another iterable. The
+ // __proto__ of the new iterable is set to null to avoid any chance
+ // of modifications to Object.prototype being observable here.
+ var iterator = %_Call(iteratorFn, iterable);
+ var newIterable = {
+ __proto__: null
+ };
+ // TODO(littledan): Computed properties don't work yet in nosnap.
+ // Rephrase when they do.
+ newIterable[iteratorSymbol] = function() { return iterator; }
+ for (var value of newIterable) {
+ list.push(value);
+ }
+ NAMEConstructByArrayLike(obj, list);
+}
+
+function NAMEConstructor(arg1, arg2, arg3) {
+ if (!IS_UNDEFINED(new.target)) {
+ if (IS_ARRAYBUFFER(arg1) || IS_SHAREDARRAYBUFFER(arg1)) {
+ NAMEConstructByArrayBuffer(this, arg1, arg2, arg3);
+ } else if (IS_NUMBER(arg1) || IS_STRING(arg1) ||
+ IS_BOOLEAN(arg1) || IS_UNDEFINED(arg1)) {
+ NAMEConstructByLength(this, arg1);
+ } else {
+ // TODO(littledan): If arg1 is a TypedArray, follow the constructor
+ // path in ES2015 22.2.4.3, and call SpeciesConstructor, in a
+ // path that seems to be an optimized version of what's below, but
+ // in an observably different way.
+ var iteratorFn = arg1[iteratorSymbol];
+ if (IS_UNDEFINED(iteratorFn) || iteratorFn === ArrayValues) {
+ NAMEConstructByArrayLike(this, arg1);
+ } else {
+ NAMEConstructByIterable(this, arg1, iteratorFn);
+ }
+ }
+ } else {
+ throw MakeTypeError(kConstructorNotFunction, "NAME")
+ }
+}
+
+// TODO(littledan): Remove this performance workaround BUG(chromium:579905)
+function NAME_GetLength() {
+ if (!(%_ClassOf(this) === 'NAME')) {
+ throw MakeTypeError(kIncompatibleMethodReceiver, "NAME.length", this);
+ }
+ return %_TypedArrayGetLength(this);
+}
+
+function NAMESubArray(begin, end) {
+ var beginInt = TO_INTEGER(begin);
+ if (!IS_UNDEFINED(end)) {
+ var endInt = TO_INTEGER(end);
+ var srcLength = %_TypedArrayGetLength(this);
+ } else {
+ var srcLength = %_TypedArrayGetLength(this);
+ var endInt = srcLength;
+ }
+
+ if (beginInt < 0) {
+ beginInt = MaxSimple(0, srcLength + beginInt);
+ } else {
+ beginInt = MinSimple(beginInt, srcLength);
+ }
+
+ if (endInt < 0) {
+ endInt = MaxSimple(0, srcLength + endInt);
+ } else {
+ endInt = MinSimple(endInt, srcLength);
+ }
+
+ if (endInt < beginInt) {
+ endInt = beginInt;
+ }
+
+ var newLength = endInt - beginInt;
+ var beginByteOffset =
+ %_ArrayBufferViewGetByteOffset(this) + beginInt * ELEMENT_SIZE;
+ return TypedArraySpeciesCreate(this, %TypedArrayGetBuffer(this),
+ beginByteOffset, newLength, true);
+}
+endmacro
+
+TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTOR)
+
+function TypedArraySubArray(begin, end) {
+ switch (%_ClassOf(this)) {
+macro TYPED_ARRAY_SUBARRAY_CASE(ARRAY_ID, NAME, ELEMENT_SIZE)
+ case "NAME":
+ return %_Call(NAMESubArray, this, begin, end);
+endmacro
+TYPED_ARRAYS(TYPED_ARRAY_SUBARRAY_CASE)
+ }
+ throw MakeTypeError(kIncompatibleMethodReceiver,
+ "get TypedArray.prototype.subarray", this);
+}
+%SetForceInlineFlag(TypedArraySubArray);
+
+function TypedArrayGetBuffer() {
+ if (!%_IsTypedArray(this)) {
+ throw MakeTypeError(kIncompatibleMethodReceiver,
+ "get TypedArray.prototype.buffer", this);
+ }
+ return %TypedArrayGetBuffer(this);
+}
+%SetForceInlineFlag(TypedArrayGetBuffer);
+
+function TypedArrayGetByteLength() {
+ if (!%_IsTypedArray(this)) {
+ throw MakeTypeError(kIncompatibleMethodReceiver,
+ "get TypedArray.prototype.byteLength", this);
+ }
+ return %_ArrayBufferViewGetByteLength(this);
+}
+%SetForceInlineFlag(TypedArrayGetByteLength);
+
+function TypedArrayGetByteOffset() {
+ if (!%_IsTypedArray(this)) {
+ throw MakeTypeError(kIncompatibleMethodReceiver,
+ "get TypedArray.prototype.byteOffset", this);
+ }
+ return %_ArrayBufferViewGetByteOffset(this);
+}
+%SetForceInlineFlag(TypedArrayGetByteOffset);
+
+function TypedArrayGetLength() {
+ if (!%_IsTypedArray(this)) {
+ throw MakeTypeError(kIncompatibleMethodReceiver,
+ "get TypedArray.prototype.length", this);
+ }
+ return %_TypedArrayGetLength(this);
+}
+%SetForceInlineFlag(TypedArrayGetLength);
+
+
+
+function TypedArraySetFromArrayLike(target, source, sourceLength, offset) {
+ if (offset > 0) {
+ for (var i = 0; i < sourceLength; i++) {
+ target[offset + i] = source[i];
+ }
+ }
+ else {
+ for (var i = 0; i < sourceLength; i++) {
+ target[i] = source[i];
+ }
+ }
+}
+
+function TypedArraySetFromOverlappingTypedArray(target, source, offset) {
+ var sourceElementSize = source.BYTES_PER_ELEMENT;
+ var targetElementSize = target.BYTES_PER_ELEMENT;
+ var sourceLength = source.length;
+
+ // Copy left part.
+ function CopyLeftPart() {
+ // First un-mutated byte after the next write
+ var targetPtr = target.byteOffset + (offset + 1) * targetElementSize;
+ // Next read at sourcePtr. We do not care for memory changing before
+ // sourcePtr - we have already copied it.
+ var sourcePtr = source.byteOffset;
+ for (var leftIndex = 0;
+ leftIndex < sourceLength && targetPtr <= sourcePtr;
+ leftIndex++) {
+ target[offset + leftIndex] = source[leftIndex];
+ targetPtr += targetElementSize;
+ sourcePtr += sourceElementSize;
+ }
+ return leftIndex;
+ }
+ var leftIndex = CopyLeftPart();
+
+ // Copy rigth part;
+ function CopyRightPart() {
+ // First unmutated byte before the next write
+ var targetPtr =
+ target.byteOffset + (offset + sourceLength - 1) * targetElementSize;
+ // Next read before sourcePtr. We do not care for memory changing after
+ // sourcePtr - we have already copied it.
+ var sourcePtr =
+ source.byteOffset + sourceLength * sourceElementSize;
+ for(var rightIndex = sourceLength - 1;
+ rightIndex >= leftIndex && targetPtr >= sourcePtr;
+ rightIndex--) {
+ target[offset + rightIndex] = source[rightIndex];
+ targetPtr -= targetElementSize;
+ sourcePtr -= sourceElementSize;
+ }
+ return rightIndex;
+ }
+ var rightIndex = CopyRightPart();
+
+ var temp = new GlobalArray(rightIndex + 1 - leftIndex);
+ for (var i = leftIndex; i <= rightIndex; i++) {
+ temp[i - leftIndex] = source[i];
+ }
+ for (i = leftIndex; i <= rightIndex; i++) {
+ target[offset + i] = temp[i - leftIndex];
+ }
+}
+
+function TypedArraySet(obj, offset) {
+ var intOffset = IS_UNDEFINED(offset) ? 0 : TO_INTEGER(offset);
+ if (intOffset < 0) throw MakeTypeError(kTypedArraySetNegativeOffset);
+
+ if (intOffset > %_MaxSmi()) {
+ throw MakeRangeError(kTypedArraySetSourceTooLarge);
+ }
+ switch (%TypedArraySetFastCases(this, obj, intOffset)) {
+ // These numbers should be synchronized with runtime.cc.
+ case 0: // TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE
+ return;
+ case 1: // TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING
+ TypedArraySetFromOverlappingTypedArray(this, obj, intOffset);
+ return;
+ case 2: // TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING
+ TypedArraySetFromArrayLike(this, obj, obj.length, intOffset);
+ return;
+ case 3: // TYPED_ARRAY_SET_NON_TYPED_ARRAY
+ var l = obj.length;
+ if (IS_UNDEFINED(l)) {
+ if (IS_NUMBER(obj)) {
+ // For number as a first argument, throw TypeError
+ // instead of silently ignoring the call, so that
+ // the user knows (s)he did something wrong.
+ // (Consistent with Firefox and Blink/WebKit)
+ throw MakeTypeError(kInvalidArgument);
+ }
+ return;
+ }
+ l = TO_LENGTH(l);
+ if (intOffset + l > this.length) {
+ throw MakeRangeError(kTypedArraySetSourceTooLarge);
+ }
+ TypedArraySetFromArrayLike(this, obj, l, intOffset);
+ return;
+ }
+}
+
+function TypedArrayGetToStringTag() {
+ if (!%_IsTypedArray(this)) return;
+ var name = %_ClassOf(this);
+ if (IS_UNDEFINED(name)) return;
+ return name;
+}
+
+
+function TypedArrayCopyWithin(target, start, end) {
+ if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+ var length = %_TypedArrayGetLength(this);
+
+ // TODO(littledan): Replace with a memcpy for better performance
+ return InnerArrayCopyWithin(target, start, end, this, length);
+}
+%FunctionSetLength(TypedArrayCopyWithin, 2);
+
+
+// ES6 draft 05-05-15, section 22.2.3.7
+function TypedArrayEvery(f, receiver) {
+ if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+ var length = %_TypedArrayGetLength(this);
+
+ return InnerArrayEvery(f, receiver, this, length);
+}
+%FunctionSetLength(TypedArrayEvery, 1);
+
+
+// ES6 draft 08-24-14, section 22.2.3.12
+function TypedArrayForEach(f, receiver) {
+ if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+ var length = %_TypedArrayGetLength(this);
+
+ InnerArrayForEach(f, receiver, this, length);
+}
+%FunctionSetLength(TypedArrayForEach, 1);
+
+
+// ES6 draft 04-05-14 section 22.2.3.8
+function TypedArrayFill(value, start, end) {
+ if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+ var length = %_TypedArrayGetLength(this);
+
+ return InnerArrayFill(value, start, end, this, length);
+}
+%FunctionSetLength(TypedArrayFill, 1);
+
+
+// ES6 draft 07-15-13, section 22.2.3.9
+function TypedArrayFilter(f, thisArg) {
+ if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+ var length = %_TypedArrayGetLength(this);
+ if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
+ var result = new InternalArray();
+ InnerArrayFilter(f, thisArg, this, length, result);
+ var captured = result.length;
+ var output = TypedArraySpeciesCreate(this, captured);
+ for (var i = 0; i < captured; i++) {
+ output[i] = result[i];
+ }
+ return output;
+}
+%FunctionSetLength(TypedArrayFilter, 1);
+
+
+// ES6 draft 07-15-13, section 22.2.3.10
+function TypedArrayFind(predicate, thisArg) {
+ if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+ var length = %_TypedArrayGetLength(this);
+
+ return InnerArrayFind(predicate, thisArg, this, length);
+}
+%FunctionSetLength(TypedArrayFind, 1);
+
+
+// ES6 draft 07-15-13, section 22.2.3.11
+function TypedArrayFindIndex(predicate, thisArg) {
+ if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+ var length = %_TypedArrayGetLength(this);
+
+ return InnerArrayFindIndex(predicate, thisArg, this, length);
+}
+%FunctionSetLength(TypedArrayFindIndex, 1);
+
+
+// ES6 draft 05-18-15, section 22.2.3.21
+function TypedArrayReverse() {
+ if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+ var length = %_TypedArrayGetLength(this);
+
+ return PackedArrayReverse(this, length);
+}
+
+
+function TypedArrayComparefn(x, y) {
+ if (IsNaN(x) && IsNaN(y)) {
+ return IsNaN(y) ? 0 : 1;
+ }
+ if (IsNaN(x)) {
+ return 1;
+ }
+ if (x === 0 && x === y) {
+ if (%_IsMinusZero(x)) {
+ if (!%_IsMinusZero(y)) {
+ return -1;
+ }
+ } else if (%_IsMinusZero(y)) {
+ return 1;
+ }
+ }
+ return x - y;
+}
+
+
+// ES6 draft 05-18-15, section 22.2.3.25
+function TypedArraySort(comparefn) {
+ if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+ var length = %_TypedArrayGetLength(this);
+
+ if (IS_UNDEFINED(comparefn)) {
+ comparefn = TypedArrayComparefn;
+ }
+
+ return InnerArraySort(this, length, comparefn);
+}
+
+
+// ES6 section 22.2.3.13
+function TypedArrayIndexOf(element, index) {
+ if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+ var length = %_TypedArrayGetLength(this);
+ return InnerArrayIndexOf(this, element, index, length);
+}
+%FunctionSetLength(TypedArrayIndexOf, 1);
+
+
+// ES6 section 22.2.3.16
+function TypedArrayLastIndexOf(element, index) {
+ if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+ var length = %_TypedArrayGetLength(this);
+
+ return InnerArrayLastIndexOf(this, element, index, length,
+ %_ArgumentsLength());
+}
+%FunctionSetLength(TypedArrayLastIndexOf, 1);
+
+
+// ES6 draft 07-15-13, section 22.2.3.18
+function TypedArrayMap(f, thisArg) {
+ if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+ var length = %_TypedArrayGetLength(this);
+ var result = TypedArraySpeciesCreate(this, length);
+ if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
+ for (var i = 0; i < length; i++) {
+ var element = this[i];
+ result[i] = %_Call(f, thisArg, element, i, this);
+ }
+ return result;
+}
+%FunctionSetLength(TypedArrayMap, 1);
+
+
+// ES6 draft 05-05-15, section 22.2.3.24
+function TypedArraySome(f, receiver) {
+ if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+ var length = %_TypedArrayGetLength(this);
+
+ return InnerArraySome(f, receiver, this, length);
+}
+%FunctionSetLength(TypedArraySome, 1);
+
+
+// ES6 section 22.2.3.27
+function TypedArrayToLocaleString() {
+ if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+ var length = %_TypedArrayGetLength(this);
+
+ return InnerArrayToLocaleString(this, length);
+}
+
+
+// ES6 section 22.2.3.28
+function TypedArrayToString() {
+ return %_Call(ArrayToString, this);
+}
+
+
+// ES6 section 22.2.3.14
+function TypedArrayJoin(separator) {
+ if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+ var length = %_TypedArrayGetLength(this);
+
+ return InnerArrayJoin(separator, this, length);
+}
+
+
+// ES6 draft 07-15-13, section 22.2.3.19
+function TypedArrayReduce(callback, current) {
+ if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+ var length = %_TypedArrayGetLength(this);
+ return InnerArrayReduce(callback, current, this, length,
+ %_ArgumentsLength());
+}
+%FunctionSetLength(TypedArrayReduce, 1);
+
+
+// ES6 draft 07-15-13, section 22.2.3.19
+function TypedArrayReduceRight(callback, current) {
+ if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+ var length = %_TypedArrayGetLength(this);
+ return InnerArrayReduceRight(callback, current, this, length,
+ %_ArgumentsLength());
+}
+%FunctionSetLength(TypedArrayReduceRight, 1);
+
+
+function TypedArraySlice(start, end) {
+ if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+ var len = %_TypedArrayGetLength(this);
+
+ var relativeStart = TO_INTEGER(start);
+
+ var k;
+ if (relativeStart < 0) {
+ k = MaxSimple(len + relativeStart, 0);
+ } else {
+ k = MinSimple(relativeStart, len);
+ }
+
+ var relativeEnd;
+ if (IS_UNDEFINED(end)) {
+ relativeEnd = len;
+ } else {
+ relativeEnd = TO_INTEGER(end);
+ }
+
+ var final;
+ if (relativeEnd < 0) {
+ final = MaxSimple(len + relativeEnd, 0);
+ } else {
+ final = MinSimple(relativeEnd, len);
+ }
+
+ var count = MaxSimple(final - k, 0);
+ var array = TypedArraySpeciesCreate(this, count);
+ // The code below is the 'then' branch; the 'else' branch species
+ // a memcpy. Because V8 doesn't canonicalize NaN, the difference is
+ // unobservable.
+ var n = 0;
+ while (k < final) {
+ var kValue = this[k];
+ array[n] = kValue;
+ k++;
+ n++;
+ }
+ return array;
+}
+
+
+// ES2016 draft, section 22.2.3.14
+function TypedArrayIncludes(searchElement, fromIndex) {
+ if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
+
+ var length = %_TypedArrayGetLength(this);
+
+ return InnerArrayIncludes(searchElement, fromIndex, this, length);
+}
+%FunctionSetLength(TypedArrayIncludes, 1);
+
+
+// ES6 draft 08-24-14, section 22.2.2.2
+function TypedArrayOf() {
+ var length = %_ArgumentsLength();
+ var array = TypedArrayCreate(this, length);
+ for (var i = 0; i < length; i++) {
+ array[i] = %_Arguments(i);
+ }
+ return array;
+}
+
+
+function TypedArrayFrom(source, mapfn, thisArg) {
+ // TODO(littledan): Investigate if there is a receiver which could be
+ // faster to accumulate on than Array, e.g., a TypedVector.
+ // TODO(littledan): Rewrite this code to ensure that things happen
+ // in the right order, e.g., the constructor needs to be called before
+ // the mapping function on array-likes.
+ var array = %_Call(ArrayFrom, GlobalArray, source, mapfn, thisArg);
+ return TypedArrayCreate(this, array);
+}
+%FunctionSetLength(TypedArrayFrom, 1);
+
+function TypedArray() {
+ if (IS_UNDEFINED(new.target)) {
+ throw MakeTypeError(kConstructorNonCallable, "TypedArray");
+ }
+ if (new.target === TypedArray) {
+ throw MakeTypeError(kConstructAbstractClass, "TypedArray");
+ }
+}
+
+// -------------------------------------------------------------------
+
+%FunctionSetPrototype(TypedArray, new GlobalObject());
+%AddNamedProperty(TypedArray.prototype,
+ "constructor", TypedArray, DONT_ENUM);
+utils.InstallFunctions(TypedArray, DONT_ENUM | DONT_DELETE | READ_ONLY, [
+ "from", TypedArrayFrom,
+ "of", TypedArrayOf
+]);
+utils.InstallGetter(TypedArray.prototype, "buffer", TypedArrayGetBuffer);
+utils.InstallGetter(TypedArray.prototype, "byteOffset", TypedArrayGetByteOffset,
+ DONT_ENUM | DONT_DELETE);
+utils.InstallGetter(TypedArray.prototype, "byteLength",
+ TypedArrayGetByteLength, DONT_ENUM | DONT_DELETE);
+utils.InstallGetter(TypedArray.prototype, "length", TypedArrayGetLength,
+ DONT_ENUM | DONT_DELETE);
+utils.InstallGetter(TypedArray.prototype, toStringTagSymbol,
+ TypedArrayGetToStringTag);
+utils.InstallFunctions(TypedArray.prototype, DONT_ENUM, [
+ "subarray", TypedArraySubArray,
+ "set", TypedArraySet,
+ "copyWithin", TypedArrayCopyWithin,
+ "every", TypedArrayEvery,
+ "fill", TypedArrayFill,
+ "filter", TypedArrayFilter,
+ "find", TypedArrayFind,
+ "findIndex", TypedArrayFindIndex,
+ "includes", TypedArrayIncludes,
+ "indexOf", TypedArrayIndexOf,
+ "join", TypedArrayJoin,
+ "lastIndexOf", TypedArrayLastIndexOf,
+ "forEach", TypedArrayForEach,
+ "map", TypedArrayMap,
+ "reduce", TypedArrayReduce,
+ "reduceRight", TypedArrayReduceRight,
+ "reverse", TypedArrayReverse,
+ "slice", TypedArraySlice,
+ "some", TypedArraySome,
+ "sort", TypedArraySort,
+ "toString", TypedArrayToString,
+ "toLocaleString", TypedArrayToLocaleString
+]);
+
+
+macro SETUP_TYPED_ARRAY(ARRAY_ID, NAME, ELEMENT_SIZE)
+ %SetCode(GlobalNAME, NAMEConstructor);
+ %FunctionSetPrototype(GlobalNAME, new GlobalObject());
+ %InternalSetPrototype(GlobalNAME, TypedArray);
+ %InternalSetPrototype(GlobalNAME.prototype, TypedArray.prototype);
+
+ %AddNamedProperty(GlobalNAME, "BYTES_PER_ELEMENT", ELEMENT_SIZE,
+ READ_ONLY | DONT_ENUM | DONT_DELETE);
+
+ %AddNamedProperty(GlobalNAME.prototype,
+ "constructor", global.NAME, DONT_ENUM);
+ %AddNamedProperty(GlobalNAME.prototype,
+ "BYTES_PER_ELEMENT", ELEMENT_SIZE,
+ READ_ONLY | DONT_ENUM | DONT_DELETE);
+ // TODO(littledan): Remove this performance workaround BUG(chromium:579905)
+ utils.InstallGetter(GlobalNAME.prototype, "length", NAME_GetLength,
+ DONT_ENUM | DONT_DELETE);
+endmacro
+
+TYPED_ARRAYS(SETUP_TYPED_ARRAY)
+
+// --------------------------- DataView -----------------------------
+
+function DataViewConstructor(buffer, byteOffset, byteLength) { // length = 3
+ if (IS_UNDEFINED(new.target)) {
+ throw MakeTypeError(kConstructorNotFunction, "DataView");
+ }
+
+ // TODO(binji): support SharedArrayBuffers?
+ if (!IS_ARRAYBUFFER(buffer)) throw MakeTypeError(kDataViewNotArrayBuffer);
+ if (!IS_UNDEFINED(byteOffset)) {
+ byteOffset = ToPositiveInteger(byteOffset, kInvalidDataViewOffset);
+ }
+ if (!IS_UNDEFINED(byteLength)) {
+ byteLength = TO_INTEGER(byteLength);
+ }
+
+ var bufferByteLength = %_ArrayBufferGetByteLength(buffer);
+
+ var offset = IS_UNDEFINED(byteOffset) ? 0 : byteOffset;
+ if (offset > bufferByteLength) throw MakeRangeError(kInvalidDataViewOffset);
+
+ var length = IS_UNDEFINED(byteLength)
+ ? bufferByteLength - offset
+ : byteLength;
+ if (length < 0 || offset + length > bufferByteLength) {
+ throw new MakeRangeError(kInvalidDataViewLength);
+ }
+ var result = %NewObject(GlobalDataView, new.target);
+ %_DataViewInitialize(result, buffer, offset, length);
+ return result;
+}
+
+function DataViewGetBufferJS() {
+ if (!IS_DATAVIEW(this)) {
+ throw MakeTypeError(kIncompatibleMethodReceiver, 'DataView.buffer', this);
+ }
+ return %DataViewGetBuffer(this);
+}
+
+function DataViewGetByteOffset() {
+ if (!IS_DATAVIEW(this)) {
+ throw MakeTypeError(kIncompatibleMethodReceiver,
+ 'DataView.byteOffset', this);
+ }
+ return %_ArrayBufferViewGetByteOffset(this);
+}
+
+function DataViewGetByteLength() {
+ if (!IS_DATAVIEW(this)) {
+ throw MakeTypeError(kIncompatibleMethodReceiver,
+ 'DataView.byteLength', this);
+ }
+ return %_ArrayBufferViewGetByteLength(this);
+}
+
+macro DATA_VIEW_TYPES(FUNCTION)
+ FUNCTION(Int8)
+ FUNCTION(Uint8)
+ FUNCTION(Int16)
+ FUNCTION(Uint16)
+ FUNCTION(Int32)
+ FUNCTION(Uint32)
+ FUNCTION(Float32)
+ FUNCTION(Float64)
+endmacro
+
+
+macro DATA_VIEW_GETTER_SETTER(TYPENAME)
+function DataViewGetTYPENAMEJS(offset, little_endian) {
+ if (!IS_DATAVIEW(this)) {
+ throw MakeTypeError(kIncompatibleMethodReceiver,
+ 'DataView.getTYPENAME', this);
+ }
+ if (%_ArgumentsLength() < 1) throw MakeTypeError(kInvalidArgument);
+ offset = ToPositiveInteger(offset, kInvalidDataViewAccessorOffset);
+ return %DataViewGetTYPENAME(this, offset, !!little_endian);
+}
+
+function DataViewSetTYPENAMEJS(offset, value, little_endian) {
+ if (!IS_DATAVIEW(this)) {
+ throw MakeTypeError(kIncompatibleMethodReceiver,
+ 'DataView.setTYPENAME', this);
+ }
+ if (%_ArgumentsLength() < 2) throw MakeTypeError(kInvalidArgument);
+ offset = ToPositiveInteger(offset, kInvalidDataViewAccessorOffset);
+ %DataViewSetTYPENAME(this, offset, TO_NUMBER(value), !!little_endian);
+}
+endmacro
+
+DATA_VIEW_TYPES(DATA_VIEW_GETTER_SETTER)
+
+// Setup the DataView constructor.
+%SetCode(GlobalDataView, DataViewConstructor);
+%FunctionSetPrototype(GlobalDataView, new GlobalObject);
+
+// Set up constructor property on the DataView prototype.
+%AddNamedProperty(GlobalDataView.prototype, "constructor", GlobalDataView,
+ DONT_ENUM);
+%AddNamedProperty(GlobalDataView.prototype, toStringTagSymbol, "DataView",
+ READ_ONLY|DONT_ENUM);
+
+utils.InstallGetter(GlobalDataView.prototype, "buffer", DataViewGetBufferJS);
+utils.InstallGetter(GlobalDataView.prototype, "byteOffset",
+ DataViewGetByteOffset);
+utils.InstallGetter(GlobalDataView.prototype, "byteLength",
+ DataViewGetByteLength);
+
+utils.InstallFunctions(GlobalDataView.prototype, DONT_ENUM, [
+ "getInt8", DataViewGetInt8JS,
+ "setInt8", DataViewSetInt8JS,
+
+ "getUint8", DataViewGetUint8JS,
+ "setUint8", DataViewSetUint8JS,
+
+ "getInt16", DataViewGetInt16JS,
+ "setInt16", DataViewSetInt16JS,
+
+ "getUint16", DataViewGetUint16JS,
+ "setUint16", DataViewSetUint16JS,
+
+ "getInt32", DataViewGetInt32JS,
+ "setInt32", DataViewSetInt32JS,
+
+ "getUint32", DataViewGetUint32JS,
+ "setUint32", DataViewSetUint32JS,
+
+ "getFloat32", DataViewGetFloat32JS,
+ "setFloat32", DataViewSetFloat32JS,
+
+ "getFloat64", DataViewGetFloat64JS,
+ "setFloat64", DataViewSetFloat64JS
+]);
+
+})