mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-26 01:35:08 +02:00
LibWeb: Replace spin_until in execute_script with deferred parser start
HTMLScriptElement::execute_script() and SVGScriptElement had spin_until calls waiting for ready_to_run_scripts to become true. The race exists because load_html_document() resolves the session history signal and starts the parser in the same deferred_invoke — so the parser can hit a <script> before update_for_history_step_application() sets the flag. Instead of spinning, defer parser->run() until the document is ready. Document gains a m_deferred_parser_start callback that is invoked when set_ready_to_run_scripts() is called. The callback is cleared before invocation to avoid reentrancy issues (parser->run() can synchronously execute scripts). All three document loading paths (HTML, XML, text) now check ready_to_run_scripts before starting the parser and defer if needed. create_document_for_inline_content() (used for error pages) now calls set_ready_to_run_scripts() before mutating the document, ensuring the invariant holds for all parser paths. The spin_until calls are replaced with VERIFY assertions.
This commit is contained in:
committed by
Alexander Kalenik
parent
df96b69e7a
commit
76d9cc4baf
Notes:
github-actions[bot]
2026-03-29 00:06:28 +00:00
Author: https://github.com/kalenikaliaksandr Commit: https://github.com/LadybirdBrowser/ladybird/commit/76d9cc4baf4 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/8661
@@ -683,6 +683,7 @@ void Document::visit_edges(Cell::Visitor& visitor)
|
||||
visitor.visit(m_render_blocking_elements);
|
||||
visitor.visit(m_policy_container);
|
||||
visitor.visit(m_style_invalidator);
|
||||
visitor.visit(m_deferred_parser_start);
|
||||
visitor.visit(m_custom_element_registry);
|
||||
}
|
||||
|
||||
@@ -5805,7 +5806,7 @@ void Document::update_for_history_step_application(GC::Ref<HTML::SessionHistoryE
|
||||
try_to_scroll_to_the_fragment();
|
||||
|
||||
// 4. At this point scripts may run for the newly-created document document.
|
||||
m_ready_to_run_scripts = true;
|
||||
set_ready_to_run_scripts();
|
||||
}
|
||||
|
||||
// 9. Otherwise, if documentsEntryChanged is false and doNotReactivate is false, then:
|
||||
@@ -5816,6 +5817,21 @@ void Document::update_for_history_step_application(GC::Ref<HTML::SessionHistoryE
|
||||
}
|
||||
}
|
||||
|
||||
void Document::set_ready_to_run_scripts()
|
||||
{
|
||||
m_ready_to_run_scripts = true;
|
||||
if (auto callback = m_deferred_parser_start) {
|
||||
m_deferred_parser_start = nullptr;
|
||||
callback->function()();
|
||||
}
|
||||
}
|
||||
|
||||
void Document::set_deferred_parser_start(GC::Ref<GC::Function<void()>> callback)
|
||||
{
|
||||
VERIFY(!m_deferred_parser_start);
|
||||
m_deferred_parser_start = callback;
|
||||
}
|
||||
|
||||
HashMap<URL::URL, GC::Ptr<HTML::SharedResourceRequest>>& Document::shared_resource_requests()
|
||||
{
|
||||
return m_shared_resource_requests;
|
||||
|
||||
Reference in New Issue
Block a user