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

@ -48,7 +48,7 @@
namespace Web::HTML {
JS_DEFINE_ALLOCATOR(HTMLParser);
GC_DEFINE_ALLOCATOR(HTMLParser);
static inline void log_parse_error(SourceLocation const& location = SourceLocation::current())
{
@ -246,7 +246,7 @@ void HTMLParser::run(const URL::URL& url, HTMLTokenizer::StopAtInsertionPoint st
}
// https://html.spec.whatwg.org/multipage/parsing.html#the-end
void HTMLParser::the_end(JS::NonnullGCPtr<DOM::Document> document, JS::GCPtr<HTMLParser> parser)
void HTMLParser::the_end(GC::Ref<DOM::Document> document, GC::Ptr<HTMLParser> parser)
{
auto& heap = document->heap();
@ -300,7 +300,7 @@ void HTMLParser::the_end(JS::NonnullGCPtr<DOM::Document> document, JS::GCPtr<HTM
while (!document->scripts_to_execute_when_parsing_has_finished().is_empty()) {
// 1. Spin the event loop until the first script in the list of scripts that will execute when the document has finished parsing
// has its "ready to be parser-executed" flag set and the parser's Document has no style sheet that is blocking scripts.
main_thread_event_loop().spin_until(JS::create_heap_function(heap, [&] {
main_thread_event_loop().spin_until(GC::create_function(heap, [&] {
return document->scripts_to_execute_when_parsing_has_finished().first()->is_ready_to_be_parser_executed()
&& !document->has_a_style_sheet_that_is_blocking_scripts();
}));
@ -313,7 +313,7 @@ void HTMLParser::the_end(JS::NonnullGCPtr<DOM::Document> document, JS::GCPtr<HTM
}
// 6. Queue a global task on the DOM manipulation task source given the Document's relevant global object to run the following substeps:
queue_global_task(HTML::Task::Source::DOMManipulation, *document, JS::create_heap_function(heap, [document = document] {
queue_global_task(HTML::Task::Source::DOMManipulation, *document, GC::create_function(heap, [document = document] {
// 1. Set the Document's load timing info's DOM content loaded event start time to the current high resolution time given the Document's relevant global object.
document->load_timing_info().dom_content_loaded_event_start_time = HighResolutionTime::current_high_resolution_time(relevant_global_object(*document));
@ -331,17 +331,17 @@ void HTMLParser::the_end(JS::NonnullGCPtr<DOM::Document> document, JS::GCPtr<HTM
}));
// 7. Spin the event loop until the set of scripts that will execute as soon as possible and the list of scripts that will execute in order as soon as possible are empty.
main_thread_event_loop().spin_until(JS::create_heap_function(heap, [&] {
main_thread_event_loop().spin_until(GC::create_function(heap, [&] {
return document->scripts_to_execute_as_soon_as_possible().is_empty();
}));
// 8. Spin the event loop until there is nothing that delays the load event in the Document.
main_thread_event_loop().spin_until(JS::create_heap_function(heap, [&] {
main_thread_event_loop().spin_until(GC::create_function(heap, [&] {
return !document->anything_is_delaying_the_load_event();
}));
// 9. Queue a global task on the DOM manipulation task source given the Document's relevant global object to run the following steps:
queue_global_task(HTML::Task::Source::DOMManipulation, *document, JS::create_heap_function(document->heap(), [document = document] {
queue_global_task(HTML::Task::Source::DOMManipulation, *document, GC::create_function(document->heap(), [document = document] {
// 1. Update the current document readiness to "complete".
document->update_readiness(HTML::DocumentReadyState::Complete);
@ -610,7 +610,7 @@ AnythingElse:
return;
}
JS::GCPtr<DOM::Element> HTMLParser::current_node()
GC::Ptr<DOM::Element> HTMLParser::current_node()
{
if (m_stack_of_open_elements.is_empty())
return nullptr;
@ -618,7 +618,7 @@ JS::GCPtr<DOM::Element> HTMLParser::current_node()
}
// https://html.spec.whatwg.org/multipage/parsing.html#adjusted-current-node
JS::GCPtr<DOM::Element> HTMLParser::adjusted_current_node()
GC::Ptr<DOM::Element> HTMLParser::adjusted_current_node()
{
// The adjusted current node is the context element if the parser was created as part of the
// HTML fragment parsing algorithm and the stack of open elements has only one element in it
@ -630,7 +630,7 @@ JS::GCPtr<DOM::Element> HTMLParser::adjusted_current_node()
return current_node();
}
JS::GCPtr<DOM::Element> HTMLParser::node_before_current_node()
GC::Ptr<DOM::Element> HTMLParser::node_before_current_node()
{
if (m_stack_of_open_elements.elements().size() < 2)
return nullptr;
@ -638,7 +638,7 @@ JS::GCPtr<DOM::Element> HTMLParser::node_before_current_node()
}
// https://html.spec.whatwg.org/multipage/parsing.html#appropriate-place-for-inserting-a-node
HTMLParser::AdjustedInsertionLocation HTMLParser::find_appropriate_place_for_inserting_node(JS::GCPtr<DOM::Element> override_target)
HTMLParser::AdjustedInsertionLocation HTMLParser::find_appropriate_place_for_inserting_node(GC::Ptr<DOM::Element> override_target)
{
// 1. If there was an override target specified, then let target be the override target.
auto& target = override_target ? *override_target.ptr() : *current_node();
@ -694,13 +694,13 @@ HTMLParser::AdjustedInsertionLocation HTMLParser::find_appropriate_place_for_ins
}
// https://html.spec.whatwg.org/multipage/parsing.html#create-an-element-for-the-token
JS::NonnullGCPtr<DOM::Element> HTMLParser::create_element_for(HTMLToken const& token, Optional<FlyString> const& namespace_, DOM::Node& intended_parent)
GC::Ref<DOM::Element> HTMLParser::create_element_for(HTMLToken const& token, Optional<FlyString> const& namespace_, DOM::Node& intended_parent)
{
// FIXME: 1. If the active speculative HTML parser is not null, then return the result of creating a speculative mock element given given namespace, the tag name of the given token, and the attributes of the given token.
// FIXME: 2. Otherwise, optionally create a speculative mock element given given namespace, the tag name of the given token, and the attributes of the given token.
// 3. Let document be intended parent's node document.
JS::NonnullGCPtr<DOM::Document> document = intended_parent.document();
GC::Ref<DOM::Document> document = intended_parent.document();
// 4. Let local name be the tag name of the token.
auto const& local_name = token.tag_name();
@ -784,7 +784,7 @@ JS::NonnullGCPtr<DOM::Element> HTMLParser::create_element_for(HTMLToken const& t
}
// https://html.spec.whatwg.org/multipage/parsing.html#insert-a-foreign-element
JS::NonnullGCPtr<DOM::Element> HTMLParser::insert_foreign_element(HTMLToken const& token, Optional<FlyString> const& namespace_, OnlyAddToElementStack only_add_to_element_stack)
GC::Ref<DOM::Element> HTMLParser::insert_foreign_element(HTMLToken const& token, Optional<FlyString> const& namespace_, OnlyAddToElementStack only_add_to_element_stack)
{
// 1. Let the adjusted insertion location be the appropriate place for inserting a node.
auto adjusted_insertion_location = find_appropriate_place_for_inserting_node();
@ -805,7 +805,7 @@ JS::NonnullGCPtr<DOM::Element> HTMLParser::insert_foreign_element(HTMLToken cons
return element;
}
JS::NonnullGCPtr<DOM::Element> HTMLParser::insert_html_element(HTMLToken const& token)
GC::Ref<DOM::Element> HTMLParser::insert_html_element(HTMLToken const& token)
{
return insert_foreign_element(token, Namespace::HTML, OnlyAddToElementStack::No);
}
@ -1487,7 +1487,7 @@ HTMLParser::AdoptionAgencyAlgorithmOutcome HTMLParser::run_the_adoption_agency_a
// 7. Let furthest block be the topmost node in the stack of open elements that is lower in the stack than formatting element,
// and is an element in the special category. There might not be one.
JS::GCPtr<DOM::Element> furthest_block = m_stack_of_open_elements.topmost_special_node_below(*formatting_element);
GC::Ptr<DOM::Element> furthest_block = m_stack_of_open_elements.topmost_special_node_below(*formatting_element);
// 8. If there is no furthest block
if (!furthest_block) {
@ -2011,7 +2011,7 @@ void HTMLParser::handle_in_body(HTMLToken& token)
// 2. Initialize node to be the current node (the bottommost node of the stack).
// 3. Loop: If node is an li element, then run these substeps:
for (ssize_t i = m_stack_of_open_elements.elements().size() - 1; i >= 0; --i) {
JS::GCPtr<DOM::Element> node = m_stack_of_open_elements.elements()[i].ptr();
GC::Ptr<DOM::Element> node = m_stack_of_open_elements.elements()[i].ptr();
if (node->local_name() == HTML::TagNames::li) {
// 1. Generate implied end tags, except for li elements.
generate_implied_end_tags(HTML::TagNames::li);
@ -2054,7 +2054,7 @@ void HTMLParser::handle_in_body(HTMLToken& token)
// 4. If node is a dt element, then run these substeps:
for (ssize_t i = m_stack_of_open_elements.elements().size() - 1; i >= 0; --i) {
// 1. Generate implied end tags, except for dd elements.
JS::GCPtr<DOM::Element> node = m_stack_of_open_elements.elements()[i].ptr();
GC::Ptr<DOM::Element> node = m_stack_of_open_elements.elements()[i].ptr();
if (node->local_name() == HTML::TagNames::dd) {
generate_implied_end_tags(HTML::TagNames::dd);
// 2. If the current node is not a dd element, then this is a parse error.
@ -2707,7 +2707,7 @@ void HTMLParser::handle_in_body(HTMLToken& token)
if (token.is_end_tag()) {
AnyOtherEndTag:
// 1. Initialize node to be the current node (the bottommost node of the stack).
JS::GCPtr<DOM::Element> node;
GC::Ptr<DOM::Element> node;
// 2. Loop: If node is an HTML element with the same tag name as the token, then:
for (ssize_t i = m_stack_of_open_elements.elements().size() - 1; i >= 0; --i) {
@ -2943,7 +2943,7 @@ void HTMLParser::handle_text(HTMLToken& token)
perform_a_microtask_checkpoint();
// Let script be the current node (which will be a script element).
JS::NonnullGCPtr<HTMLScriptElement> script = verify_cast<HTMLScriptElement>(*current_node());
GC::Ref<HTMLScriptElement> script = verify_cast<HTMLScriptElement>(*current_node());
// Pop the current node off the stack of open elements.
(void)m_stack_of_open_elements.pop();
@ -3005,7 +3005,7 @@ void HTMLParser::handle_text(HTMLToken& token)
if (m_document->has_a_style_sheet_that_is_blocking_scripts() || the_script->is_ready_to_be_parser_executed() == false) {
// spin the event loop until the parser's Document has no style sheet that is blocking scripts
// and the script's ready to be parser-executed becomes true.
main_thread_event_loop().spin_until(JS::create_heap_function(heap(), [&] {
main_thread_event_loop().spin_until(GC::create_function(heap(), [&] {
return !m_document->has_a_style_sheet_that_is_blocking_scripts() && the_script->is_ready_to_be_parser_executed();
}));
}
@ -4265,7 +4265,7 @@ void HTMLParser::process_using_the_rules_for_foreign_content(HTMLToken& token)
// -> Any other end tag
if (token.is_end_tag()) {
// 1. Initialize node to be the current node (the bottommost node of the stack).
JS::GCPtr<DOM::Element> node = current_node();
GC::Ptr<DOM::Element> node = current_node();
// 2. If node's tag name, converted to ASCII lowercase, is not the same as the tag name of the token, then this is a parse error.
if (node->tag_name().equals_ignoring_ascii_case(token.tag_name()))
@ -4309,7 +4309,7 @@ void HTMLParser::reset_the_insertion_mode_appropriately()
for (ssize_t i = m_stack_of_open_elements.elements().size() - 1; i >= 0; --i) {
bool last = i == 0;
// NOTE: When parsing fragments, we substitute the context element for the root of the stack of open elements.
JS::GCPtr<DOM::Element> node;
GC::Ptr<DOM::Element> node;
if (last && m_parsing_fragment) {
node = m_context_element.ptr();
} else {
@ -4423,7 +4423,7 @@ DOM::Document& HTMLParser::document()
}
// https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments
Vector<JS::Handle<DOM::Node>> HTMLParser::parse_html_fragment(DOM::Element& context_element, StringView markup, AllowDeclarativeShadowRoots allow_declarative_shadow_roots)
Vector<GC::Root<DOM::Node>> HTMLParser::parse_html_fragment(DOM::Element& context_element, StringView markup, AllowDeclarativeShadowRoots allow_declarative_shadow_roots)
{
// 1. Create a new Document node, and mark it as being an HTML document.
auto temp_document = DOM::Document::create_for_fragment_parsing(context_element.realm());
@ -4515,21 +4515,21 @@ Vector<JS::Handle<DOM::Node>> HTMLParser::parse_html_fragment(DOM::Element& cont
parser->run(context_element.document().url());
// 15. Return the child nodes of root, in tree order.
Vector<JS::Handle<DOM::Node>> children;
while (JS::GCPtr<DOM::Node> child = root->first_child()) {
Vector<GC::Root<DOM::Node>> children;
while (GC::Ptr<DOM::Node> child = root->first_child()) {
MUST(root->remove_child(*child));
context_element.document().adopt_node(*child);
children.append(JS::make_handle(*child));
children.append(GC::make_root(*child));
}
return children;
}
JS::NonnullGCPtr<HTMLParser> HTMLParser::create_for_scripting(DOM::Document& document)
GC::Ref<HTMLParser> HTMLParser::create_for_scripting(DOM::Document& document)
{
return document.heap().allocate<HTMLParser>(document);
}
JS::NonnullGCPtr<HTMLParser> HTMLParser::create_with_uncertain_encoding(DOM::Document& document, ByteBuffer const& input, Optional<MimeSniff::MimeType> maybe_mime_type)
GC::Ref<HTMLParser> HTMLParser::create_with_uncertain_encoding(DOM::Document& document, ByteBuffer const& input, Optional<MimeSniff::MimeType> maybe_mime_type)
{
if (document.has_encoding())
return document.heap().allocate<HTMLParser>(document, input, document.encoding().value().to_byte_string());
@ -4538,7 +4538,7 @@ JS::NonnullGCPtr<HTMLParser> HTMLParser::create_with_uncertain_encoding(DOM::Doc
return document.heap().allocate<HTMLParser>(document, input, encoding);
}
JS::NonnullGCPtr<HTMLParser> HTMLParser::create(DOM::Document& document, StringView input, StringView encoding)
GC::Ref<HTMLParser> HTMLParser::create(DOM::Document& document, StringView input, StringView encoding)
{
return document.heap().allocate<HTMLParser>(document, input, encoding);
}
@ -4574,7 +4574,7 @@ static String escape_string(StringView string, AttributeMode attribute_mode)
}
// https://html.spec.whatwg.org/multipage/parsing.html#html-fragment-serialisation-algorithm
String HTMLParser::serialize_html_fragment(DOM::Node const& node, SerializableShadowRoots serializable_shadow_roots, Vector<JS::Handle<DOM::ShadowRoot>> const& shadow_roots, DOM::FragmentSerializationMode fragment_serialization_mode)
String HTMLParser::serialize_html_fragment(DOM::Node const& node, SerializableShadowRoots serializable_shadow_roots, Vector<GC::Root<DOM::ShadowRoot>> const& shadow_roots, DOM::FragmentSerializationMode fragment_serialization_mode)
{
// NOTE: Steps in this function are jumbled a bit to accommodate the Element.outerHTML API.
// When called with FragmentSerializationMode::Outer, we will serialize the element itself,
@ -4668,7 +4668,7 @@ String HTMLParser::serialize_html_fragment(DOM::Node const& node, SerializableSh
// The algorithm takes as input a DOM Element, Document, or DocumentFragment referred to as the node.
VERIFY(node.is_element() || node.is_document() || node.is_document_fragment());
JS::NonnullGCPtr<DOM::Node const> actual_node = node;
GC::Ref<DOM::Node const> actual_node = node;
if (is<DOM::Element>(node)) {
auto const& element = verify_cast<DOM::Element>(node);
@ -5092,7 +5092,7 @@ void HTMLParser::abort()
}
// https://html.spec.whatwg.org/multipage/parsing.html#insert-an-element-at-the-adjusted-insertion-location
void HTMLParser::insert_an_element_at_the_adjusted_insertion_location(JS::NonnullGCPtr<DOM::Element> element)
void HTMLParser::insert_an_element_at_the_adjusted_insertion_location(GC::Ref<DOM::Element> element)
{
// 1. Let the adjusted insertion location be the appropriate place for inserting a node.
auto adjusted_insertion_location = find_appropriate_place_for_inserting_node();