Coverage Report

Created: 2026-02-14 08:01

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