[typedarrays] Check detached buffer at start of typed array methods
- Throw TypeError in ValidateTypedArray, matching JSC, SpiderMonkey and ChakraCore. - Validate typed arrays at start of each typed array prototype methods in src/js/typedarrays.js - Add tests to check detached buffers - Remove an unnecessary parameter of TypedArraySpeciesCreate in src/js/typedarrays.js - Standardize TypedArray.prototype.subarray - Update test262.status to pass detached buffer tests BUG=v8:4648,v8:4665,v8:4953 Review-Url: https://codereview.chromium.org/2778623003 Cr-Commit-Position: refs/heads/master@{#44357}
This commit is contained in:
parent
6cdd377586
commit
238d5b4453
@ -17,7 +17,8 @@ namespace internal {
|
||||
// ES6 section 22.2.3.1 get %TypedArray%.prototype.buffer
|
||||
BUILTIN(TypedArrayPrototypeBuffer) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSTypedArray, typed_array, "get TypedArray.prototype.buffer");
|
||||
CHECK_RECEIVER(JSTypedArray, typed_array,
|
||||
"get %TypedArray%.prototype.buffer");
|
||||
return *typed_array->GetBuffer();
|
||||
}
|
||||
|
||||
@ -128,8 +129,6 @@ BUILTIN(TypedArrayPrototypeCopyWithin) {
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, array, JSTypedArray::Validate(isolate, args.receiver(), method));
|
||||
|
||||
if (V8_UNLIKELY(array->WasNeutered())) return *array;
|
||||
|
||||
int64_t len = array->length_value();
|
||||
int64_t to = 0;
|
||||
int64_t from = 0;
|
||||
@ -193,8 +192,6 @@ BUILTIN(TypedArrayPrototypeFill) {
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, array, JSTypedArray::Validate(isolate, args.receiver(), method));
|
||||
|
||||
if (V8_UNLIKELY(array->WasNeutered())) return *array;
|
||||
|
||||
int64_t len = array->length_value();
|
||||
int64_t start = 0;
|
||||
int64_t end = len;
|
||||
@ -340,8 +337,6 @@ BUILTIN(TypedArrayPrototypeReverse) {
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, array, JSTypedArray::Validate(isolate, args.receiver(), method));
|
||||
|
||||
if (V8_UNLIKELY(array->WasNeutered())) return *array;
|
||||
|
||||
ElementsAccessor* elements = array->GetElementsAccessor();
|
||||
elements->Reverse(*array);
|
||||
return *array;
|
||||
|
@ -86,6 +86,8 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
|
||||
case Runtime::kInlineArrayBufferViewGetByteOffset:
|
||||
return ReduceArrayBufferViewField(
|
||||
node, AccessBuilder::ForJSArrayBufferViewByteOffset());
|
||||
case Runtime::kInlineArrayBufferViewWasNeutered:
|
||||
return ReduceArrayBufferViewWasNeutered(node);
|
||||
case Runtime::kInlineMaxSmi:
|
||||
return ReduceMaxSmi(node);
|
||||
case Runtime::kInlineTypedArrayGetLength:
|
||||
@ -374,6 +376,22 @@ Reduction JSIntrinsicLowering::ReduceArrayBufferViewField(
|
||||
return Replace(value);
|
||||
}
|
||||
|
||||
Reduction JSIntrinsicLowering::ReduceArrayBufferViewWasNeutered(Node* node) {
|
||||
Node* receiver = NodeProperties::GetValueInput(node, 0);
|
||||
Node* effect = NodeProperties::GetEffectInput(node);
|
||||
Node* control = NodeProperties::GetControlInput(node);
|
||||
|
||||
// Check if the {receiver}s buffer was neutered.
|
||||
Node* receiver_buffer = effect = graph()->NewNode(
|
||||
simplified()->LoadField(AccessBuilder::ForJSArrayBufferViewBuffer()),
|
||||
receiver, effect, control);
|
||||
Node* value = effect = graph()->NewNode(
|
||||
simplified()->ArrayBufferWasNeutered(), receiver_buffer, effect, control);
|
||||
|
||||
ReplaceWithValue(node, value, effect, control);
|
||||
return Replace(value);
|
||||
}
|
||||
|
||||
Reduction JSIntrinsicLowering::ReduceMaxSmi(Node* node) {
|
||||
Node* value = jsgraph()->Constant(Smi::kMaxValue);
|
||||
ReplaceWithValue(node, value);
|
||||
|
@ -68,6 +68,7 @@ class V8_EXPORT_PRIVATE JSIntrinsicLowering final
|
||||
// TODO(turbofan): typedarray.js support; drop once TypedArrays are
|
||||
// converted to proper CodeStubAssembler based builtins.
|
||||
Reduction ReduceArrayBufferViewField(Node* node, FieldAccess const& access);
|
||||
Reduction ReduceArrayBufferViewWasNeutered(Node* node);
|
||||
Reduction ReduceMaxSmi(Node* node);
|
||||
Reduction ReduceTypedArrayMaxSizeInHeap(Node* node);
|
||||
|
||||
|
@ -9924,6 +9924,23 @@ void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteOffset(
|
||||
FieldIndex::ForInObjectOffset(JSArrayBufferView::kByteOffsetOffset)));
|
||||
}
|
||||
|
||||
void HOptimizedGraphBuilder::GenerateArrayBufferViewWasNeutered(
|
||||
CallRuntime* expr) {
|
||||
NoObservableSideEffectsScope scope(this);
|
||||
DCHECK_EQ(expr->arguments()->length(), 1);
|
||||
CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
|
||||
HValue* view = Pop();
|
||||
|
||||
HInstruction* buffer = Add<HLoadNamedField>(
|
||||
view, nullptr, HObjectAccess::ForJSArrayBufferViewBuffer());
|
||||
HInstruction* flags = Add<HLoadNamedField>(
|
||||
buffer, nullptr, HObjectAccess::ForJSArrayBufferBitField());
|
||||
HValue* was_neutered_mask =
|
||||
Add<HConstant>(1 << JSArrayBuffer::WasNeutered::kShift);
|
||||
HValue* was_neutered =
|
||||
AddUncasted<HBitwise>(Token::BIT_AND, flags, was_neutered_mask);
|
||||
return ast_context()->ReturnValue(was_neutered);
|
||||
}
|
||||
|
||||
void HOptimizedGraphBuilder::GenerateTypedArrayGetLength(
|
||||
CallRuntime* expr) {
|
||||
|
@ -2175,6 +2175,7 @@ class HOptimizedGraphBuilder : public HGraphBuilder,
|
||||
F(TypedArrayMaxSizeInHeap) \
|
||||
F(ArrayBufferViewGetByteLength) \
|
||||
F(ArrayBufferViewGetByteOffset) \
|
||||
F(ArrayBufferViewWasNeutered) \
|
||||
F(TypedArrayGetLength) \
|
||||
/* ArrayBuffer */ \
|
||||
F(ArrayBufferGetByteLength) \
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
// array.js has to come before typedarray.js for this to work
|
||||
var ArrayToString = utils.ImportNow("ArrayToString");
|
||||
var ArrayValues;
|
||||
var GetIterator;
|
||||
var GetMethod;
|
||||
var GlobalArray = global.Array;
|
||||
@ -56,7 +55,6 @@ TYPED_ARRAYS(DECLARE_GLOBALS)
|
||||
var GlobalTypedArray = %object_get_prototype_of(GlobalUint8Array);
|
||||
|
||||
utils.Import(function(from) {
|
||||
ArrayValues = from.ArrayValues;
|
||||
GetIterator = from.GetIterator;
|
||||
GetMethod = from.GetMethod;
|
||||
InnerArrayFilter = from.InnerArrayFilter;
|
||||
@ -74,6 +72,14 @@ utils.Import(function(from) {
|
||||
|
||||
// --------------- Typed Arrays ---------------------
|
||||
|
||||
// ES6 section 22.2.3.5.1 ValidateTypedArray ( O )
|
||||
function ValidateTypedArray(array, methodName) {
|
||||
if (!IS_TYPEDARRAY(array)) throw %make_type_error(kNotTypedArray);
|
||||
|
||||
if (%_ArrayBufferViewWasNeutered(array))
|
||||
throw %make_type_error(kDetachedOperation, methodName);
|
||||
}
|
||||
|
||||
function TypedArrayDefaultConstructor(typedArray) {
|
||||
switch (%_ClassOf(typedArray)) {
|
||||
macro TYPED_ARRAY_CONSTRUCTOR_CASE(NAME, ELEMENT_SIZE)
|
||||
@ -94,20 +100,16 @@ function TypedArrayCreate(constructor, arg0, arg1, arg2) {
|
||||
} else {
|
||||
var newTypedArray = new constructor(arg0, arg1, arg2);
|
||||
}
|
||||
if (!IS_TYPEDARRAY(newTypedArray)) throw %make_type_error(kNotTypedArray);
|
||||
// TODO(littledan): Check for being detached, here and elsewhere
|
||||
// All callers where the first argument is a Number have no additional
|
||||
// arguments.
|
||||
ValidateTypedArray(newTypedArray, "TypedArrayCreate");
|
||||
if (IS_NUMBER(arg0) && %_TypedArrayGetLength(newTypedArray) < arg0) {
|
||||
throw %make_type_error(kTypedArrayTooShort);
|
||||
}
|
||||
return newTypedArray;
|
||||
}
|
||||
|
||||
function TypedArraySpeciesCreate(exemplar, arg0, arg1, arg2, conservative) {
|
||||
function TypedArraySpeciesCreate(exemplar, arg0, arg1, arg2) {
|
||||
var defaultConstructor = TypedArrayDefaultConstructor(exemplar);
|
||||
var constructor = SpeciesConstructor(exemplar, defaultConstructor,
|
||||
conservative);
|
||||
var constructor = SpeciesConstructor(exemplar, defaultConstructor);
|
||||
return TypedArrayCreate(constructor, arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
@ -207,10 +209,8 @@ function NAMESubArray(begin, end) {
|
||||
var newLength = endInt - beginInt;
|
||||
var beginByteOffset =
|
||||
%_ArrayBufferViewGetByteOffset(this) + beginInt * ELEMENT_SIZE;
|
||||
// BUG(v8:4665): For web compatibility, subarray needs to always build an
|
||||
// instance of the default constructor.
|
||||
// TODO(littledan): Switch to the standard or standardize the fix
|
||||
return new GlobalNAME(%TypedArrayGetBuffer(this), beginByteOffset, newLength);
|
||||
return TypedArraySpeciesCreate(this, %TypedArrayGetBuffer(this),
|
||||
beginByteOffset, newLength);
|
||||
}
|
||||
endmacro
|
||||
|
||||
@ -225,7 +225,7 @@ endmacro
|
||||
TYPED_ARRAYS(TYPED_ARRAY_SUBARRAY_CASE)
|
||||
}
|
||||
throw %make_type_error(kIncompatibleMethodReceiver,
|
||||
"get TypedArray.prototype.subarray", this);
|
||||
"get %TypedArray%.prototype.subarray", this);
|
||||
}
|
||||
%SetForceInlineFlag(TypedArraySubArray);
|
||||
|
||||
@ -361,7 +361,7 @@ function InnerTypedArrayEvery(f, receiver, array, length) {
|
||||
|
||||
// ES6 draft 05-05-15, section 22.2.3.7
|
||||
function TypedArrayEvery(f, receiver) {
|
||||
if (!IS_TYPEDARRAY(this)) throw %make_type_error(kNotTypedArray);
|
||||
ValidateTypedArray(this, "%TypedArray%.prototype.every");
|
||||
|
||||
var length = %_TypedArrayGetLength(this);
|
||||
|
||||
@ -391,7 +391,7 @@ function InnerTypedArrayForEach(f, receiver, array, length) {
|
||||
|
||||
// ES6 draft 08-24-14, section 22.2.3.12
|
||||
function TypedArrayForEach(f, receiver) {
|
||||
if (!IS_TYPEDARRAY(this)) throw %make_type_error(kNotTypedArray);
|
||||
ValidateTypedArray(this, "%TypedArray%.prototype.forEach");
|
||||
|
||||
var length = %_TypedArrayGetLength(this);
|
||||
|
||||
@ -402,7 +402,7 @@ function TypedArrayForEach(f, receiver) {
|
||||
|
||||
// ES6 draft 07-15-13, section 22.2.3.9
|
||||
function TypedArrayFilter(f, thisArg) {
|
||||
if (!IS_TYPEDARRAY(this)) throw %make_type_error(kNotTypedArray);
|
||||
ValidateTypedArray(this, "%TypeArray%.prototype.filter");
|
||||
|
||||
var length = %_TypedArrayGetLength(this);
|
||||
if (!IS_CALLABLE(f)) throw %make_type_error(kCalledNonCallable, f);
|
||||
@ -420,7 +420,7 @@ function TypedArrayFilter(f, thisArg) {
|
||||
|
||||
// ES6 draft 07-15-13, section 22.2.3.10
|
||||
function TypedArrayFind(predicate, thisArg) {
|
||||
if (!IS_TYPEDARRAY(this)) throw %make_type_error(kNotTypedArray);
|
||||
ValidateTypedArray(this, "%TypedArray%.prototype.find");
|
||||
|
||||
var length = %_TypedArrayGetLength(this);
|
||||
|
||||
@ -431,7 +431,7 @@ function TypedArrayFind(predicate, thisArg) {
|
||||
|
||||
// ES6 draft 07-15-13, section 22.2.3.11
|
||||
function TypedArrayFindIndex(predicate, thisArg) {
|
||||
if (!IS_TYPEDARRAY(this)) throw %make_type_error(kNotTypedArray);
|
||||
ValidateTypedArray(this, "%TypedArray%.prototype.findIndex");
|
||||
|
||||
var length = %_TypedArrayGetLength(this);
|
||||
|
||||
@ -442,7 +442,7 @@ function TypedArrayFindIndex(predicate, thisArg) {
|
||||
|
||||
// ES6 draft 05-18-15, section 22.2.3.25
|
||||
function TypedArraySort(comparefn) {
|
||||
if (!IS_TYPEDARRAY(this)) throw %make_type_error(kNotTypedArray);
|
||||
ValidateTypedArray(this, "%TypedArray%.prototype.sort");
|
||||
|
||||
var length = %_TypedArrayGetLength(this);
|
||||
|
||||
@ -456,7 +456,7 @@ function TypedArraySort(comparefn) {
|
||||
|
||||
// ES6 draft 07-15-13, section 22.2.3.18
|
||||
function TypedArrayMap(f, thisArg) {
|
||||
if (!IS_TYPEDARRAY(this)) throw %make_type_error(kNotTypedArray);
|
||||
ValidateTypedArray(this, "%TypedArray%.prototype.map");
|
||||
|
||||
var length = %_TypedArrayGetLength(this);
|
||||
var result = TypedArraySpeciesCreate(this, length);
|
||||
@ -483,7 +483,7 @@ function InnerTypedArraySome(f, receiver, array, length) {
|
||||
|
||||
// ES6 draft 05-05-15, section 22.2.3.24
|
||||
function TypedArraySome(f, receiver) {
|
||||
if (!IS_TYPEDARRAY(this)) throw %make_type_error(kNotTypedArray);
|
||||
ValidateTypedArray(this, "%TypedArray%.prototype.some");
|
||||
|
||||
var length = %_TypedArrayGetLength(this);
|
||||
|
||||
@ -494,7 +494,7 @@ function TypedArraySome(f, receiver) {
|
||||
|
||||
// ES6 section 22.2.3.27
|
||||
function TypedArrayToLocaleString() {
|
||||
if (!IS_TYPEDARRAY(this)) throw %make_type_error(kNotTypedArray);
|
||||
ValidateTypedArray(this, "%TypedArray%.prototype.toLocaleString");
|
||||
|
||||
var length = %_TypedArrayGetLength(this);
|
||||
|
||||
@ -504,7 +504,7 @@ function TypedArrayToLocaleString() {
|
||||
|
||||
// ES6 section 22.2.3.14
|
||||
function TypedArrayJoin(separator) {
|
||||
if (!IS_TYPEDARRAY(this)) throw %make_type_error(kNotTypedArray);
|
||||
ValidateTypedArray(this, "%TypedArray%.prototype.join");
|
||||
|
||||
var length = %_TypedArrayGetLength(this);
|
||||
|
||||
@ -539,7 +539,7 @@ function InnerTypedArrayReduce(
|
||||
|
||||
// ES6 draft 07-15-13, section 22.2.3.19
|
||||
function TypedArrayReduce(callback, current) {
|
||||
if (!IS_TYPEDARRAY(this)) throw %make_type_error(kNotTypedArray);
|
||||
ValidateTypedArray(this, "%TypedArray%.prototype.reduce");
|
||||
|
||||
var length = %_TypedArrayGetLength(this);
|
||||
return InnerTypedArrayReduce(
|
||||
@ -575,7 +575,7 @@ function InnerArrayReduceRight(callback, current, array, length,
|
||||
|
||||
// ES6 draft 07-15-13, section 22.2.3.19
|
||||
function TypedArrayReduceRight(callback, current) {
|
||||
if (!IS_TYPEDARRAY(this)) throw %make_type_error(kNotTypedArray);
|
||||
ValidateTypedArray(this, "%TypedArray%.prototype.reduceRight");
|
||||
|
||||
var length = %_TypedArrayGetLength(this);
|
||||
return InnerArrayReduceRight(callback, current, this, length,
|
||||
|
@ -6914,8 +6914,18 @@ MaybeHandle<JSTypedArray> JSTypedArray::Validate(Isolate* isolate,
|
||||
THROW_NEW_ERROR(isolate, NewTypeError(message), JSTypedArray);
|
||||
}
|
||||
|
||||
// TODO(caitp): throw if array.[[ViewedArrayBuffer]] is neutered (per v8:4648)
|
||||
return Handle<JSTypedArray>::cast(receiver);
|
||||
Handle<JSTypedArray> array = Handle<JSTypedArray>::cast(receiver);
|
||||
if (V8_UNLIKELY(array->WasNeutered())) {
|
||||
const MessageTemplate::Template message =
|
||||
MessageTemplate::kDetachedOperation;
|
||||
Handle<String> operation =
|
||||
isolate->factory()->NewStringFromAsciiChecked(method_name);
|
||||
THROW_NEW_ERROR(isolate, NewTypeError(message, operation), JSTypedArray);
|
||||
}
|
||||
|
||||
// spec describes to return `buffer`, but it may disrupt current
|
||||
// implementations, and it's much useful to return array for now.
|
||||
return array;
|
||||
}
|
||||
|
||||
#ifdef VERIFY_HEAP
|
||||
|
@ -56,6 +56,12 @@ BUFFER_VIEW_GETTER(TypedArray, Length, length)
|
||||
|
||||
#undef BUFFER_VIEW_GETTER
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_ArrayBufferViewWasNeutered) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
return isolate->heap()->ToBoolean(JSTypedArray::cast(args[0])->WasNeutered());
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_TypedArrayGetBuffer) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
@ -214,7 +220,6 @@ RUNTIME_FUNCTION(Runtime_IsTypedArray) {
|
||||
return isolate->heap()->ToBoolean(args[0]->IsJSTypedArray());
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_IsSharedTypedArray) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
|
@ -613,19 +613,20 @@ namespace internal {
|
||||
F(WasmNumInterpretedCalls, 1, 1) \
|
||||
F(RedirectToWasmInterpreter, 2, 1)
|
||||
|
||||
#define FOR_EACH_INTRINSIC_TYPEDARRAY(F) \
|
||||
F(ArrayBufferGetByteLength, 1, 1) \
|
||||
F(ArrayBufferNeuter, 1, 1) \
|
||||
F(ArrayBufferViewGetByteLength, 1, 1) \
|
||||
F(ArrayBufferViewGetByteOffset, 1, 1) \
|
||||
F(TypedArrayGetLength, 1, 1) \
|
||||
F(TypedArrayGetBuffer, 1, 1) \
|
||||
F(TypedArraySetFastCases, 3, 1) \
|
||||
F(TypedArraySortFast, 1, 1) \
|
||||
F(TypedArrayMaxSizeInHeap, 0, 1) \
|
||||
F(IsTypedArray, 1, 1) \
|
||||
F(IsSharedTypedArray, 1, 1) \
|
||||
F(IsSharedIntegerTypedArray, 1, 1) \
|
||||
#define FOR_EACH_INTRINSIC_TYPEDARRAY(F) \
|
||||
F(ArrayBufferGetByteLength, 1, 1) \
|
||||
F(ArrayBufferNeuter, 1, 1) \
|
||||
F(ArrayBufferViewGetByteLength, 1, 1) \
|
||||
F(ArrayBufferViewGetByteOffset, 1, 1) \
|
||||
F(ArrayBufferViewWasNeutered, 1, 1) \
|
||||
F(TypedArrayGetLength, 1, 1) \
|
||||
F(TypedArrayGetBuffer, 1, 1) \
|
||||
F(TypedArraySetFastCases, 3, 1) \
|
||||
F(TypedArraySortFast, 1, 1) \
|
||||
F(TypedArrayMaxSizeInHeap, 0, 1) \
|
||||
F(IsTypedArray, 1, 1) \
|
||||
F(IsSharedTypedArray, 1, 1) \
|
||||
F(IsSharedIntegerTypedArray, 1, 1) \
|
||||
F(IsSharedInteger32TypedArray, 1, 1)
|
||||
|
||||
#define FOR_EACH_INTRINSIC_WASM(F) \
|
||||
|
@ -240,8 +240,6 @@ CheckEachTypedArray(function parametersNotCalledIfDetached(constructor) {
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
%ArrayBufferNeuter(array.buffer);
|
||||
|
||||
// TODO(caitp): this should throw due to being invoked on a TypedArray with a
|
||||
// detached buffer (per v8:4648).
|
||||
array.copyWithin(tmp, tmp, tmp);
|
||||
assertThrows(() => array.copyWithin(tmp, tmp, tmp), TypeError);
|
||||
assertEquals(0, array.length, "array.[[ViewedArrayBuffer]] is detached");
|
||||
});
|
||||
|
@ -159,6 +159,11 @@ function TestTypedArrayForEach(constructor) {
|
||||
assertEquals(Array.prototype.every.call(a,
|
||||
function(elt) { x += elt; return true; }), true);
|
||||
assertEquals(x, 4);
|
||||
|
||||
// Detached Operation
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
%ArrayBufferNeuter(array.buffer);
|
||||
assertThrows(() => array.every(() => true), TypeError);
|
||||
}
|
||||
|
||||
for (i = 0; i < typedArrayConstructors.length; i++) {
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --allow-natives-syntax
|
||||
|
||||
var intArrayConstructors = [
|
||||
Uint8Array,
|
||||
Int8Array,
|
||||
@ -76,6 +78,19 @@ Symbol(Symbol.toStringTag)
|
||||
assertArrayEquals([3, 3], [a[0], a[1]]);
|
||||
Array.prototype.fill.call(a, 4);
|
||||
assertArrayEquals([4, 3], [a[0], a[1]]);
|
||||
|
||||
// Detached Operation
|
||||
var tmp = {
|
||||
[Symbol.toPrimitive]() {
|
||||
assertUnreachable("Parameter should not be processed when " +
|
||||
"array.[[ViewedArrayBuffer]] is neutered.");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
%ArrayBufferNeuter(array.buffer);
|
||||
assertThrows(() => array.fill(tmp), TypeError);
|
||||
}
|
||||
|
||||
for (var constructor of intArrayConstructors) {
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --allow-natives-syntax
|
||||
|
||||
var typedArrayConstructors = [
|
||||
Uint8Array,
|
||||
Int8Array,
|
||||
@ -184,4 +186,17 @@ assertEquals(Array.prototype.find.call(a,
|
||||
function(elt) { x += elt; return false; }), undefined);
|
||||
assertEquals(x, 4);
|
||||
|
||||
// Detached Operation
|
||||
var tmp = {
|
||||
[Symbol.toPrimitive]() {
|
||||
assertUnreachable("Parameter should not be processed when " +
|
||||
"array.[[ViewedArrayBuffer]] is neutered.");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
%ArrayBufferNeuter(array.buffer);
|
||||
|
||||
assertThrows(() => array.find(tmp), TypeError);
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --allow-natives-syntax
|
||||
|
||||
var typedArrayConstructors = [
|
||||
Uint8Array,
|
||||
Int8Array,
|
||||
@ -184,4 +186,17 @@ assertEquals(Array.prototype.findIndex.call(a,
|
||||
function(elt) { x += elt; return false; }), -1);
|
||||
assertEquals(x, 4);
|
||||
|
||||
// Detached Operation
|
||||
var tmp = {
|
||||
[Symbol.toPrimitive]() {
|
||||
assertUnreachable("Parameter should not be processed when " +
|
||||
"array.[[ViewedArrayBuffer]] is neutered.");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
%ArrayBufferNeuter(array.buffer);
|
||||
|
||||
assertThrows(() => array.findIndex(tmp), TypeError);
|
||||
}
|
||||
|
@ -148,6 +148,11 @@ function TestTypedArrayForEach(constructor) {
|
||||
assertEquals(Array.prototype.forEach.call(a,
|
||||
function(elt) { x += elt; }), undefined);
|
||||
assertEquals(x, 4);
|
||||
|
||||
// Detached Operation
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
%ArrayBufferNeuter(array.buffer);
|
||||
assertThrows(() => array.forEach(() => true), TypeError);
|
||||
}
|
||||
|
||||
for (i = 0; i < typedArrayConstructors.length; i++) {
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --allow-natives-syntax
|
||||
|
||||
var typedArrayConstructors = [
|
||||
Uint8Array,
|
||||
Int8Array,
|
||||
@ -14,6 +16,14 @@ var typedArrayConstructors = [
|
||||
Float64Array
|
||||
];
|
||||
|
||||
var tmp = {
|
||||
[Symbol.toPrimitive]() {
|
||||
assertUnreachable("Parameter should not be processed when " +
|
||||
"array.[[ViewedArrayBuffer]] is neutered.");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
for (var constructor of typedArrayConstructors) {
|
||||
var array = new constructor([1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]);
|
||||
|
||||
@ -53,6 +63,12 @@ for (var constructor of typedArrayConstructors) {
|
||||
}
|
||||
assertEquals(-1, array.indexOf(NaN));
|
||||
|
||||
// Detached Operation
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
%ArrayBufferNeuter(array.buffer);
|
||||
|
||||
assertThrows(() => array.indexOf(tmp), TypeError);
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// %TypedArray%.prototype.lastIndexOf.
|
||||
// ----------------------------------------------------------------------
|
||||
@ -89,4 +105,9 @@ for (var constructor of typedArrayConstructors) {
|
||||
assertEquals(-1, array.lastIndexOf(-Infinity));
|
||||
}
|
||||
assertEquals(-1, array.lastIndexOf(NaN));
|
||||
|
||||
// Detached Operation
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
%ArrayBufferNeuter(array.buffer);
|
||||
assertThrows(() => array.lastIndexOf(tmp), TypeError);
|
||||
}
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
// Tests for standard TypedArray array iteration functions.
|
||||
|
||||
// Flags: --allow-natives-syntax
|
||||
|
||||
var typedArrayConstructors = [
|
||||
Uint8Array,
|
||||
Int8Array,
|
||||
@ -77,6 +79,11 @@ for (var constructor of typedArrayConstructors) {
|
||||
assertArrayLikeEquals([2], a.filter(function(elt) {
|
||||
return elt == 2;
|
||||
}), constructor);
|
||||
|
||||
// Detached Operation
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
%ArrayBufferNeuter(array.buffer);
|
||||
assertThrows(() => array.filter(() => false), TypeError);
|
||||
})();
|
||||
|
||||
(function TypedArrayMapTest() {
|
||||
@ -130,6 +137,11 @@ for (var constructor of typedArrayConstructors) {
|
||||
return NaN;
|
||||
}), constructor);
|
||||
}
|
||||
|
||||
// Detached Operation
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
%ArrayBufferNeuter(array.buffer);
|
||||
assertThrows(() => array.map((v) => v), TypeError);
|
||||
})();
|
||||
|
||||
//
|
||||
@ -189,6 +201,11 @@ for (var constructor of typedArrayConstructors) {
|
||||
assertEquals(false, Array.prototype.some.call(a, function(elt) {
|
||||
return elt == 2;
|
||||
}));
|
||||
|
||||
// Detached Operation
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
%ArrayBufferNeuter(array.buffer);
|
||||
assertThrows(() => array.some((v) => false), TypeError);
|
||||
})();
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --allow-natives-syntax
|
||||
|
||||
var typedArrayConstructors = [
|
||||
Uint8Array,
|
||||
Int8Array,
|
||||
@ -247,4 +249,18 @@ for (var constructor of typedArrayConstructors) {
|
||||
|
||||
assertEquals(1, constructor.prototype.reduce.length);
|
||||
assertEquals(1, constructor.prototype.reduceRight.length);
|
||||
|
||||
// Detached Operation
|
||||
var tmp = {
|
||||
[Symbol.toPrimitive]() {
|
||||
assertUnreachable("Parameter should not be processed when " +
|
||||
"array.[[ViewedArrayBuffer]] is neutered.");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
%ArrayBufferNeuter(array.buffer);
|
||||
assertThrows(() => array.reduce(sum, tmp), TypeError);
|
||||
assertThrows(() => array.reduceRight(sum, tmp), TypeError);
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --allow-natives-syntax
|
||||
|
||||
function ArrayMaker(x) {
|
||||
return x;
|
||||
}
|
||||
@ -51,4 +53,11 @@ for (var constructor of arrayConstructors) {
|
||||
}
|
||||
|
||||
assertEquals(0, a.reverse.length);
|
||||
|
||||
// Detached Operation
|
||||
if (constructor != ArrayMaker) {
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
%ArrayBufferNeuter(array.buffer);
|
||||
assertThrows(() => array.reverse(), TypeError);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --allow-natives-syntax
|
||||
|
||||
var typedArrayConstructors = [
|
||||
Uint8Array,
|
||||
Int8Array,
|
||||
@ -69,6 +71,19 @@ for (var constructor of typedArrayConstructors) {
|
||||
assertEquals(3, slice[1]);
|
||||
assertTrue(slice instanceof constructor);
|
||||
|
||||
// Detached Operation
|
||||
var tmp = {
|
||||
[Symbol.toPrimitive]() {
|
||||
assertUnreachable("Parameter should not be processed when " +
|
||||
"array.[[ViewedArrayBuffer]] is neutered.");
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
%ArrayBufferNeuter(array.buffer);
|
||||
assertThrows(() => array.slice(tmp, tmp), TypeError);
|
||||
|
||||
// Check that the species array must be a typed array
|
||||
class MyTypedArray extends constructor {
|
||||
static get[Symbol.species]() {
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --allow-natives-syntax
|
||||
|
||||
var typedArrayConstructors = [
|
||||
Uint8Array,
|
||||
Int8Array,
|
||||
@ -60,4 +62,9 @@ for (var constructor of typedArrayConstructors) {
|
||||
b[0] = 3; b[1] = 2; b[2] = 1;
|
||||
a.sort();
|
||||
assertArrayLikeEquals(a, [1, 2], constructor);
|
||||
|
||||
// Detached Operation
|
||||
var array = new constructor([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
%ArrayBufferNeuter(array.buffer);
|
||||
assertThrows(() => array.sort(), TypeError);
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
// Array's toString should call the object's own join method, if one exists and
|
||||
// is callable. Otherwise, just use the original Object.toString function.
|
||||
|
||||
// Flags: --allow-natives-syntax
|
||||
|
||||
var typedArrayConstructors = [
|
||||
Uint8Array,
|
||||
Int8Array,
|
||||
@ -96,4 +98,11 @@ for (var constructor of typedArrayConstructors) {
|
||||
|
||||
Number.prototype.toLocaleString = NumberToLocaleString;
|
||||
})();
|
||||
|
||||
// Detached Operation
|
||||
var array = new constructor([1, 2, 3]);
|
||||
%ArrayBufferNeuter(array.buffer);
|
||||
assertThrows(() => array.join(), TypeError);
|
||||
assertThrows(() => array.toLocalString(), TypeError);
|
||||
assertThrows(() => array.toString(), TypeError);
|
||||
}
|
||||
|
@ -59,18 +59,18 @@ assertThrows(function() {
|
||||
|
||||
var buffer9 = new ArrayBuffer(1024);
|
||||
var array9 = new Uint8Array(buffer9);
|
||||
var array10 = array9.subarray({valueOf : function() {
|
||||
assertThrows(() =>
|
||||
array9.subarray({valueOf : function() {
|
||||
%ArrayBufferNeuter(buffer9);
|
||||
return 0;
|
||||
}}, 1024);
|
||||
}}, 1024), TypeError);
|
||||
assertEquals(0, array9.length);
|
||||
assertEquals(0, array10.length);
|
||||
|
||||
var buffer11 = new ArrayBuffer(1024);
|
||||
var array11 = new Uint8Array(buffer11);
|
||||
var array12 = array11.subarray(0, {valueOf : function() {
|
||||
%ArrayBufferNeuter(buffer11);
|
||||
return 1024;
|
||||
}});
|
||||
assertThrows(() =>
|
||||
array11.subarray(0, {valueOf : function() {
|
||||
%ArrayBufferNeuter(buffer11);
|
||||
return 1024;
|
||||
}}), TypeError);
|
||||
assertEquals(0, array11.length);
|
||||
assertEquals(0, array12.length);
|
||||
|
@ -11,12 +11,14 @@ FirstBuffer.__proto__ = Uint8Array
|
||||
var buf = new Uint8Array(10)
|
||||
buf.__proto__ = FirstBuffer.prototype
|
||||
|
||||
var buf2 = buf.subarray(2)
|
||||
assertEquals(8, buf2.length);
|
||||
assertThrows(() => buf.subarray(2), TypeError);
|
||||
|
||||
// Second test case
|
||||
|
||||
let seen_args = [];
|
||||
|
||||
function SecondBuffer (arg) {
|
||||
seen_args.push(arg);
|
||||
var arr = new Uint8Array(arg)
|
||||
arr.__proto__ = SecondBuffer.prototype
|
||||
return arr
|
||||
@ -25,7 +27,9 @@ SecondBuffer.prototype.__proto__ = Uint8Array.prototype
|
||||
SecondBuffer.__proto__ = Uint8Array
|
||||
|
||||
var buf3 = new SecondBuffer(10)
|
||||
assertEquals([10], seen_args);
|
||||
|
||||
var buf4 = buf3.subarray(2)
|
||||
|
||||
assertEquals(8, buf4.length);
|
||||
assertEquals(10, buf4.length);
|
||||
assertEquals([10, buf3.buffer], seen_args);
|
||||
|
@ -112,7 +112,6 @@
|
||||
'built-ins/TypedArray/prototype/slice/detached-buffer-custom-ctor-other-targettype': [FAIL],
|
||||
'built-ins/TypedArray/prototype/slice/detached-buffer-custom-ctor-same-targettype': [FAIL],
|
||||
'built-ins/TypedArray/prototype/slice/detached-buffer-get-ctor': [FAIL],
|
||||
'built-ins/TypedArray/prototype/slice/detached-buffer-speciesctor-get-species-custom-ctor-throws': [FAIL],
|
||||
'built-ins/TypedArray/prototype/some/callbackfn-detachbuffer': [FAIL],
|
||||
'built-ins/TypedArray/prototype/sort/detached-buffer-comparefn': [FAIL],
|
||||
# DataView functions should also throw on detached buffers
|
||||
@ -153,27 +152,6 @@
|
||||
'built-ins/DataView/prototype/setUint8/detached-buffer': [FAIL],
|
||||
'built-ins/DataView/prototype/setUint8/detached-buffer-before-outofrange-byteoffset': [FAIL],
|
||||
|
||||
# https://bugs.chromium.org/p/v8/issues/detail?id=4648
|
||||
'built-ins/TypedArray/prototype/copyWithin/detached-buffer': [FAIL],
|
||||
'built-ins/TypedArray/prototype/every/detached-buffer': [FAIL],
|
||||
'built-ins/TypedArray/prototype/fill/detached-buffer': [FAIL],
|
||||
'built-ins/TypedArray/prototype/filter/detached-buffer': [FAIL],
|
||||
'built-ins/TypedArray/prototype/find/detached-buffer': [FAIL],
|
||||
'built-ins/TypedArray/prototype/findIndex/detached-buffer': [FAIL],
|
||||
'built-ins/TypedArray/prototype/forEach/detached-buffer': [FAIL],
|
||||
'built-ins/TypedArray/prototype/includes/detached-buffer': [FAIL],
|
||||
'built-ins/TypedArray/prototype/indexOf/detached-buffer': [FAIL],
|
||||
'built-ins/TypedArray/prototype/join/detached-buffer': [FAIL],
|
||||
'built-ins/TypedArray/prototype/lastIndexOf/detached-buffer': [FAIL],
|
||||
'built-ins/TypedArray/prototype/map/detached-buffer': [FAIL],
|
||||
'built-ins/TypedArray/prototype/reverse/detached-buffer': [FAIL],
|
||||
'built-ins/TypedArray/prototype/slice/detached-buffer': [FAIL],
|
||||
'built-ins/TypedArray/prototype/some/detached-buffer': [FAIL],
|
||||
'built-ins/TypedArray/prototype/sort/detached-buffer': [FAIL],
|
||||
'built-ins/TypedArray/prototype/subarray/detached-buffer': [FAIL],
|
||||
'built-ins/TypedArray/prototype/toLocaleString/detached-buffer': [FAIL],
|
||||
'built-ins/TypedArray/prototype/toString/detached-buffer': [FAIL],
|
||||
|
||||
# https://bugs.chromium.org/p/v8/issues/detail?id=4034
|
||||
'built-ins/ThrowTypeError/unique-per-realm-function-proto': [FAIL],
|
||||
|
||||
@ -547,19 +525,6 @@
|
||||
# https://code.google.com/p/v8/issues/detail?id=4693
|
||||
'language/block-scope/syntax/redeclaration-in-block/attempt-to-redeclare-function-declaration-with-function-declaration': [PASS, FAIL_SLOPPY],
|
||||
|
||||
# https://bugs.chromium.org/p/v8/issues/detail?id=4953
|
||||
'built-ins/TypedArray/prototype/subarray/speciesctor-get-ctor': [FAIL],
|
||||
'built-ins/TypedArray/prototype/subarray/speciesctor-get-ctor-abrupt': [FAIL],
|
||||
'built-ins/TypedArray/prototype/subarray/speciesctor-get-ctor-inherited': [FAIL],
|
||||
'built-ins/TypedArray/prototype/subarray/speciesctor-get-ctor-returns-throws': [FAIL],
|
||||
'built-ins/TypedArray/prototype/subarray/speciesctor-get-species': [FAIL],
|
||||
'built-ins/TypedArray/prototype/subarray/speciesctor-get-species-abrupt': [FAIL],
|
||||
'built-ins/TypedArray/prototype/subarray/speciesctor-get-species-custom-ctor': [FAIL],
|
||||
'built-ins/TypedArray/prototype/subarray/speciesctor-get-species-custom-ctor-invocation': [FAIL],
|
||||
'built-ins/TypedArray/prototype/subarray/speciesctor-get-species-custom-ctor-returns-another-instance': [FAIL],
|
||||
'built-ins/TypedArray/prototype/subarray/speciesctor-get-species-custom-ctor-throws': [FAIL],
|
||||
'built-ins/TypedArray/prototype/subarray/speciesctor-get-species-returns-throws': [FAIL],
|
||||
|
||||
# We do not expose Array.prototype.values due to webcompat issues.
|
||||
# Most recent incompatability: https://crbug.com/615873
|
||||
# https://code.google.com/p/v8/issues/detail?id=4247
|
||||
|
Loading…
Reference in New Issue
Block a user