| Index: src/js/typedarray.js
|
| diff --git a/src/js/typedarray.js b/src/js/typedarray.js
|
| index 0ecc69a17cd2623202a120bbd1a45fe7a8d592b3..631add44eb5999df1ef45bdc5d5701adc6a54478 100644
|
| --- a/src/js/typedarray.js
|
| +++ b/src/js/typedarray.js
|
| @@ -18,6 +18,7 @@ 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;
|
| @@ -41,6 +42,7 @@ 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");
|
| @@ -87,17 +89,51 @@ utils.Import(function(from) {
|
| IsNaN = from.IsNaN;
|
| MakeRangeError = from.MakeRangeError;
|
| MakeTypeError = from.MakeTypeError;
|
| - MakeTypeError = from.MakeTypeError;
|
| MaxSimple = from.MaxSimple;
|
| - MaxSimple = from.MaxSimple;
|
| - MinSimple = from.MinSimple;
|
| 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) {
|
| + var defaultConstructor = TypedArrayDefaultConstructor(exemplar);
|
| + var constructor = SpeciesConstructor(exemplar, defaultConstructor);
|
| + 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)) {
|
| @@ -210,6 +246,10 @@ function NAMEConstructor(arg1, arg2, arg3) {
|
| 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);
|
| @@ -251,8 +291,8 @@ function NAMESubArray(begin, end) {
|
| var newLength = endInt - beginInt;
|
| var beginByteOffset =
|
| %_ArrayBufferViewGetByteOffset(this) + beginInt * ELEMENT_SIZE;
|
| - return new GlobalNAME(%TypedArrayGetBuffer(this),
|
| - beginByteOffset, newLength);
|
| + return TypedArraySpeciesCreate(this, %TypedArrayGetBuffer(this),
|
| + beginByteOffset, newLength);
|
| }
|
| endmacro
|
|
|
| @@ -420,32 +460,6 @@ function TypedArrayGetToStringTag() {
|
| }
|
|
|
|
|
| -function ConstructTypedArray(constructor, arg) {
|
| - // TODO(littledan): This is an approximation of the spec, which requires
|
| - // that only real TypedArray classes should be accepted (22.2.2.1.1)
|
| - if (!%IsConstructor(constructor) || IS_UNDEFINED(constructor.prototype) ||
|
| - !%HasOwnProperty(constructor.prototype, "BYTES_PER_ELEMENT")) {
|
| - throw MakeTypeError(kNotTypedArray);
|
| - }
|
| -
|
| - // TODO(littledan): The spec requires that, rather than directly calling
|
| - // the constructor, a TypedArray is created with the proper proto and
|
| - // underlying size and element size, and elements are put in one by one.
|
| - // By contrast, this would allow subclasses to make a radically different
|
| - // constructor with different semantics.
|
| - return new constructor(arg);
|
| -}
|
| -
|
| -
|
| -function ConstructTypedArrayLike(typedArray, arg) {
|
| - // TODO(littledan): The spec requires that we actuallly use
|
| - // typedArray.constructor[Symbol.species] (bug v8:4093)
|
| - // Also, it should default to the default constructor from
|
| - // table 49 if typedArray.constructor doesn't exist.
|
| - return ConstructTypedArray(typedArray.constructor, arg);
|
| -}
|
| -
|
| -
|
| function TypedArrayCopyWithin(target, start, end) {
|
| if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
|
|
| @@ -499,7 +513,7 @@ function TypedArrayFilter(f, thisArg) {
|
| var result = new InternalArray();
|
| InnerArrayFilter(f, thisArg, this, length, result);
|
| var captured = result.length;
|
| - var output = ConstructTypedArrayLike(this, captured);
|
| + var output = TypedArraySpeciesCreate(this, captured);
|
| for (var i = 0; i < captured; i++) {
|
| output[i] = result[i];
|
| }
|
| @@ -601,7 +615,7 @@ function TypedArrayMap(f, thisArg) {
|
| if (!%_IsTypedArray(this)) throw MakeTypeError(kNotTypedArray);
|
|
|
| var length = %_TypedArrayGetLength(this);
|
| - var result = ConstructTypedArrayLike(this, length);
|
| + var result = TypedArraySpeciesCreate(this, length);
|
| if (!IS_CALLABLE(f)) throw MakeTypeError(kCalledNonCallable, f);
|
| for (var i = 0; i < length; i++) {
|
| var element = this[i];
|
| @@ -699,15 +713,13 @@ function TypedArraySlice(start, end) {
|
| }
|
|
|
| var count = MaxSimple(final - k, 0);
|
| - var array = ConstructTypedArrayLike(this, count);
|
| + 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];
|
| - // TODO(littledan): The spec says to throw on an error in setting;
|
| - // does this throw?
|
| array[n] = kValue;
|
| k++;
|
| n++;
|
| @@ -730,7 +742,7 @@ function TypedArrayIncludes(searchElement, fromIndex) {
|
| // ES6 draft 08-24-14, section 22.2.2.2
|
| function TypedArrayOf() {
|
| var length = %_ArgumentsLength();
|
| - var array = new this(length);
|
| + var array = TypedArrayCreate(this, length);
|
| for (var i = 0; i < length; i++) {
|
| array[i] = %_Arguments(i);
|
| }
|
| @@ -741,8 +753,11 @@ function TypedArrayOf() {
|
| 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 ConstructTypedArray(this, array);
|
| + return TypedArrayCreate(this, array);
|
| }
|
| %FunctionSetLength(TypedArrayFrom, 1);
|
|
|
|
|