1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 11:37:44 +00:00

LibJS: Convert typed_array_create() to ThrowCompletionOr

Also add spec step comments to it while we're here.
This commit is contained in:
Linus Groh 2021-10-03 21:03:57 +01:00
parent 04ff12740c
commit 253d9a38d1
4 changed files with 25 additions and 30 deletions

View file

@ -345,29 +345,32 @@ static ThrowCompletionOr<void> initialize_typed_array_from_list(GlobalObject& gl
} }
// 23.2.4.2 TypedArrayCreate ( constructor, argumentList ), https://tc39.es/ecma262/#typedarray-create // 23.2.4.2 TypedArrayCreate ( constructor, argumentList ), https://tc39.es/ecma262/#typedarray-create
TypedArrayBase* typed_array_create(GlobalObject& global_object, FunctionObject& constructor, MarkedValueList arguments) ThrowCompletionOr<TypedArrayBase*> typed_array_create(GlobalObject& global_object, FunctionObject& constructor, MarkedValueList arguments)
{ {
auto& vm = global_object.vm(); auto& vm = global_object.vm();
auto argument_count = arguments.size(); Optional<Value> first_argument;
auto first_argument = argument_count > 0 ? arguments[0] : js_undefined(); if (!arguments.is_empty())
first_argument = arguments[0];
// 1. Let newTypedArray be ? Construct(constructor, argumentList).
auto new_typed_array = vm.construct(constructor, constructor, move(arguments)); auto new_typed_array = vm.construct(constructor, constructor, move(arguments));
if (vm.exception()) if (auto* exception = vm.exception())
return nullptr; return throw_completion(exception->value());
if (!new_typed_array.is_object() || !new_typed_array.as_object().is_typed_array()) {
vm.throw_exception<TypeError>(global_object, ErrorType::NotAnObjectOfType, "TypedArray"); // 2. Perform ? ValidateTypedArray(newTypedArray).
return nullptr; if (!new_typed_array.is_object() || !new_typed_array.as_object().is_typed_array())
} return vm.throw_completion<TypeError>(global_object, ErrorType::NotAnObjectOfType, "TypedArray");
auto& typed_array = static_cast<TypedArrayBase&>(new_typed_array.as_object()); auto& typed_array = static_cast<TypedArrayBase&>(new_typed_array.as_object());
if (typed_array.viewed_array_buffer()->is_detached()) { TRY(validate_typed_array(global_object, typed_array));
vm.throw_exception<TypeError>(global_object, ErrorType::DetachedArrayBuffer);
return nullptr; // 3. If argumentList is a List of a single Number, then
} if (first_argument.has_value() && first_argument->is_number()) {
if (argument_count == 1 && first_argument.is_number() && typed_array.array_length() < first_argument.as_double()) { // a. If newTypedArray.[[ArrayLength]] < (argumentList[0]), throw a TypeError exception.
vm.throw_exception<TypeError>(global_object, ErrorType::InvalidLength, "typed array"); if (typed_array.array_length() < first_argument->as_double())
return nullptr; return vm.throw_completion<TypeError>(global_object, ErrorType::InvalidLength, "typed array");
} }
// 4. Return newTypedArray.
return &typed_array; return &typed_array;
} }

View file

@ -480,7 +480,7 @@ private:
virtual bool is_typed_array() const final { return true; } virtual bool is_typed_array() const final { return true; }
}; };
TypedArrayBase* typed_array_create(GlobalObject& global_object, FunctionObject& constructor, MarkedValueList arguments); ThrowCompletionOr<TypedArrayBase*> typed_array_create(GlobalObject& global_object, FunctionObject& constructor, MarkedValueList arguments);
#define JS_DECLARE_TYPED_ARRAY(ClassName, snake_name, PrototypeName, ConstructorName, Type) \ #define JS_DECLARE_TYPED_ARRAY(ClassName, snake_name, PrototypeName, ConstructorName, Type) \
class ClassName : public TypedArray<Type> { \ class ClassName : public TypedArray<Type> { \

View file

@ -85,9 +85,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::from)
MarkedValueList arguments(vm.heap()); MarkedValueList arguments(vm.heap());
arguments.empend(values.size()); arguments.empend(values.size());
auto target_object = typed_array_create(global_object, constructor.as_function(), move(arguments)); auto target_object = TRY_OR_DISCARD(typed_array_create(global_object, constructor.as_function(), move(arguments)));
if (vm.exception())
return {};
for (size_t k = 0; k < values.size(); ++k) { for (size_t k = 0; k < values.size(); ++k) {
auto k_value = values[k]; auto k_value = values[k];
@ -107,9 +105,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::from)
MarkedValueList arguments(vm.heap()); MarkedValueList arguments(vm.heap());
arguments.empend(length); arguments.empend(length);
auto target_object = typed_array_create(global_object, constructor.as_function(), move(arguments)); auto target_object = TRY_OR_DISCARD(typed_array_create(global_object, constructor.as_function(), move(arguments)));
if (vm.exception())
return {};
for (size_t k = 0; k < length; ++k) { for (size_t k = 0; k < length; ++k) {
auto k_value = TRY_OR_DISCARD(array_like->get(k)); auto k_value = TRY_OR_DISCARD(array_like->get(k));
@ -135,9 +131,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::of)
} }
MarkedValueList arguments(vm.heap()); MarkedValueList arguments(vm.heap());
arguments.append(Value(length)); arguments.append(Value(length));
auto new_object = typed_array_create(global_object, constructor.as_function(), move(arguments)); auto new_object = TRY_OR_DISCARD(typed_array_create(global_object, constructor.as_function(), move(arguments)));
if (vm.exception())
return {};
for (size_t k = 0; k < length; ++k) { for (size_t k = 0; k < length; ++k) {
auto success = TRY_OR_DISCARD(new_object->set(k, vm.argument(k), Object::ShouldThrowExceptions::Yes)); auto success = TRY_OR_DISCARD(new_object->set(k, vm.argument(k), Object::ShouldThrowExceptions::Yes));
if (!success) { if (!success) {

View file

@ -177,9 +177,7 @@ static TypedArrayBase* typed_array_species_create(GlobalObject& global_object, T
auto* constructor = TRY_OR_DISCARD(species_constructor(global_object, exemplar, *typed_array_default_constructor)); auto* constructor = TRY_OR_DISCARD(species_constructor(global_object, exemplar, *typed_array_default_constructor));
auto* result = typed_array_create(global_object, *constructor, move(arguments)); auto* result = TRY_OR_DISCARD(typed_array_create(global_object, *constructor, move(arguments)));
if (vm.exception())
return nullptr;
if (result->content_type() != exemplar.content_type()) { if (result->content_type() != exemplar.content_type()) {
vm.throw_exception<TypeError>(global_object, ErrorType::TypedArrayContentTypeMismatch, result->class_name(), exemplar.class_name()); vm.throw_exception<TypeError>(global_object, ErrorType::TypedArrayContentTypeMismatch, result->class_name(), exemplar.class_name());