mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 17:27:35 +00:00
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().
This commit is contained in:
parent
63122d0276
commit
b1968b8bed
19 changed files with 270 additions and 169 deletions
|
@ -17,9 +17,9 @@
|
|||
|
||||
namespace Web::Fetch {
|
||||
|
||||
Response::Response(JS::Realm& realm, NonnullRefPtr<Infrastructure::Response> response)
|
||||
Response::Response(JS::Realm& realm, JS::NonnullGCPtr<Infrastructure::Response> response)
|
||||
: PlatformObject(realm)
|
||||
, m_response(move(response))
|
||||
, m_response(response)
|
||||
{
|
||||
set_prototype(&Bindings::cached_web_prototype(realm, "Response"));
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ Response::~Response() = default;
|
|||
void Response::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_response);
|
||||
visitor.visit(m_headers);
|
||||
}
|
||||
|
||||
|
@ -64,18 +65,14 @@ Optional<Infrastructure::Body&> Response::body_impl()
|
|||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#response-create
|
||||
JS::NonnullGCPtr<Response> Response::create(NonnullRefPtr<Infrastructure::Response> response, Headers::Guard guard, JS::Realm& realm)
|
||||
JS::NonnullGCPtr<Response> Response::create(JS::Realm& realm, JS::NonnullGCPtr<Infrastructure::Response> response, Headers::Guard guard)
|
||||
{
|
||||
// Copy a NonnullRefPtr to the response's header list before response is being move()'d.
|
||||
auto response_reader_list = response->header_list();
|
||||
|
||||
// 1. Let responseObject be a new Response object with realm.
|
||||
// 2. Set responseObject’s response to response.
|
||||
auto* response_object = realm.heap().allocate<Response>(realm, realm, move(response));
|
||||
auto* response_object = realm.heap().allocate<Response>(realm, realm, response);
|
||||
|
||||
// 3. Set responseObject’s headers to a new Headers object with realm, whose headers list is response’s headers list and guard is guard.
|
||||
response_object->m_headers = realm.heap().allocate<Headers>(realm, realm);
|
||||
response_object->m_headers->set_header_list(move(response_reader_list));
|
||||
response_object->m_headers = realm.heap().allocate<Headers>(realm, realm, response->header_list());
|
||||
response_object->m_headers->set_guard(guard);
|
||||
|
||||
// 4. Return responseObject.
|
||||
|
@ -126,16 +123,17 @@ WebIDL::ExceptionOr<void> Response::initialize_response(ResponseInit const& init
|
|||
// https://fetch.spec.whatwg.org/#dom-response
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::construct_impl(JS::Realm& realm, Optional<BodyInit> const& body, ResponseInit const& init)
|
||||
{
|
||||
auto& vm = realm.vm();
|
||||
|
||||
// Referred to as 'this' in the spec.
|
||||
auto response_object = JS::NonnullGCPtr { *realm.heap().allocate<Response>(realm, realm, Infrastructure::Response::create()) };
|
||||
auto response_object = JS::NonnullGCPtr { *realm.heap().allocate<Response>(realm, realm, Infrastructure::Response::create(vm)) };
|
||||
|
||||
// 1. Set this’s response to a new response.
|
||||
// NOTE: This is done at the beginning as the 'this' value Response object
|
||||
// cannot exist with a null Infrastructure::Response.
|
||||
|
||||
// 2. Set this’s headers to a new Headers object with this’s relevant Realm, whose header list is this’s response’s header list and guard is "response".
|
||||
response_object->m_headers = realm.heap().allocate<Headers>(realm, realm);
|
||||
response_object->m_headers->set_header_list(response_object->response()->header_list());
|
||||
response_object->m_headers = realm.heap().allocate<Headers>(realm, realm, response_object->response()->header_list());
|
||||
response_object->m_headers->set_guard(Headers::Guard::Response);
|
||||
|
||||
// 3. Let bodyWithType be null.
|
||||
|
@ -156,7 +154,7 @@ JS::NonnullGCPtr<Response> Response::error(JS::VM& vm)
|
|||
{
|
||||
// The static error() method steps are to return the result of creating a Response object, given a new network error, "immutable", and this’s relevant Realm.
|
||||
// FIXME: How can we reliably get 'this', i.e. the object the function was called on, in IDL-defined functions?
|
||||
return Response::create(Infrastructure::Response::network_error(), Headers::Guard::Immutable, *vm.current_realm());
|
||||
return Response::create(*vm.current_realm(), Infrastructure::Response::network_error(vm), Headers::Guard::Immutable);
|
||||
}
|
||||
|
||||
// https://fetch.spec.whatwg.org/#dom-response-redirect
|
||||
|
@ -178,7 +176,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::redirect(JS::VM& vm, S
|
|||
|
||||
// 4. Let responseObject be the result of creating a Response object, given a new response, "immutable", and this’s relevant Realm.
|
||||
// FIXME: How can we reliably get 'this', i.e. the object the function was called on, in IDL-defined functions?
|
||||
auto response_object = Response::create(Infrastructure::Response::create(), Headers::Guard::Immutable, realm);
|
||||
auto response_object = Response::create(realm, Infrastructure::Response::create(vm), Headers::Guard::Immutable);
|
||||
|
||||
// 5. Set responseObject’s response’s status to status.
|
||||
response_object->response()->set_status(status);
|
||||
|
@ -207,7 +205,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::json(JS::VM& vm, JS::V
|
|||
|
||||
// 3. Let responseObject be the result of creating a Response object, given a new response, "response", and this’s relevant Realm.
|
||||
// FIXME: How can we reliably get 'this', i.e. the object the function was called on, in IDL-defined functions?
|
||||
auto response_object = Response::create(Infrastructure::Response::create(), Headers::Guard::Response, realm);
|
||||
auto response_object = Response::create(realm, Infrastructure::Response::create(vm), Headers::Guard::Response);
|
||||
|
||||
// 4. Perform initialize a response given responseObject, init, and (body, "application/json").
|
||||
auto body_with_type = Infrastructure::BodyWithType {
|
||||
|
@ -274,15 +272,17 @@ JS::NonnullGCPtr<Headers> Response::headers() const
|
|||
// https://fetch.spec.whatwg.org/#dom-response-clone
|
||||
WebIDL::ExceptionOr<JS::NonnullGCPtr<Response>> Response::clone() const
|
||||
{
|
||||
auto& vm = this->vm();
|
||||
|
||||
// 1. If this is unusable, then throw a TypeError.
|
||||
if (is_unusable())
|
||||
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Response is unusable"sv };
|
||||
|
||||
// 2. Let clonedResponse be the result of cloning this’s response.
|
||||
auto cloned_response = TRY(m_response->clone());
|
||||
auto cloned_response = TRY(m_response->clone(vm));
|
||||
|
||||
// 3. Return the result of creating a Response object, given clonedResponse, this’s headers’s guard, and this’s relevant Realm.
|
||||
return Response::create(move(cloned_response), m_headers->guard(), HTML::relevant_realm(*this));
|
||||
return Response::create(HTML::relevant_realm(*this), cloned_response, m_headers->guard());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue