diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp index 4c7d96129b9..0c4a03a5884 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp @@ -1415,7 +1415,7 @@ public: if (interface.is_legacy_platform_object()) { generator.append(R"~~~( - virtual Optional internal_get_own_property(JS::PropertyName const&) const override; + virtual JS::ThrowCompletionOr> internal_get_own_property(JS::PropertyName const&) const override; virtual bool internal_set(JS::PropertyName const&, JS::Value, JS::Value) override; virtual bool internal_define_own_property(JS::PropertyName const&, JS::PropertyDescriptor const&) override; virtual bool internal_delete(JS::PropertyName const&) override; @@ -1618,7 +1618,7 @@ static JS::Value wrap_for_legacy_platform_object_get_own_property(JS::GlobalObje scoped_generator.append(R"~~~( bool @class_name@::is_named_property_exposed_on_object(JS::PropertyName const& property_name) const { - auto& vm = this->vm(); + [[maybe_unused]] auto& vm = this->vm(); // The spec doesn't say anything about the type of the property name here. // Numbers can be converted to a string, which is fine and what other engines do. @@ -1636,9 +1636,7 @@ bool @class_name@::is_named_property_exposed_on_object(JS::PropertyName const& p // 2. If O has an own property named P, then return false. // NOTE: This has to be done manually instead of using Object::has_own_property, as that would use the overrided internal_get_own_property. - auto own_property_named_p = Object::internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto own_property_named_p = TRY_OR_DISCARD(Object::internal_get_own_property(property_name)); if (own_property_named_p.has_value()) return false; @@ -1769,7 +1767,7 @@ Optional @class_name@::legacy_platform_object_get_own_pr // 3. Set ignoreNamedProps to true. // NOTE: To reduce complexity of WrapperGenerator, this just returns early instead of keeping track of another variable. - return Object::internal_get_own_property(property_name); + return TRY_OR_DISCARD(Object::internal_get_own_property(property_name)); } )~~~"); } @@ -1850,7 +1848,7 @@ Optional @class_name@::legacy_platform_object_get_own_pr // 3. Return OrdinaryGetOwnProperty(O, P). get_own_property_generator.append(R"~~~( - return Object::internal_get_own_property(property_name); + return TRY_OR_DISCARD(Object::internal_get_own_property(property_name)); } )~~~"); }; @@ -1979,7 +1977,7 @@ static void invoke_indexed_property_setter(JS::GlobalObject& global_object, @ful // 3.9.1. [[GetOwnProperty]], https://heycam.github.io/webidl/#legacy-platform-object-getownproperty scoped_generator.append(R"~~~( -Optional @class_name@::internal_get_own_property(JS::PropertyName const& property_name) const +JS::ThrowCompletionOr> @class_name@::internal_get_own_property(JS::PropertyName const& property_name) const { // 1. Return LegacyPlatformObjectGetOwnProperty(O, P, false). return legacy_platform_object_get_own_property_for_get_own_property_slot(property_name); @@ -2112,9 +2110,7 @@ bool @class_name@::internal_define_own_property(JS::PropertyName const& property if (!interface.extended_attributes.contains("LegacyOverrideBuiltIns")) { scoped_generator.append(R"~~~( // NOTE: This has to be done manually instead of using Object::has_own_property, as that would use the overrided internal_get_own_property. - auto own_property_named_p = Object::internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto own_property_named_p = TRY_OR_DISCARD(Object::internal_get_own_property(property_name)); if (!own_property_named_p.has_value()))~~~"); } @@ -2181,7 +2177,7 @@ bool @class_name@::internal_define_own_property(JS::PropertyName const& property scoped_generator.append(R"~~~( bool @class_name@::internal_delete(JS::PropertyName const& property_name) { - auto& vm = this->vm(); + [[maybe_unused]] auto& vm = this->vm(); auto& global_object = this->global_object(); )~~~"); @@ -2273,9 +2269,7 @@ bool @class_name@::internal_delete(JS::PropertyName const& property_name) scoped_generator.append(R"~~~( // 3. If O has an own property with name P, then: - auto own_property_named_p_descriptor = Object::internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto own_property_named_p_descriptor = TRY_OR_DISCARD(Object::internal_get_own_property(property_name)); if (own_property_named_p_descriptor.has_value()) { // 1. If the property is not configurable, then return false. diff --git a/Userland/Libraries/LibJS/Runtime/ArgumentsObject.cpp b/Userland/Libraries/LibJS/Runtime/ArgumentsObject.cpp index 2cd408bed2c..4fc89d52ae5 100644 --- a/Userland/Libraries/LibJS/Runtime/ArgumentsObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ArgumentsObject.cpp @@ -5,6 +5,7 @@ */ #include +#include #include namespace JS { @@ -102,10 +103,10 @@ bool ArgumentsObject::internal_delete(PropertyName const& property_name) } // 10.4.4.1 [[GetOwnProperty]] ( P ), https://tc39.es/ecma262/#sec-arguments-exotic-objects-getownproperty-p -Optional ArgumentsObject::internal_get_own_property(PropertyName const& property_name) const +ThrowCompletionOr> ArgumentsObject::internal_get_own_property(PropertyName const& property_name) const { // 1. Let desc be OrdinaryGetOwnProperty(args, P). - auto desc = Object::internal_get_own_property(property_name); + auto desc = Object::internal_get_own_property(property_name).release_value(); // 2. If desc is undefined, return desc. if (!desc.has_value()) return desc; diff --git a/Userland/Libraries/LibJS/Runtime/ArgumentsObject.h b/Userland/Libraries/LibJS/Runtime/ArgumentsObject.h index 363cf4f5cc7..11e85076a58 100644 --- a/Userland/Libraries/LibJS/Runtime/ArgumentsObject.h +++ b/Userland/Libraries/LibJS/Runtime/ArgumentsObject.h @@ -6,6 +6,7 @@ #pragma once +#include #include #include @@ -22,7 +23,7 @@ public: Environment& environment() { return m_environment; } - virtual Optional internal_get_own_property(PropertyName const&) const override; + virtual ThrowCompletionOr> internal_get_own_property(PropertyName const&) const override; virtual bool internal_define_own_property(PropertyName const&, PropertyDescriptor const&) override; virtual Value internal_get(PropertyName const&, Value receiver) const override; virtual bool internal_set(PropertyName const&, Value value, Value receiver) override; diff --git a/Userland/Libraries/LibJS/Runtime/Array.cpp b/Userland/Libraries/LibJS/Runtime/Array.cpp index 9998c912a7d..af20cd0c4b6 100644 --- a/Userland/Libraries/LibJS/Runtime/Array.cpp +++ b/Userland/Libraries/LibJS/Runtime/Array.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -157,11 +158,11 @@ bool Array::set_length(PropertyDescriptor const& property_descriptor) } // NON-STANDARD: Used to return the value of the ephemeral length property -Optional Array::internal_get_own_property(PropertyName const& property_name) const +ThrowCompletionOr> Array::internal_get_own_property(PropertyName const& property_name) const { auto& vm = this->vm(); if (property_name.is_string() && property_name.as_string() == vm.names.length.as_string()) - return PropertyDescriptor { .value = Value(indexed_properties().array_like_size()), .writable = m_length_writable, .enumerable = false, .configurable = false }; + return { PropertyDescriptor { .value = Value(indexed_properties().array_like_size()), .writable = m_length_writable, .enumerable = false, .configurable = false } }; return Object::internal_get_own_property(property_name); } diff --git a/Userland/Libraries/LibJS/Runtime/Array.h b/Userland/Libraries/LibJS/Runtime/Array.h index 703d16d6d55..d8c432705c9 100644 --- a/Userland/Libraries/LibJS/Runtime/Array.h +++ b/Userland/Libraries/LibJS/Runtime/Array.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -37,7 +38,7 @@ public: explicit Array(Object& prototype); virtual ~Array() override; - virtual Optional internal_get_own_property(PropertyName const&) const override; + virtual ThrowCompletionOr> internal_get_own_property(PropertyName const&) const override; virtual bool internal_define_own_property(PropertyName const&, PropertyDescriptor const&) override; virtual bool internal_delete(PropertyName const&) override; virtual MarkedValueList internal_own_property_keys() const override; diff --git a/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.cpp b/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.cpp index c184376229b..14026b4fcce 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.cpp +++ b/Userland/Libraries/LibJS/Runtime/GlobalEnvironment.cpp @@ -142,11 +142,8 @@ bool GlobalEnvironment::has_lexical_declaration(FlyString const& name) const // 9.1.1.4.14 HasRestrictedGlobalProperty ( N ), https://tc39.es/ecma262/#sec-hasrestrictedglobalproperty bool GlobalEnvironment::has_restricted_global_property(FlyString const& name) const { - auto& vm = this->vm(); auto& global_object = m_object_record->binding_object(); - auto existing_prop = global_object.internal_get_own_property(name); - if (vm.exception()) - return {}; + auto existing_prop = TRY_OR_DISCARD(global_object.internal_get_own_property(name)); if (!existing_prop.has_value()) return false; if (*existing_prop->configurable) @@ -170,11 +167,8 @@ bool GlobalEnvironment::can_declare_global_var(FlyString const& name) const // 9.1.1.4.16 CanDeclareGlobalFunction ( N ), https://tc39.es/ecma262/#sec-candeclareglobalfunction bool GlobalEnvironment::can_declare_global_function(FlyString const& name) const { - auto& vm = this->vm(); auto& global_object = m_object_record->binding_object(); - auto existing_prop = global_object.internal_get_own_property(name); - if (vm.exception()) - return {}; + auto existing_prop = TRY_OR_DISCARD(global_object.internal_get_own_property(name)); if (!existing_prop.has_value()) return global_object.is_extensible(); if (*existing_prop->configurable) @@ -212,9 +206,10 @@ void GlobalEnvironment::create_global_function_binding(FlyString const& name, Va { auto& vm = this->vm(); auto& global_object = m_object_record->binding_object(); - auto existing_prop = global_object.internal_get_own_property(name); - if (vm.exception()) + auto existing_prop_or_error = global_object.internal_get_own_property(name); + if (existing_prop_or_error.is_error()) return; + auto existing_prop = existing_prop_or_error.release_value(); PropertyDescriptor desc; if (!existing_prop.has_value() || *existing_prop->configurable) desc = { .value = value, .writable = true, .enumerable = true, .configurable = can_be_deleted }; diff --git a/Userland/Libraries/LibJS/Runtime/Object.cpp b/Userland/Libraries/LibJS/Runtime/Object.cpp index ce0a3b28366..78da28bf899 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.cpp +++ b/Userland/Libraries/LibJS/Runtime/Object.cpp @@ -269,17 +269,13 @@ bool Object::has_property(PropertyName const& property_name) const // 7.3.12 HasOwnProperty ( O, P ), https://tc39.es/ecma262/#sec-hasownproperty bool Object::has_own_property(PropertyName const& property_name) const { - auto& vm = this->vm(); - // 1. Assert: Type(O) is Object. // 2. Assert: IsPropertyKey(P) is true. VERIFY(property_name.is_valid()); // 3. Let desc be ? O.[[GetOwnProperty]](P). - auto descriptor = internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto descriptor = TRY_OR_DISCARD(internal_get_own_property(property_name)); // 4. If desc is undefined, return false. if (!descriptor.has_value()) @@ -333,9 +329,7 @@ bool Object::set_integrity_level(IntegrityLevel level) auto property_name = PropertyName::from_value(global_object, key); // i. Let currentDesc be ? O.[[GetOwnProperty]](k). - auto current_descriptor = internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto current_descriptor = TRY_OR_DISCARD(internal_get_own_property(property_name)); // ii. If currentDesc is not undefined, then if (!current_descriptor.has_value()) @@ -395,9 +389,7 @@ bool Object::test_integrity_level(IntegrityLevel level) const auto property_name = PropertyName::from_value(global_object(), key); // a. Let currentDesc be ? O.[[GetOwnProperty]](k). - auto current_descriptor = internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto current_descriptor = TRY_OR_DISCARD(internal_get_own_property(property_name)); // b. If currentDesc is not undefined, then if (!current_descriptor.has_value()) @@ -445,9 +437,10 @@ MarkedValueList Object::enumerable_own_property_names(PropertyKind kind) const auto property_name = PropertyName::from_value(global_object, key); // i. Let desc be ? O.[[GetOwnProperty]](key). - auto descriptor = internal_get_own_property(property_name); - if (vm.exception()) + auto descriptor_or_error = internal_get_own_property(property_name); + if (descriptor_or_error.is_error()) return MarkedValueList { heap() }; + auto descriptor = descriptor_or_error.release_value(); // ii. If desc is not undefined and desc.[[Enumerable]] is true, then if (descriptor.has_value() && *descriptor->enumerable) { @@ -562,14 +555,14 @@ ThrowCompletionOr Object::internal_prevent_extensions() } // 10.1.5 [[GetOwnProperty]] ( P ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-getownproperty-p -Optional Object::internal_get_own_property(PropertyName const& property_name) const +ThrowCompletionOr> Object::internal_get_own_property(PropertyName const& property_name) const { // 1. Assert: IsPropertyKey(P) is true. VERIFY(property_name.is_valid()); // 2. If O does not have an own property with key P, return undefined. if (!storage_has(property_name)) - return {}; + return Optional {}; // 3. Let D be a newly created Property Descriptor with no fields. PropertyDescriptor descriptor; @@ -603,7 +596,7 @@ Optional Object::internal_get_own_property(PropertyName cons descriptor.configurable = attributes.is_configurable(); // 9. Return D. - return descriptor; + return { descriptor }; } // 10.1.6 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-defineownproperty-p-desc @@ -613,9 +606,7 @@ bool Object::internal_define_own_property(PropertyName const& property_name, Pro auto& vm = this->vm(); // 1. Let current be ? O.[[GetOwnProperty]](P). - auto current = internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto current = TRY_OR_DISCARD(internal_get_own_property(property_name)); // 2. Let extensible be ? IsExtensible(O). auto extensible = is_extensible(); @@ -629,15 +620,11 @@ bool Object::internal_define_own_property(PropertyName const& property_name, Pro // 10.1.7 [[HasProperty]] ( P ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-hasproperty-p bool Object::internal_has_property(PropertyName const& property_name) const { - auto& vm = this->vm(); - // 1. Assert: IsPropertyKey(P) is true. VERIFY(property_name.is_valid()); // 2. Let hasOwn be ? O.[[GetOwnProperty]](P). - auto has_own = internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto has_own = TRY_OR_DISCARD(internal_get_own_property(property_name)); // 3. If hasOwn is not undefined, return true. if (has_own.has_value()) @@ -666,9 +653,7 @@ Value Object::internal_get(PropertyName const& property_name, Value receiver) co VERIFY(property_name.is_valid()); // 2. Let desc be ? O.[[GetOwnProperty]](P). - auto descriptor = internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto descriptor = TRY_OR_DISCARD(internal_get_own_property(property_name)); // 3. If desc is undefined, then if (!descriptor.has_value()) { @@ -706,15 +691,12 @@ bool Object::internal_set(PropertyName const& property_name, Value value, Value { VERIFY(!value.is_empty()); VERIFY(!receiver.is_empty()); - auto& vm = this->vm(); // 1. Assert: IsPropertyKey(P) is true. VERIFY(property_name.is_valid()); // 2. Let ownDesc be ? O.[[GetOwnProperty]](P). - auto own_descriptor = internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto own_descriptor = TRY_OR_DISCARD(internal_get_own_property(property_name)); // 3. Return OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc). return ordinary_set_with_own_descriptor(property_name, value, receiver, own_descriptor); @@ -761,9 +743,7 @@ bool Object::ordinary_set_with_own_descriptor(PropertyName const& property_name, return false; // c. Let existingDescriptor be ? Receiver.[[GetOwnProperty]](P). - auto existing_descriptor = receiver.as_object().internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto existing_descriptor = TRY_OR_DISCARD(receiver.as_object().internal_get_own_property(property_name)); // d. If existingDescriptor is not undefined, then if (existing_descriptor.has_value()) { @@ -811,15 +791,11 @@ bool Object::ordinary_set_with_own_descriptor(PropertyName const& property_name, // 10.1.10 [[Delete]] ( P ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-delete-p bool Object::internal_delete(PropertyName const& property_name) { - auto& vm = this->vm(); - // 1. Assert: IsPropertyKey(P) is true. VERIFY(property_name.is_valid()); // 2. Let desc be ? O.[[GetOwnProperty]](P). - auto descriptor = internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto descriptor = TRY_OR_DISCARD(internal_get_own_property(property_name)); // 3. If desc is undefined, return true. if (!descriptor.has_value()) @@ -1119,9 +1095,7 @@ Object* Object::define_properties(Value properties) auto property_name = PropertyName::from_value(global_object, next_key); // a. Let propDesc be ? props.[[GetOwnProperty]](nextKey). - auto property_descriptor = props->internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto property_descriptor = TRY_OR_DISCARD(props->internal_get_own_property(property_name)); // b. If propDesc is not undefined and propDesc.[[Enumerable]] is true, then if (property_descriptor.has_value() && *property_descriptor->enumerable) { diff --git a/Userland/Libraries/LibJS/Runtime/Object.h b/Userland/Libraries/LibJS/Runtime/Object.h index fe2e63cca06..ef1daa4de04 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.h +++ b/Userland/Libraries/LibJS/Runtime/Object.h @@ -95,7 +95,7 @@ public: virtual ThrowCompletionOr internal_set_prototype_of(Object* prototype); virtual ThrowCompletionOr internal_is_extensible() const; virtual ThrowCompletionOr internal_prevent_extensions(); - virtual Optional internal_get_own_property(PropertyName const&) const; + virtual ThrowCompletionOr> internal_get_own_property(PropertyName const&) const; virtual bool internal_define_own_property(PropertyName const&, PropertyDescriptor const&); virtual bool internal_has_property(PropertyName const&) const; virtual Value internal_get(PropertyName const&, Value receiver) const; diff --git a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp index 34b7d1c9231..9e5e6061c8e 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp @@ -291,9 +291,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptor) auto key = vm.argument(1).to_property_key(global_object); if (vm.exception()) return {}; - auto descriptor = object->internal_get_own_property(key); - if (vm.exception()) - return {}; + auto descriptor = TRY_OR_DISCARD(object->internal_get_own_property(key)); return from_property_descriptor(global_object, descriptor); } @@ -315,9 +313,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::get_own_property_descriptors) auto property_name = PropertyName::from_value(global_object, key); // a. Let desc be ? obj.[[GetOwnProperty]](key). - auto desc = object->internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto desc = TRY_OR_DISCARD(object->internal_get_own_property(property_name)); // b. Let descriptor be ! FromPropertyDescriptor(desc). auto descriptor = from_property_descriptor(global_object, desc); @@ -484,9 +480,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::assign) auto property_name = PropertyName::from_value(global_object, next_key); // 1. Let desc be ? from.[[GetOwnProperty]](nextKey). - auto desc = from->internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto desc = TRY_OR_DISCARD(from->internal_get_own_property(property_name)); // 2. If desc is not undefined and desc.[[Enumerable]] is true, then if (!desc.has_value() || !*desc->enumerable) diff --git a/Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp b/Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp index 7d6502917cc..60c1607dda7 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp +++ b/Userland/Libraries/LibJS/Runtime/ObjectEnvironment.cpp @@ -103,7 +103,10 @@ void ObjectEnvironment::set_mutable_binding(GlobalObject& global_object, FlyStri // Note: Nothing like this in the spec, this is here to produce nicer errors instead of the generic one thrown by Object::set(). if (!result && strict) { - auto property = m_binding_object.internal_get_own_property(name); + auto property_or_error = m_binding_object.internal_get_own_property(name); + if (property_or_error.is_error()) + return; + auto property = property_or_error.release_value(); if (property.has_value() && !property->writable.value_or(true)) { vm.clear_exception(); vm.throw_exception(global_object, ErrorType::DescWriteNonWritable, name); diff --git a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp index f8af0d625da..7361d6bdb28 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp @@ -166,9 +166,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::property_is_enumerable) if (!this_object) return {}; // 3. Let desc be ? O.[[GetOwnProperty]](P). - auto property_descriptor = this_object->internal_get_own_property(property_key); - if (vm.exception()) - return {}; + auto property_descriptor = TRY_OR_DISCARD(this_object->internal_get_own_property(property_key)); // 4. If desc is undefined, return false. if (!property_descriptor.has_value()) return Value(false); @@ -260,9 +258,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::lookup_getter) return {}; while (object) { - auto desc = object->internal_get_own_property(key); - if (vm.exception()) - return {}; + auto desc = TRY_OR_DISCARD(object->internal_get_own_property(key)); if (desc.has_value()) { if (desc->is_accessor_descriptor()) return *desc->get ?: js_undefined(); @@ -286,9 +282,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::lookup_setter) return {}; while (object) { - auto desc = object->internal_get_own_property(key); - if (vm.exception()) - return {}; + auto desc = TRY_OR_DISCARD(object->internal_get_own_property(key)); if (desc.has_value()) { if (desc->is_accessor_descriptor()) return *desc->set ?: js_undefined(); diff --git a/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp b/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp index 64c959185c3..c345b3788f6 100644 --- a/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp @@ -231,7 +231,7 @@ ThrowCompletionOr ProxyObject::internal_prevent_extensions() } // 10.5.5 [[GetOwnProperty]] ( P ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p -Optional ProxyObject::internal_get_own_property(const PropertyName& property_name) const +ThrowCompletionOr> ProxyObject::internal_get_own_property(const PropertyName& property_name) const { auto& vm = this->vm(); auto& global_object = this->global_object(); @@ -242,16 +242,14 @@ Optional ProxyObject::internal_get_own_property(const Proper // 2. Let handler be O.[[ProxyHandler]]. // 3. If handler is null, throw a TypeError exception. - if (m_is_revoked) { - vm.throw_exception(global_object, ErrorType::ProxyRevoked); - return {}; - } + if (m_is_revoked) + return vm.throw_completion(global_object, ErrorType::ProxyRevoked); // 4. Assert: Type(handler) is Object. // 5. Let target be O.[[ProxyTarget]]. // 6. Let trap be ? GetMethod(handler, "getOwnPropertyDescriptor"). - auto trap = TRY_OR_DISCARD(Value(&m_handler).get_method(global_object, vm.names.getOwnPropertyDescriptor)); + auto trap = TRY(Value(&m_handler).get_method(global_object, vm.names.getOwnPropertyDescriptor)); // 7. If trap is undefined, then if (!trap) { @@ -260,55 +258,47 @@ Optional ProxyObject::internal_get_own_property(const Proper } // 8. Let trapResultObj be ? Call(trap, handler, « target, P »). - auto trap_result = TRY_OR_DISCARD(vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name))); + auto trap_result = TRY(vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name))); // 9. If Type(trapResultObj) is neither Object nor Undefined, throw a TypeError exception. - if (!trap_result.is_object() && !trap_result.is_undefined()) { - vm.throw_exception(global_object, ErrorType::ProxyGetOwnDescriptorReturn); - return {}; - } + if (!trap_result.is_object() && !trap_result.is_undefined()) + return vm.throw_completion(global_object, ErrorType::ProxyGetOwnDescriptorReturn); // 10. Let targetDesc be ? target.[[GetOwnProperty]](P). - auto target_descriptor = m_target.internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto target_descriptor = TRY(m_target.internal_get_own_property(property_name)); // 11. If trapResultObj is undefined, then if (trap_result.is_undefined()) { // a. If targetDesc is undefined, return undefined. if (!target_descriptor.has_value()) - return {}; + return Optional {}; // b. If targetDesc.[[Configurable]] is false, throw a TypeError exception. - if (!*target_descriptor->configurable) { - vm.throw_exception(global_object, ErrorType::ProxyGetOwnDescriptorNonConfigurable); - return {}; - } + if (!*target_descriptor->configurable) + return vm.throw_completion(global_object, ErrorType::ProxyGetOwnDescriptorNonConfigurable); // c. Let extensibleTarget be ? IsExtensible(target). auto extensible_target = m_target.is_extensible(); - if (vm.exception()) - return {}; + if (auto* exception = vm.exception()) + return throw_completion(exception->value()); // d. If extensibleTarget is false, throw a TypeError exception. - if (!extensible_target) { - vm.throw_exception(global_object, ErrorType::ProxyGetOwnDescriptorUndefinedReturn); - return {}; - } + if (!extensible_target) + return vm.throw_completion(global_object, ErrorType::ProxyGetOwnDescriptorUndefinedReturn); // e. Return undefined. - return {}; + return Optional {}; } // 12. Let extensibleTarget be ? IsExtensible(target). auto extensible_target = m_target.is_extensible(); - if (vm.exception()) - return {}; + if (auto* exception = vm.exception()) + return throw_completion(exception->value()); // 13. Let resultDesc be ? ToPropertyDescriptor(trapResultObj). auto result_desc = to_property_descriptor(global_object, trap_result); - if (vm.exception()) - return {}; + if (auto* exception = vm.exception()) + return throw_completion(exception->value()); // 14. Call CompletePropertyDescriptor(resultDesc). result_desc.complete(); @@ -317,31 +307,26 @@ Optional ProxyObject::internal_get_own_property(const Proper auto valid = is_compatible_property_descriptor(extensible_target, result_desc, target_descriptor); // 16. If valid is false, throw a TypeError exception. - if (!valid) { - vm.throw_exception(global_object, ErrorType::ProxyGetOwnDescriptorInvalidDescriptor); - return {}; - } + if (!valid) + return vm.throw_completion(global_object, ErrorType::ProxyGetOwnDescriptorInvalidDescriptor); // 17. If resultDesc.[[Configurable]] is false, then if (!*result_desc.configurable) { // a. If targetDesc is undefined or targetDesc.[[Configurable]] is true, then - if (!target_descriptor.has_value() || *target_descriptor->configurable) { + if (!target_descriptor.has_value() || *target_descriptor->configurable) // i. Throw a TypeError exception. - vm.throw_exception(global_object, ErrorType::ProxyGetOwnDescriptorInvalidNonConfig); - return {}; - } + return vm.throw_completion(global_object, ErrorType::ProxyGetOwnDescriptorInvalidNonConfig); + // b. If resultDesc has a [[Writable]] field and resultDesc.[[Writable]] is false, then if (result_desc.writable.has_value() && !*result_desc.writable) { // i. If targetDesc.[[Writable]] is true, throw a TypeError exception. - if (*target_descriptor->writable) { - vm.throw_exception(global_object, ErrorType::ProxyGetOwnDescriptorNonConfigurableNonWritable); - return {}; - } + if (*target_descriptor->writable) + return vm.throw_completion(global_object, ErrorType::ProxyGetOwnDescriptorNonConfigurableNonWritable); } } // 18. Return resultDesc. - return result_desc; + return { result_desc }; } // 10.5.6 [[DefineOwnProperty]] ( P, Desc ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc @@ -384,9 +369,7 @@ bool ProxyObject::internal_define_own_property(PropertyName const& property_name return false; // 11. Let targetDesc be ? target.[[GetOwnProperty]](P). - auto target_descriptor = m_target.internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto target_descriptor = TRY_OR_DISCARD(m_target.internal_get_own_property(property_name)); // 12. Let extensibleTarget be ? IsExtensible(target). auto extensible_target = m_target.is_extensible(); @@ -476,9 +459,7 @@ bool ProxyObject::internal_has_property(PropertyName const& property_name) const // 9. If booleanTrapResult is false, then if (!trap_result) { // a. Let targetDesc be ? target.[[GetOwnProperty]](P). - auto target_descriptor = m_target.internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto target_descriptor = TRY_OR_DISCARD(m_target.internal_get_own_property(property_name)); // b. If targetDesc is not undefined, then if (target_descriptor.has_value()) { @@ -558,9 +539,7 @@ Value ProxyObject::internal_get(PropertyName const& property_name, Value receive auto trap_result = TRY_OR_DISCARD(vm.call(*trap, &m_handler, &m_target, property_name_to_value(vm, property_name), receiver)); // 9. Let targetDesc be ? target.[[GetOwnProperty]](P). - auto target_descriptor = m_target.internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto target_descriptor = TRY_OR_DISCARD(m_target.internal_get_own_property(property_name)); // 10. If targetDesc is not undefined and targetDesc.[[Configurable]] is false, then if (target_descriptor.has_value() && !*target_descriptor->configurable) { @@ -626,9 +605,7 @@ bool ProxyObject::internal_set(PropertyName const& property_name, Value value, V return false; // 10. Let targetDesc be ? target.[[GetOwnProperty]](P). - auto target_descriptor = m_target.internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto target_descriptor = TRY_OR_DISCARD(m_target.internal_get_own_property(property_name)); // 11. If targetDesc is not undefined and targetDesc.[[Configurable]] is false, then if (target_descriptor.has_value() && !*target_descriptor->configurable) { @@ -691,9 +668,7 @@ bool ProxyObject::internal_delete(PropertyName const& property_name) return false; // 10. Let targetDesc be ? target.[[GetOwnProperty]](P). - auto target_descriptor = m_target.internal_get_own_property(property_name); - if (vm.exception()) - return {}; + auto target_descriptor = TRY_OR_DISCARD(m_target.internal_get_own_property(property_name)); // 11. If targetDesc is undefined, return true. if (!target_descriptor.has_value()) @@ -799,7 +774,10 @@ MarkedValueList ProxyObject::internal_own_property_keys() const // 16. For each element key of targetKeys, do for (auto& key : target_keys) { // a. Let desc be ? target.[[GetOwnProperty]](key). - auto descriptor = m_target.internal_get_own_property(PropertyName::from_value(global_object, key)); + auto descriptor_or_error = m_target.internal_get_own_property(PropertyName::from_value(global_object, key)); + if (descriptor_or_error.is_error()) + return MarkedValueList { heap() }; + auto descriptor = descriptor_or_error.release_value(); // b. If desc is not undefined and desc.[[Configurable]] is false, then if (descriptor.has_value() && !*descriptor->configurable) { diff --git a/Userland/Libraries/LibJS/Runtime/ProxyObject.h b/Userland/Libraries/LibJS/Runtime/ProxyObject.h index aab0000d04b..c410a15c399 100644 --- a/Userland/Libraries/LibJS/Runtime/ProxyObject.h +++ b/Userland/Libraries/LibJS/Runtime/ProxyObject.h @@ -39,7 +39,7 @@ public: virtual ThrowCompletionOr internal_set_prototype_of(Object* prototype) override; virtual ThrowCompletionOr internal_is_extensible() const override; virtual ThrowCompletionOr internal_prevent_extensions() override; - virtual Optional internal_get_own_property(PropertyName const&) const override; + virtual ThrowCompletionOr> internal_get_own_property(PropertyName const&) const override; virtual bool internal_define_own_property(PropertyName const&, PropertyDescriptor const&) override; virtual bool internal_has_property(PropertyName const&) const override; virtual Value internal_get(PropertyName const&, Value receiver) const override; diff --git a/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp b/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp index ac2d057d173..bec3c3c7462 100644 --- a/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp @@ -192,9 +192,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::get_own_property_descriptor) return {}; // 3. Let desc be ? target.[[GetOwnProperty]](key). - auto descriptor = target.as_object().internal_get_own_property(key); - if (vm.exception()) - return {}; + auto descriptor = TRY_OR_DISCARD(target.as_object().internal_get_own_property(key)); // 4. Return FromPropertyDescriptor(desc). return from_property_descriptor(global_object, descriptor); diff --git a/Userland/Libraries/LibJS/Runtime/StringObject.cpp b/Userland/Libraries/LibJS/Runtime/StringObject.cpp index 06fe93fa088..6002d27e7a8 100644 --- a/Userland/Libraries/LibJS/Runtime/StringObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/StringObject.cpp @@ -92,12 +92,12 @@ static Optional string_get_own_property(GlobalObject& global } // 10.4.3.1 [[GetOwnProperty]] ( P ), https://tc39.es/ecma262/#sec-string-exotic-objects-getownproperty-p -Optional StringObject::internal_get_own_property(PropertyName const& property_name) const +ThrowCompletionOr> StringObject::internal_get_own_property(PropertyName const& property_name) const { // Assert: IsPropertyKey(P) is true. // 2. Let desc be OrdinaryGetOwnProperty(S, P). - auto descriptor = Object::internal_get_own_property(property_name); + auto descriptor = Object::internal_get_own_property(property_name).release_value(); // 3. If desc is not undefined, return desc. if (descriptor.has_value()) diff --git a/Userland/Libraries/LibJS/Runtime/StringObject.h b/Userland/Libraries/LibJS/Runtime/StringObject.h index 2fd5fb77e6f..b0ef348f2b7 100644 --- a/Userland/Libraries/LibJS/Runtime/StringObject.h +++ b/Userland/Libraries/LibJS/Runtime/StringObject.h @@ -27,7 +27,7 @@ public: } private: - virtual Optional internal_get_own_property(PropertyName const&) const override; + virtual ThrowCompletionOr> internal_get_own_property(PropertyName const&) const override; virtual bool internal_define_own_property(PropertyName const&, PropertyDescriptor const&) override; virtual MarkedValueList internal_own_property_keys() const override; diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.h b/Userland/Libraries/LibJS/Runtime/TypedArray.h index fe048577147..721b340aeab 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArray.h +++ b/Userland/Libraries/LibJS/Runtime/TypedArray.h @@ -188,7 +188,7 @@ class TypedArray : public TypedArrayBase { public: // 10.4.5.1 [[GetOwnProperty]] ( P ), https://tc39.es/ecma262/#sec-integer-indexed-exotic-objects-getownproperty-p - virtual Optional internal_get_own_property(PropertyName const& property_name) const override + virtual ThrowCompletionOr> internal_get_own_property(PropertyName const& property_name) const override { // 1. Assert: IsPropertyKey(P) is true. VERIFY(property_name.is_valid()); @@ -211,15 +211,15 @@ public: // ii. If value is undefined, return undefined. if (value.is_undefined()) - return {}; + return Optional {}; // iii. Return the PropertyDescriptor { [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }. - return PropertyDescriptor { + return { PropertyDescriptor { .value = value, .writable = true, .enumerable = true, .configurable = true, - }; + } }; } } diff --git a/Userland/Services/WebContent/ConsoleGlobalObject.cpp b/Userland/Services/WebContent/ConsoleGlobalObject.cpp index 2fdfc273666..e835bc520d6 100644 --- a/Userland/Services/WebContent/ConsoleGlobalObject.cpp +++ b/Userland/Services/WebContent/ConsoleGlobalObject.cpp @@ -57,9 +57,9 @@ JS::ThrowCompletionOr ConsoleGlobalObject::internal_prevent_extensions() return m_window_object->internal_prevent_extensions(); } -Optional ConsoleGlobalObject::internal_get_own_property(JS::PropertyName const& property_name) const +JS::ThrowCompletionOr> ConsoleGlobalObject::internal_get_own_property(JS::PropertyName const& property_name) const { - if (auto result = m_window_object->internal_get_own_property(property_name); result.has_value()) + if (auto result = TRY(m_window_object->internal_get_own_property(property_name)); result.has_value()) return result; return Base::internal_get_own_property(property_name); diff --git a/Userland/Services/WebContent/ConsoleGlobalObject.h b/Userland/Services/WebContent/ConsoleGlobalObject.h index 427dbaa0a91..e0a54e43fec 100644 --- a/Userland/Services/WebContent/ConsoleGlobalObject.h +++ b/Userland/Services/WebContent/ConsoleGlobalObject.h @@ -27,7 +27,7 @@ public: virtual JS::ThrowCompletionOr internal_set_prototype_of(Object* prototype) override; virtual JS::ThrowCompletionOr internal_is_extensible() const override; virtual JS::ThrowCompletionOr internal_prevent_extensions() override; - virtual Optional internal_get_own_property(JS::PropertyName const& name) const override; + virtual JS::ThrowCompletionOr> internal_get_own_property(JS::PropertyName const& name) const override; virtual bool internal_define_own_property(JS::PropertyName const& name, JS::PropertyDescriptor const& descriptor) override; virtual bool internal_has_property(JS::PropertyName const& name) const override; virtual JS::Value internal_get(JS::PropertyName const&, JS::Value) const override;