diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWindowOrWorkerInterfaces.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWindowOrWorkerInterfaces.cpp index 6ecdec0e5fa..0204e2612b3 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWindowOrWorkerInterfaces.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWindowOrWorkerInterfaces.cpp @@ -166,7 +166,7 @@ static ErrorOr generate_intrinsic_definitions(StringView output_path, Vect namespace Web::Bindings { )~~~"); - auto add_interface = [&](SourceGenerator& gen, StringView name, StringView prototype_class, StringView constructor_class, Optional const& legacy_constructor, bool attach_to_global) { + auto add_interface = [&](SourceGenerator& gen, StringView name, StringView prototype_class, StringView constructor_class, Optional const& legacy_constructor) { gen.set("interface_name", name); gen.set("prototype_class", prototype_class); gen.set("constructor_class", constructor_class); @@ -182,15 +182,7 @@ void Intrinsics::create_web_prototype_and_constructor<@prototype_class@>(JS::Rea auto constructor = heap().allocate<@constructor_class@>(realm, realm); m_constructors.set("@interface_name@"sv, constructor); -)~~~"); - if (attach_to_global) { - gen.append(R"~~~( - auto& global = realm.global_object(); - global.define_direct_property("@interface_name@", constructor.ptr(), JS::Attribute::Writable | JS::Attribute::Configurable);)~~~"); - } - - gen.append(R"~~~( prototype->define_direct_property(vm.names.constructor, constructor.ptr(), JS::Attribute::Writable | JS::Attribute::Configurable); constructor->define_direct_property(vm.names.name, JS::PrimitiveString::create(vm, "@interface_name@"sv), JS::Attribute::Configurable); )~~~"); @@ -201,14 +193,7 @@ void Intrinsics::create_web_prototype_and_constructor<@prototype_class@>(JS::Rea gen.append(R"~~~( auto legacy_constructor = heap().allocate<@legacy_constructor_class@>(realm, realm); m_constructors.set("@legacy_interface_name@"sv, legacy_constructor); -)~~~"); - if (attach_to_global) { - gen.append(R"~~~( - global.define_direct_property("@legacy_interface_name@", legacy_constructor.ptr(), JS::Attribute::Writable | JS::Attribute::Configurable);)~~~"); - } - - gen.append(R"~~~( legacy_constructor->define_direct_property(vm.names.name, JS::PrimitiveString::create(vm, "@legacy_interface_name@"sv), JS::Attribute::Configurable);)~~~"); } @@ -219,23 +204,23 @@ void Intrinsics::create_web_prototype_and_constructor<@prototype_class@>(JS::Rea for (auto& interface : exposed_interfaces) { auto gen = generator.fork(); - add_interface(gen, interface.name, interface.prototype_class, interface.constructor_class, lookup_legacy_constructor(interface), true); + add_interface(gen, interface.name, interface.prototype_class, interface.constructor_class, lookup_legacy_constructor(interface)); } // FIXME: Special case window. We should convert Window and Location to use IDL { auto gen = generator.fork(); - add_interface(gen, "Window"sv, "WindowPrototype"sv, "WindowConstructor"sv, {}, true); - add_interface(gen, "Location"sv, "LocationPrototype"sv, "LocationConstructor"sv, {}, true); + add_interface(gen, "Window"sv, "WindowPrototype"sv, "WindowConstructor"sv, {}); + add_interface(gen, "Location"sv, "LocationPrototype"sv, "LocationConstructor"sv, {}); } // FIXME: Special case WebAssembly. We should convert WASM to use IDL. { auto gen = generator.fork(); - add_interface(gen, "WebAssembly.Memory"sv, "WebAssemblyMemoryPrototype"sv, "WebAssemblyMemoryConstructor"sv, {}, false); - add_interface(gen, "WebAssembly.Instance"sv, "WebAssemblyInstancePrototype"sv, "WebAssemblyInstanceConstructor"sv, {}, false); - add_interface(gen, "WebAssembly.Module"sv, "WebAssemblyModulePrototype"sv, "WebAssemblyModuleConstructor"sv, {}, false); - add_interface(gen, "WebAssembly.Table"sv, "WebAssemblyTablePrototype"sv, "WebAssemblyTableConstructor"sv, {}, false); + add_interface(gen, "WebAssembly.Memory"sv, "WebAssemblyMemoryPrototype"sv, "WebAssemblyMemoryConstructor"sv, {}); + add_interface(gen, "WebAssembly.Instance"sv, "WebAssemblyInstancePrototype"sv, "WebAssemblyInstanceConstructor"sv, {}); + add_interface(gen, "WebAssembly.Module"sv, "WebAssemblyModulePrototype"sv, "WebAssemblyModuleConstructor"sv, {}); + add_interface(gen, "WebAssembly.Table"sv, "WebAssemblyTablePrototype"sv, "WebAssemblyTableConstructor"sv, {}); } generator.append(R"~~~( @@ -262,7 +247,7 @@ static ErrorOr generate_exposed_interface_header(StringView class_name, St namespace Web::Bindings { -void add_@global_object_snake_name@_exposed_interfaces(JS::Object&, JS::Realm&); +void add_@global_object_snake_name@_exposed_interfaces(JS::Object&); } @@ -284,7 +269,6 @@ static ErrorOr generate_exposed_interface_implementation(StringView class_ generator.set("global_object_snake_name", DeprecatedString(class_name).to_snakecase()); generator.append(R"~~~( -#include #include #include #include @@ -317,15 +301,9 @@ static ErrorOr generate_exposed_interface_implementation(StringView class_ generator.append(R"~~~( namespace Web::Bindings { -void add_@global_object_snake_name@_exposed_interfaces(JS::Object& global, JS::Realm& realm) +void add_@global_object_snake_name@_exposed_interfaces(JS::Object& global) { - auto& vm = global.vm(); - // FIXME: Should we use vm.current_realm() here? - - // NOTE: Temporarily disable garbage collection to prevent GC from triggering while a not-fully-constructed - // prototype or constructor object has been allocated. This is a hack. - // FIXME: Find a nicer way to solve this. - JS::DeferGC defer_gc(vm.heap()); + static constexpr u8 attr = JS::Attribute::Writable | JS::Attribute::Configurable; )~~~"); auto add_interface = [](SourceGenerator& gen, StringView name, StringView prototype_class) { @@ -333,7 +311,7 @@ void add_@global_object_snake_name@_exposed_interfaces(JS::Object& global, JS::R gen.set("prototype_class", prototype_class); gen.append(R"~~~( - (void)ensure_web_prototype<@prototype_class@>(realm, "@interface_name@"sv);)~~~"); }; + global.define_intrinsic_accessor("@interface_name@", attr, [](auto& realm) -> JS::Value { return &ensure_web_constructor<@prototype_class@>(realm, "@interface_name@"sv); });)~~~"); }; for (auto& interface : exposed_interfaces) { auto gen = generator.fork(); diff --git a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp index f4aca506d41..0c582ca0cd1 100644 --- a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp +++ b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp @@ -387,7 +387,7 @@ JS::VM& main_thread_vm() JS::DeferGC defer_gc(root_realm->heap()); auto object = JS::Object::create(*root_realm, nullptr); root_realm->set_global_object(object, object); - add_window_exposed_interfaces(*object, *root_realm); + add_window_exposed_interfaces(*object); vm->push_execution_context(*custom_data.root_execution_context); } diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.h b/Userland/Libraries/LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.h index 1fd43d2352a..28136f3f062 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.h +++ b/Userland/Libraries/LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.h @@ -35,7 +35,7 @@ public: realm->set_host_defined(move(host_defined)); // FIXME: Shared workers should use the shared worker method - Bindings::add_dedicated_worker_exposed_interfaces(realm->global_object(), *realm); + Bindings::add_dedicated_worker_exposed_interfaces(realm->global_object()); return settings_object; } diff --git a/Userland/Libraries/LibWeb/HTML/Window.cpp b/Userland/Libraries/LibWeb/HTML/Window.cpp index f00a8cccdad..661b92b887e 100644 --- a/Userland/Libraries/LibWeb/HTML/Window.cpp +++ b/Userland/Libraries/LibWeb/HTML/Window.cpp @@ -1061,7 +1061,7 @@ HTML::BrowsingContext* Window::browsing_context() void Window::initialize_web_interfaces(Badge) { auto& realm = this->realm(); - add_window_exposed_interfaces(*this, realm); + add_window_exposed_interfaces(*this); Object::set_prototype(&Bindings::ensure_web_prototype(realm, "Window"));