summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp31
-rw-r--r--Userland/Libraries/LibJS/Runtime/AbstractOperations.h2
-rw-r--r--Userland/Libraries/LibJS/Runtime/ArrayBufferPrototype.cpp4
-rw-r--r--Userland/Libraries/LibJS/Runtime/PromisePrototype.cpp8
-rw-r--r--Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp8
-rw-r--r--Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp4
6 files changed, 29 insertions, 28 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp
index 57e837c819..b163f15118 100644
--- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp
+++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.cpp
@@ -97,25 +97,38 @@ ThrowCompletionOr<MarkedValueList> create_list_from_array_like(GlobalObject& glo
}
// 7.3.22 SpeciesConstructor ( O, defaultConstructor ), https://tc39.es/ecma262/#sec-speciesconstructor
-FunctionObject* species_constructor(GlobalObject& global_object, Object const& object, FunctionObject& default_constructor)
+ThrowCompletionOr<FunctionObject*> species_constructor(GlobalObject& global_object, Object const& object, FunctionObject& default_constructor)
{
auto& vm = global_object.vm();
+
+ // 1. Let C be ? Get(O, "constructor").
auto constructor = object.get(vm.names.constructor);
- if (vm.exception())
- return nullptr;
+ if (auto* exception = vm.exception())
+ return throw_completion(exception->value());
+
+ // 2. If C is undefined, return defaultConstructor.
if (constructor.is_undefined())
return &default_constructor;
- if (!constructor.is_object()) {
- vm.throw_exception<TypeError>(global_object, ErrorType::NotAConstructor, constructor.to_string_without_side_effects());
- return nullptr;
- }
+
+ // 3. If Type(C) is not Object, throw a TypeError exception.
+ if (!constructor.is_object())
+ return vm.throw_completion<TypeError>(global_object, ErrorType::NotAConstructor, constructor.to_string_without_side_effects());
+
+ // 4. Let S be ? Get(C, @@species).
auto species = constructor.as_object().get(*vm.well_known_symbol_species());
+ if (auto* exception = vm.exception())
+ return throw_completion(exception->value());
+
+ // 5. If S is either undefined or null, return defaultConstructor.
if (species.is_nullish())
return &default_constructor;
+
+ // 6. If IsConstructor(S) is true, return S.
if (species.is_constructor())
return &species.as_function();
- vm.throw_exception<TypeError>(global_object, ErrorType::NotAConstructor, species.to_string_without_side_effects());
- return nullptr;
+
+ // 7. Throw a TypeError exception.
+ return vm.throw_completion<TypeError>(global_object, ErrorType::NotAConstructor, species.to_string_without_side_effects());
}
// 7.3.24 GetFunctionRealm ( obj ), https://tc39.es/ecma262/#sec-getfunctionrealm
diff --git a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h
index acdae60347..51c6541560 100644
--- a/Userland/Libraries/LibJS/Runtime/AbstractOperations.h
+++ b/Userland/Libraries/LibJS/Runtime/AbstractOperations.h
@@ -22,7 +22,7 @@ Reference make_super_property_reference(GlobalObject&, Value actual_this, String
ThrowCompletionOr<Value> require_object_coercible(GlobalObject&, Value);
size_t length_of_array_like(GlobalObject&, Object const&);
ThrowCompletionOr<MarkedValueList> create_list_from_array_like(GlobalObject&, Value, Function<ThrowCompletionOr<void>(Value)> = {});
-FunctionObject* species_constructor(GlobalObject&, Object const&, FunctionObject& default_constructor);
+ThrowCompletionOr<FunctionObject*> species_constructor(GlobalObject&, Object const&, FunctionObject& default_constructor);
Realm* get_function_realm(GlobalObject&, FunctionObject const&);
bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const&, Optional<PropertyDescriptor> const& current);
bool validate_and_apply_property_descriptor(Object*, PropertyName const&, bool extensible, PropertyDescriptor const&, Optional<PropertyDescriptor> const& current);
diff --git a/Userland/Libraries/LibJS/Runtime/ArrayBufferPrototype.cpp b/Userland/Libraries/LibJS/Runtime/ArrayBufferPrototype.cpp
index f426754539..cf75b6cac9 100644
--- a/Userland/Libraries/LibJS/Runtime/ArrayBufferPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/ArrayBufferPrototype.cpp
@@ -71,9 +71,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayBufferPrototype::slice)
auto new_length = max(final - first, 0.0);
- auto constructor = species_constructor(global_object, *array_buffer_object, *global_object.array_buffer_constructor());
- if (vm.exception())
- return {};
+ auto* constructor = TRY_OR_DISCARD(species_constructor(global_object, *array_buffer_object, *global_object.array_buffer_constructor()));
MarkedValueList arguments(vm.heap());
arguments.append(Value(new_length));
diff --git a/Userland/Libraries/LibJS/Runtime/PromisePrototype.cpp b/Userland/Libraries/LibJS/Runtime/PromisePrototype.cpp
index 3ea98179ee..8efcb6e85e 100644
--- a/Userland/Libraries/LibJS/Runtime/PromisePrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/PromisePrototype.cpp
@@ -43,9 +43,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::then)
return {};
auto on_fulfilled = vm.argument(0);
auto on_rejected = vm.argument(1);
- auto* constructor = species_constructor(global_object, *promise, *global_object.promise_constructor());
- if (vm.exception())
- return {};
+ auto* constructor = TRY_OR_DISCARD(species_constructor(global_object, *promise, *global_object.promise_constructor()));
auto result_capability = new_promise_capability(global_object, constructor);
if (vm.exception())
return {};
@@ -66,9 +64,7 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
auto* promise = vm.this_value(global_object).to_object(global_object);
if (!promise)
return {};
- auto* constructor = species_constructor(global_object, *promise, *global_object.promise_constructor());
- if (vm.exception())
- return {};
+ auto* constructor = TRY_OR_DISCARD(species_constructor(global_object, *promise, *global_object.promise_constructor()));
Value then_finally;
Value catch_finally;
auto on_finally = vm.argument(0);
diff --git a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp b/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp
index ffd505e528..9bf56c5025 100644
--- a/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/RegExpPrototype.cpp
@@ -515,9 +515,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_match_all)
if (vm.exception())
return {};
- auto* constructor = species_constructor(global_object, *regexp_object, *global_object.regexp_constructor());
- if (vm.exception())
- return {};
+ auto* constructor = TRY_OR_DISCARD(species_constructor(global_object, *regexp_object, *global_object.regexp_constructor()));
auto flags_value = regexp_object->get(vm.names.flags);
if (vm.exception())
@@ -784,9 +782,7 @@ JS_DEFINE_NATIVE_FUNCTION(RegExpPrototype::symbol_split)
return {};
auto string_view = string.view();
- auto* constructor = species_constructor(global_object, *regexp_object, *global_object.regexp_constructor());
- if (vm.exception())
- return {};
+ auto* constructor = TRY_OR_DISCARD(species_constructor(global_object, *regexp_object, *global_object.regexp_constructor()));
auto flags_object = regexp_object->get(vm.names.flags);
if (vm.exception())
diff --git a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp
index 5efb49a60f..f2f4d9860b 100644
--- a/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp
@@ -175,9 +175,7 @@ static TypedArrayBase* typed_array_species_create(GlobalObject& global_object, T
VERIFY(typed_array_default_constructor);
- auto* constructor = species_constructor(global_object, exemplar, *typed_array_default_constructor);
- if (vm.exception())
- return nullptr;
+ auto* constructor = TRY_OR_DISCARD(species_constructor(global_object, exemplar, *typed_array_default_constructor));
auto* result = typed_array_create(global_object, *constructor, move(arguments));
if (vm.exception())