From ee825d6d9e1cb4d106a2fc87d9dafe517915d4de Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Thu, 23 Sep 2021 21:24:51 +0300 Subject: LibJS: Convert get_method to ThrowCompletionOr --- .../Libraries/LibJS/Runtime/ArrayConstructor.cpp | 4 +- .../Libraries/LibJS/Runtime/IteratorOperations.cpp | 20 +++++--- Userland/Libraries/LibJS/Runtime/ProxyObject.cpp | 53 ++++++---------------- .../Libraries/LibJS/Runtime/StringPrototype.cpp | 24 +++------- .../Libraries/LibJS/Runtime/Temporal/Calendar.cpp | 4 +- .../Libraries/LibJS/Runtime/Temporal/TimeZone.cpp | 4 +- Userland/Libraries/LibJS/Runtime/TypedArray.cpp | 4 +- .../LibJS/Runtime/TypedArrayConstructor.cpp | 4 +- Userland/Libraries/LibJS/Runtime/Value.cpp | 20 +++----- Userland/Libraries/LibJS/Runtime/Value.h | 2 +- 10 files changed, 47 insertions(+), 92 deletions(-) (limited to 'Userland/Libraries') diff --git a/Userland/Libraries/LibJS/Runtime/ArrayConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ArrayConstructor.cpp index 4660d78eec..2e92962e1a 100644 --- a/Userland/Libraries/LibJS/Runtime/ArrayConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/ArrayConstructor.cpp @@ -108,9 +108,7 @@ JS_DEFINE_NATIVE_FUNCTION(ArrayConstructor::from) auto this_arg = vm.argument(2); auto items = vm.argument(0); - auto using_iterator = items.get_method(global_object, *vm.well_known_symbol_iterator()); - if (vm.exception()) - return {}; + auto using_iterator = TRY_OR_DISCARD(items.get_method(global_object, *vm.well_known_symbol_iterator())); if (using_iterator) { Value array; if (constructor.is_constructor()) { diff --git a/Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp b/Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp index 9dccef24ac..1fbf437851 100644 --- a/Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp +++ b/Userland/Libraries/LibJS/Runtime/IteratorOperations.cpp @@ -124,16 +124,22 @@ void iterator_close(Object& iterator) vm.unwind(unwind_until, unwind_until_label); }; - auto return_method = Value(&iterator).get_method(global_object, vm.names.return_); - if (!return_method) - return restore_completion(); // If return is undefined, return Completion(completion). - - auto result_or_error = vm.call(*return_method, &iterator); + auto return_method_or_error = Value(&iterator).get_method(global_object, vm.names.return_); + Value result; + if (!return_method_or_error.is_error()) { // If innerResult.[[Type]] is normal, then + auto return_method = return_method_or_error.release_value(); + if (!return_method) + return restore_completion(); // If return is undefined, return Completion(completion). + auto result_or_error = vm.call(*return_method, &iterator); + if (result_or_error.is_error()) + return_method_or_error = result_or_error.release_error(); + else + result = result_or_error.release_value(); + } if (completion_exception) return restore_completion(); // If completion.[[Type]] is throw, return Completion(completion). - if (result_or_error.is_error()) + if (return_method_or_error.is_error()) return; // If innerResult.[[Type]] is throw, return Completion(innerResult). - auto result = result_or_error.release_value(); if (!result.is_object()) { vm.throw_exception(global_object, ErrorType::IterableReturnBadReturn); return; // If Type(innerResult.[[Value]]) is not Object, throw a TypeError exception. diff --git a/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp b/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp index ac2d9628f2..37f0db4d5a 100644 --- a/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp @@ -62,9 +62,7 @@ Object* ProxyObject::internal_get_prototype_of() const // 4. Let target be O.[[ProxyTarget]]. // 5. Let trap be ? GetMethod(handler, "getPrototypeOf"). - auto trap = Value(&m_handler).get_method(global_object, vm.names.getPrototypeOf); - if (vm.exception()) - return {}; + auto trap = TRY_OR_DISCARD(Value(&m_handler).get_method(global_object, vm.names.getPrototypeOf)); // 6. If trap is undefined, then if (!trap) { @@ -124,9 +122,7 @@ bool ProxyObject::internal_set_prototype_of(Object* prototype) // 5. Let target be O.[[ProxyTarget]]. // 6. Let trap be ? GetMethod(handler, "setPrototypeOf"). - auto trap = Value(&m_handler).get_method(global_object, vm.names.setPrototypeOf); - if (vm.exception()) - return {}; + auto trap = TRY_OR_DISCARD(Value(&m_handler).get_method(global_object, vm.names.setPrototypeOf)); // 7. If trap is undefined, then if (!trap) { @@ -183,9 +179,7 @@ bool ProxyObject::internal_is_extensible() const // 4. Let target be O.[[ProxyTarget]]. // 5. Let trap be ? GetMethod(handler, "isExtensible"). - auto trap = Value(&m_handler).get_method(global_object, vm.names.isExtensible); - if (vm.exception()) - return {}; + auto trap = TRY_OR_DISCARD(Value(&m_handler).get_method(global_object, vm.names.isExtensible)); // 6. If trap is undefined, then if (!trap) { @@ -229,9 +223,7 @@ bool ProxyObject::internal_prevent_extensions() // 4. Let target be O.[[ProxyTarget]]. // 5. Let trap be ? GetMethod(handler, "preventExtensions"). - auto trap = Value(&m_handler).get_method(global_object, vm.names.preventExtensions); - if (vm.exception()) - return {}; + auto trap = TRY_OR_DISCARD(Value(&m_handler).get_method(global_object, vm.names.preventExtensions)); // 6. If trap is undefined, then if (!trap) { @@ -281,9 +273,7 @@ Optional ProxyObject::internal_get_own_property(const Proper // 5. Let target be O.[[ProxyTarget]]. // 6. Let trap be ? GetMethod(handler, "getOwnPropertyDescriptor"). - auto trap = Value(&m_handler).get_method(global_object, vm.names.getOwnPropertyDescriptor); - if (vm.exception()) - return {}; + auto trap = TRY_OR_DISCARD(Value(&m_handler).get_method(global_object, vm.names.getOwnPropertyDescriptor)); // 7. If trap is undefined, then if (!trap) { @@ -397,9 +387,7 @@ bool ProxyObject::internal_define_own_property(PropertyName const& property_name // 5. Let target be O.[[ProxyTarget]]. // 6. Let trap be ? GetMethod(handler, "defineProperty"). - auto trap = Value(&m_handler).get_method(global_object, vm.names.defineProperty); - if (vm.exception()) - return {}; + auto trap = TRY_OR_DISCARD(Value(&m_handler).get_method(global_object, vm.names.defineProperty)); // 7. If trap is undefined, then if (!trap) { @@ -496,9 +484,7 @@ bool ProxyObject::internal_has_property(PropertyName const& property_name) const // 5. Let target be O.[[ProxyTarget]]. // 6. Let trap be ? GetMethod(handler, "has"). - auto trap = Value(&m_handler).get_method(global_object, vm.names.has); - if (vm.exception()) - return {}; + auto trap = TRY_OR_DISCARD(Value(&m_handler).get_method(global_object, vm.names.has)); // 7. If trap is undefined, then if (!trap) { @@ -582,9 +568,7 @@ Value ProxyObject::internal_get(PropertyName const& property_name, Value receive } // 6. Let trap be ? GetMethod(handler, "get"). - auto trap = Value(&m_handler).get_method(global_object, vm.names.get); - if (vm.exception()) - return {}; + auto trap = TRY_OR_DISCARD(Value(&m_handler).get_method(global_object, vm.names.get)); // 7. If trap is undefined, then if (!trap) { @@ -648,9 +632,7 @@ bool ProxyObject::internal_set(PropertyName const& property_name, Value value, V // 5. Let target be O.[[ProxyTarget]]. // 6. Let trap be ? GetMethod(handler, "set"). - auto trap = Value(&m_handler).get_method(global_object, vm.names.set); - if (vm.exception()) - return {}; + auto trap = TRY_OR_DISCARD(Value(&m_handler).get_method(global_object, vm.names.set)); // 7. If trap is undefined, then if (!trap) { @@ -715,9 +697,7 @@ bool ProxyObject::internal_delete(PropertyName const& property_name) // 5. Let target be O.[[ProxyTarget]]. // 6. Let trap be ? GetMethod(handler, "deleteProperty"). - auto trap = Value(&m_handler).get_method(global_object, vm.names.deleteProperty); - if (vm.exception()) - return {}; + auto trap = TRY_OR_DISCARD(Value(&m_handler).get_method(global_object, vm.names.deleteProperty)); // 7. If trap is undefined, then if (!trap) { @@ -780,9 +760,10 @@ MarkedValueList ProxyObject::internal_own_property_keys() const // 4. Let target be O.[[ProxyTarget]]. // 5. Let trap be ? GetMethod(handler, "ownKeys"). - auto trap = Value(&m_handler).get_method(global_object, vm.names.ownKeys); - if (vm.exception()) + auto trap_or_error = Value(&m_handler).get_method(global_object, vm.names.ownKeys); + if (trap_or_error.is_error()) return MarkedValueList { heap() }; + auto trap = trap_or_error.release_value(); // 6. If trap is undefined, then if (!trap) { @@ -931,9 +912,7 @@ Value ProxyObject::call() // 4. Let target be O.[[ProxyTarget]]. // 5. Let trap be ? GetMethod(handler, "apply"). - auto trap = Value(&m_handler).get_method(global_object, vm.names.apply); - if (vm.exception()) - return {}; + auto trap = TRY_OR_DISCARD(Value(&m_handler).get_method(global_object, vm.names.apply)); // 6. If trap is undefined, then if (!trap) { @@ -976,9 +955,7 @@ Value ProxyObject::construct(FunctionObject& new_target) // 5. Assert: IsConstructor(target) is true. // 6. Let trap be ? GetMethod(handler, "construct"). - auto trap = Value(&m_handler).get_method(global_object, vm.names.construct); - if (vm.exception()) - return {}; + auto trap = TRY_OR_DISCARD(Value(&m_handler).get_method(global_object, vm.names.construct)); // 7. If trap is undefined, then if (!trap) { diff --git a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp index e22ef1f45d..6fb4f8d613 100644 --- a/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/StringPrototype.cpp @@ -710,9 +710,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::split) auto limit_argument = vm.argument(1); if (!separator_argument.is_nullish()) { - auto splitter = separator_argument.get_method(global_object, *vm.well_known_symbol_split()); - if (vm.exception()) - return {}; + auto splitter = TRY_OR_DISCARD(separator_argument.get_method(global_object, *vm.well_known_symbol_split())); if (splitter) return TRY_OR_DISCARD(vm.call(*splitter, separator_argument, object, limit_argument)); } @@ -860,10 +858,8 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::match) auto this_object = TRY_OR_DISCARD(require_object_coercible(global_object, vm.this_value(global_object))); auto regexp = vm.argument(0); if (!regexp.is_nullish()) { - if (auto* matcher = regexp.get_method(global_object, *vm.well_known_symbol_match())) + if (auto* matcher = TRY_OR_DISCARD(regexp.get_method(global_object, *vm.well_known_symbol_match()))) return TRY_OR_DISCARD(vm.call(*matcher, regexp, this_object)); - if (vm.exception()) - return {}; } auto string = this_object.to_utf16_string(global_object); @@ -896,10 +892,8 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::match_all) return {}; } } - if (auto* matcher = regexp.get_method(global_object, *vm.well_known_symbol_match_all())) + if (auto* matcher = TRY_OR_DISCARD(regexp.get_method(global_object, *vm.well_known_symbol_match_all()))) return TRY_OR_DISCARD(vm.call(*matcher, regexp, this_object)); - if (vm.exception()) - return {}; } auto string = this_object.to_utf16_string(global_object); @@ -920,10 +914,8 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace) auto replace_value = vm.argument(1); if (!search_value.is_nullish()) { - if (auto* replacer = search_value.get_method(global_object, *vm.well_known_symbol_replace())) + if (auto* replacer = TRY_OR_DISCARD(search_value.get_method(global_object, *vm.well_known_symbol_replace()))) return TRY_OR_DISCARD(vm.call(*replacer, search_value, this_object, replace_value)); - if (vm.exception()) - return {}; } auto string = this_object.to_utf16_string(global_object); @@ -991,9 +983,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::replace_all) } } - auto* replacer = search_value.get_method(global_object, *vm.well_known_symbol_replace()); - if (vm.exception()) - return {}; + auto* replacer = TRY_OR_DISCARD(search_value.get_method(global_object, *vm.well_known_symbol_replace())); if (replacer) return TRY_OR_DISCARD(vm.call(*replacer, search_value, this_object, replace_value)); } @@ -1061,10 +1051,8 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::search) auto this_object = TRY_OR_DISCARD(require_object_coercible(global_object, vm.this_value(global_object))); auto regexp = vm.argument(0); if (!regexp.is_nullish()) { - if (auto* searcher = regexp.get_method(global_object, *vm.well_known_symbol_search())) + if (auto* searcher = TRY_OR_DISCARD(regexp.get_method(global_object, *vm.well_known_symbol_search()))) return TRY_OR_DISCARD(vm.call(*searcher, regexp, this_object)); - if (vm.exception()) - return {}; } auto string = this_object.to_utf16_string(global_object); diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp index b691651ba2..8e13aee3b7 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/Calendar.cpp @@ -90,9 +90,7 @@ ThrowCompletionOr> calendar_fields(GlobalObject& global_object, O auto& vm = global_object.vm(); // 1. Let fields be ? GetMethod(calendar, "fields"). - auto fields = Value(&calendar).get_method(global_object, vm.names.fields); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto fields = TRY(Value(&calendar).get_method(global_object, vm.names.fields)); // 2. Let fieldsArray be ! CreateArrayFromList(fieldNames). auto field_names_values = MarkedValueList { vm.heap() }; diff --git a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp index 6c91304ec8..8e6109736e 100644 --- a/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp +++ b/Userland/Libraries/LibJS/Runtime/Temporal/TimeZone.cpp @@ -365,9 +365,7 @@ ThrowCompletionOr get_offset_nanoseconds_for(GlobalObject& global_object auto& vm = global_object.vm(); // 1. Let getOffsetNanosecondsFor be ? GetMethod(timeZone, "getOffsetNanosecondsFor"). - auto* get_offset_nanoseconds_for = time_zone.get_method(global_object, vm.names.getOffsetNanosecondsFor); - if (auto* exception = vm.exception()) - return throw_completion(exception->value()); + auto* get_offset_nanoseconds_for = TRY(time_zone.get_method(global_object, vm.names.getOffsetNanosecondsFor)); // 2. If getOffsetNanosecondsFor is undefined, set getOffsetNanosecondsFor to %Temporal.TimeZone.prototype.getOffsetNanosecondsFor%. if (!get_offset_nanoseconds_for) diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp index 38bb7f8837..7efde510bc 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp +++ b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp @@ -363,9 +363,7 @@ void TypedArrayBase::visit_edges(Visitor& visitor) if (vm.exception()) \ return {}; \ } else { \ - auto iterator = first_argument.get_method(global_object(), *vm.well_known_symbol_iterator()); \ - if (vm.exception()) \ - return {}; \ + auto iterator = TRY_OR_DISCARD(first_argument.get_method(global_object(), *vm.well_known_symbol_iterator())); \ if (iterator) { \ auto values = iterable_to_list(global_object(), first_argument, iterator); \ if (vm.exception()) \ diff --git a/Userland/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp b/Userland/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp index 35567fb22e..c6b5b13f0b 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/TypedArrayConstructor.cpp @@ -77,9 +77,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayConstructor::from) auto source = vm.argument(0); auto this_arg = vm.argument(2); - auto using_iterator = source.get_method(global_object, *vm.well_known_symbol_iterator()); - if (vm.exception()) - return {}; + auto using_iterator = TRY_OR_DISCARD(source.get_method(global_object, *vm.well_known_symbol_iterator())); if (using_iterator) { auto values = iterable_to_list(global_object, source, using_iterator); if (vm.exception()) diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp index 4c98b30faa..ed2a129951 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.cpp +++ b/Userland/Libraries/LibJS/Runtime/Value.cpp @@ -418,9 +418,7 @@ Value Value::to_primitive(GlobalObject& global_object, PreferredType preferred_t }; if (is_object()) { auto& vm = global_object.vm(); - auto to_primitive_method = get_method(global_object, *vm.well_known_symbol_to_primitive()); - if (vm.exception()) - return {}; + auto to_primitive_method = TRY_OR_DISCARD(get_method(global_object, *vm.well_known_symbol_to_primitive())); if (to_primitive_method) { auto hint = get_hint_for_preferred_type(); auto result = TRY_OR_DISCARD(vm.call(*to_primitive_method, *this, js_string(vm, hint))); @@ -818,7 +816,7 @@ Value Value::get(GlobalObject& global_object, PropertyName const& property_name) } // 7.3.10 GetMethod ( V, P ), https://tc39.es/ecma262/#sec-getmethod -FunctionObject* Value::get_method(GlobalObject& global_object, PropertyName const& property_name) const +ThrowCompletionOr Value::get_method(GlobalObject& global_object, PropertyName const& property_name) const { auto& vm = global_object.vm(); @@ -827,18 +825,16 @@ FunctionObject* Value::get_method(GlobalObject& global_object, PropertyName cons // 2. Let func be ? GetV(V, P). auto function = get(global_object, property_name); - if (vm.exception()) - return nullptr; + if (auto* exception = vm.exception()) + return throw_completion(exception->value()); // 3. If func is either undefined or null, return undefined. if (function.is_nullish()) return nullptr; // 4. If IsCallable(func) is false, throw a TypeError exception. - if (!function.is_function()) { - vm.throw_exception(global_object, ErrorType::NotAFunction, function.to_string_without_side_effects()); - return nullptr; - } + if (!function.is_function()) + return vm.throw_completion(global_object, ErrorType::NotAFunction, function.to_string_without_side_effects()); // 5. Return func. return &function.as_function(); @@ -1292,9 +1288,7 @@ Value instance_of(GlobalObject& global_object, Value lhs, Value rhs) vm.throw_exception(global_object, ErrorType::NotAnObject, rhs.to_string_without_side_effects()); return {}; } - auto has_instance_method = rhs.get_method(global_object, *vm.well_known_symbol_has_instance()); - if (vm.exception()) - return {}; + auto has_instance_method = TRY_OR_DISCARD(rhs.get_method(global_object, *vm.well_known_symbol_has_instance())); if (has_instance_method) { auto has_instance_result = TRY_OR_DISCARD(vm.call(*has_instance_method, rhs, lhs)); return Value(has_instance_result.to_boolean()); diff --git a/Userland/Libraries/LibJS/Runtime/Value.h b/Userland/Libraries/LibJS/Runtime/Value.h index c8e4528795..330d7d30e9 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.h +++ b/Userland/Libraries/LibJS/Runtime/Value.h @@ -276,7 +276,7 @@ public: bool to_boolean() const; Value get(GlobalObject&, PropertyName const&) const; - FunctionObject* get_method(GlobalObject&, PropertyName const&) const; + ThrowCompletionOr get_method(GlobalObject&, PropertyName const&) const; String to_string_without_side_effects() const; -- cgit v1.2.3