ShadowRealmConstructor.cpp 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. /*
  2. * Copyright (c) 2021, Linus Groh <linusg@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibJS/Runtime/AbstractOperations.h>
  7. #include <LibJS/Runtime/ShadowRealm.h>
  8. #include <LibJS/Runtime/ShadowRealmConstructor.h>
  9. namespace JS {
  10. // 3.2 The ShadowRealm Constructor, https://tc39.es/proposal-shadowrealm/#sec-shadowrealm-constructor
  11. ShadowRealmConstructor::ShadowRealmConstructor(GlobalObject& global_object)
  12. : NativeFunction(vm().names.ShadowRealm.as_string(), *global_object.function_prototype())
  13. {
  14. }
  15. void ShadowRealmConstructor::initialize(GlobalObject& global_object)
  16. {
  17. auto& vm = this->vm();
  18. NativeFunction::initialize(global_object);
  19. // 3.3.1 ShadowRealm.prototype, https://tc39.es/proposal-shadowrealm/#sec-shadowrealm.prototype
  20. define_direct_property(vm.names.prototype, global_object.shadow_realm_prototype(), 0);
  21. define_direct_property(vm.names.length, Value(0), Attribute::Configurable);
  22. }
  23. // 3.2.1 ShadowRealm ( ), https://tc39.es/proposal-shadowrealm/#sec-shadowrealm
  24. ThrowCompletionOr<Value> ShadowRealmConstructor::call()
  25. {
  26. auto& vm = this->vm();
  27. // 1. If NewTarget is undefined, throw a TypeError exception.
  28. return vm.throw_completion<TypeError>(global_object(), ErrorType::ConstructorWithoutNew, vm.names.ShadowRealm);
  29. }
  30. // 3.2.1 ShadowRealm ( ), https://tc39.es/proposal-shadowrealm/#sec-shadowrealm
  31. ThrowCompletionOr<Object*> ShadowRealmConstructor::construct(FunctionObject& new_target)
  32. {
  33. auto& vm = this->vm();
  34. auto& global_object = this->global_object();
  35. // 3. Let realmRec be CreateRealm().
  36. auto* realm = Realm::create(vm);
  37. // 5. Let context be a new execution context.
  38. auto context = ExecutionContext { vm.heap() };
  39. // 6. Set the Function of context to null.
  40. context.function = nullptr;
  41. // 7. Set the Realm of context to realmRec.
  42. context.realm = realm;
  43. // 8. Set the ScriptOrModule of context to null.
  44. // FIXME: Our execution context struct currently does not track this item.
  45. // 2. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%ShadowRealm.prototype%", « [[ShadowRealm]], [[ExecutionContext]] »).
  46. // 4. Set O.[[ShadowRealm]] to realmRec.
  47. // 9. Set O.[[ExecutionContext]] to context.
  48. auto* object = TRY(ordinary_create_from_constructor<ShadowRealm>(global_object, new_target, &GlobalObject::shadow_realm_prototype, *realm, move(context)));
  49. // 10. Perform ? SetRealmGlobalObject(realmRec, undefined, undefined).
  50. auto* new_global_object = vm.heap().allocate_without_global_object<GlobalObject>();
  51. new_global_object->initialize_global_object();
  52. realm->set_global_object(*new_global_object, nullptr);
  53. // TODO: I don't think we should have these exactly like this, that doesn't work well with how
  54. // we create global objects. Still, it should be possible to make a ShadowRealm with a
  55. // non-LibJS GlobalObject somehow.
  56. // 11. Perform ? SetDefaultGlobalBindings(O.[[ShadowRealm]]).
  57. // 12. Perform ? HostInitializeShadowRealm(O.[[ShadowRealm]]).
  58. // 13. Return O.
  59. return object;
  60. }
  61. }