LibGC+Everywhere: Factor out a LibGC from LibJS

Resulting in a massive rename across almost everywhere! Alongside the
namespace change, we now have the following names:

 * JS::NonnullGCPtr -> GC::Ref
 * JS::GCPtr -> GC::Ptr
 * JS::HeapFunction -> GC::Function
 * JS::CellImpl -> GC::Cell
 * JS::Handle -> GC::Root
This commit is contained in:
Shannon Booth 2024-11-15 04:01:23 +13:00 committed by Andreas Kling
parent ce23efc5f6
commit f87041bf3a
Notes: github-actions[bot] 2024-11-15 13:50:17 +00:00
1722 changed files with 9939 additions and 9906 deletions

View file

@ -56,9 +56,9 @@
namespace Web::XHR {
JS_DEFINE_ALLOCATOR(XMLHttpRequest);
GC_DEFINE_ALLOCATOR(XMLHttpRequest);
WebIDL::ExceptionOr<JS::NonnullGCPtr<XMLHttpRequest>> XMLHttpRequest::construct_impl(JS::Realm& realm)
WebIDL::ExceptionOr<GC::Ref<XMLHttpRequest>> XMLHttpRequest::construct_impl(JS::Realm& realm)
{
auto upload_object = realm.create<XMLHttpRequestUpload>(realm);
auto author_request_headers = Fetch::Infrastructure::HeaderList::create(realm.vm());
@ -95,7 +95,7 @@ void XMLHttpRequest::visit_edges(Cell::Visitor& visitor)
visitor.visit(m_response);
visitor.visit(m_fetch_controller);
if (auto* value = m_response_object.get_pointer<JS::NonnullGCPtr<JS::Object>>())
if (auto* value = m_response_object.get_pointer<GC::Ref<JS::Object>>())
visitor.visit(*value);
}
@ -129,7 +129,7 @@ WebIDL::ExceptionOr<String> XMLHttpRequest::response_text() const
}
// https://xhr.spec.whatwg.org/#dom-xmlhttprequest-responsexml
WebIDL::ExceptionOr<JS::GCPtr<DOM::Document>> XMLHttpRequest::response_xml()
WebIDL::ExceptionOr<GC::Ptr<DOM::Document>> XMLHttpRequest::response_xml()
{
// 1. If thiss response type is not the empty string or "document", then throw an "InvalidStateError" DOMException.
if (m_response_type != Bindings::XMLHttpRequestResponseType::Empty && m_response_type != Bindings::XMLHttpRequestResponseType::Document)
@ -144,7 +144,7 @@ WebIDL::ExceptionOr<JS::GCPtr<DOM::Document>> XMLHttpRequest::response_xml()
// 4. If thiss response object is non-null, then return it.
if (!m_response_object.has<Empty>())
return &verify_cast<DOM::Document>(*m_response_object.get<JS::NonnullGCPtr<JS::Object>>());
return &verify_cast<DOM::Document>(*m_response_object.get<GC::Ref<JS::Object>>());
// 5. Set a document response for this.
set_document_response();
@ -152,7 +152,7 @@ WebIDL::ExceptionOr<JS::GCPtr<DOM::Document>> XMLHttpRequest::response_xml()
// 6. Return thiss response object.
if (m_response_object.has<Empty>())
return nullptr;
return &verify_cast<DOM::Document>(*m_response_object.get<JS::NonnullGCPtr<JS::Object>>());
return &verify_cast<DOM::Document>(*m_response_object.get<GC::Ref<JS::Object>>());
}
// https://xhr.spec.whatwg.org/#dom-xmlhttprequest-responsetype
@ -199,7 +199,7 @@ WebIDL::ExceptionOr<JS::Value> XMLHttpRequest::response()
// 4. If thiss response object is non-null, then return it.
if (!m_response_object.has<Empty>())
return m_response_object.get<JS::NonnullGCPtr<JS::Object>>();
return m_response_object.get<GC::Ref<JS::Object>>();
// 5. If thiss response type is "arraybuffer",
if (m_response_type == Bindings::XMLHttpRequestResponseType::Arraybuffer) {
@ -212,14 +212,14 @@ WebIDL::ExceptionOr<JS::Value> XMLHttpRequest::response()
auto buffer = buffer_result.release_value();
buffer->buffer().overwrite(0, m_received_bytes.data(), m_received_bytes.size());
m_response_object = JS::NonnullGCPtr<JS::Object> { buffer };
m_response_object = GC::Ref<JS::Object> { buffer };
}
// 6. Otherwise, if thiss response type is "blob", set thiss response object to a new Blob object representing thiss received bytes with type set to the result of get a final MIME type for this.
else if (m_response_type == Bindings::XMLHttpRequestResponseType::Blob) {
auto mime_type_as_string = get_final_mime_type().serialized();
auto blob_part = FileAPI::Blob::create(realm(), m_received_bytes, move(mime_type_as_string));
auto blob = FileAPI::Blob::create(realm(), Vector<FileAPI::BlobPart> { JS::make_handle(*blob_part) });
m_response_object = JS::NonnullGCPtr<JS::Object> { blob };
auto blob = FileAPI::Blob::create(realm(), Vector<FileAPI::BlobPart> { GC::make_root(*blob_part) });
m_response_object = GC::Ref<JS::Object> { blob };
}
// 7. Otherwise, if thiss response type is "document", set a document response for this.
else if (m_response_type == Bindings::XMLHttpRequestResponseType::Document) {
@ -241,14 +241,14 @@ WebIDL::ExceptionOr<JS::Value> XMLHttpRequest::response()
// 4. Set thiss response object to jsonObject.
if (json_object_result.value().is_object())
m_response_object = JS::NonnullGCPtr<JS::Object> { json_object_result.release_value().as_object() };
m_response_object = GC::Ref<JS::Object> { json_object_result.release_value().as_object() };
else
m_response_object = Empty {};
}
// 9. Return thiss response object.
return m_response_object.visit(
[](JS::NonnullGCPtr<JS::Object> object) -> JS::Value { return object; },
[](GC::Ref<JS::Object> object) -> JS::Value { return object; },
[](auto const&) -> JS::Value { return JS::js_null(); });
}
@ -300,7 +300,7 @@ void XMLHttpRequest::set_document_response()
// 5. If finalMIME is an HTML MIME type, then:
Optional<String> charset;
JS::GCPtr<DOM::Document> document;
GC::Ptr<DOM::Document> document;
if (final_mime.is_html()) {
// 5.1. Let charset be the result of get a final encoding for xhr.
if (auto final_encoding = get_final_encoding(); final_encoding.has_value())
@ -350,7 +350,7 @@ void XMLHttpRequest::set_document_response()
document->set_origin(HTML::relevant_settings_object(*this).origin());
// 12. Set xhrs response object to document.
m_response_object = JS::NonnullGCPtr<JS::Object> { *document };
m_response_object = GC::Ref<JS::Object> { *document };
}
// https://xhr.spec.whatwg.org/#final-mime-type
@ -572,8 +572,8 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
Optional<ByteBuffer> extracted_content_type;
// 2. If body is a Document, then set thiss request body to body, serialized, converted, and UTF-8 encoded.
if (body->has<JS::Handle<DOM::Document>>()) {
auto string_serialized_document = TRY(body->get<JS::Handle<DOM::Document>>().cell()->serialize_fragment(DOMParsing::RequireWellFormed::No));
if (body->has<GC::Root<DOM::Document>>()) {
auto string_serialized_document = TRY(body->get<GC::Root<DOM::Document>>().cell()->serialize_fragment(DOMParsing::RequireWellFormed::No));
m_request_body = TRY(Fetch::Infrastructure::byte_sequence_as_body(realm, string_serialized_document.bytes()));
}
// 3. Otherwise:
@ -594,7 +594,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
// 5. If originalAuthorContentType is non-null, then:
if (original_author_content_type.has_value()) {
// 1. If body is a Document or a USVString, then:
if (body->has<JS::Handle<DOM::Document>>() || body->has<String>()) {
if (body->has<GC::Root<DOM::Document>>() || body->has<String>()) {
// 1. Let contentTypeRecord be the result of parsing originalAuthorContentType.
auto content_type_record = MimeSniff::MimeType::parse(original_author_content_type.value());
@ -617,8 +617,8 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
}
// 6. Otherwise:
else {
if (body->has<JS::Handle<DOM::Document>>()) {
auto document = body->get<JS::Handle<DOM::Document>>();
if (body->has<GC::Root<DOM::Document>>()) {
auto document = body->get<GC::Root<DOM::Document>>();
// NOTE: A document can only be an HTML document or XML document.
// 1. If body is an HTML document, then set (`Content-Type`, `text/html;charset=UTF-8`) in thiss author request headers.
@ -667,7 +667,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
// body
// Thiss request body.
if (m_request_body)
request->set_body(JS::NonnullGCPtr { *m_request_body });
request->set_body(GC::Ref { *m_request_body });
// client
// Thiss relevant settings object.
@ -738,7 +738,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
// 7. Let processRequestBodyChunkLength, given a bytesLength, be these steps:
// NOTE: request_body_length is captured by copy as to not UAF it when we leave `send()` and the callback gets called.
// NOTE: `this` is kept alive by FetchAlgorithms using JS::HeapFunction.
// NOTE: `this` is kept alive by FetchAlgorithms using GC::HeapFunction.
auto process_request_body_chunk_length = [this, request_body_length](u64 bytes_length) {
// 1. Increase requestBodyTransmitted by bytesLength.
m_request_body_transmitted += bytes_length;
@ -752,7 +752,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
// 8. Let processRequestEndOfBody be these steps:
// NOTE: request_body_length is captured by copy as to not UAF it when we leave `send()` and the callback gets called.
// NOTE: `this` is kept alive by FetchAlgorithms using JS::HeapFunction.
// NOTE: `this` is kept alive by FetchAlgorithms using GC::HeapFunction.
auto process_request_end_of_body = [this, request_body_length]() {
// 1. Set thiss upload complete flag.
m_upload_complete = true;
@ -772,8 +772,8 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
};
// 9. Let processResponse, given a response, be these steps:
// NOTE: `this` is kept alive by FetchAlgorithms using JS::HeapFunction.
auto process_response = [this](JS::NonnullGCPtr<Fetch::Infrastructure::Response> response) {
// NOTE: `this` is kept alive by FetchAlgorithms using GC::HeapFunction.
auto process_response = [this](GC::Ref<Fetch::Infrastructure::Response> response) {
// 1. Set thiss response to response.
m_response = response;
@ -816,7 +816,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
// FIXME: We can't implement these steps yet, as we don't fully implement the Streams standard.
// 10. Let processBodyChunk given bytes be these steps:
auto process_body_chunks = JS::create_heap_function(heap(), [this, length](ByteBuffer byte_buffer) {
auto process_body_chunks = GC::create_function(heap(), [this, length](ByteBuffer byte_buffer) {
// 1. Append bytes to thiss received bytes.
m_received_bytes.append(byte_buffer);
@ -835,14 +835,14 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
});
// 11. Let processEndOfBody be this step: run handle response end-of-body for this.
auto process_end_of_body = JS::create_heap_function(heap(), [this]() {
auto process_end_of_body = GC::create_function(heap(), [this]() {
// NOTE: This cannot throw, as `handle_response_end_of_body` only throws in a synchronous context.
// FIXME: However, we can receive allocation failures, but we can't propagate them anywhere currently.
handle_response_end_of_body().release_value_but_fixme_should_propagate_errors();
});
// 12. Let processBodyError be these steps:
auto process_body_error = JS::create_heap_function(heap(), [this](JS::Value) {
auto process_body_error = GC::create_function(heap(), [this](JS::Value) {
auto& vm = this->vm();
// 1. Set thiss response to a network error.
m_response = Fetch::Infrastructure::Response::network_error(vm, "A network error occurred processing body."sv);
@ -853,7 +853,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
});
// 13. Incrementally read thiss responses body, given processBodyChunk, processEndOfBody, processBodyError, and thiss relevant global object.
auto global_object = JS::NonnullGCPtr<JS::Object> { HTML::relevant_global_object(*this) };
auto global_object = GC::Ref<JS::Object> { HTML::relevant_global_object(*this) };
response->body()->incrementally_read(process_body_chunks, process_end_of_body, process_body_error, global_object);
};
@ -880,7 +880,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
// NOTE: `timer` is kept alive by capturing into the lambda for the GC to see
// NOTE: `this` and `request` is kept alive by Platform::Timer using a Handle.
timer->on_timeout = JS::create_heap_function(heap(), [this, request, timer = JS::make_handle(timer)]() {
timer->on_timeout = GC::create_function(heap(), [this, request, timer = GC::make_root(timer)]() {
(void)timer;
if (!request->done()) {
m_timed_out = true;
@ -895,7 +895,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
bool processed_response = false;
// 2. Let processResponseConsumeBody, given a response and nullOrFailureOrBytes, be these steps:
auto process_response_consume_body = [this, &processed_response](JS::NonnullGCPtr<Fetch::Infrastructure::Response> response, Variant<Empty, Fetch::Infrastructure::FetchAlgorithms::ConsumeBodyFailureTag, ByteBuffer> null_or_failure_or_bytes) {
auto process_response_consume_body = [this, &processed_response](GC::Ref<Fetch::Infrastructure::Response> response, Variant<Empty, Fetch::Infrastructure::FetchAlgorithms::ConsumeBodyFailureTag, ByteBuffer> null_or_failure_or_bytes) {
// 1. If nullOrFailureOrBytes is not failure, then set thiss response to response.
if (!null_or_failure_or_bytes.has<Fetch::Infrastructure::FetchAlgorithms::ConsumeBodyFailureTag>())
m_response = response;
@ -933,7 +933,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
auto timer = Platform::Timer::create_single_shot(heap(), m_timeout, nullptr);
// NOTE: `timer` is kept alive by capturing into the lambda for the GC to see
timer->on_timeout = JS::create_heap_function(heap(), [timer = JS::make_handle(timer), &did_time_out]() {
timer->on_timeout = GC::create_function(heap(), [timer = GC::make_root(timer), &did_time_out]() {
(void)timer;
did_time_out = true;
});
@ -942,7 +942,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest
}
// FIXME: This is not exactly correct, as it allows the HTML event loop to continue executing tasks.
Platform::EventLoopPlugin::the().spin_until(JS::create_heap_function(heap(), [&]() {
Platform::EventLoopPlugin::the().spin_until(GC::create_function(heap(), [&]() {
return processed_response || did_time_out;
}));
@ -1145,7 +1145,7 @@ void XMLHttpRequest::abort()
}
// https://xhr.spec.whatwg.org/#dom-xmlhttprequest-upload
JS::NonnullGCPtr<XMLHttpRequestUpload> XMLHttpRequest::upload() const
GC::Ref<XMLHttpRequestUpload> XMLHttpRequest::upload() const
{
// The upload getter steps are to return thiss upload object.
return m_upload_object;
@ -1236,7 +1236,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::handle_errors()
return {};
}
JS::ThrowCompletionOr<void> XMLHttpRequest::request_error_steps(FlyString const& event_name, JS::GCPtr<WebIDL::DOMException> exception)
JS::ThrowCompletionOr<void> XMLHttpRequest::request_error_steps(FlyString const& event_name, GC::Ptr<WebIDL::DOMException> exception)
{
// 1. Set xhrs state to done.
m_state = State::Done;