mirror of
				https://github.com/LadybirdBrowser/ladybird.git
				synced 2025-10-31 05:10:57 +00:00 
			
		
		
		
	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:
		
							parent
							
								
									ce23efc5f6
								
							
						
					
					
						commit
						f87041bf3a
					
				
				
				Notes:
				
					github-actions[bot]
				
				2024-11-15 13:50:17 +00:00 
				
			
			Author: https://github.com/shannonbooth
Commit: f87041bf3a
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2345
			
					 1722 changed files with 9939 additions and 9906 deletions
				
			
		|  | @ -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 this’s 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 this’s 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 this’s 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 this’s 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 this’s 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 this’s response type is "blob", set this’s response object to a new Blob object representing this’s 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 this’s 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 this’s 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 this’s 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 xhr’s 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 this’s 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 this’s author request headers.
 | ||||
|  | @ -667,7 +667,7 @@ WebIDL::ExceptionOr<void> XMLHttpRequest::send(Optional<DocumentOrXMLHttpRequest | |||
|     // body
 | ||||
|     //    This’s request body.
 | ||||
|     if (m_request_body) | ||||
|         request->set_body(JS::NonnullGCPtr { *m_request_body }); | ||||
|         request->set_body(GC::Ref { *m_request_body }); | ||||
| 
 | ||||
|     // client
 | ||||
|     //    This’s 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 this’s 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 this’s 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 this’s 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 this’s 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 this’s response’s body, given processBodyChunk, processEndOfBody, processBodyError, and this’s 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 this’s 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 this’s 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 xhr’s state to done.
 | ||||
|     m_state = State::Done; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Shannon Booth
						Shannon Booth