Selaa lähdekoodia

LibWeb: Make module maps GC-allocated

This allows them to mark JS modules, and fixes a crash seen on
https://shopify.com/
Andreas Kling 2 vuotta sitten
vanhempi
commit
3811be2f7c

+ 9 - 1
Userland/Libraries/LibWeb/HTML/Scripting/Environments.cpp

@@ -33,10 +33,18 @@ EnvironmentSettingsObject::~EnvironmentSettingsObject()
     responsible_event_loop().unregister_environment_settings_object({}, *this);
 }
 
+JS::ThrowCompletionOr<void> EnvironmentSettingsObject::initialize(JS::Realm& realm)
+{
+    MUST_OR_THROW_OOM(Base::initialize(realm));
+    m_module_map = realm.heap().allocate_without_realm<ModuleMap>();
+    return {};
+}
+
 void EnvironmentSettingsObject::visit_edges(Cell::Visitor& visitor)
 {
     Base::visit_edges(visitor);
     visitor.visit(target_browsing_context);
+    visitor.visit(m_module_map);
     visitor.ignore(m_outstanding_rejected_promises_weak_set);
 }
 
@@ -48,7 +56,7 @@ JS::ExecutionContext& EnvironmentSettingsObject::realm_execution_context()
 
 ModuleMap& EnvironmentSettingsObject::module_map()
 {
-    return m_module_map;
+    return *m_module_map;
 }
 
 // https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object%27s-realm

+ 2 - 1
Userland/Libraries/LibWeb/HTML/Scripting/Environments.h

@@ -60,6 +60,7 @@ struct EnvironmentSettingsObject
     JS_CELL(EnvironmentSettingsObject, JS::Cell);
 
     virtual ~EnvironmentSettingsObject() override;
+    virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
 
     // https://html.spec.whatwg.org/multipage/webappapis.html#concept-environment-target-browsing-context
     JS::ExecutionContext& realm_execution_context();
@@ -124,7 +125,7 @@ protected:
 
 private:
     NonnullOwnPtr<JS::ExecutionContext> m_realm_execution_context;
-    ModuleMap m_module_map;
+    JS::GCPtr<ModuleMap> m_module_map;
 
     EventLoop* m_responsible_event_loop { nullptr };
 

+ 8 - 0
Userland/Libraries/LibWeb/HTML/Scripting/ModuleMap.cpp

@@ -8,6 +8,14 @@
 
 namespace Web::HTML {
 
+void ModuleMap::visit_edges(Visitor& visitor)
+{
+    Base::visit_edges(visitor);
+    for (auto& it : m_values) {
+        visitor.visit(it.value.module_script);
+    }
+}
+
 bool ModuleMap::is_fetching(AK::URL const& url, DeprecatedString const& type) const
 {
     return is(url, type, EntryType::Fetching);

+ 5 - 2
Userland/Libraries/LibWeb/HTML/Scripting/ModuleMap.h

@@ -7,6 +7,7 @@
 #pragma once
 
 #include <AK/URL.h>
+#include <LibJS/Heap/Cell.h>
 #include <LibWeb/HTML/Scripting/ModuleScript.h>
 
 namespace Web::HTML {
@@ -33,8 +34,8 @@ private:
 };
 
 // https://html.spec.whatwg.org/multipage/webappapis.html#module-map
-class ModuleMap {
-    AK_MAKE_NONCOPYABLE(ModuleMap);
+class ModuleMap final : public JS::Cell {
+    JS_CELL(ModuleMap, Cell);
 
 public:
     ModuleMap() = default;
@@ -63,6 +64,8 @@ public:
     void wait_for_change(AK::URL const& url, DeprecatedString const& type, Function<void(Entry)> callback);
 
 private:
+    virtual void visit_edges(JS::Cell::Visitor&) override;
+
     HashMap<ModuleLocationTuple, Entry> m_values;
     HashMap<ModuleLocationTuple, Vector<Function<void(Entry)>>> m_callbacks;
 };