From 0ec8af5b70702e9ee2edc7269c103fa49e6987c1 Mon Sep 17 00:00:00 2001 From: Shannon Booth Date: Wed, 23 Oct 2024 17:27:20 +1300 Subject: [PATCH] LibJS: Initialize ShadowRealm internal slots through setters This allows us to align our implementation in the same order as the specification. No functional change with the current implementation of this AO. However, this change is required in order to correctly implement a proposed update of the shadow realm proposal for integration with the HTML spec host bindings in order to give the ShadowRealm object the correct 'intrinsic' realm. This is due to that proposed change adding a step which manipulates the currently executing Javascript execution context, making the ordering important. --- Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp | 4 +--- Userland/Libraries/LibJS/Runtime/ShadowRealm.h | 13 ++++++++----- .../LibJS/Runtime/ShadowRealmConstructor.cpp | 11 ++++++++--- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp b/Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp index cba817471f4..4326e75b2b4 100644 --- a/Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp +++ b/Userland/Libraries/LibJS/Runtime/ShadowRealm.cpp @@ -22,10 +22,8 @@ namespace JS { JS_DEFINE_ALLOCATOR(ShadowRealm); -ShadowRealm::ShadowRealm(Realm& shadow_realm, NonnullOwnPtr execution_context, Object& prototype) +ShadowRealm::ShadowRealm(Object& prototype) : Object(ConstructWithPrototypeTag::Tag, prototype) - , m_shadow_realm(shadow_realm) - , m_execution_context(move(execution_context)) { } diff --git a/Userland/Libraries/LibJS/Runtime/ShadowRealm.h b/Userland/Libraries/LibJS/Runtime/ShadowRealm.h index b183e81e0d3..e0b29583fe8 100644 --- a/Userland/Libraries/LibJS/Runtime/ShadowRealm.h +++ b/Userland/Libraries/LibJS/Runtime/ShadowRealm.h @@ -20,19 +20,22 @@ class ShadowRealm final : public Object { public: virtual ~ShadowRealm() override = default; - [[nodiscard]] Realm const& shadow_realm() const { return m_shadow_realm; } - [[nodiscard]] Realm& shadow_realm() { return m_shadow_realm; } + [[nodiscard]] Realm const& shadow_realm() const { return *m_shadow_realm; } + [[nodiscard]] Realm& shadow_realm() { return *m_shadow_realm; } + void set_shadow_realm(NonnullGCPtr realm) { m_shadow_realm = realm; } + [[nodiscard]] ExecutionContext const& execution_context() const { return *m_execution_context; } [[nodiscard]] ExecutionContext& execution_context() { return *m_execution_context; } + void set_execution_context(NonnullOwnPtr context) { m_execution_context = move(context); } private: - ShadowRealm(Realm&, NonnullOwnPtr, Object& prototype); + ShadowRealm(Object& prototype); virtual void visit_edges(Visitor&) override; // 3.5 Properties of ShadowRealm Instances, https://tc39.es/proposal-shadowrealm/#sec-properties-of-shadowrealm-instances - NonnullGCPtr m_shadow_realm; // [[ShadowRealm]] - NonnullOwnPtr m_execution_context; // [[ExecutionContext]] + GCPtr m_shadow_realm; // [[ShadowRealm]] + OwnPtr m_execution_context; // [[ExecutionContext]] }; ThrowCompletionOr copy_name_and_length(VM&, FunctionObject& function, FunctionObject& target, Optional prefix = {}, Optional arg_count = {}); diff --git a/Userland/Libraries/LibJS/Runtime/ShadowRealmConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ShadowRealmConstructor.cpp index 10753c48d09..ebee50d1173 100644 --- a/Userland/Libraries/LibJS/Runtime/ShadowRealmConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/ShadowRealmConstructor.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2021-2023, Linus Groh + * Copyright (c) 2024, Shannon Booth * * SPDX-License-Identifier: BSD-2-Clause */ @@ -43,9 +44,15 @@ ThrowCompletionOr> ShadowRealmConstructor::construct(Functi { auto& vm = this->vm(); + // 2. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%ShadowRealm.prototype%", « [[ShadowRealm]], [[ExecutionContext]] »). + auto object = TRY(ordinary_create_from_constructor(vm, new_target, &Intrinsics::shadow_realm_prototype)); + // 3. Let realmRec be CreateRealm(). auto realm = MUST_OR_THROW_OOM(Realm::create(vm)); + // 4. Set O.[[ShadowRealm]] to realmRec. + object->set_shadow_realm(realm); + // 5. Let context be a new execution context. auto context = ExecutionContext::create(); @@ -58,10 +65,8 @@ ThrowCompletionOr> ShadowRealmConstructor::construct(Functi // 8. Set the ScriptOrModule of context to null. // Note: This is already the default value. - // 2. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%ShadowRealm.prototype%", « [[ShadowRealm]], [[ExecutionContext]] »). - // 4. Set O.[[ShadowRealm]] to realmRec. // 9. Set O.[[ExecutionContext]] to context. - auto object = TRY(ordinary_create_from_constructor(vm, new_target, &Intrinsics::shadow_realm_prototype, *realm, move(context))); + object->set_execution_context(move(context)); // 10. Perform ? SetRealmGlobalObject(realmRec, undefined, undefined). realm->set_global_object(nullptr, nullptr);