diff options
author | Linus Groh <mail@linusgroh.de> | 2022-10-30 01:52:07 +0000 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-10-30 11:30:23 +0000 |
commit | b1968b8bedbe4266c3a488589e64492955023799 (patch) | |
tree | 5e04e2ac323fa1ebeca28ffb36d3e3499618ec93 /Userland/Libraries/LibWeb/Fetch/Infrastructure | |
parent | 63122d0276c3e44c005d0c5eaf57f297ecd567f0 (diff) | |
download | serenity-b1968b8bedbe4266c3a488589e64492955023799.zip |
LibWeb: Make Fetch::Infrastructure::{Request,Response,HeaderList} GC'd
This is the way.
On a more serious note, there's no reason to keep adding ref-counted
classes to LibWeb now that the majority of classes is GC'd - it only
adds the risk of discovering some cycle down the line, and forces us to
use handles as we can't visit().
Diffstat (limited to 'Userland/Libraries/LibWeb/Fetch/Infrastructure')
6 files changed, 178 insertions, 93 deletions
diff --git a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Headers.cpp b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Headers.cpp index 0147f03883..838ce31906 100644 --- a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Headers.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Headers.cpp @@ -11,6 +11,8 @@ #include <AK/GenericLexer.h> #include <AK/QuickSort.h> #include <AK/ScopeGuard.h> +#include <LibJS/Heap/Heap.h> +#include <LibJS/Runtime/VM.h> #include <LibRegex/Regex.h> #include <LibWeb/Fetch/Infrastructure/HTTP.h> #include <LibWeb/Fetch/Infrastructure/HTTP/Headers.h> @@ -42,6 +44,11 @@ ErrorOr<Header> Header::from_string_pair(StringView name, StringView value) }; } +JS::NonnullGCPtr<HeaderList> HeaderList::create(JS::VM& vm) +{ + return { *vm.heap().allocate_without_realm<HeaderList>() }; +} + // https://fetch.spec.whatwg.org/#header-list-contains bool HeaderList::contains(ReadonlyBytes name) const { diff --git a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Headers.h b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Headers.h index 71a8932644..15ad9355e2 100644 --- a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Headers.h +++ b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Headers.h @@ -13,6 +13,8 @@ #include <AK/Optional.h> #include <AK/String.h> #include <AK/Vector.h> +#include <LibJS/Forward.h> +#include <LibJS/Heap/Cell.h> #include <LibWeb/MimeSniff/MimeType.h> namespace Web::Fetch::Infrastructure { @@ -29,13 +31,17 @@ struct Header { // https://fetch.spec.whatwg.org/#concept-header-list // A header list is a list of zero or more headers. It is initially the empty list. class HeaderList final - : public RefCounted<HeaderList> + : public JS::Cell , Vector<Header> { + JS_CELL(HeaderList, JS::Cell); + public: using Vector::begin; using Vector::clear; using Vector::end; + [[nodiscard]] static JS::NonnullGCPtr<HeaderList> create(JS::VM&); + [[nodiscard]] bool contains(ReadonlyBytes) const; [[nodiscard]] ErrorOr<Optional<ByteBuffer>> get(ReadonlyBytes) const; [[nodiscard]] ErrorOr<Optional<Vector<String>>> get_decode_and_split(ReadonlyBytes) const; diff --git a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.cpp b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.cpp index fa9c8d978f..2e2db5be8c 100644 --- a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.cpp @@ -5,18 +5,26 @@ */ #include <AK/Array.h> +#include <LibJS/Heap/Heap.h> +#include <LibJS/Runtime/Realm.h> #include <LibWeb/Fetch/Infrastructure/HTTP/Requests.h> namespace Web::Fetch::Infrastructure { -Request::Request() - : m_header_list(make_ref_counted<HeaderList>()) +Request::Request(JS::NonnullGCPtr<HeaderList> header_list) + : m_header_list(header_list) { } -NonnullRefPtr<Request> Request::create() +void Request::visit_edges(JS::Cell::Visitor& visitor) { - return adopt_ref(*new Request()); + Base::visit_edges(visitor); + visitor.visit(m_header_list); +} + +JS::NonnullGCPtr<Request> Request::create(JS::VM& vm) +{ + return { *vm.heap().allocate_without_realm<Request>(HeaderList::create(vm)) }; } // https://fetch.spec.whatwg.org/#concept-request-url @@ -181,12 +189,12 @@ ErrorOr<ByteBuffer> Request::byte_serialize_origin() const } // https://fetch.spec.whatwg.org/#concept-request-clone -WebIDL::ExceptionOr<NonnullRefPtr<Request>> Request::clone() const +WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> Request::clone(JS::VM& vm) const { // To clone a request request, run these steps: // 1. Let newRequest be a copy of request, except for its body. - auto new_request = Infrastructure::Request::create(); + auto new_request = Infrastructure::Request::create(vm); new_request->set_method(m_method); new_request->set_local_urls_only(m_local_urls_only); for (auto const& header : *m_header_list) diff --git a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.h b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.h index ff78135a5b..2bca0f6bda 100644 --- a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.h +++ b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Requests.h @@ -10,11 +10,12 @@ #include <AK/Error.h> #include <AK/Forward.h> #include <AK/Optional.h> -#include <AK/RefCounted.h> #include <AK/String.h> #include <AK/URL.h> #include <AK/Variant.h> #include <AK/Vector.h> +#include <LibJS/Forward.h> +#include <LibJS/Heap/Cell.h> #include <LibWeb/Fetch/Infrastructure/HTTP/Bodies.h> #include <LibWeb/Fetch/Infrastructure/HTTP/Headers.h> #include <LibWeb/HTML/Origin.h> @@ -24,7 +25,9 @@ namespace Web::Fetch::Infrastructure { // https://fetch.spec.whatwg.org/#concept-request -class Request final : public RefCounted<Request> { +class Request final : public JS::Cell { + JS_CELL(Request, JS::Cell); + public: enum class CacheMode { Default, @@ -156,7 +159,7 @@ public: using ReservedClientType = Variant<Empty, HTML::Environment*, HTML::EnvironmentSettingsObject*>; using WindowType = Variant<Window, HTML::EnvironmentSettingsObject*>; - static NonnullRefPtr<Request> create(); + [[nodiscard]] static JS::NonnullGCPtr<Request> create(JS::VM&); [[nodiscard]] ReadonlyBytes method() const { return m_method; } void set_method(ByteBuffer method) { m_method = move(method); } @@ -164,9 +167,8 @@ public: [[nodiscard]] bool local_urls_only() const { return m_local_urls_only; } void set_local_urls_only(bool local_urls_only) { m_local_urls_only = local_urls_only; } - [[nodiscard]] NonnullRefPtr<HeaderList> const& header_list() const { return m_header_list; } - [[nodiscard]] NonnullRefPtr<HeaderList>& header_list() { return m_header_list; } - void set_header_list(NonnullRefPtr<HeaderList> header_list) { m_header_list = move(header_list); } + [[nodiscard]] JS::NonnullGCPtr<HeaderList> header_list() const { return m_header_list; } + void set_header_list(JS::NonnullGCPtr<HeaderList> header_list) { m_header_list = header_list; } [[nodiscard]] bool unsafe_request() const { return m_unsafe_request; } void set_unsafe_request(bool unsafe_request) { m_unsafe_request = unsafe_request; } @@ -294,14 +296,16 @@ public: [[nodiscard]] String serialize_origin() const; [[nodiscard]] ErrorOr<ByteBuffer> byte_serialize_origin() const; - [[nodiscard]] WebIDL::ExceptionOr<NonnullRefPtr<Request>> clone() const; + [[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<Request>> clone(JS::VM&) const; [[nodiscard]] ErrorOr<void> add_range_header(u64 first, Optional<u64> const& last); [[nodiscard]] bool cross_origin_embedder_policy_allows_credentials() const; private: - Request(); + explicit Request(JS::NonnullGCPtr<HeaderList>); + + virtual void visit_edges(JS::Cell::Visitor&) override; // https://fetch.spec.whatwg.org/#concept-request-method // A request has an associated method (a method). Unless stated otherwise it is `GET`. @@ -313,7 +317,7 @@ private: // https://fetch.spec.whatwg.org/#concept-request-header-list // A request has an associated header list (a header list). Unless stated otherwise it is empty. - NonnullRefPtr<HeaderList> m_header_list; + JS::NonnullGCPtr<HeaderList> m_header_list; // https://fetch.spec.whatwg.org/#unsafe-request-flag // A request has an associated unsafe-request flag. Unless stated otherwise it is unset. diff --git a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.cpp b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.cpp index 398f7fed19..bc53c3cd21 100644 --- a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.cpp +++ b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.cpp @@ -4,36 +4,44 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <LibJS/Heap/Heap.h> +#include <LibJS/Runtime/VM.h> #include <LibWeb/Bindings/MainThreadVM.h> #include <LibWeb/Fetch/Infrastructure/HTTP/Bodies.h> #include <LibWeb/Fetch/Infrastructure/HTTP/Responses.h> namespace Web::Fetch::Infrastructure { -Response::Response() - : m_header_list(make_ref_counted<HeaderList>()) +Response::Response(JS::NonnullGCPtr<HeaderList> header_list) + : m_header_list(header_list) { } -NonnullRefPtr<Response> Response::create() +void Response::visit_edges(JS::Cell::Visitor& visitor) { - return adopt_ref(*new Response()); + Base::visit_edges(visitor); + visitor.visit(m_header_list); +} + +JS::NonnullGCPtr<Response> Response::create(JS::VM& vm) +{ + return { *vm.heap().allocate_without_realm<Response>(HeaderList::create(vm)) }; } // https://fetch.spec.whatwg.org/#ref-for-concept-network-error%E2%91%A3 // A network error is a response whose status is always 0, status message is always // the empty byte sequence, header list is always empty, and body is always null. -NonnullRefPtr<Response> Response::aborted_network_error() +JS::NonnullGCPtr<Response> Response::aborted_network_error(JS::VM& vm) { - auto response = network_error(); + auto response = network_error(vm); response->set_aborted(true); return response; } -NonnullRefPtr<Response> Response::network_error() +JS::NonnullGCPtr<Response> Response::network_error(JS::VM& vm) { - auto response = Response::create(); + auto response = Response::create(vm); response->set_status(0); response->set_type(Type::Error); VERIFY(!response->body().has_value()); @@ -93,29 +101,28 @@ ErrorOr<Optional<AK::URL>> Response::location_url(Optional<String> const& reques } // https://fetch.spec.whatwg.org/#concept-response-clone -WebIDL::ExceptionOr<NonnullRefPtr<Response>> Response::clone() const +WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::clone(JS::VM& vm) const { // To clone a response response, run these steps: - auto& vm = Bindings::main_thread_vm(); auto& realm = *vm.current_realm(); // 1. If response is a filtered response, then return a new identical filtered response whose internal response is a clone of response’s internal response. if (is<FilteredResponse>(*this)) { - auto internal_response = TRY(static_cast<FilteredResponse const&>(*this).internal_response()->clone()); + auto internal_response = TRY(static_cast<FilteredResponse const&>(*this).internal_response()->clone(vm)); if (is<BasicFilteredResponse>(*this)) - return TRY_OR_RETURN_OOM(realm, BasicFilteredResponse::create(move(internal_response))); + return TRY_OR_RETURN_OOM(realm, BasicFilteredResponse::create(vm, internal_response)); if (is<CORSFilteredResponse>(*this)) - return TRY_OR_RETURN_OOM(realm, CORSFilteredResponse::create(move(internal_response))); + return TRY_OR_RETURN_OOM(realm, CORSFilteredResponse::create(vm, internal_response)); if (is<OpaqueFilteredResponse>(*this)) - return OpaqueFilteredResponse::create(move(internal_response)); + return OpaqueFilteredResponse::create(vm, internal_response); if (is<OpaqueRedirectFilteredResponse>(*this)) - return OpaqueRedirectFilteredResponse::create(move(internal_response)); + return OpaqueRedirectFilteredResponse::create(vm, internal_response); VERIFY_NOT_REACHED(); } // 2. Let newResponse be a copy of response, except for its body. - auto new_response = Infrastructure::Response::create(); + auto new_response = Infrastructure::Response::create(vm); new_response->set_type(m_type); new_response->set_aborted(m_aborted); new_response->set_url_list(m_url_list); @@ -139,8 +146,9 @@ WebIDL::ExceptionOr<NonnullRefPtr<Response>> Response::clone() const return new_response; } -FilteredResponse::FilteredResponse(NonnullRefPtr<Response> internal_response) - : m_internal_response(move(internal_response)) +FilteredResponse::FilteredResponse(JS::NonnullGCPtr<Response> internal_response, JS::NonnullGCPtr<HeaderList> header_list) + : Response(header_list) + , m_internal_response(internal_response) { } @@ -148,26 +156,38 @@ FilteredResponse::~FilteredResponse() { } -ErrorOr<NonnullRefPtr<BasicFilteredResponse>> BasicFilteredResponse::create(NonnullRefPtr<Response> internal_response) +void FilteredResponse::visit_edges(JS::Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(m_internal_response); +} + +ErrorOr<JS::NonnullGCPtr<BasicFilteredResponse>> BasicFilteredResponse::create(JS::VM& vm, JS::NonnullGCPtr<Response> internal_response) { // A basic filtered response is a filtered response whose type is "basic" and header list excludes // any headers in internal response’s header list whose name is a forbidden response-header name. - auto header_list = make_ref_counted<HeaderList>(); + auto header_list = HeaderList::create(vm); for (auto const& header : *internal_response->header_list()) { if (!is_forbidden_response_header_name(header.name)) TRY(header_list->append(header)); } - return adopt_ref(*new BasicFilteredResponse(move(internal_response), move(header_list))); + return { *vm.heap().allocate_without_realm<BasicFilteredResponse>(internal_response, header_list) }; } -BasicFilteredResponse::BasicFilteredResponse(NonnullRefPtr<Response> internal_response, NonnullRefPtr<HeaderList> header_list) - : FilteredResponse(move(internal_response)) - , m_header_list(move(header_list)) +BasicFilteredResponse::BasicFilteredResponse(JS::NonnullGCPtr<Response> internal_response, JS::NonnullGCPtr<HeaderList> header_list) + : FilteredResponse(internal_response, header_list) + , m_header_list(header_list) { } -ErrorOr<NonnullRefPtr<CORSFilteredResponse>> CORSFilteredResponse::create(NonnullRefPtr<Response> internal_response) +void BasicFilteredResponse::visit_edges(JS::Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(m_header_list); +} + +ErrorOr<JS::NonnullGCPtr<CORSFilteredResponse>> CORSFilteredResponse::create(JS::VM& vm, JS::NonnullGCPtr<Response> internal_response) { // A CORS filtered response is a filtered response whose type is "cors" and header list excludes // any headers in internal response’s header list whose name is not a CORS-safelisted response-header @@ -176,43 +196,63 @@ ErrorOr<NonnullRefPtr<CORSFilteredResponse>> CORSFilteredResponse::create(Nonnul for (auto const& header_name : internal_response->cors_exposed_header_name_list()) cors_exposed_header_name_list.append(header_name.span()); - auto header_list = make_ref_counted<HeaderList>(); + auto header_list = HeaderList::create(vm); for (auto const& header : *internal_response->header_list()) { if (is_cors_safelisted_response_header_name(header.name, cors_exposed_header_name_list)) TRY(header_list->append(header)); } - return adopt_ref(*new CORSFilteredResponse(move(internal_response), move(header_list))); + return { *vm.heap().allocate_without_realm<CORSFilteredResponse>(internal_response, header_list) }; } -CORSFilteredResponse::CORSFilteredResponse(NonnullRefPtr<Response> internal_response, NonnullRefPtr<HeaderList> header_list) - : FilteredResponse(move(internal_response)) - , m_header_list(move(header_list)) +CORSFilteredResponse::CORSFilteredResponse(JS::NonnullGCPtr<Response> internal_response, JS::NonnullGCPtr<HeaderList> header_list) + : FilteredResponse(internal_response, header_list) + , m_header_list(header_list) { } -NonnullRefPtr<OpaqueFilteredResponse> OpaqueFilteredResponse::create(NonnullRefPtr<Response> internal_response) +void CORSFilteredResponse::visit_edges(JS::Cell::Visitor& visitor) { - // An opaque-redirect filtered response is a filtered response whose type is "opaqueredirect", + Base::visit_edges(visitor); + visitor.visit(m_header_list); +} + +JS::NonnullGCPtr<OpaqueFilteredResponse> OpaqueFilteredResponse::create(JS::VM& vm, JS::NonnullGCPtr<Response> internal_response) +{ + // An opaque filtered response is a filtered response whose type is "opaque", URL list is the empty list, // status is 0, status message is the empty byte sequence, header list is empty, and body is null. - return adopt_ref(*new OpaqueFilteredResponse(move(internal_response))); + return { *vm.heap().allocate_without_realm<OpaqueFilteredResponse>(internal_response, HeaderList::create(vm)) }; +} + +OpaqueFilteredResponse::OpaqueFilteredResponse(JS::NonnullGCPtr<Response> internal_response, JS::NonnullGCPtr<HeaderList> header_list) + : FilteredResponse(internal_response, header_list) + , m_header_list(header_list) +{ } -OpaqueFilteredResponse::OpaqueFilteredResponse(NonnullRefPtr<Response> internal_response) - : FilteredResponse(move(internal_response)) - , m_header_list(make_ref_counted<HeaderList>()) +void OpaqueFilteredResponse::visit_edges(JS::Cell::Visitor& visitor) { + Base::visit_edges(visitor); + visitor.visit(m_header_list); +} + +JS::NonnullGCPtr<OpaqueRedirectFilteredResponse> OpaqueRedirectFilteredResponse::create(JS::VM& vm, JS::NonnullGCPtr<Response> internal_response) +{ + // An opaque-redirect filtered response is a filtered response whose type is "opaqueredirect", + // status is 0, status message is the empty byte sequence, header list is empty, and body is null. + return { *vm.heap().allocate_without_realm<OpaqueRedirectFilteredResponse>(internal_response, HeaderList::create(vm)) }; } -NonnullRefPtr<OpaqueRedirectFilteredResponse> OpaqueRedirectFilteredResponse::create(NonnullRefPtr<Response> internal_response) +OpaqueRedirectFilteredResponse::OpaqueRedirectFilteredResponse(JS::NonnullGCPtr<Response> internal_response, JS::NonnullGCPtr<HeaderList> header_list) + : FilteredResponse(internal_response, header_list) + , m_header_list(header_list) { - return adopt_ref(*new OpaqueRedirectFilteredResponse(move(internal_response))); } -OpaqueRedirectFilteredResponse::OpaqueRedirectFilteredResponse(NonnullRefPtr<Response> internal_response) - : FilteredResponse(move(internal_response)) - , m_header_list(make_ref_counted<HeaderList>()) +void OpaqueRedirectFilteredResponse::visit_edges(JS::Cell::Visitor& visitor) { + Base::visit_edges(visitor); + visitor.visit(m_header_list); } } diff --git a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.h b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.h index 4df9eb9b50..589bcbbc0f 100644 --- a/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.h +++ b/Userland/Libraries/LibWeb/Fetch/Infrastructure/HTTP/Responses.h @@ -10,9 +10,10 @@ #include <AK/Error.h> #include <AK/Forward.h> #include <AK/Optional.h> -#include <AK/RefCounted.h> #include <AK/URL.h> #include <AK/Vector.h> +#include <LibJS/Forward.h> +#include <LibJS/Heap/Cell.h> #include <LibWeb/Fetch/Infrastructure/HTTP/Bodies.h> #include <LibWeb/Fetch/Infrastructure/HTTP/Headers.h> #include <LibWeb/Fetch/Infrastructure/HTTP/Statuses.h> @@ -20,7 +21,9 @@ namespace Web::Fetch::Infrastructure { // https://fetch.spec.whatwg.org/#concept-response -class Response : public RefCounted<Response> { +class Response : public JS::Cell { + JS_CELL(Response, JS::Cell); + public: enum class CacheState { Local, @@ -45,9 +48,9 @@ public: u64 decoded_size { 0 }; }; - [[nodiscard]] static NonnullRefPtr<Response> create(); - [[nodiscard]] static NonnullRefPtr<Response> aborted_network_error(); - [[nodiscard]] static NonnullRefPtr<Response> network_error(); + [[nodiscard]] static JS::NonnullGCPtr<Response> create(JS::VM&); + [[nodiscard]] static JS::NonnullGCPtr<Response> aborted_network_error(JS::VM&); + [[nodiscard]] static JS::NonnullGCPtr<Response> network_error(JS::VM&); virtual ~Response() = default; @@ -67,9 +70,8 @@ public: [[nodiscard]] virtual ReadonlyBytes status_message() const { return m_status_message; } void set_status_message(ByteBuffer status_message) { m_status_message = move(status_message); } - [[nodiscard]] virtual NonnullRefPtr<HeaderList> const& header_list() const { return m_header_list; } - [[nodiscard]] virtual NonnullRefPtr<HeaderList>& header_list() { return m_header_list; } - void set_header_list(NonnullRefPtr<HeaderList> header_list) { m_header_list = move(header_list); } + [[nodiscard]] virtual JS::NonnullGCPtr<HeaderList> header_list() const { return m_header_list; } + void set_header_list(JS::NonnullGCPtr<HeaderList> header_list) { m_header_list = header_list; } [[nodiscard]] virtual Optional<Body> const& body() const { return m_body; } [[nodiscard]] virtual Optional<Body>& body() { return m_body; } @@ -99,10 +101,12 @@ public: [[nodiscard]] Optional<AK::URL const&> url() const; [[nodiscard]] ErrorOr<Optional<AK::URL>> location_url(Optional<String> const& request_fragment) const; - [[nodiscard]] WebIDL::ExceptionOr<NonnullRefPtr<Response>> clone() const; + [[nodiscard]] WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> clone(JS::VM&) const; protected: - Response(); + explicit Response(JS::NonnullGCPtr<HeaderList>); + + virtual void visit_edges(JS::Cell::Visitor&) override; private: // https://fetch.spec.whatwg.org/#concept-response-type @@ -127,7 +131,7 @@ private: // https://fetch.spec.whatwg.org/#concept-response-header-list // A response has an associated header list (a header list). Unless stated otherwise it is empty. - NonnullRefPtr<HeaderList> m_header_list; + JS::NonnullGCPtr<HeaderList> m_header_list; // https://fetch.spec.whatwg.org/#concept-response-body // A response has an associated body (null or a body). Unless stated otherwise it is null. @@ -163,8 +167,10 @@ private: // https://fetch.spec.whatwg.org/#concept-filtered-response class FilteredResponse : public Response { + JS_CELL(FilteredResponse, Response); + public: - explicit FilteredResponse(NonnullRefPtr<Response>); + FilteredResponse(JS::NonnullGCPtr<Response>, JS::NonnullGCPtr<HeaderList>); virtual ~FilteredResponse() = 0; [[nodiscard]] virtual Type type() const override { return m_internal_response->type(); } @@ -173,8 +179,7 @@ public: [[nodiscard]] virtual Vector<AK::URL>& url_list() override { return m_internal_response->url_list(); } [[nodiscard]] virtual Status status() const override { return m_internal_response->status(); } [[nodiscard]] virtual ReadonlyBytes status_message() const override { return m_internal_response->status_message(); } - [[nodiscard]] virtual NonnullRefPtr<HeaderList> const& header_list() const override { return m_internal_response->header_list(); } - [[nodiscard]] virtual NonnullRefPtr<HeaderList>& header_list() override { return m_internal_response->header_list(); } + [[nodiscard]] virtual JS::NonnullGCPtr<HeaderList> header_list() const override { return m_internal_response->header_list(); } [[nodiscard]] virtual Optional<Body> const& body() const override { return m_internal_response->body(); } [[nodiscard]] virtual Optional<Body>& body() override { return m_internal_response->body(); } [[nodiscard]] virtual Optional<CacheState> const& cache_state() const override { return m_internal_response->cache_state(); } @@ -184,83 +189,98 @@ public: [[nodiscard]] virtual bool timing_allow_passed() const override { return m_internal_response->timing_allow_passed(); } [[nodiscard]] virtual BodyInfo const& body_info() const override { return m_internal_response->body_info(); } - [[nodiscard]] NonnullRefPtr<Response> internal_response() const { return m_internal_response; } + [[nodiscard]] JS::NonnullGCPtr<Response> internal_response() const { return m_internal_response; } protected: + virtual void visit_edges(JS::Cell::Visitor&) override; + +private: // https://fetch.spec.whatwg.org/#concept-internal-response - NonnullRefPtr<Response> m_internal_response; + JS::NonnullGCPtr<Response> m_internal_response; }; // https://fetch.spec.whatwg.org/#concept-filtered-response-basic class BasicFilteredResponse final : public FilteredResponse { + JS_CELL(OpaqueRedirectFilteredResponse, FilteredResponse); + public: - static ErrorOr<NonnullRefPtr<BasicFilteredResponse>> create(NonnullRefPtr<Response>); + [[nodiscard]] static ErrorOr<JS::NonnullGCPtr<BasicFilteredResponse>> create(JS::VM&, JS::NonnullGCPtr<Response>); [[nodiscard]] virtual Type type() const override { return Type::Basic; } - [[nodiscard]] virtual NonnullRefPtr<HeaderList> const& header_list() const override { return m_header_list; } - [[nodiscard]] virtual NonnullRefPtr<HeaderList>& header_list() override { return m_header_list; } + [[nodiscard]] virtual JS::NonnullGCPtr<HeaderList> header_list() const override { return m_header_list; } private: - BasicFilteredResponse(NonnullRefPtr<Response>, NonnullRefPtr<HeaderList>); + BasicFilteredResponse(JS::NonnullGCPtr<Response>, JS::NonnullGCPtr<HeaderList>); + + virtual void visit_edges(JS::Cell::Visitor&) override; - NonnullRefPtr<HeaderList> m_header_list; + JS::NonnullGCPtr<HeaderList> m_header_list; }; // https://fetch.spec.whatwg.org/#concept-filtered-response-cors class CORSFilteredResponse final : public FilteredResponse { + JS_CELL(CORSFilteredResponse, FilteredResponse); + public: - static ErrorOr<NonnullRefPtr<CORSFilteredResponse>> create(NonnullRefPtr<Response>); + [[nodiscard]] static ErrorOr<JS::NonnullGCPtr<CORSFilteredResponse>> create(JS::VM&, JS::NonnullGCPtr<Response>); [[nodiscard]] virtual Type type() const override { return Type::CORS; } - [[nodiscard]] virtual NonnullRefPtr<HeaderList> const& header_list() const override { return m_header_list; } - [[nodiscard]] virtual NonnullRefPtr<HeaderList>& header_list() override { return m_header_list; } + [[nodiscard]] virtual JS::NonnullGCPtr<HeaderList> header_list() const override { return m_header_list; } private: - CORSFilteredResponse(NonnullRefPtr<Response>, NonnullRefPtr<HeaderList>); + CORSFilteredResponse(JS::NonnullGCPtr<Response>, JS::NonnullGCPtr<HeaderList>); + + virtual void visit_edges(JS::Cell::Visitor&) override; - NonnullRefPtr<HeaderList> m_header_list; + JS::NonnullGCPtr<HeaderList> m_header_list; }; // https://fetch.spec.whatwg.org/#concept-filtered-response-opaque class OpaqueFilteredResponse final : public FilteredResponse { + JS_CELL(OpaqueFilteredResponse, FilteredResponse); + public: - static NonnullRefPtr<OpaqueFilteredResponse> create(NonnullRefPtr<Response>); + [[nodiscard]] static JS::NonnullGCPtr<OpaqueFilteredResponse> create(JS::VM&, JS::NonnullGCPtr<Response>); [[nodiscard]] virtual Type type() const override { return Type::Opaque; } [[nodiscard]] virtual Vector<AK::URL> const& url_list() const override { return m_url_list; } [[nodiscard]] virtual Vector<AK::URL>& url_list() override { return m_url_list; } [[nodiscard]] virtual Status status() const override { return 0; } [[nodiscard]] virtual ReadonlyBytes status_message() const override { return {}; } - [[nodiscard]] virtual NonnullRefPtr<HeaderList> const& header_list() const override { return m_header_list; } - [[nodiscard]] virtual NonnullRefPtr<HeaderList>& header_list() override { return m_header_list; } + [[nodiscard]] virtual JS::NonnullGCPtr<HeaderList> header_list() const override { return m_header_list; } [[nodiscard]] virtual Optional<Body> const& body() const override { return m_body; } [[nodiscard]] virtual Optional<Body>& body() override { return m_body; } private: - explicit OpaqueFilteredResponse(NonnullRefPtr<Response>); + OpaqueFilteredResponse(JS::NonnullGCPtr<Response>, JS::NonnullGCPtr<HeaderList>); + + virtual void visit_edges(JS::Cell::Visitor&) override; Vector<AK::URL> m_url_list; - NonnullRefPtr<HeaderList> m_header_list; + JS::NonnullGCPtr<HeaderList> m_header_list; Optional<Body> m_body; }; // https://fetch.spec.whatwg.org/#concept-filtered-response-opaque-redirect class OpaqueRedirectFilteredResponse final : public FilteredResponse { + JS_CELL(OpaqueRedirectFilteredResponse, FilteredResponse); + public: - static NonnullRefPtr<OpaqueRedirectFilteredResponse> create(NonnullRefPtr<Response>); + [[nodiscard]] static JS::NonnullGCPtr<OpaqueRedirectFilteredResponse> create(JS::VM&, JS::NonnullGCPtr<Response>); [[nodiscard]] virtual Type type() const override { return Type::OpaqueRedirect; } [[nodiscard]] virtual Status status() const override { return 0; } [[nodiscard]] virtual ReadonlyBytes status_message() const override { return {}; } - [[nodiscard]] virtual NonnullRefPtr<HeaderList> const& header_list() const override { return m_header_list; } - [[nodiscard]] virtual NonnullRefPtr<HeaderList>& header_list() override { return m_header_list; } + [[nodiscard]] virtual JS::NonnullGCPtr<HeaderList> header_list() const override { return m_header_list; } [[nodiscard]] virtual Optional<Body> const& body() const override { return m_body; } [[nodiscard]] virtual Optional<Body>& body() override { return m_body; } private: - explicit OpaqueRedirectFilteredResponse(NonnullRefPtr<Response>); + OpaqueRedirectFilteredResponse(JS::NonnullGCPtr<Response>, JS::NonnullGCPtr<HeaderList>); + + virtual void visit_edges(JS::Cell::Visitor&) override; - NonnullRefPtr<HeaderList> m_header_list; + JS::NonnullGCPtr<HeaderList> m_header_list; Optional<Body> m_body; }; |