1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-20 13:35:07 +00:00
serenity/Userland/Libraries/LibJS/Runtime/ShadowRealmConstructor.cpp
Linus Groh e992a9f469 LibJS+LibWeb: Replace GlobalObject with Realm in Heap::allocate<T>()
This is a continuation of the previous three commits.

Now that create() receives the allocating realm, we can simply forward
that to allocate(), which accounts for the majority of these changes.
Additionally, we can get rid of the realm_from_global_object() in one
place, with one more remaining in VM::throw_completion().
2022-08-23 13:58:30 +01:00

80 lines
3 KiB
C++

/*
* Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Runtime/AbstractOperations.h>
#include <LibJS/Runtime/ShadowRealm.h>
#include <LibJS/Runtime/ShadowRealmConstructor.h>
namespace JS {
// 3.2 The ShadowRealm Constructor, https://tc39.es/proposal-shadowrealm/#sec-shadowrealm-constructor
ShadowRealmConstructor::ShadowRealmConstructor(Realm& realm)
: NativeFunction(vm().names.ShadowRealm.as_string(), *realm.global_object().function_prototype())
{
}
void ShadowRealmConstructor::initialize(Realm& realm)
{
auto& vm = this->vm();
NativeFunction::initialize(realm);
// 3.3.1 ShadowRealm.prototype, https://tc39.es/proposal-shadowrealm/#sec-shadowrealm.prototype
define_direct_property(vm.names.prototype, realm.global_object().shadow_realm_prototype(), 0);
define_direct_property(vm.names.length, Value(0), Attribute::Configurable);
}
// 3.2.1 ShadowRealm ( ), https://tc39.es/proposal-shadowrealm/#sec-shadowrealm
ThrowCompletionOr<Value> ShadowRealmConstructor::call()
{
auto& vm = this->vm();
// 1. If NewTarget is undefined, throw a TypeError exception.
return vm.throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, vm.names.ShadowRealm);
}
// 3.2.1 ShadowRealm ( ), https://tc39.es/proposal-shadowrealm/#sec-shadowrealm
ThrowCompletionOr<Object*> ShadowRealmConstructor::construct(FunctionObject& new_target)
{
auto& vm = this->vm();
auto& global_object = this->global_object();
// 3. Let realmRec be CreateRealm().
auto* realm = Realm::create(vm);
// 5. Let context be a new execution context.
auto context = ExecutionContext { vm.heap() };
// 6. Set the Function of context to null.
context.function = nullptr;
// 7. Set the Realm of context to realmRec.
context.realm = realm;
// 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<ShadowRealm>(global_object, new_target, &GlobalObject::shadow_realm_prototype, *realm, move(context)));
// 10. Perform ? SetRealmGlobalObject(realmRec, undefined, undefined).
auto* new_global_object = vm.heap().allocate_without_realm<GlobalObject>(*realm);
realm->set_global_object(new_global_object, nullptr);
new_global_object->initialize_global_object();
// TODO: I don't think we should have these exactly like this, that doesn't work well with how
// we create global objects. Still, it should be possible to make a ShadowRealm with a
// non-LibJS GlobalObject somehow.
// 11. Perform ? SetDefaultGlobalBindings(O.[[ShadowRealm]]).
// 12. Perform ? HostInitializeShadowRealm(O.[[ShadowRealm]]).
// 13. Return O.
return object;
}
}