diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp index 61b0c9a04f..25195cda90 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/WrapperGenerator.cpp @@ -1553,7 +1553,7 @@ namespace Web::Bindings { @wrapper_class@::@wrapper_class@(JS::GlobalObject& global_object, @fully_qualified_name@& impl) : @wrapper_base_class@(global_object, impl) { - auto success = internal_set_prototype_of(&static_cast(global_object).ensure_web_prototype<@prototype_class@>("@name@")); + auto success = internal_set_prototype_of(&static_cast(global_object).ensure_web_prototype<@prototype_class@>("@name@")).release_value(); VERIFY(success); } )~~~"); @@ -2808,12 +2808,12 @@ namespace Web::Bindings { // https://heycam.github.io/webidl/#es-DOMException-specialness // Object.getPrototypeOf(DOMException.prototype) === Error.prototype generator.append(R"~~~( - auto success = internal_set_prototype_of(global_object.error_prototype()); + auto success = internal_set_prototype_of(global_object.error_prototype()).release_value(); VERIFY(success); )~~~"); } else if (!interface.parent_name.is_empty()) { generator.append(R"~~~( - auto success = internal_set_prototype_of(&static_cast(global_object).ensure_web_prototype<@prototype_base_class@>("@parent_name@")); + auto success = internal_set_prototype_of(&static_cast(global_object).ensure_web_prototype<@prototype_base_class@>("@parent_name@")).release_value(); VERIFY(success); )~~~"); } diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index c49f6cc5c3..09bdbe2ff7 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -906,7 +906,7 @@ Value ClassExpression::execute(Interpreter& interpreter, GlobalObject& global_ob class_constructor->define_direct_property(vm.names.prototype, prototype, Attribute::Writable); if (interpreter.exception()) return {}; - class_constructor->internal_set_prototype_of(super_constructor.is_null() ? global_object.function_prototype() : &super_constructor.as_object()); + TRY_OR_DISCARD(class_constructor->internal_set_prototype_of(super_constructor.is_null() ? global_object.function_prototype() : &super_constructor.as_object())); } auto class_prototype = class_constructor->get(vm.names.prototype); diff --git a/Userland/Libraries/LibJS/Runtime/BoundFunction.cpp b/Userland/Libraries/LibJS/Runtime/BoundFunction.cpp index 794e1e4aee..397cbb4b0a 100644 --- a/Userland/Libraries/LibJS/Runtime/BoundFunction.cpp +++ b/Userland/Libraries/LibJS/Runtime/BoundFunction.cpp @@ -38,11 +38,8 @@ Value BoundFunction::call() Value BoundFunction::construct(FunctionObject& new_target) { - if (auto this_value = vm().this_value(global_object()); m_constructor_prototype && this_value.is_object()) { - this_value.as_object().internal_set_prototype_of(m_constructor_prototype); - if (vm().exception()) - return {}; - } + if (auto this_value = vm().this_value(global_object()); m_constructor_prototype && this_value.is_object()) + TRY_OR_DISCARD(this_value.as_object().internal_set_prototype_of(m_constructor_prototype)); return m_bound_target_function->construct(new_target); } diff --git a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp index a72336e390..df3fd9e1d0 100644 --- a/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ECMAScriptFunctionObject.cpp @@ -81,7 +81,7 @@ void ECMAScriptFunctionObject::initialize(GlobalObject& global_object) break; case FunctionKind::Generator: // prototype is "g1.prototype" in figure-2 (https://tc39.es/ecma262/img/figure-2.png) - prototype->internal_set_prototype_of(global_object.generator_object_prototype()); + (void)prototype->internal_set_prototype_of(global_object.generator_object_prototype()); break; } define_direct_property(vm.names.prototype, prototype, Attribute::Writable); diff --git a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp index 504f5f3615..6f4ab44266 100644 --- a/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/GlobalObject.cpp @@ -144,7 +144,7 @@ void GlobalObject::initialize_global_object() static_cast(m_object_prototype)->initialize(*this); m_object_prototype->set_initialized(Badge {}); - auto success = Object::internal_set_prototype_of(m_object_prototype); + auto success = Object::internal_set_prototype_of(m_object_prototype).release_value(); VERIFY(success); // This must be initialized before allocating AggregateErrorPrototype, which uses ErrorPrototype as its prototype. diff --git a/Userland/Libraries/LibJS/Runtime/Object.cpp b/Userland/Libraries/LibJS/Runtime/Object.cpp index b05ad6ba13..7b860d1c32 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.cpp +++ b/Userland/Libraries/LibJS/Runtime/Object.cpp @@ -48,7 +48,8 @@ Object::Object(ConstructWithoutPrototypeTag, GlobalObject& global_object) Object::Object(Object& prototype) { m_shape = prototype.global_object().empty_object_shape(); - auto success = internal_set_prototype_of(&prototype); + // FIXME: Factor out step 9 into a simple prototype setter and use that + auto success = internal_set_prototype_of(&prototype).release_value(); VERIFY(success); } @@ -496,7 +497,7 @@ ThrowCompletionOr Object::internal_get_prototype_of() const } // 10.1.2 [[SetPrototypeOf]] ( V ), https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-setprototypeof-v -bool Object::internal_set_prototype_of(Object* new_prototype) +ThrowCompletionOr Object::internal_set_prototype_of(Object* new_prototype) { // 1. Assert: Either Type(V) is Object or Type(V) is Null. diff --git a/Userland/Libraries/LibJS/Runtime/Object.h b/Userland/Libraries/LibJS/Runtime/Object.h index d46ca392b9..dfdb57db49 100644 --- a/Userland/Libraries/LibJS/Runtime/Object.h +++ b/Userland/Libraries/LibJS/Runtime/Object.h @@ -92,7 +92,7 @@ public: // 10.1 Ordinary Object Internal Methods and Internal Slots, https://tc39.es/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots virtual ThrowCompletionOr internal_get_prototype_of() const; - virtual bool internal_set_prototype_of(Object* prototype); + virtual ThrowCompletionOr internal_set_prototype_of(Object* prototype); virtual bool internal_is_extensible() const; virtual bool internal_prevent_extensions(); virtual Optional internal_get_own_property(PropertyName const&) const; diff --git a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp index 5c489a3ec4..a93b509610 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/ObjectConstructor.cpp @@ -162,9 +162,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectConstructor::set_prototype_of) return object; // 4. Let status be ? O.[[SetPrototypeOf]](proto). - auto status = object.as_object().internal_set_prototype_of(proto.is_null() ? nullptr : &proto.as_object()); - if (vm.exception()) - return {}; + auto status = TRY_OR_DISCARD(object.as_object().internal_set_prototype_of(proto.is_null() ? nullptr : &proto.as_object())); // 5. If status is false, throw a TypeError exception. if (!status) { diff --git a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp index e32f5a7920..f8af0d625d 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -52,7 +53,7 @@ ObjectPrototype::~ObjectPrototype() } // 10.4.7.1 [[SetPrototypeOf]] ( V ), https://tc39.es/ecma262/#sec-immutable-prototype-exotic-objects-setprototypeof-v -bool ObjectPrototype::internal_set_prototype_of(Object* prototype) +ThrowCompletionOr ObjectPrototype::internal_set_prototype_of(Object* prototype) { return set_immutable_prototype(prototype); } @@ -320,9 +321,7 @@ JS_DEFINE_NATIVE_FUNCTION(ObjectPrototype::proto_setter) if (!object.is_object()) return js_undefined(); - auto status = object.as_object().internal_set_prototype_of(proto.is_object() ? &proto.as_object() : nullptr); - if (vm.exception()) - return {}; + auto status = TRY_OR_DISCARD(object.as_object().internal_set_prototype_of(proto.is_object() ? &proto.as_object() : nullptr)); if (!status) { // FIXME: Improve/contextualize error message vm.throw_exception(global_object, ErrorType::ObjectSetPrototypeOfReturnedFalse); diff --git a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.h b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.h index 969ea442dd..ef1f5ee785 100644 --- a/Userland/Libraries/LibJS/Runtime/ObjectPrototype.h +++ b/Userland/Libraries/LibJS/Runtime/ObjectPrototype.h @@ -6,6 +6,7 @@ #pragma once +#include #include namespace JS { @@ -20,7 +21,7 @@ public: // 10.4.7 Immutable Prototype Exotic Objects, https://tc39.es/ecma262/#sec-immutable-prototype-exotic-objects - virtual bool internal_set_prototype_of(Object* prototype) override; + virtual ThrowCompletionOr internal_set_prototype_of(Object* prototype) override; // public to serve as intrinsic function %Object.prototype.toString% JS_DECLARE_NATIVE_FUNCTION(to_string); diff --git a/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp b/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp index 8f4dae9ca0..92ea6aaca0 100644 --- a/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ProxyObject.cpp @@ -96,7 +96,7 @@ ThrowCompletionOr ProxyObject::internal_get_prototype_of() const } // 10.5.2 [[SetPrototypeOf]] ( V ), https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v -bool ProxyObject::internal_set_prototype_of(Object* prototype) +ThrowCompletionOr ProxyObject::internal_set_prototype_of(Object* prototype) { auto& vm = this->vm(); auto& global_object = this->global_object(); @@ -105,16 +105,14 @@ bool ProxyObject::internal_set_prototype_of(Object* prototype) // 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, "setPrototypeOf"). - auto trap = TRY_OR_DISCARD(Value(&m_handler).get_method(global_object, vm.names.setPrototypeOf)); + auto trap = TRY(Value(&m_handler).get_method(global_object, vm.names.setPrototypeOf)); // 7. If trap is undefined, then if (!trap) { @@ -123,7 +121,7 @@ bool ProxyObject::internal_set_prototype_of(Object* prototype) } // 8. Let booleanTrapResult be ! ToBoolean(? Call(trap, handler, « target, V »)). - auto trap_result = TRY_OR_DISCARD(vm.call(*trap, &m_handler, &m_target, prototype)).to_boolean(); + auto trap_result = TRY(vm.call(*trap, &m_handler, &m_target, prototype)).to_boolean(); // 9. If booleanTrapResult is false, return false. if (!trap_result) @@ -131,21 +129,19 @@ bool ProxyObject::internal_set_prototype_of(Object* prototype) // 10. 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()); // 11. If extensibleTarget is true, return true. if (extensible_target) return true; // 12. Let targetProto be ? target.[[GetPrototypeOf]](). - auto* target_proto = TRY_OR_DISCARD(m_target.internal_get_prototype_of()); + auto* target_proto = TRY(m_target.internal_get_prototype_of()); // 13. If SameValue(V, targetProto) is false, throw a TypeError exception. - if (!same_value(prototype, target_proto)) { - vm.throw_exception(global_object, ErrorType::ProxySetPrototypeOfNonExtensible); - return {}; - } + if (!same_value(prototype, target_proto)) + return vm.throw_completion(global_object, ErrorType::ProxySetPrototypeOfNonExtensible); // 14. Return true. return true; diff --git a/Userland/Libraries/LibJS/Runtime/ProxyObject.h b/Userland/Libraries/LibJS/Runtime/ProxyObject.h index a60557ae8a..d48954502d 100644 --- a/Userland/Libraries/LibJS/Runtime/ProxyObject.h +++ b/Userland/Libraries/LibJS/Runtime/ProxyObject.h @@ -36,7 +36,7 @@ public: // 10.5 Proxy Object Internal Methods and Internal Slots, https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots virtual ThrowCompletionOr internal_get_prototype_of() const override; - virtual bool internal_set_prototype_of(Object* prototype) override; + virtual ThrowCompletionOr internal_set_prototype_of(Object* prototype) override; virtual bool internal_is_extensible() const override; virtual bool internal_prevent_extensions() override; virtual Optional internal_get_own_property(PropertyName const&) const override; diff --git a/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp b/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp index 990bd27f65..bd9810e320 100644 --- a/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp +++ b/Userland/Libraries/LibJS/Runtime/ReflectObject.cpp @@ -334,7 +334,7 @@ JS_DEFINE_NATIVE_FUNCTION(ReflectObject::set_prototype_of) } // 3. Return ? target.[[SetPrototypeOf]](proto). - return Value(target.as_object().internal_set_prototype_of(proto.is_null() ? nullptr : &proto.as_object())); + return Value(TRY_OR_DISCARD(target.as_object().internal_set_prototype_of(proto.is_null() ? nullptr : &proto.as_object()))); } } diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp index 18afb21d21..a5ec997946 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.cpp +++ b/Userland/Libraries/LibJS/Runtime/VM.cpp @@ -537,11 +537,8 @@ Value VM::construct(FunctionObject& function, FunctionObject& new_target, Option auto prototype = new_target.get(names.prototype); if (exception()) return {}; - if (prototype.is_object()) { - result.as_object().internal_set_prototype_of(&prototype.as_object()); - if (exception()) - return {}; - } + if (prototype.is_object()) + TRY_OR_DISCARD(result.as_object().internal_set_prototype_of(&prototype.as_object())); return result; } diff --git a/Userland/Libraries/LibWeb/Bindings/LocationObject.cpp b/Userland/Libraries/LibWeb/Bindings/LocationObject.cpp index 0702ad4ce1..86eeff93d9 100644 --- a/Userland/Libraries/LibWeb/Bindings/LocationObject.cpp +++ b/Userland/Libraries/LibWeb/Bindings/LocationObject.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -125,7 +126,7 @@ JS_DEFINE_NATIVE_FUNCTION(LocationObject::reload) } // https://html.spec.whatwg.org/multipage/history.html#location-setprototypeof -bool LocationObject::internal_set_prototype_of(Object* prototype) +JS::ThrowCompletionOr LocationObject::internal_set_prototype_of(Object* prototype) { // 1. Return ! SetImmutablePrototype(this, V). return set_immutable_prototype(prototype); diff --git a/Userland/Libraries/LibWeb/Bindings/LocationObject.h b/Userland/Libraries/LibWeb/Bindings/LocationObject.h index d1e3ea5212..8f24d01a39 100644 --- a/Userland/Libraries/LibWeb/Bindings/LocationObject.h +++ b/Userland/Libraries/LibWeb/Bindings/LocationObject.h @@ -6,6 +6,7 @@ #pragma once +#include #include #include @@ -20,7 +21,7 @@ public: virtual void initialize(JS::GlobalObject&) override; virtual ~LocationObject() override; - virtual bool internal_set_prototype_of(Object* prototype) override; + virtual JS::ThrowCompletionOr internal_set_prototype_of(Object* prototype) override; virtual bool internal_is_extensible() const override; virtual bool internal_prevent_extensions() override; diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp b/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp index 18a46e07db..612a2db08d 100644 --- a/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp +++ b/Userland/Libraries/LibWeb/Bindings/WindowObject.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -52,7 +53,7 @@ void WindowObject::initialize_global_object() { Base::initialize_global_object(); - auto success = Object::internal_set_prototype_of(&ensure_web_prototype("EventTarget")); + auto success = Object::internal_set_prototype_of(&ensure_web_prototype("EventTarget")).release_value(); VERIFY(success); // FIXME: These should be native accessors, not properties @@ -143,7 +144,7 @@ Origin WindowObject::origin() const } // https://heycam.github.io/webidl/#platform-object-setprototypeof -bool WindowObject::internal_set_prototype_of(JS::Object* prototype) +JS::ThrowCompletionOr WindowObject::internal_set_prototype_of(JS::Object* prototype) { // 1. Return ? SetImmutablePrototype(O, V). return set_immutable_prototype(prototype); diff --git a/Userland/Libraries/LibWeb/Bindings/WindowObject.h b/Userland/Libraries/LibWeb/Bindings/WindowObject.h index 1c29fbf788..911a93bee7 100644 --- a/Userland/Libraries/LibWeb/Bindings/WindowObject.h +++ b/Userland/Libraries/LibWeb/Bindings/WindowObject.h @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -60,7 +61,7 @@ public: return *constructor; } - virtual bool internal_set_prototype_of(JS::Object* prototype) override; + virtual JS::ThrowCompletionOr internal_set_prototype_of(JS::Object* prototype) override; private: virtual void visit_edges(Visitor&) override; diff --git a/Userland/Services/WebContent/ConsoleGlobalObject.cpp b/Userland/Services/WebContent/ConsoleGlobalObject.cpp index db79202572..2b5a61b6c5 100644 --- a/Userland/Services/WebContent/ConsoleGlobalObject.cpp +++ b/Userland/Services/WebContent/ConsoleGlobalObject.cpp @@ -42,7 +42,7 @@ JS::ThrowCompletionOr ConsoleGlobalObject::internal_get_prototype_o return m_window_object->internal_get_prototype_of(); } -bool ConsoleGlobalObject::internal_set_prototype_of(JS::Object* prototype) +JS::ThrowCompletionOr ConsoleGlobalObject::internal_set_prototype_of(JS::Object* prototype) { return m_window_object->internal_set_prototype_of(prototype); } diff --git a/Userland/Services/WebContent/ConsoleGlobalObject.h b/Userland/Services/WebContent/ConsoleGlobalObject.h index c33f9f5f26..d92ec49cd8 100644 --- a/Userland/Services/WebContent/ConsoleGlobalObject.h +++ b/Userland/Services/WebContent/ConsoleGlobalObject.h @@ -24,7 +24,7 @@ public: virtual ~ConsoleGlobalObject() override; virtual JS::ThrowCompletionOr internal_get_prototype_of() const override; - virtual bool internal_set_prototype_of(Object* prototype) override; + virtual JS::ThrowCompletionOr internal_set_prototype_of(Object* prototype) override; virtual bool internal_is_extensible() const override; virtual bool internal_prevent_extensions() override; virtual Optional internal_get_own_property(JS::PropertyName const& name) const override;