mirror of
https://github.com/RGBCube/serenity
synced 2025-05-20 13:35:07 +00:00

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().
80 lines
3 KiB
C++
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;
|
|
}
|
|
|
|
}
|