From 967a3e5a45af23f7922cffab9d77c0870ecbf3f2 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 8 Aug 2022 15:52:48 +0200 Subject: LibWeb: Make DOMImplementation GC-allocated --- .../Libraries/LibWeb/DOM/DOMImplementation.cpp | 20 ++++++++++++- Userland/Libraries/LibWeb/DOM/DOMImplementation.h | 35 ++++++++++++---------- Userland/Libraries/LibWeb/DOM/Document.cpp | 7 +++-- Userland/Libraries/LibWeb/DOM/Document.h | 4 +-- Userland/Libraries/LibWeb/Forward.h | 1 - Userland/Libraries/LibWeb/idl_files.cmake | 2 +- 6 files changed, 45 insertions(+), 24 deletions(-) diff --git a/Userland/Libraries/LibWeb/DOM/DOMImplementation.cpp b/Userland/Libraries/LibWeb/DOM/DOMImplementation.cpp index d2261f8a25..2216cc2f46 100644 --- a/Userland/Libraries/LibWeb/DOM/DOMImplementation.cpp +++ b/Userland/Libraries/LibWeb/DOM/DOMImplementation.cpp @@ -1,9 +1,12 @@ /* * Copyright (c) 2020, the SerenityOS developers. + * Copyright (c) 2022, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ +#include +#include #include #include #include @@ -14,9 +17,24 @@ namespace Web::DOM { +JS::NonnullGCPtr DOMImplementation::create(Document& document) +{ + auto& window_object = document.preferred_window_object(); + return *window_object.heap().allocate(window_object.realm(), document); +} + DOMImplementation::DOMImplementation(Document& document) - : RefCountForwarder(document) + : PlatformObject(document.preferred_window_object().ensure_web_prototype("DOMImplementation")) + , m_document(document) +{ +} + +DOMImplementation::~DOMImplementation() = default; + +void DOMImplementation::visit_edges(Cell::Visitor& visitor) { + Base::visit_edges(visitor); + visitor.visit(m_document); } // https://dom.spec.whatwg.org/#dom-domimplementation-createdocument diff --git a/Userland/Libraries/LibWeb/DOM/DOMImplementation.h b/Userland/Libraries/LibWeb/DOM/DOMImplementation.h index 1c8d828696..136cd83e1b 100644 --- a/Userland/Libraries/LibWeb/DOM/DOMImplementation.h +++ b/Userland/Libraries/LibWeb/DOM/DOMImplementation.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, the SerenityOS developers. + * Copyright (c) 2022, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ @@ -7,25 +8,20 @@ #pragma once #include -#include -#include -#include -#include +#include #include namespace Web::DOM { -class DOMImplementation final - : public RefCountForwarder - , public Weakable - , public Bindings::Wrappable { +class DOMImplementation final : public Bindings::PlatformObject { + JS_OBJECT(DOMImplementation, Bindings::PlatformObject); + public: - using WrapperType = Bindings::DOMImplementationWrapper; + static JS::NonnullGCPtr create(Document&); + explicit DOMImplementation(Document&); + virtual ~DOMImplementation(); - static NonnullOwnPtr create(Badge, Document& document) - { - return adopt_own(*new DOMImplementation(document)); - } + DOMImplementation& impl() { return *this; } ExceptionOr> create_document(String const&, String const&, RefPtr) const; NonnullRefPtr create_html_document(String const& title) const; @@ -35,10 +31,17 @@ public: bool has_feature() const { return true; } private: - explicit DOMImplementation(Document&); + virtual void visit_edges(Cell::Visitor&) override; - Document& document() { return ref_count_target(); } - Document const& document() const { return ref_count_target(); } + Document& document() { return m_document; } + Document const& document() const { return m_document; } + + Document& m_document; }; } + +namespace Web::Bindings { +inline JS::Object* wrap(JS::Realm&, Web::DOM::DOMImplementation& object) { return &object; } +using DOMImplementationWrapper = Web::DOM::DOMImplementation; +} diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index 0f816d1246..b15b17d3b4 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -281,7 +281,6 @@ Document::Document(const AK::URL& url) , m_style_computer(make(*this)) , m_url(url) , m_window(HTML::Window::create_with_document(*this)) - , m_implementation(DOMImplementation::create({}, *this)) , m_history(HTML::History::create(*this)) { m_style_sheets = JS::make_handle(CSS::StyleSheetList::create(*this)); @@ -1621,9 +1620,11 @@ void Document::evaluate_media_rules() } } -NonnullRefPtr Document::implementation() const +DOMImplementation* Document::implementation() { - return *m_implementation; + if (!m_implementation.cell()) + m_implementation = JS::make_handle(*DOMImplementation::create(*this)); + return m_implementation.cell(); } bool Document::has_focus() const diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h index a2920ffc1d..ee8cd13dbc 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.h +++ b/Userland/Libraries/LibWeb/DOM/Document.h @@ -300,7 +300,7 @@ public: void completely_finish_loading(); - NonnullRefPtr implementation() const; + DOMImplementation* implementation(); RefPtr current_script() const { return m_current_script; } void set_current_script(Badge, RefPtr script) { m_current_script = move(script); } @@ -457,7 +457,7 @@ private: bool m_ready_for_post_load_tasks { false }; - NonnullOwnPtr m_implementation; + JS::Handle m_implementation; RefPtr m_current_script; bool m_should_invalidate_styles_on_attribute_changes { true }; diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index e24163f47a..ed97f604f2 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -464,7 +464,6 @@ class DocumentFragmentWrapper; class DocumentTypeWrapper; class DocumentWrapper; class DOMExceptionWrapper; -class DOMImplementationWrapper; class DOMParserWrapper; class DOMPointWrapper; class DOMPointReadOnlyWrapper; diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index faa10bd512..e8a895a944 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -32,7 +32,7 @@ libweb_js_wrapper(DOM/Document) libweb_js_wrapper(DOM/DocumentFragment) libweb_js_wrapper(DOM/DocumentType) libweb_js_wrapper(DOM/DOMException) -libweb_js_wrapper(DOM/DOMImplementation) +libweb_js_wrapper(DOM/DOMImplementation NO_INSTANCE) libweb_js_wrapper(DOM/DOMTokenList NO_INSTANCE) libweb_js_wrapper(DOM/Element) libweb_js_wrapper(DOM/Event) -- cgit v1.2.3