Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2218)

Unified Diff: src/js/typedarray.js

Issue 1470193002: Array/TypedArray/ArrayBuffer method subclassing and @@species (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/js/runtime.js ('k') | src/messages.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/js/typedarray.js
diff --git a/src/js/typedarray.js b/src/js/typedarray.js
index 0ecc69a17cd2623202a120bbd1a45fe7a8d592b3..9b72e9a993598da2880a2ed1fa3d8e74df6c3ea3 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,49 @@ 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, skipCheckLength) {
+ 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
+ if (!skipCheckLength && %_TypedArrayGetLength(newTypedArray) < arg0) {
+ throw MakeTypeError(kTypedArrayTooShort);
+ }
+ return newTypedArray;
+}
+
+function TypedArraySpeciesCreate(exemplar, arg0, arg1, arg2, skipCheckLength) {
+ var defaultConstructor = TypedArrayDefaultConstructor(exemplar);
+ var constructor = SpeciesConstructor(exemplar, defaultConstructor);
+ return TypedArrayCreate(constructor, arg0, arg1, arg2, skipCheckLength);
+}
+
macro TYPED_ARRAY_CONSTRUCTOR(ARRAY_ID, NAME, ELEMENT_SIZE)
function NAMEConstructByArrayBuffer(obj, buffer, byteOffset, length) {
if (!IS_UNDEFINED(byteOffset)) {
@@ -210,6 +244,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 +289,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, true);
}
endmacro
@@ -420,32 +458,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 +511,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 +613,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 +711,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 +740,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 +751,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 write 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, UNDEFINED, UNDEFINED, true);
}
%FunctionSetLength(TypedArrayFrom, 1);
« no previous file with comments | « src/js/runtime.js ('k') | src/messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698