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:
littledan 2015-12-28 09:28:14 -08:00 committed by Commit bot
parent 9c304f1e78
commit 07c91dccbe
13 changed files with 254 additions and 195 deletions

View File

@ -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

View File

@ -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)

View File

@ -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'") \

View File

@ -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');

View File

@ -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);
})();

View File

@ -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) {

View File

@ -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);

View File

@ -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);
}

View File

@ -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
}
}

View File

@ -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,
];

View File

@ -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,
];

View File

@ -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
}
}

View File

@ -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);