diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWindowOrWorkerInterfaces.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWindowOrWorkerInterfaces.cpp index f0707e1545..b831b2a458 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWindowOrWorkerInterfaces.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWindowOrWorkerInterfaces.cpp @@ -53,6 +53,7 @@ static ErrorOr generate_exposed_interface_implementation(StringView class_ generator.set("global_object_snake_name", String(class_name).to_snakecase()); generator.append(R"~~~( +#include #include #include #include @@ -85,6 +86,11 @@ void add_@global_object_snake_name@_exposed_interfaces(JS::Object& global, JS::R { 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()); )~~~"); auto add_interface = [](SourceGenerator& gen, StringView name, StringView prototype_class, StringView constructor_class) { diff --git a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp index 3be2ff74d8..a1fd290993 100644 --- a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp +++ b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp @@ -6,6 +6,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include #include @@ -16,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -374,6 +376,15 @@ JS::VM& main_thread_vm() auto host_defined = make(nullptr, *intrinsics); root_realm->set_host_defined(move(host_defined)); + // NOTE: We make sure the internal realm has all the Window intrinsics initialized. + // The DeferGC is a hack to avoid nested GC allocations due to lazy ensure_web_prototype() + // and ensure_web_constructor() invocations. + // FIXME: Find a nicer way to do this. + 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); + vm->push_execution_context(*custom_data.root_execution_context); } return *vm;