Realm.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
  3. * Copyright (c) 2022, Andreas Kling <andreas@ladybird.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <AK/TypeCasts.h>
  8. #include <LibJS/Heap/DeferGC.h>
  9. #include <LibJS/Runtime/GlobalEnvironment.h>
  10. #include <LibJS/Runtime/GlobalObject.h>
  11. #include <LibJS/Runtime/Realm.h>
  12. #include <LibJS/Runtime/VM.h>
  13. namespace JS {
  14. JS_DEFINE_ALLOCATOR(Realm);
  15. // 9.3.1 InitializeHostDefinedRealm ( ), https://tc39.es/ecma262/#sec-initializehostdefinedrealm
  16. ThrowCompletionOr<NonnullOwnPtr<ExecutionContext>> Realm::initialize_host_defined_realm(VM& vm, Function<Object*(Realm&)> create_global_object, Function<Object*(Realm&)> create_global_this_value)
  17. {
  18. DeferGC defer_gc(vm.heap());
  19. // 1. Let realm be a new Realm Record
  20. auto realm = vm.heap().allocate<Realm>();
  21. // 2. Perform CreateIntrinsics(realm).
  22. MUST(Intrinsics::create(*realm));
  23. // FIXME: 3. Set realm.[[AgentSignifier]] to AgentSignifier().
  24. // NOTE: Done on step 1.
  25. // 4. Set realm.[[GlobalObject]] to undefined.
  26. // 5. Set realm.[[GlobalEnv]] to undefined.
  27. // FIXME: 6. Set realm.[[TemplateMap]] to a new empty List.
  28. // 7. Let newContext be a new execution context.
  29. auto new_context = ExecutionContext::create();
  30. // 8. Set the Function of newContext to null.
  31. new_context->function = nullptr;
  32. // 9. Set the Realm of newContext to realm.
  33. new_context->realm = realm;
  34. // 10. Set the ScriptOrModule of newContext to null.
  35. new_context->script_or_module = {};
  36. // 11. Push newContext onto the execution context stack; newContext is now the running execution context.
  37. vm.push_execution_context(*new_context);
  38. // 12. If the host requires use of an exotic object to serve as realm's global object, then
  39. Object* global = nullptr;
  40. if (create_global_object) {
  41. // a. Let global be such an object created in a host-defined manner.
  42. global = create_global_object(*realm);
  43. }
  44. // 13. Else,
  45. else {
  46. // a. Let global be OrdinaryObjectCreate(realm.[[Intrinsics]].[[%Object.prototype%]]).
  47. // NOTE: We allocate a proper GlobalObject directly as this plain object is
  48. // turned into one via SetDefaultGlobalBindings in the spec.
  49. global = vm.heap().allocate<GlobalObject>(realm);
  50. }
  51. // 14. If the host requires that the this binding in realm's global scope return an object other than the global object, then
  52. Object* this_value = nullptr;
  53. if (create_global_this_value) {
  54. // a. Let thisValue be such an object created in a host-defined manner.
  55. this_value = create_global_this_value(*realm);
  56. }
  57. // 15. Else,
  58. else {
  59. // a. Let thisValue be global.
  60. this_value = global;
  61. }
  62. // 16. Set realm.[[GlobalObject]] to global.
  63. realm->m_global_object = global;
  64. // 17. Set realm.[[GlobalEnv]] to NewGlobalEnvironment(global, thisValue).
  65. realm->m_global_environment = vm.heap().allocate<GlobalEnvironment>(*global, *this_value);
  66. // 18. Perform ? SetDefaultGlobalBindings(realm).
  67. set_default_global_bindings(*realm);
  68. // 19. Create any host-defined global object properties on global.
  69. global->initialize(*realm);
  70. // 20. Return unused.
  71. return new_context;
  72. }
  73. void Realm::visit_edges(Visitor& visitor)
  74. {
  75. Base::visit_edges(visitor);
  76. visitor.visit(m_intrinsics);
  77. visitor.visit(m_global_object);
  78. visitor.visit(m_global_environment);
  79. if (m_host_defined)
  80. m_host_defined->visit_edges(visitor);
  81. }
  82. }