From 041ff0c7ffbe7410597d1c351f17486c44542f2e Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Thu, 24 Apr 2025 15:22:25 +1200 Subject: [PATCH] LibWeb/HTML: Hook up a WorkerAgent for web workers --- Libraries/LibWeb/Bindings/MainThreadVM.cpp | 24 +++++++++++++++---- Libraries/LibWeb/Bindings/MainThreadVM.h | 10 +++++++- Libraries/LibWeb/CMakeLists.txt | 1 + .../Scripting/SimilarOriginWindowAgent.cpp | 6 +++-- .../HTML/Scripting/SimilarOriginWindowAgent.h | 2 +- .../LibWeb/HTML/Scripting/WorkerAgent.cpp | 19 +++++++++++++++ Libraries/LibWeb/HTML/Scripting/WorkerAgent.h | 22 +++++++++++++++++ Meta/Lagom/Fuzzers/FuzzCSSParser.cpp | 2 +- Services/WebContent/main.cpp | 2 +- Services/WebWorker/main.cpp | 2 +- 10 files changed, 78 insertions(+), 12 deletions(-) create mode 100644 Libraries/LibWeb/HTML/Scripting/WorkerAgent.cpp create mode 100644 Libraries/LibWeb/HTML/Scripting/WorkerAgent.h diff --git a/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Libraries/LibWeb/Bindings/MainThreadVM.cpp index cbab212b00b..98ea74e4f62 100644 --- a/Libraries/LibWeb/Bindings/MainThreadVM.cpp +++ b/Libraries/LibWeb/Bindings/MainThreadVM.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -72,15 +73,28 @@ HTML::Script* active_script() }); } -void initialize_main_thread_vm(HTML::EventLoop::Type type) +static NonnullOwnPtr create_agent(GC::Heap& heap, AgentType type) +{ + switch (type) { + case AgentType::SimilarOriginWindow: + return HTML::SimilarOriginWindowAgent::create(heap); + case AgentType::DedicatedWorker: + case AgentType::SharedWorker: + return HTML::WorkerAgent::create(heap, JS::Agent::CanBlock::Yes); + case AgentType::ServiceWorker: + return HTML::WorkerAgent::create(heap, JS::Agent::CanBlock::No); + default: + break; + } + VERIFY_NOT_REACHED(); +} + +void initialize_main_thread_vm(AgentType type) { VERIFY(!s_main_thread_vm); s_main_thread_vm = JS::VM::create(); - s_main_thread_vm->set_agent(HTML::SimilarOriginWindowAgent::create()); - - auto& agent = as(*s_main_thread_vm->agent()); - agent.event_loop = s_main_thread_vm->heap().allocate(type); + s_main_thread_vm->set_agent(create_agent(s_main_thread_vm->heap(), type)); s_main_thread_vm->on_unimplemented_property_access = [](auto const& object, auto const& property_key) { dbgln("FIXME: Unimplemented IDL interface: '{}.{}'", object.class_name(), property_key.to_string()); diff --git a/Libraries/LibWeb/Bindings/MainThreadVM.h b/Libraries/LibWeb/Bindings/MainThreadVM.h index 364900207a2..d1ba23fd440 100644 --- a/Libraries/LibWeb/Bindings/MainThreadVM.h +++ b/Libraries/LibWeb/Bindings/MainThreadVM.h @@ -32,7 +32,15 @@ struct WebEngineCustomJobCallbackData final : public JS::JobCallback::CustomData HTML::Script* active_script(); -void initialize_main_thread_vm(HTML::EventLoop::Type); +enum class AgentType : u8 { + SimilarOriginWindow, + DedicatedWorker, + SharedWorker, + ServiceWorker, + Worklet, +}; + +void initialize_main_thread_vm(AgentType); JS::VM& main_thread_vm(); void queue_mutation_observer_microtask(DOM::Document const&); diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index d040a2905f8..633d0612c7c 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -508,6 +508,7 @@ set(SOURCES HTML/Scripting/SyntheticRealmSettings.cpp HTML/Scripting/TemporaryExecutionContext.cpp HTML/Scripting/WindowEnvironmentSettingsObject.cpp + HTML/Scripting/WorkerAgent.cpp HTML/Scripting/WorkerEnvironmentSettingsObject.cpp HTML/Scripting/SerializedEnvironmentSettingsObject.cpp HTML/SelectedFile.cpp diff --git a/Libraries/LibWeb/HTML/Scripting/SimilarOriginWindowAgent.cpp b/Libraries/LibWeb/HTML/Scripting/SimilarOriginWindowAgent.cpp index 40d324873b9..44aa4bb1018 100644 --- a/Libraries/LibWeb/HTML/Scripting/SimilarOriginWindowAgent.cpp +++ b/Libraries/LibWeb/HTML/Scripting/SimilarOriginWindowAgent.cpp @@ -11,10 +11,12 @@ namespace Web::HTML { -NonnullOwnPtr SimilarOriginWindowAgent::create() +NonnullOwnPtr SimilarOriginWindowAgent::create(GC::Heap& heap) { // See 'creating an agent' step in: https://html.spec.whatwg.org/multipage/webappapis.html#obtain-similar-origin-window-agent - return adopt_own(*new SimilarOriginWindowAgent(CanBlock::No)); + auto agent = adopt_own(*new SimilarOriginWindowAgent(CanBlock::No)); + agent->event_loop = heap.allocate(HTML::EventLoop::Type::Window); + return agent; } // https://html.spec.whatwg.org/multipage/webappapis.html#relevant-agent diff --git a/Libraries/LibWeb/HTML/Scripting/SimilarOriginWindowAgent.h b/Libraries/LibWeb/HTML/Scripting/SimilarOriginWindowAgent.h index 51cb491a236..bccfa0ec114 100644 --- a/Libraries/LibWeb/HTML/Scripting/SimilarOriginWindowAgent.h +++ b/Libraries/LibWeb/HTML/Scripting/SimilarOriginWindowAgent.h @@ -20,7 +20,7 @@ namespace Web::HTML { // https://html.spec.whatwg.org/multipage/webappapis.html#similar-origin-window-agent struct SimilarOriginWindowAgent : public Agent { - static NonnullOwnPtr create(); + static NonnullOwnPtr create(GC::Heap&); // https://dom.spec.whatwg.org/#mutation-observer-compound-microtask-queued-flag // Each similar-origin window agent has a mutation observer microtask queued (a boolean), which is initially false. [HTML] diff --git a/Libraries/LibWeb/HTML/Scripting/WorkerAgent.cpp b/Libraries/LibWeb/HTML/Scripting/WorkerAgent.cpp new file mode 100644 index 00000000000..f414cddb10c --- /dev/null +++ b/Libraries/LibWeb/HTML/Scripting/WorkerAgent.cpp @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025, Shannon Booth + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +namespace Web::HTML { + +NonnullOwnPtr WorkerAgent::create(GC::Heap& heap, CanBlock can_block) +{ + auto agent = adopt_own(*new WorkerAgent(can_block)); + agent->event_loop = heap.allocate(HTML::EventLoop::Type::Worker); + return agent; +} + +} diff --git a/Libraries/LibWeb/HTML/Scripting/WorkerAgent.h b/Libraries/LibWeb/HTML/Scripting/WorkerAgent.h new file mode 100644 index 00000000000..1a7608db402 --- /dev/null +++ b/Libraries/LibWeb/HTML/Scripting/WorkerAgent.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025, Shannon Booth + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Web::HTML { + +// https://html.spec.whatwg.org/multipage/webappapis.html#dedicated-worker-agent +// https://html.spec.whatwg.org/multipage/webappapis.html#shared-worker-agent +struct WorkerAgent : public Agent { + static NonnullOwnPtr create(GC::Heap&, CanBlock); + +private: + using Agent::Agent; +}; + +} diff --git a/Meta/Lagom/Fuzzers/FuzzCSSParser.cpp b/Meta/Lagom/Fuzzers/FuzzCSSParser.cpp index bd3cabc2928..893e777aada 100644 --- a/Meta/Lagom/Fuzzers/FuzzCSSParser.cpp +++ b/Meta/Lagom/Fuzzers/FuzzCSSParser.cpp @@ -17,7 +17,7 @@ struct Globals { Globals::Globals() { Web::Platform::EventLoopPlugin::install(*new Web::Platform::EventLoopPluginSerenity); - Web::Bindings::initialize_main_thread_vm(Web::HTML::EventLoop::Type::Window); + Web::Bindings::initialize_main_thread_vm(Web::Bindings::AgentType::SimilarOriginWindow); } } diff --git a/Services/WebContent/main.cpp b/Services/WebContent/main.cpp index a5ef5ebe275..e1373f13e11 100644 --- a/Services/WebContent/main.cpp +++ b/Services/WebContent/main.cpp @@ -191,7 +191,7 @@ ErrorOr serenity_main(Main::Arguments arguments) Web::Platform::FontPlugin::install(*new WebView::FontPlugin(is_layout_test_mode, &font_provider)); - Web::Bindings::initialize_main_thread_vm(Web::HTML::EventLoop::Type::Window); + Web::Bindings::initialize_main_thread_vm(Web::Bindings::AgentType::SimilarOriginWindow); if (collect_garbage_on_every_allocation) Web::Bindings::main_thread_vm().heap().set_should_collect_on_every_allocation(true); diff --git a/Services/WebWorker/main.cpp b/Services/WebWorker/main.cpp index 42376637174..3f4253bc205 100644 --- a/Services/WebWorker/main.cpp +++ b/Services/WebWorker/main.cpp @@ -68,7 +68,7 @@ ErrorOr serenity_main(Main::Arguments arguments) Web::Platform::FontPlugin::install(*new WebView::FontPlugin(false)); - Web::Bindings::initialize_main_thread_vm(Web::HTML::EventLoop::Type::Worker); + Web::Bindings::initialize_main_thread_vm(Web::Bindings::AgentType::DedicatedWorker); TRY(initialize_resource_loader(Web::Bindings::main_thread_vm().heap(), request_server_socket));