LibJS: Switch Agent [[CanBlock]] slot to a enum member

It turns out it was a mistake to make this a virtual since
ServiceWorkerAgents are effectively the exact same as
DedicatedWorkerAgents and SharedWorkerAgents just with [[CanBlock]]
set to false.
This commit is contained in:
Shannon Booth 2025-04-24 16:16:08 +12:00 committed by Andreas Kling
commit 5290ebfe19
Notes: github-actions[bot] 2025-04-25 14:45:34 +00:00
6 changed files with 31 additions and 9 deletions

View file

@ -22,7 +22,7 @@ bool agent_can_suspend(VM const& vm)
// NOTE: We default to true if no agent has been provided (standalone LibJS with no embedder). // NOTE: We default to true if no agent has been provided (standalone LibJS with no embedder).
if (!agent) if (!agent)
return true; return true;
return agent->can_block(); return agent->can_block() == Agent::CanBlock::Yes;
} }
} }

View file

@ -16,12 +16,26 @@ namespace JS {
// https://tc39.es/ecma262/#sec-agents // https://tc39.es/ecma262/#sec-agents
class Agent { class Agent {
public: public:
enum class CanBlock {
Yes,
No,
};
virtual ~Agent(); virtual ~Agent();
// [[CanBlock]] CanBlock can_block() const { return m_can_block; }
virtual bool can_block() const = 0;
virtual void spin_event_loop_until(GC::Root<GC::Function<bool()>> goal_condition) = 0; virtual void spin_event_loop_until(GC::Root<GC::Function<bool()>> goal_condition) = 0;
protected:
explicit Agent(CanBlock can_block)
: m_can_block(can_block)
{
}
private:
// [[CanBlock]]
CanBlock m_can_block { false };
}; };
bool agent_can_suspend(VM const&); bool agent_can_suspend(VM const&);

View file

@ -77,7 +77,7 @@ void initialize_main_thread_vm(HTML::EventLoop::Type type)
VERIFY(!s_main_thread_vm); VERIFY(!s_main_thread_vm);
s_main_thread_vm = JS::VM::create(); s_main_thread_vm = JS::VM::create();
s_main_thread_vm->set_agent(make<HTML::SimilarOriginWindowAgent>()); s_main_thread_vm->set_agent(HTML::SimilarOriginWindowAgent::create());
auto& agent = as<HTML::Agent>(*s_main_thread_vm->agent()); auto& agent = as<HTML::Agent>(*s_main_thread_vm->agent());
agent.event_loop = s_main_thread_vm->heap().allocate<HTML::EventLoop>(type); agent.event_loop = s_main_thread_vm->heap().allocate<HTML::EventLoop>(type);

View file

@ -21,6 +21,9 @@ struct Agent : public JS::Agent {
GC::Root<HTML::EventLoop> event_loop; GC::Root<HTML::EventLoop> event_loop;
virtual void spin_event_loop_until(GC::Root<GC::Function<bool()>> goal_condition) override; virtual void spin_event_loop_until(GC::Root<GC::Function<bool()>> goal_condition) override;
protected:
using JS::Agent::Agent;
}; };
Agent& relevant_agent(JS::Object const&); Agent& relevant_agent(JS::Object const&);

View file

@ -11,10 +11,10 @@
namespace Web::HTML { namespace Web::HTML {
bool SimilarOriginWindowAgent::can_block() const NonnullOwnPtr<SimilarOriginWindowAgent> SimilarOriginWindowAgent::create()
{ {
// similar-origin window agents can not block, see: https://html.spec.whatwg.org/multipage/webappapis.html#obtain-similar-origin-window-agent // See 'creating an agent' step in: https://html.spec.whatwg.org/multipage/webappapis.html#obtain-similar-origin-window-agent
return false; return adopt_own(*new SimilarOriginWindowAgent(CanBlock::No));
} }
// https://html.spec.whatwg.org/multipage/webappapis.html#relevant-agent // https://html.spec.whatwg.org/multipage/webappapis.html#relevant-agent

View file

@ -20,6 +20,8 @@ namespace Web::HTML {
// https://html.spec.whatwg.org/multipage/webappapis.html#similar-origin-window-agent // https://html.spec.whatwg.org/multipage/webappapis.html#similar-origin-window-agent
struct SimilarOriginWindowAgent : public Agent { struct SimilarOriginWindowAgent : public Agent {
static NonnullOwnPtr<SimilarOriginWindowAgent> create();
// https://dom.spec.whatwg.org/#mutation-observer-compound-microtask-queued-flag // 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] // Each similar-origin window agent has a mutation observer microtask queued (a boolean), which is initially false. [HTML]
bool mutation_observer_microtask_queued { false }; bool mutation_observer_microtask_queued { false };
@ -41,8 +43,11 @@ struct SimilarOriginWindowAgent : public Agent {
Vector<GC::Root<DOM::Element>>& current_element_queue() { return custom_element_reactions_stack.element_queue_stack.last(); } Vector<GC::Root<DOM::Element>>& current_element_queue() { return custom_element_reactions_stack.element_queue_stack.last(); }
Vector<GC::Root<DOM::Element>> const& current_element_queue() const { return custom_element_reactions_stack.element_queue_stack.last(); } Vector<GC::Root<DOM::Element>> const& current_element_queue() const { return custom_element_reactions_stack.element_queue_stack.last(); }
// [[CanBlock]] private:
virtual bool can_block() const override; explicit SimilarOriginWindowAgent(CanBlock can_block)
: Agent(can_block)
{
}
}; };
SimilarOriginWindowAgent& relevant_similar_origin_window_agent(JS::Object const&); SimilarOriginWindowAgent& relevant_similar_origin_window_agent(JS::Object const&);