Use ES2015-style TypedArray prototype chain
This patch switches TypedArrays to use the prototype chain described in the ES2015 specification, which adds a %TypedArray% superclass above all individual TypedArray types. Most methods are defined on the superclass rather than the subclasses. In order to prevent a performance regression, a few methods are marked as inline. Inlining might prevent code which was previously monomorphic from becoming polymorphic, and it was specifically applied in places where methods became more polymorphic than before. Tests with realistic workloads would be nice to do before this ships in stable. This patch does not bring TypedArrays up to full spec compliance. In particular, @@species is not yet supported. R=cbruni BUG=v8:4085 LOG=Y Review URL: https://codereview.chromium.org/1541233002 Cr-Commit-Position: refs/heads/master@{#33050}
This commit is contained in:
parent
9c304f1e78
commit
07c91dccbe
@ -22,24 +22,7 @@ var IteratorPrototype = utils.ImportNow("IteratorPrototype");
|
||||
var iteratorSymbol = utils.ImportNow("iterator_symbol");
|
||||
var MakeTypeError;
|
||||
var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
|
||||
|
||||
macro TYPED_ARRAYS(FUNCTION)
|
||||
FUNCTION(Uint8Array)
|
||||
FUNCTION(Int8Array)
|
||||
FUNCTION(Uint16Array)
|
||||
FUNCTION(Int16Array)
|
||||
FUNCTION(Uint32Array)
|
||||
FUNCTION(Int32Array)
|
||||
FUNCTION(Float32Array)
|
||||
FUNCTION(Float64Array)
|
||||
FUNCTION(Uint8ClampedArray)
|
||||
endmacro
|
||||
|
||||
macro COPY_FROM_GLOBAL(NAME)
|
||||
var GlobalNAME = global.NAME;
|
||||
endmacro
|
||||
|
||||
TYPED_ARRAYS(COPY_FROM_GLOBAL)
|
||||
var GlobalTypedArray = global.Uint8Array.__proto__;
|
||||
|
||||
utils.Import(function(from) {
|
||||
MakeTypeError = from.MakeTypeError;
|
||||
@ -152,15 +135,12 @@ utils.SetFunctionName(ArrayValues, 'values');
|
||||
%AddNamedProperty(GlobalArray.prototype, iteratorSymbol, ArrayValues,
|
||||
DONT_ENUM);
|
||||
|
||||
macro EXTEND_TYPED_ARRAY(NAME)
|
||||
%AddNamedProperty(GlobalNAME.prototype, 'entries', ArrayEntries, DONT_ENUM);
|
||||
%AddNamedProperty(GlobalNAME.prototype, 'values', ArrayValues, DONT_ENUM);
|
||||
%AddNamedProperty(GlobalNAME.prototype, 'keys', ArrayKeys, DONT_ENUM);
|
||||
%AddNamedProperty(GlobalNAME.prototype, iteratorSymbol, ArrayValues,
|
||||
DONT_ENUM);
|
||||
endmacro
|
||||
|
||||
TYPED_ARRAYS(EXTEND_TYPED_ARRAY)
|
||||
%AddNamedProperty(GlobalTypedArray.prototype,
|
||||
'entries', ArrayEntries, DONT_ENUM);
|
||||
%AddNamedProperty(GlobalTypedArray.prototype, 'values', ArrayValues, DONT_ENUM);
|
||||
%AddNamedProperty(GlobalTypedArray.prototype, 'keys', ArrayKeys, DONT_ENUM);
|
||||
%AddNamedProperty(GlobalTypedArray.prototype,
|
||||
iteratorSymbol, ArrayValues, DONT_ENUM);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Exports
|
||||
|
@ -224,38 +224,7 @@ function NAMEConstructor(arg1, arg2, arg3) {
|
||||
}
|
||||
}
|
||||
|
||||
function NAME_GetBuffer() {
|
||||
if (!(%_ClassOf(this) === 'NAME')) {
|
||||
throw MakeTypeError(kIncompatibleMethodReceiver, "NAME.buffer", this);
|
||||
}
|
||||
return %TypedArrayGetBuffer(this);
|
||||
}
|
||||
|
||||
function NAME_GetByteLength() {
|
||||
if (!(%_ClassOf(this) === 'NAME')) {
|
||||
throw MakeTypeError(kIncompatibleMethodReceiver, "NAME.byteLength", this);
|
||||
}
|
||||
return %_ArrayBufferViewGetByteLength(this);
|
||||
}
|
||||
|
||||
function NAME_GetByteOffset() {
|
||||
if (!(%_ClassOf(this) === 'NAME')) {
|
||||
throw MakeTypeError(kIncompatibleMethodReceiver, "NAME.byteOffset", this);
|
||||
}
|
||||
return %_ArrayBufferViewGetByteOffset(this);
|
||||
}
|
||||
|
||||
function NAME_GetLength() {
|
||||
if (!(%_ClassOf(this) === 'NAME')) {
|
||||
throw MakeTypeError(kIncompatibleMethodReceiver, "NAME.length", this);
|
||||
}
|
||||
return %_TypedArrayGetLength(this);
|
||||
}
|
||||
|
||||
function NAMESubArray(begin, end) {
|
||||
if (!(%_ClassOf(this) === 'NAME')) {
|
||||
throw MakeTypeError(kIncompatibleMethodReceiver, "NAME.subarray", this);
|
||||
}
|
||||
var beginInt = TO_INTEGER(begin);
|
||||
if (!IS_UNDEFINED(end)) {
|
||||
var endInt = TO_INTEGER(end);
|
||||
@ -291,6 +260,56 @@ 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) {
|
||||
@ -719,59 +738,73 @@ function TypedArrayFrom(source, mapfn, thisArg) {
|
||||
}
|
||||
%FunctionSetLength(TypedArrayFrom, 1);
|
||||
|
||||
function TypedArray() {
|
||||
if (IS_UNDEFINED(new.target)) {
|
||||
throw MakeTypeError(kConstructorNonCallable, "TypedArray");
|
||||
}
|
||||
if (new.target === TypedArray) {
|
||||
throw MakeTypeError(kConstructAbstractClass, "TypedArray");
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// TODO(littledan): Fix the TypedArray proto chain (bug v8:4085).
|
||||
%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);
|
||||
|
||||
utils.InstallFunctions(GlobalNAME, DONT_ENUM | DONT_DELETE | READ_ONLY, [
|
||||
"from", TypedArrayFrom,
|
||||
"of", TypedArrayOf
|
||||
]);
|
||||
|
||||
%AddNamedProperty(GlobalNAME.prototype,
|
||||
"constructor", global.NAME, DONT_ENUM);
|
||||
%AddNamedProperty(GlobalNAME.prototype,
|
||||
"BYTES_PER_ELEMENT", ELEMENT_SIZE,
|
||||
READ_ONLY | DONT_ENUM | DONT_DELETE);
|
||||
utils.InstallGetter(GlobalNAME.prototype, "buffer", NAME_GetBuffer);
|
||||
utils.InstallGetter(GlobalNAME.prototype, "byteOffset", NAME_GetByteOffset,
|
||||
DONT_ENUM | DONT_DELETE);
|
||||
utils.InstallGetter(GlobalNAME.prototype, "byteLength", NAME_GetByteLength,
|
||||
DONT_ENUM | DONT_DELETE);
|
||||
utils.InstallGetter(GlobalNAME.prototype, "length", NAME_GetLength,
|
||||
DONT_ENUM | DONT_DELETE);
|
||||
utils.InstallGetter(GlobalNAME.prototype, toStringTagSymbol,
|
||||
TypedArrayGetToStringTag);
|
||||
utils.InstallFunctions(GlobalNAME.prototype, DONT_ENUM, [
|
||||
"subarray", NAMESubArray,
|
||||
"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
|
||||
]);
|
||||
endmacro
|
||||
|
||||
TYPED_ARRAYS(SETUP_TYPED_ARRAY)
|
||||
|
@ -100,6 +100,7 @@ class CallSite {
|
||||
T(CannotFreezeArrayBufferView, \
|
||||
"Cannot freeze array buffer views with elements") \
|
||||
T(CircularStructure, "Converting circular structure to JSON") \
|
||||
T(ConstructAbstractClass, "Abstract class % not directly constructable") \
|
||||
T(ConstAssign, "Assignment to constant variable.") \
|
||||
T(ConstructorNonCallable, \
|
||||
"Class constructor % cannot be invoked without 'new'") \
|
||||
|
@ -23,25 +23,13 @@ assertGetterName('get size', Set.prototype, 'size');
|
||||
assertGetterName('get size', Map.prototype, 'size');
|
||||
|
||||
|
||||
let typedArrays = [
|
||||
Uint8Array,
|
||||
Int8Array,
|
||||
Uint16Array,
|
||||
Int16Array,
|
||||
Uint32Array,
|
||||
Int32Array,
|
||||
Float32Array,
|
||||
Float64Array,
|
||||
Uint8ClampedArray
|
||||
];
|
||||
let TypedArray = Uint8Array.__proto__;
|
||||
|
||||
for (let f of typedArrays) {
|
||||
assertGetterName('get buffer', f.prototype, 'buffer');
|
||||
assertGetterName('get byteOffset', f.prototype, 'byteOffset');
|
||||
assertGetterName('get byteLength', f.prototype, 'byteLength');
|
||||
assertGetterName('get length', f.prototype, 'length');
|
||||
assertGetterName('get [Symbol.toStringTag]', f.prototype, Symbol.toStringTag);
|
||||
}
|
||||
assertGetterName('get buffer', TypedArray.prototype, 'buffer');
|
||||
assertGetterName('get byteOffset', TypedArray.prototype, 'byteOffset');
|
||||
assertGetterName('get byteLength', TypedArray.prototype, 'byteLength');
|
||||
assertGetterName('get length', TypedArray.prototype, 'length');
|
||||
assertGetterName('get [Symbol.toStringTag]', TypedArray.prototype, Symbol.toStringTag);
|
||||
|
||||
|
||||
assertGetterName('get buffer', DataView.prototype, 'buffer');
|
||||
|
@ -349,7 +349,43 @@ function TestErrorSubclassing(error) {
|
||||
})();
|
||||
|
||||
|
||||
function TestArraySubclassing(array) {
|
||||
(function TestArraySubclassing() {
|
||||
class A extends Array {
|
||||
constructor(...args) {
|
||||
assertFalse(new.target === undefined);
|
||||
super(...args);
|
||||
this.a = 42;
|
||||
this.d = 4.2;
|
||||
this.o = {foo:153};
|
||||
}
|
||||
}
|
||||
|
||||
var o = new Array(13);
|
||||
assertTrue(o instanceof Object);
|
||||
assertTrue(o instanceof Array);
|
||||
assertEquals("object", typeof o);
|
||||
checkPrototypeChain(o, [Array, Object]);
|
||||
assertEquals(13, o.length);
|
||||
|
||||
var o = new A(10);
|
||||
assertTrue(o instanceof Object);
|
||||
assertTrue(o instanceof Array);
|
||||
assertTrue(o instanceof A);
|
||||
assertEquals("object", typeof o);
|
||||
checkPrototypeChain(o, [A, Array, Object]);
|
||||
assertEquals(10, o.length);
|
||||
assertEquals(42, o.a);
|
||||
assertEquals(4.2, o.d);
|
||||
assertEquals(153, o.o.foo);
|
||||
|
||||
var o1 = new A(7);
|
||||
assertTrue(%HaveSameMap(o, o1));
|
||||
})();
|
||||
|
||||
|
||||
var TypedArray = Uint8Array.__proto__;
|
||||
|
||||
function TestTypedArraySubclassing(array) {
|
||||
class A extends array {
|
||||
constructor(...args) {
|
||||
assertFalse(new.target === undefined);
|
||||
@ -362,17 +398,19 @@ function TestArraySubclassing(array) {
|
||||
|
||||
var o = new array(13);
|
||||
assertTrue(o instanceof Object);
|
||||
assertTrue(o instanceof TypedArray);
|
||||
assertTrue(o instanceof array);
|
||||
assertEquals("object", typeof o);
|
||||
checkPrototypeChain(o, [array, Object]);
|
||||
checkPrototypeChain(o, [array, TypedArray, Object]);
|
||||
assertEquals(13, o.length);
|
||||
|
||||
var o = new A(10);
|
||||
assertTrue(o instanceof Object);
|
||||
assertTrue(o instanceof TypedArray);
|
||||
assertTrue(o instanceof array);
|
||||
assertTrue(o instanceof A);
|
||||
assertEquals("object", typeof o);
|
||||
checkPrototypeChain(o, [A, array, Object]);
|
||||
checkPrototypeChain(o, [A, array, TypedArray, Object]);
|
||||
assertEquals(10, o.length);
|
||||
assertEquals(42, o.a);
|
||||
assertEquals(4.2, o.d);
|
||||
@ -384,16 +422,15 @@ function TestArraySubclassing(array) {
|
||||
|
||||
|
||||
(function() {
|
||||
TestArraySubclassing(Array);
|
||||
TestArraySubclassing(Int8Array);
|
||||
TestArraySubclassing(Uint8Array);
|
||||
TestArraySubclassing(Uint8ClampedArray);
|
||||
TestArraySubclassing(Int16Array);
|
||||
TestArraySubclassing(Uint16Array);
|
||||
TestArraySubclassing(Int32Array);
|
||||
TestArraySubclassing(Uint32Array);
|
||||
TestArraySubclassing(Float32Array);
|
||||
TestArraySubclassing(Float64Array);
|
||||
TestTypedArraySubclassing(Int8Array);
|
||||
TestTypedArraySubclassing(Uint8Array);
|
||||
TestTypedArraySubclassing(Uint8ClampedArray);
|
||||
TestTypedArraySubclassing(Int16Array);
|
||||
TestTypedArraySubclassing(Uint16Array);
|
||||
TestTypedArraySubclassing(Int32Array);
|
||||
TestTypedArraySubclassing(Uint32Array);
|
||||
TestTypedArraySubclassing(Float32Array);
|
||||
TestTypedArraySubclassing(Float64Array);
|
||||
})();
|
||||
|
||||
|
||||
|
@ -9,23 +9,22 @@ var constructors = [Uint8Array, Int8Array,
|
||||
Float32Array, Float64Array,
|
||||
Uint8ClampedArray];
|
||||
|
||||
function TestTypedArrayPrototype(constructor) {
|
||||
assertTrue(constructor.prototype.hasOwnProperty('entries'));
|
||||
assertTrue(constructor.prototype.hasOwnProperty('values'));
|
||||
assertTrue(constructor.prototype.hasOwnProperty('keys'));
|
||||
assertTrue(constructor.prototype.hasOwnProperty(Symbol.iterator));
|
||||
var TypedArrayPrototype = Uint8Array.prototype.__proto__;
|
||||
|
||||
assertFalse(constructor.prototype.propertyIsEnumerable('entries'));
|
||||
assertFalse(constructor.prototype.propertyIsEnumerable('values'));
|
||||
assertFalse(constructor.prototype.propertyIsEnumerable('keys'));
|
||||
assertFalse(constructor.prototype.propertyIsEnumerable(Symbol.iterator));
|
||||
assertTrue(TypedArrayPrototype.hasOwnProperty('entries'));
|
||||
assertTrue(TypedArrayPrototype.hasOwnProperty('values'));
|
||||
assertTrue(TypedArrayPrototype.hasOwnProperty('keys'));
|
||||
assertTrue(TypedArrayPrototype.hasOwnProperty(Symbol.iterator));
|
||||
|
||||
assertEquals(Array.prototype.entries, constructor.prototype.entries);
|
||||
assertEquals(Array.prototype[Symbol.iterator], constructor.prototype.values);
|
||||
assertEquals(Array.prototype.keys, constructor.prototype.keys);
|
||||
assertEquals(Array.prototype[Symbol.iterator], constructor.prototype[Symbol.iterator]);
|
||||
}
|
||||
constructors.forEach(TestTypedArrayPrototype);
|
||||
assertFalse(TypedArrayPrototype.propertyIsEnumerable('entries'));
|
||||
assertFalse(TypedArrayPrototype.propertyIsEnumerable('values'));
|
||||
assertFalse(TypedArrayPrototype.propertyIsEnumerable('keys'));
|
||||
assertFalse(TypedArrayPrototype.propertyIsEnumerable(Symbol.iterator));
|
||||
|
||||
assertEquals(Array.prototype.entries, TypedArrayPrototype.entries);
|
||||
assertEquals(Array.prototype[Symbol.iterator], TypedArrayPrototype.values);
|
||||
assertEquals(Array.prototype.keys, TypedArrayPrototype.keys);
|
||||
assertEquals(Array.prototype[Symbol.iterator], TypedArrayPrototype[Symbol.iterator]);
|
||||
|
||||
|
||||
function TestTypedArrayValues(constructor) {
|
||||
|
@ -109,7 +109,7 @@ function TestTypedArrayOf(constructor) {
|
||||
assertEquals("pass", status);
|
||||
|
||||
// Check superficial features of %TypedArray%.of.
|
||||
var desc = Object.getOwnPropertyDescriptor(constructor, "of");
|
||||
var desc = Object.getOwnPropertyDescriptor(constructor.__proto__, "of");
|
||||
|
||||
assertEquals(desc.configurable, false);
|
||||
assertEquals(desc.enumerable, false);
|
||||
|
@ -4,12 +4,10 @@
|
||||
|
||||
// Test that the methods for different TypedArray types have the same
|
||||
// identity.
|
||||
// TODO(dehrenberg): Test that the TypedArray proto hierarchy is set
|
||||
// up properly.
|
||||
// TODO(dehrenberg): subarray is currently left out because that still
|
||||
// uses per-type methods. When that's fixed, stop leaving it out.
|
||||
|
||||
var typedArrayConstructors = [
|
||||
'use strict';
|
||||
|
||||
let typedArrayConstructors = [
|
||||
Uint8Array,
|
||||
Int8Array,
|
||||
Uint16Array,
|
||||
@ -20,6 +18,18 @@ var typedArrayConstructors = [
|
||||
Float32Array,
|
||||
Float64Array];
|
||||
|
||||
let TypedArray = Uint8Array.__proto__;
|
||||
let TypedArrayPrototype = TypedArray.prototype;
|
||||
|
||||
assertEquals(TypedArray.__proto__, Function.prototype);
|
||||
assertEquals(TypedArrayPrototype.__proto__, Object.prototype);
|
||||
|
||||
// There are extra own class properties due to it simply being a function
|
||||
let classProperties = new Set([
|
||||
"length", "name", "arguments", "caller", "prototype", "BYTES_PER_ELEMENT"
|
||||
]);
|
||||
let instanceProperties = new Set(["BYTES_PER_ELEMENT", "constructor", "prototype"]);
|
||||
|
||||
function functionProperties(object) {
|
||||
return Object.getOwnPropertyNames(object).filter(function(name) {
|
||||
return typeof Object.getOwnPropertyDescriptor(object, name).value
|
||||
@ -28,15 +38,33 @@ function functionProperties(object) {
|
||||
});
|
||||
}
|
||||
|
||||
var typedArrayMethods = functionProperties(Uint8Array.prototype);
|
||||
var typedArrayClassMethods = functionProperties(Uint8Array);
|
||||
let typedArrayMethods = functionProperties(Uint8Array.prototype);
|
||||
let typedArrayClassMethods = functionProperties(Uint8Array);
|
||||
|
||||
for (var constructor of typedArrayConstructors) {
|
||||
for (var method of typedArrayMethods) {
|
||||
assertEquals(constructor.prototype[method],
|
||||
Uint8Array.prototype[method], method);
|
||||
for (let constructor of typedArrayConstructors) {
|
||||
for (let property of Object.getOwnPropertyNames(constructor.prototype)) {
|
||||
assertTrue(instanceProperties.has(property), property);
|
||||
}
|
||||
for (var classMethod of typedArrayClassMethods) {
|
||||
assertEquals(constructor[method], Uint8Array[method], classMethod);
|
||||
for (let property of Object.getOwnPropertyNames(constructor)) {
|
||||
assertTrue(classProperties.has(property), property);
|
||||
}
|
||||
}
|
||||
|
||||
// Abstract %TypedArray% class can't be constructed directly
|
||||
|
||||
assertThrows(() => new TypedArray(), TypeError);
|
||||
|
||||
// The "prototype" property is nonconfigurable, nonenumerable, nonwritable,
|
||||
// both for %TypedArray% and for all subclasses
|
||||
|
||||
let desc = Object.getOwnPropertyDescriptor(TypedArray, "prototype");
|
||||
assertFalse(desc.writable);
|
||||
assertFalse(desc.configurable);
|
||||
assertFalse(desc.enumerable);
|
||||
|
||||
for (let constructor of typedArrayConstructors) {
|
||||
let desc = Object.getOwnPropertyDescriptor(constructor, "prototype");
|
||||
assertFalse(desc.writable);
|
||||
assertFalse(desc.configurable);
|
||||
assertFalse(desc.enumerable);
|
||||
}
|
||||
|
@ -270,7 +270,7 @@ function TestTypedArray(constr, elementSize, typicalElement) {
|
||||
assertEquals("[object " + constr.name + "]",
|
||||
Object.prototype.toString.call(a));
|
||||
var desc = Object.getOwnPropertyDescriptor(
|
||||
constr.prototype, Symbol.toStringTag);
|
||||
constr.prototype.__proto__, Symbol.toStringTag);
|
||||
assertTrue(desc.configurable);
|
||||
assertFalse(desc.enumerable);
|
||||
assertFalse(!!desc.writable);
|
||||
@ -418,17 +418,13 @@ var typedArrayConstructors = [
|
||||
function TestPropertyTypeChecks(constructor) {
|
||||
function CheckProperty(name) {
|
||||
assertThrows(function() { 'use strict'; new constructor(10)[name] = 0; })
|
||||
var d = Object.getOwnPropertyDescriptor(constructor.prototype, name);
|
||||
var d = Object.getOwnPropertyDescriptor(constructor.prototype.__proto__, name);
|
||||
var o = {};
|
||||
assertThrows(function() {d.get.call(o);}, TypeError);
|
||||
for (var i = 0; i < typedArrayConstructors.length; i++) {
|
||||
var ctor = typedArrayConstructors[i];
|
||||
var a = new ctor(10);
|
||||
if (ctor === constructor) {
|
||||
d.get.call(a); // shouldn't throw
|
||||
} else {
|
||||
assertThrows(function() {d.get.call(a);}, TypeError);
|
||||
}
|
||||
d.get.call(a); // shouldn't throw
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,12 +82,12 @@ var functions = [
|
||||
// DataView,
|
||||
Date,
|
||||
Error,
|
||||
Float32Array,
|
||||
Float64Array,
|
||||
// Float32Array, prototype is %TypedArray%
|
||||
// Float64Array,
|
||||
Function,
|
||||
Int16Array,
|
||||
Int32Array,
|
||||
Int8Array,
|
||||
// Int16Array,
|
||||
// Int32Array,
|
||||
// Int8Array,
|
||||
Map,
|
||||
Number,
|
||||
Object,
|
||||
@ -96,10 +96,10 @@ var functions = [
|
||||
Set,
|
||||
String,
|
||||
// Symbol, not constructible
|
||||
Uint16Array,
|
||||
Uint32Array,
|
||||
Uint8Array,
|
||||
Uint8ClampedArray,
|
||||
// Uint16Array,
|
||||
// Uint32Array,
|
||||
// Uint8Array,
|
||||
// Uint8ClampedArray,
|
||||
WeakMap,
|
||||
WeakSet,
|
||||
];
|
||||
|
@ -105,12 +105,12 @@ var functions = [
|
||||
// DataView,
|
||||
Date,
|
||||
Error,
|
||||
Float32Array,
|
||||
Float64Array,
|
||||
// Float32Array, prototype is %TypedArray%
|
||||
// Float64Array,
|
||||
Function,
|
||||
Int16Array,
|
||||
Int32Array,
|
||||
Int8Array,
|
||||
// Int16Array,
|
||||
// Int32Array,
|
||||
// Int8Array,
|
||||
Map,
|
||||
Number,
|
||||
Object,
|
||||
@ -119,10 +119,10 @@ var functions = [
|
||||
Set,
|
||||
String,
|
||||
// Symbol, not constructible
|
||||
Uint16Array,
|
||||
Uint32Array,
|
||||
Uint8Array,
|
||||
Uint8ClampedArray,
|
||||
// Uint16Array,
|
||||
// Uint32Array,
|
||||
// Uint8Array,
|
||||
// Uint8ClampedArray,
|
||||
WeakMap,
|
||||
WeakSet,
|
||||
];
|
||||
|
@ -204,7 +204,7 @@ function TestTypedArray(constr, elementSize, typicalElement) {
|
||||
assertEquals("[object " + constr.name + "]",
|
||||
Object.prototype.toString.call(a));
|
||||
var desc = Object.getOwnPropertyDescriptor(
|
||||
constr.prototype, Symbol.toStringTag);
|
||||
constr.prototype.__proto__, Symbol.toStringTag);
|
||||
assertTrue(desc.configurable);
|
||||
assertFalse(desc.enumerable);
|
||||
assertFalse(!!desc.writable);
|
||||
@ -310,17 +310,14 @@ var typedArrayConstructors = [
|
||||
|
||||
function TestPropertyTypeChecks(constructor) {
|
||||
function CheckProperty(name) {
|
||||
var d = Object.getOwnPropertyDescriptor(constructor.prototype, name);
|
||||
var d = Object.getOwnPropertyDescriptor(constructor.prototype.__proto__,
|
||||
name);
|
||||
var o = {};
|
||||
assertThrows(function() {d.get.call(o);}, TypeError);
|
||||
for (var i = 0; i < typedArrayConstructors.length; i++) {
|
||||
var ctor = typedArrayConstructors[i];
|
||||
var a = MakeSharedTypedArray(ctor, 10);
|
||||
if (ctor === constructor) {
|
||||
d.get.call(a); // shouldn't throw
|
||||
} else {
|
||||
assertThrows(function() {d.get.call(a);}, TypeError);
|
||||
}
|
||||
d.get.call(a); // shouldn't throw
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,12 +109,12 @@ assertEquals(undefined, get(a));
|
||||
})();
|
||||
|
||||
// Ensure we cannot delete length, byteOffset, byteLength.
|
||||
assertTrue(Int32Array.prototype.hasOwnProperty("length"));
|
||||
assertTrue(Int32Array.prototype.hasOwnProperty("byteOffset"));
|
||||
assertTrue(Int32Array.prototype.hasOwnProperty("byteLength"));
|
||||
assertFalse(delete Int32Array.prototype.length);
|
||||
assertFalse(delete Int32Array.prototype.byteOffset);
|
||||
assertFalse(delete Int32Array.prototype.byteLength);
|
||||
assertTrue(Int32Array.prototype.__proto__.hasOwnProperty("length"));
|
||||
assertTrue(Int32Array.prototype.__proto__.hasOwnProperty("byteOffset"));
|
||||
assertTrue(Int32Array.prototype.__proto__.hasOwnProperty("byteLength"));
|
||||
assertFalse(delete Int32Array.prototype.__proto__.length);
|
||||
assertFalse(delete Int32Array.prototype.__proto__.byteOffset);
|
||||
assertFalse(delete Int32Array.prototype.__proto__.byteLength);
|
||||
|
||||
a = new Int32Array(100);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user