LibJS: Split detached buffer checking into validate_typed_array

Not all of the TypedArray prototype methods and accessors require
detached buffer validation (only the ones who call ValidateTypedArray)
so this behaviour was split from typed_array_from and the usage was
updated per the spec in each location.
This commit is contained in:
Idan Horowitz 2021-07-09 16:50:52 +03:00 committed by Linus Groh
parent 67362b1f85
commit 8127e30169

View file

@ -60,8 +60,9 @@ TypedArrayPrototype::~TypedArrayPrototype()
{ {
} }
static TypedArrayBase* typed_array_from(VM& vm, GlobalObject& global_object) static TypedArrayBase* typed_array_from(GlobalObject& global_object)
{ {
auto& vm = global_object.vm();
auto* this_object = vm.this_value(global_object).to_object(global_object); auto* this_object = vm.this_value(global_object).to_object(global_object);
if (!this_object) if (!this_object)
return nullptr; return nullptr;
@ -69,11 +70,22 @@ static TypedArrayBase* typed_array_from(VM& vm, GlobalObject& global_object)
vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "TypedArray"); vm.throw_exception<TypeError>(global_object, ErrorType::NotA, "TypedArray");
return nullptr; return nullptr;
} }
auto* typed_array = static_cast<TypedArrayBase*>(this_object); return static_cast<TypedArrayBase*>(this_object);
}
static TypedArrayBase* validate_typed_array(GlobalObject& global_object)
{
auto& vm = global_object.vm();
auto* typed_array = typed_array_from(global_object);
if (vm.exception())
return nullptr;
if (typed_array->viewed_array_buffer()->is_detached()) { if (typed_array->viewed_array_buffer()->is_detached()) {
vm.throw_exception<TypeError>(global_object, ErrorType::DetachedArrayBuffer); vm.throw_exception<TypeError>(global_object, ErrorType::DetachedArrayBuffer);
return nullptr; return nullptr;
} }
return typed_array; return typed_array;
} }
@ -94,7 +106,7 @@ static FunctionObject* callback_from_args(GlobalObject& global_object, const Str
static void for_each_item(VM& vm, GlobalObject& global_object, const String& name, Function<IterationDecision(size_t index, Value value, Value callback_result)> callback) static void for_each_item(VM& vm, GlobalObject& global_object, const String& name, Function<IterationDecision(size_t index, Value value, Value callback_result)> callback)
{ {
auto* typed_array = typed_array_from(vm, global_object); auto* typed_array = validate_typed_array(global_object);
if (!typed_array) if (!typed_array)
return; return;
@ -155,7 +167,7 @@ static TypedArrayBase* typed_array_species_create(GlobalObject& global_object, T
// 23.2.3.18 get %TypedArray%.prototype.length, https://tc39.es/ecma262/#sec-get-%typedarray%.prototype.length // 23.2.3.18 get %TypedArray%.prototype.length, https://tc39.es/ecma262/#sec-get-%typedarray%.prototype.length
JS_DEFINE_NATIVE_GETTER(TypedArrayPrototype::length_getter) JS_DEFINE_NATIVE_GETTER(TypedArrayPrototype::length_getter)
{ {
auto typed_array = typed_array_from(vm, global_object); auto typed_array = typed_array_from(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};
auto* array_buffer = typed_array->viewed_array_buffer(); auto* array_buffer = typed_array->viewed_array_buffer();
@ -168,7 +180,7 @@ JS_DEFINE_NATIVE_GETTER(TypedArrayPrototype::length_getter)
// 4.1 %TypedArray%.prototype.at ( index ), https://tc39.es/proposal-relative-indexing-method/#sec-%typedarray%.prototype.at // 4.1 %TypedArray%.prototype.at ( index ), https://tc39.es/proposal-relative-indexing-method/#sec-%typedarray%.prototype.at
JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::at) JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::at)
{ {
auto typed_array = typed_array_from(vm, global_object); auto* typed_array = validate_typed_array(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};
auto length = typed_array->array_length(); auto length = typed_array->array_length();
@ -206,7 +218,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::every)
// 23.2.3.8 %TypedArray%.prototype.fill ( value [ , start [ , end ] ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.fill // 23.2.3.8 %TypedArray%.prototype.fill ( value [ , start [ , end ] ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.fill
JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::fill) JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::fill)
{ {
auto typed_array = typed_array_from(vm, global_object); auto typed_array = validate_typed_array(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};
@ -306,7 +318,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::for_each)
// 23.2.3.13 %TypedArray%.prototype.includes ( searchElement [ , fromIndex ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.includes // 23.2.3.13 %TypedArray%.prototype.includes ( searchElement [ , fromIndex ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.includes
JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::includes) JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::includes)
{ {
auto typed_array = typed_array_from(vm, global_object); auto typed_array = validate_typed_array(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};
@ -349,7 +361,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::includes)
// 23.2.3.14 %TypedArray%.prototype.indexOf ( searchElement [ , fromIndex ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.indexof // 23.2.3.14 %TypedArray%.prototype.indexOf ( searchElement [ , fromIndex ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.indexof
JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::index_of) JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::index_of)
{ {
auto typed_array = typed_array_from(vm, global_object); auto typed_array = validate_typed_array(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};
@ -395,7 +407,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::index_of)
// 23.2.3.17 %TypedArray%.prototype.lastIndexOf ( searchElement [ , fromIndex ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.lastindexof // 23.2.3.17 %TypedArray%.prototype.lastIndexOf ( searchElement [ , fromIndex ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.lastindexof
JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::last_index_of) JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::last_index_of)
{ {
auto typed_array = typed_array_from(vm, global_object); auto typed_array = validate_typed_array(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};
@ -443,7 +455,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::last_index_of)
// 23.2.3.20 %TypedArray%.prototype.reduce ( callbackfn [ , initialValue ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.reduce // 23.2.3.20 %TypedArray%.prototype.reduce ( callbackfn [ , initialValue ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.reduce
JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::reduce) JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::reduce)
{ {
auto* typed_array = typed_array_from(vm, global_object); auto* typed_array = validate_typed_array(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};
@ -481,7 +493,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::reduce)
// 23.2.3.21 %TypedArray%.prototype.reduceRight ( callbackfn [ , initialValue ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.reduce // 23.2.3.21 %TypedArray%.prototype.reduceRight ( callbackfn [ , initialValue ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.reduce
JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::reduce_right) JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::reduce_right)
{ {
auto* typed_array = typed_array_from(vm, global_object); auto* typed_array = validate_typed_array(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};
@ -533,7 +545,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::some)
// 23.2.3.15 %TypedArray%.prototype.join ( separator ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.join // 23.2.3.15 %TypedArray%.prototype.join ( separator ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.join
JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::join) JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::join)
{ {
auto typed_array = typed_array_from(vm, global_object); auto* typed_array = validate_typed_array(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};
auto length = typed_array->array_length(); auto length = typed_array->array_length();
@ -565,7 +577,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::join)
// 23.2.3.16 %TypedArray%.prototype.keys ( ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.keys // 23.2.3.16 %TypedArray%.prototype.keys ( ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.keys
JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::keys) JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::keys)
{ {
auto typed_array = typed_array_from(vm, global_object); auto* typed_array = validate_typed_array(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};
return ArrayIterator::create(global_object, typed_array, Object::PropertyKind::Key); return ArrayIterator::create(global_object, typed_array, Object::PropertyKind::Key);
@ -574,7 +586,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::keys)
// 23.2.3.30 %TypedArray%.prototype.values ( ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.values // 23.2.3.30 %TypedArray%.prototype.values ( ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.values
JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::values) JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::values)
{ {
auto typed_array = typed_array_from(vm, global_object); auto* typed_array = typed_array_from(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};
return ArrayIterator::create(global_object, typed_array, Object::PropertyKind::Value); return ArrayIterator::create(global_object, typed_array, Object::PropertyKind::Value);
@ -583,7 +595,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::values)
// 23.2.3.6 %TypedArray%.prototype.entries ( ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.entries // 23.2.3.6 %TypedArray%.prototype.entries ( ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.entries
JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::entries) JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::entries)
{ {
auto typed_array = typed_array_from(vm, global_object); auto* typed_array = validate_typed_array(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};
return ArrayIterator::create(global_object, typed_array, Object::PropertyKind::KeyAndValue); return ArrayIterator::create(global_object, typed_array, Object::PropertyKind::KeyAndValue);
@ -592,7 +604,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::entries)
// 23.2.3.1 get %TypedArray%.prototype.buffer, https://tc39.es/ecma262/#sec-get-%typedarray%.prototype.buffer // 23.2.3.1 get %TypedArray%.prototype.buffer, https://tc39.es/ecma262/#sec-get-%typedarray%.prototype.buffer
JS_DEFINE_NATIVE_GETTER(TypedArrayPrototype::buffer_getter) JS_DEFINE_NATIVE_GETTER(TypedArrayPrototype::buffer_getter)
{ {
auto typed_array = typed_array_from(vm, global_object); auto* typed_array = typed_array_from(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};
auto* array_buffer = typed_array->viewed_array_buffer(); auto* array_buffer = typed_array->viewed_array_buffer();
@ -603,7 +615,7 @@ JS_DEFINE_NATIVE_GETTER(TypedArrayPrototype::buffer_getter)
// 23.2.3.2 get %TypedArray%.prototype.byteLength, https://tc39.es/ecma262/#sec-get-%typedarray%.prototype.bytelength // 23.2.3.2 get %TypedArray%.prototype.byteLength, https://tc39.es/ecma262/#sec-get-%typedarray%.prototype.bytelength
JS_DEFINE_NATIVE_GETTER(TypedArrayPrototype::byte_length_getter) JS_DEFINE_NATIVE_GETTER(TypedArrayPrototype::byte_length_getter)
{ {
auto typed_array = typed_array_from(vm, global_object); auto* typed_array = typed_array_from(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};
auto* array_buffer = typed_array->viewed_array_buffer(); auto* array_buffer = typed_array->viewed_array_buffer();
@ -616,7 +628,7 @@ JS_DEFINE_NATIVE_GETTER(TypedArrayPrototype::byte_length_getter)
// 23.2.3.3 get %TypedArray%.prototype.byteOffset, https://tc39.es/ecma262/#sec-get-%typedarray%.prototype.byteoffset // 23.2.3.3 get %TypedArray%.prototype.byteOffset, https://tc39.es/ecma262/#sec-get-%typedarray%.prototype.byteoffset
JS_DEFINE_NATIVE_GETTER(TypedArrayPrototype::byte_offset_getter) JS_DEFINE_NATIVE_GETTER(TypedArrayPrototype::byte_offset_getter)
{ {
auto typed_array = typed_array_from(vm, global_object); auto* typed_array = typed_array_from(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};
auto* array_buffer = typed_array->viewed_array_buffer(); auto* array_buffer = typed_array->viewed_array_buffer();
@ -641,7 +653,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_string_tag_getter)
// 23.2.3.23 %TypedArray%.prototype.set ( source [ , offset ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.set // 23.2.3.23 %TypedArray%.prototype.set ( source [ , offset ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.set
JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::set) JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::set)
{ {
auto* typed_array = typed_array_from(vm, global_object); auto* typed_array = typed_array_from(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};
@ -809,7 +821,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::reverse)
{ {
// 1. Let O be the this value. // 1. Let O be the this value.
// 2. Perform ? ValidateTypedArray(O). // 2. Perform ? ValidateTypedArray(O).
auto* typed_array = typed_array_from(vm, global_object); auto* typed_array = validate_typed_array(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};
@ -851,7 +863,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::copy_within)
{ {
// 1. Let O be the this value. // 1. Let O be the this value.
// 2. Perform ? ValidateTypedArray(O). // 2. Perform ? ValidateTypedArray(O).
auto* typed_array = typed_array_from(vm, global_object); auto* typed_array = validate_typed_array(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};
@ -1030,7 +1042,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::filter)
{ {
// 1. Let O be the this value. // 1. Let O be the this value.
// 2. Perform ? ValidateTypedArray(O). // 2. Perform ? ValidateTypedArray(O).
auto* typed_array = typed_array_from(vm, global_object); auto* typed_array = validate_typed_array(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};
@ -1102,7 +1114,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::map)
{ {
// 1. Let O be the this value. // 1. Let O be the this value.
// 2. Perform ? ValidateTypedArray(O). // 2. Perform ? ValidateTypedArray(O).
auto* typed_array = typed_array_from(vm, global_object); auto* typed_array = validate_typed_array(global_object);
if (!typed_array) if (!typed_array)
return {}; return {};