From fe9c5395d4de6f0127e46ef20f0f86ff22fbde91 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 4 Sep 2022 14:04:42 +0200 Subject: LibWeb: Make URL, URLSearchParams & URLSearchParamsIterator GC-allocated --- Userland/Libraries/LibWeb/Forward.h | 3 -- Userland/Libraries/LibWeb/URL/URL.cpp | 28 +++++++++++++-- Userland/Libraries/LibWeb/URL/URL.h | 28 +++++++-------- Userland/Libraries/LibWeb/URL/URLSearchParams.cpp | 31 +++++++++++++--- Userland/Libraries/LibWeb/URL/URLSearchParams.h | 28 ++++++--------- .../LibWeb/URL/URLSearchParamsIterator.cpp | 41 ++++++++++++++-------- .../Libraries/LibWeb/URL/URLSearchParamsIterator.h | 32 ++++++----------- Userland/Libraries/LibWeb/XHR/XMLHttpRequest.cpp | 2 +- Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h | 2 +- Userland/Libraries/LibWeb/idl_files.cmake | 4 +-- 10 files changed, 117 insertions(+), 82 deletions(-) (limited to 'Userland') diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h index 1c8686b87d..2ce0367fe5 100644 --- a/Userland/Libraries/LibWeb/Forward.h +++ b/Userland/Libraries/LibWeb/Forward.h @@ -453,9 +453,6 @@ class IntersectionObserverWrapper; class LocationObject; class OptionConstructor; class RangePrototype; -class URLSearchParamsIteratorWrapper; -class URLSearchParamsWrapper; -class URLWrapper; class WindowProxy; class WorkerLocationWrapper; class WorkerNavigatorWrapper; diff --git a/Userland/Libraries/LibWeb/URL/URL.cpp b/Userland/Libraries/LibWeb/URL/URL.cpp index 8878ca32a2..882f3c1e2a 100644 --- a/Userland/Libraries/LibWeb/URL/URL.cpp +++ b/Userland/Libraries/LibWeb/URL/URL.cpp @@ -6,11 +6,17 @@ */ #include +#include #include namespace Web::URL { -DOM::ExceptionOr> URL::create_with_global_object(HTML::Window& window_object, String const& url, String const& base) +JS::NonnullGCPtr URL::create(HTML::Window& window, AK::URL url, JS::NonnullGCPtr query) +{ + return *window.heap().allocate(window.realm(), window, move(url), move(query)); +} + +DOM::ExceptionOr> URL::create_with_global_object(HTML::Window& window, String const& url, String const& base) { // 1. Let parsedBase be null. Optional parsed_base; @@ -35,15 +41,31 @@ DOM::ExceptionOr> URL::create_with_global_object(HTML::Window auto& query = parsed_url.query().is_null() ? String::empty() : parsed_url.query(); // 6. Set this’s URL to parsedURL. // 7. Set this’s query object to a new URLSearchParams object. - auto query_object = MUST(URLSearchParams::create_with_global_object(window_object, query)); + auto query_object = MUST(URLSearchParams::create_with_global_object(window, query)); // 8. Initialize this’s query object with query. - auto result_url = URL::create(move(parsed_url), move(query_object)); + auto result_url = URL::create(window, move(parsed_url), move(query_object)); // 9. Set this’s query object’s URL object to this. result_url->m_query->m_url = result_url; return result_url; } +URL::URL(HTML::Window& window, AK::URL url, JS::NonnullGCPtr query) + : PlatformObject(window.realm()) + , m_url(move(url)) + , m_query(move(query)) +{ + set_prototype(&window.cached_web_prototype("URL")); +} + +URL::~URL() = default; + +void URL::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(m_query.ptr()); +} + String URL::href() const { // return the serialization of this’s URL. diff --git a/Userland/Libraries/LibWeb/URL/URL.h b/Userland/Libraries/LibWeb/URL/URL.h index c5e59e272e..3cb110e5f4 100644 --- a/Userland/Libraries/LibWeb/URL/URL.h +++ b/Userland/Libraries/LibWeb/URL/URL.h @@ -9,24 +9,20 @@ #include #include -#include +#include #include #include namespace Web::URL { -class URL : public Bindings::Wrappable - , public RefCounted - , public Weakable { -public: - using WrapperType = Bindings::URLWrapper; +class URL : public Bindings::PlatformObject { + WEB_PLATFORM_OBJECT(URL, Bindings::PlatformObject); - static NonnullRefPtr create(AK::URL url, NonnullRefPtr query) - { - return adopt_ref(*new URL(move(url), move(query))); - } +public: + static JS::NonnullGCPtr create(HTML::Window&, AK::URL url, JS::NonnullGCPtr query); + static DOM::ExceptionOr> create_with_global_object(HTML::Window&, String const& url, String const& base); - static DOM::ExceptionOr> create_with_global_object(HTML::Window&, String const& url, String const& base); + virtual ~URL() override; String href() const; DOM::ExceptionOr set_href(String const&); @@ -67,12 +63,14 @@ public: void set_query(Badge, String query) { m_url.set_query(move(query)); } private: - explicit URL(AK::URL url, NonnullRefPtr query) - : m_url(move(url)) - , m_query(move(query)) {}; + URL(HTML::Window&, AK::URL, JS::NonnullGCPtr query); + + virtual void visit_edges(Cell::Visitor&) override; AK::URL m_url; - NonnullRefPtr m_query; + JS::NonnullGCPtr m_query; }; } + +WRAPPER_HACK(URL, Web::URL) diff --git a/Userland/Libraries/LibWeb/URL/URLSearchParams.cpp b/Userland/Libraries/LibWeb/URL/URLSearchParams.cpp index 1c0d82927d..511e6f878f 100644 --- a/Userland/Libraries/LibWeb/URL/URLSearchParams.cpp +++ b/Userland/Libraries/LibWeb/URL/URLSearchParams.cpp @@ -7,11 +7,27 @@ #include #include #include +#include #include #include namespace Web::URL { +URLSearchParams::URLSearchParams(HTML::Window& window, Vector list) + : PlatformObject(window.realm()) + , m_list(move(list)) +{ + set_prototype(&window.cached_web_prototype("URLSearchParams")); +} + +URLSearchParams::~URLSearchParams() = default; + +void URLSearchParams::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(m_url); +} + String url_encode(Vector const& pairs, AK::URL::PercentEncodeSet percent_encode_set) { StringBuilder builder; @@ -66,9 +82,14 @@ Vector url_decode(StringView input) return output; } +JS::NonnullGCPtr URLSearchParams::create(HTML::Window& window, Vector list) +{ + return *window.heap().allocate(window.realm(), window, move(list)); +} + // https://url.spec.whatwg.org/#dom-urlsearchparams-urlsearchparams // https://url.spec.whatwg.org/#urlsearchparams-initialize -DOM::ExceptionOr> URLSearchParams::create_with_global_object(HTML::Window&, Variant>, OrderedHashMap, String> const& init) +DOM::ExceptionOr> URLSearchParams::create_with_global_object(HTML::Window& window, Variant>, OrderedHashMap, String> const& init) { // 1. If init is a string and starts with U+003F (?), then remove the first code point from init. // NOTE: We do this when we know that it's a string on step 3 of initialization. @@ -93,7 +114,7 @@ DOM::ExceptionOr> URLSearchParams::create_with_gl list.append(QueryParam { .name = pair[0], .value = pair[1] }); } - return URLSearchParams::create(move(list)); + return URLSearchParams::create(window, move(list)); } // 2. Otherwise, if init is a record, then for each name → value of init, append a new name-value pair whose name is name and value is value, to query’s list. @@ -106,7 +127,7 @@ DOM::ExceptionOr> URLSearchParams::create_with_gl for (auto const& pair : init_record) list.append(QueryParam { .name = pair.key, .value = pair.value }); - return URLSearchParams::create(move(list)); + return URLSearchParams::create(window, move(list)); } // 3. Otherwise: @@ -118,7 +139,7 @@ DOM::ExceptionOr> URLSearchParams::create_with_gl StringView stripped_init = init_string.substring_view(init_string.starts_with('?')); // b. Set query’s list to the result of parsing init. - return URLSearchParams::create(url_decode(stripped_init)); + return URLSearchParams::create(window, url_decode(stripped_init)); } void URLSearchParams::append(String const& name, String const& value) @@ -132,7 +153,7 @@ void URLSearchParams::append(String const& name, String const& value) void URLSearchParams::update() { // 1. If query’s URL object is null, then return. - if (m_url.is_null()) + if (!m_url) return; // 2. Let serializedQuery be the serialization of query’s list. auto serialized_query = to_string(); diff --git a/Userland/Libraries/LibWeb/URL/URLSearchParams.h b/Userland/Libraries/LibWeb/URL/URLSearchParams.h index 15f45ea7b1..208a90c92d 100644 --- a/Userland/Libraries/LibWeb/URL/URLSearchParams.h +++ b/Userland/Libraries/LibWeb/URL/URLSearchParams.h @@ -20,17 +20,14 @@ struct QueryParam { String url_encode(Vector const&, AK::URL::PercentEncodeSet); Vector url_decode(StringView); -class URLSearchParams : public Bindings::Wrappable - , public RefCounted { -public: - using WrapperType = Bindings::URLSearchParamsWrapper; +class URLSearchParams : public Bindings::PlatformObject { + WEB_PLATFORM_OBJECT(URLSearchParams, Bindings::PlatformObject); - static NonnullRefPtr create(Vector list) - { - return adopt_ref(*new URLSearchParams(move(list))); - } +public: + static JS::NonnullGCPtr create(HTML::Window&, Vector list); + static DOM::ExceptionOr> create_with_global_object(HTML::Window&, Variant>, OrderedHashMap, String> const& init); - static DOM::ExceptionOr> create_with_global_object(HTML::Window&, Variant>, OrderedHashMap, String> const& init); + virtual ~URLSearchParams() override; void append(String const& name, String const& value); void delete_(String const& name); @@ -50,19 +47,16 @@ private: friend class URL; friend class URLSearchParamsIterator; - explicit URLSearchParams(Vector list) - : m_list(move(list)) {}; + URLSearchParams(HTML::Window&, Vector list); + + virtual void visit_edges(Cell::Visitor&) override; void update(); Vector m_list; - WeakPtr m_url; + JS::GCPtr m_url; }; } -namespace Web::Bindings { - -URLSearchParamsWrapper* wrap(JS::Realm&, URL::URLSearchParams&); - -} +WRAPPER_HACK(URLSearchParams, Web::URL) diff --git a/Userland/Libraries/LibWeb/URL/URLSearchParamsIterator.cpp b/Userland/Libraries/LibWeb/URL/URLSearchParamsIterator.cpp index bf21003141..e70a40f946 100644 --- a/Userland/Libraries/LibWeb/URL/URLSearchParamsIterator.cpp +++ b/Userland/Libraries/LibWeb/URL/URLSearchParamsIterator.cpp @@ -6,32 +6,45 @@ #include #include -#include -#include +#include +#include #include namespace Web::URL { -JS::Object* URLSearchParamsIterator::next() +JS::NonnullGCPtr URLSearchParamsIterator::create(URLSearchParams const& url_search_params, JS::Object::PropertyKind iteration_kind) +{ + return *url_search_params.heap().allocate(url_search_params.realm(), url_search_params, iteration_kind); +} + +URLSearchParamsIterator::URLSearchParamsIterator(URLSearchParams const& url_search_params, JS::Object::PropertyKind iteration_kind) + : PlatformObject(url_search_params.realm()) + , m_url_search_params(url_search_params) + , m_iteration_kind(iteration_kind) +{ + set_prototype(&url_search_params.global_object().ensure_web_prototype("URLSearchParamsIterator")); +} + +URLSearchParamsIterator::~URLSearchParamsIterator() = default; + +void URLSearchParamsIterator::visit_edges(JS::Cell::Visitor& visitor) { - auto& vm = wrapper()->vm(); - auto& realm = *vm.current_realm(); + Base::visit_edges(visitor); + visitor.visit(&m_url_search_params); +} +JS::Object* URLSearchParamsIterator::next() +{ if (m_index >= m_url_search_params.m_list.size()) - return create_iterator_result_object(vm, JS::js_undefined(), true); + return create_iterator_result_object(vm(), JS::js_undefined(), true); auto& entry = m_url_search_params.m_list[m_index++]; if (m_iteration_kind == JS::Object::PropertyKind::Key) - return create_iterator_result_object(vm, JS::js_string(vm, entry.name), false); + return create_iterator_result_object(vm(), JS::js_string(vm(), entry.name), false); else if (m_iteration_kind == JS::Object::PropertyKind::Value) - return create_iterator_result_object(vm, JS::js_string(vm, entry.value), false); + return create_iterator_result_object(vm(), JS::js_string(vm(), entry.value), false); - return create_iterator_result_object(vm, JS::Array::create_from(realm, { JS::js_string(vm, entry.name), JS::js_string(vm, entry.value) }), false); -} - -void URLSearchParamsIterator::visit_edges(JS::Cell::Visitor& visitor) -{ - visitor.visit(m_url_search_params.wrapper()); + return create_iterator_result_object(vm(), JS::Array::create_from(realm(), { JS::js_string(vm(), entry.name), JS::js_string(vm(), entry.value) }), false); } } diff --git a/Userland/Libraries/LibWeb/URL/URLSearchParamsIterator.h b/Userland/Libraries/LibWeb/URL/URLSearchParamsIterator.h index baec659ffb..59a89beda9 100644 --- a/Userland/Libraries/LibWeb/URL/URLSearchParamsIterator.h +++ b/Userland/Libraries/LibWeb/URL/URLSearchParamsIterator.h @@ -6,41 +6,31 @@ #pragma once -#include "URLSearchParams.h" -#include +#include #include namespace Web::URL { -class URLSearchParamsIterator : public Bindings::Wrappable - , public RefCounted { +class URLSearchParamsIterator : public Bindings::PlatformObject { + WEB_PLATFORM_OBJECT(URLSearchParamsIterator, Bindings::PlatformObject); + public: - using WrapperType = Bindings::URLSearchParamsIteratorWrapper; + static JS::NonnullGCPtr create(URLSearchParams const&, JS::Object::PropertyKind iteration_kind); - static NonnullRefPtr create(URLSearchParams const& url_search_params, JS::Object::PropertyKind iteration_kind) - { - return adopt_ref(*new URLSearchParamsIterator(url_search_params, iteration_kind)); - } + virtual ~URLSearchParamsIterator() override; JS::Object* next(); - void visit_edges(JS::Cell::Visitor&); - private: - explicit URLSearchParamsIterator(URLSearchParams const& url_search_params, JS::Object::PropertyKind iteration_kind) - : m_url_search_params(url_search_params) - , m_iteration_kind(iteration_kind) - { - } + URLSearchParamsIterator(URLSearchParams const&, JS::Object::PropertyKind iteration_kind); + + virtual void visit_edges(Cell::Visitor&) override; URLSearchParams const& m_url_search_params; JS::Object::PropertyKind m_iteration_kind; size_t m_index { 0 }; }; -} - -namespace Web::Bindings { - -URLSearchParamsIteratorWrapper* wrap(JS::Realm&, URL::URLSearchParamsIterator&); } + +WRAPPER_HACK(URLSearchParamsIterator, Web::URL) diff --git a/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.cpp b/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.cpp index 56e6a7c764..2f50023426 100644 --- a/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.cpp +++ b/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.cpp @@ -301,7 +301,7 @@ static ErrorOr extract_body(XMLHttpRequestB source = TRY(Bindings::IDL::get_buffer_source_copy(*buffer_source.cell())); return {}; }, - [&](NonnullRefPtr const& url_search_params) -> ErrorOr { + [&](JS::Handle const& url_search_params) -> ErrorOr { // Set source to the result of running the application/x-www-form-urlencoded serializer with object’s list. source = url_search_params->to_string().to_byte_buffer(); // Set type to `application/x-www-form-urlencoded;charset=UTF-8`. diff --git a/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h b/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h index edea21ab67..50bffd0278 100644 --- a/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h +++ b/Userland/Libraries/LibWeb/XHR/XMLHttpRequest.h @@ -24,7 +24,7 @@ namespace Web::XHR { // https://fetch.spec.whatwg.org/#typedefdef-xmlhttprequestbodyinit -using XMLHttpRequestBodyInit = Variant, JS::Handle, NonnullRefPtr, String>; +using XMLHttpRequestBodyInit = Variant, JS::Handle, JS::Handle, String>; class XMLHttpRequest final : public XMLHttpRequestEventTarget { WEB_PLATFORM_OBJECT(XMLHttpRequest, XMLHttpRequestEventTarget); diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake index 19dfb19387..ec5bd20db9 100644 --- a/Userland/Libraries/LibWeb/idl_files.cmake +++ b/Userland/Libraries/LibWeb/idl_files.cmake @@ -180,8 +180,8 @@ libweb_js_wrapper(UIEvents/FocusEvent NO_INSTANCE) libweb_js_wrapper(UIEvents/KeyboardEvent NO_INSTANCE) libweb_js_wrapper(UIEvents/MouseEvent NO_INSTANCE) libweb_js_wrapper(UIEvents/UIEvent NO_INSTANCE) -libweb_js_wrapper(URL/URL) -libweb_js_wrapper(URL/URLSearchParams ITERABLE) +libweb_js_wrapper(URL/URL NO_INSTANCE) +libweb_js_wrapper(URL/URLSearchParams ITERABLE NO_INSTANCE) libweb_js_wrapper(WebGL/WebGLContextEvent NO_INSTANCE) libweb_js_wrapper(WebGL/WebGLRenderingContext NO_INSTANCE) libweb_js_wrapper(WebSockets/WebSocket NO_INSTANCE) -- cgit v1.2.3