Skip to content

Commit

Permalink
LibJS: Also apply AD-HOC execution context fixup on host defined path
Browse files Browse the repository at this point in the history
As described in the comments, this was a bug in the shadow realm spec.
For now, just apply a fixup to the execution context so that it works as
intended.

Once tc39/proposal-shadowrealm#392 is updated to
match these changes to the spec we should be able to implement this in a
better way :^)
  • Loading branch information
shannonbooth committed Nov 2, 2024
1 parent 78f5362 commit 028e3f0
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 6 deletions.
26 changes: 21 additions & 5 deletions Userland/Libraries/LibJS/Runtime/ShadowRealmConstructor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ ThrowCompletionOr<Value> ShadowRealmConstructor::call()
return vm.throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, vm.names.ShadowRealm);
}

// https://github.com/tc39/proposal-shadowrealm/pull/392
// The default implementation of HostInitializeShadowRealm performs the following steps when called:
static NonnullGCPtr<Object> default_create_global_object(JS::Realm& realm)
{
// Return NormalCompletion(OrdinaryObjectCreate(realm.[[Intrinsics]].[[%Object.prototype%]])).
return Object::create(realm, realm.intrinsics().object_prototype());
}

// https://github.com/tc39/proposal-shadowrealm/pull/392
static ThrowCompletionOr<NonnullGCPtr<Object>> initialize_shadow_realm(ShadowRealm& object)
{
Expand All @@ -50,15 +58,23 @@ static ThrowCompletionOr<NonnullGCPtr<Object>> initialize_shadow_realm(ShadowRea
// 2. Let realm be the Realm of context.
auto& realm = *context.realm;

// FIXME: Spec bug. InitializeHostDefinedRealm is pushing on an execution context and active realm that we need to undo here.
//
// This relates to spec changes:
// - https://github.com/tc39/proposal-shadowrealm/commit/76bb92682c448b8caf5cb7012c5f826be121880a
// - https://github.com/tc39/proposal-shadowrealm/commit/28b0cc3f749ddcbb05290f4481bddf5b8253a4c7
//
// The proposed change to integrate with the Web Platform: https://github.com/tc39/proposal-shadowrealm/pull/392
//
// Needs to be adjusted to align with these updates.
vm.pop_execution_context();
object.set_execution_context(vm.running_execution_context().copy());

// 3. Return ? HostInitializeShadowRealm(realm, context, O).
if (vm.host_initialize_shadow_realm)
return TRY(vm.host_initialize_shadow_realm(realm, context.copy(), object));

// AD-HOC: Fallback for when there is no host defined implementation.
vm.pop_execution_context();
object.set_execution_context(vm.running_execution_context().copy());
object.set_shadow_realm(*vm.running_execution_context().realm);
return Object::create(realm, realm.intrinsics().object_prototype());
return default_create_global_object(realm);
}

// 3.2.1 ShadowRealm ( ), https://tc39.es/proposal-shadowrealm/#sec-shadowrealm
Expand Down
2 changes: 1 addition & 1 deletion Userland/Libraries/LibJS/Runtime/VM.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ class VM : public RefCounted<VM> {
Function<ThrowCompletionOr<void>(Object&)> host_ensure_can_add_private_element;
Function<ThrowCompletionOr<HandledByHost>(ArrayBuffer&, size_t)> host_resize_array_buffer;
Function<void(StringView)> host_unrecognized_date_string;
Function<ThrowCompletionOr<NonnullGCPtr<ShadowRealm>>(Realm&, NonnullOwnPtr<ExecutionContext>, ShadowRealm&)> host_initialize_shadow_realm;
Function<ThrowCompletionOr<NonnullGCPtr<Object>>(Realm&, NonnullOwnPtr<ExecutionContext>, ShadowRealm&)> host_initialize_shadow_realm;

Vector<StackTraceElement> stack_trace() const;

Expand Down

0 comments on commit 028e3f0

Please sign in to comment.