Coverage Report

Created: 2026-11-13 08:07

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibJS/Runtime/ExecutionContext.h
Line
Count
Source
1
/*
2
 * Copyright (c) 2020-2024, Andreas Kling <kling@serenityos.org>
3
 * Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
4
 * Copyright (c) 2022, Luke Wilde <lukew@serenityos.org>
5
 *
6
 * SPDX-License-Identifier: BSD-2-Clause
7
 */
8
9
#pragma once
10
11
#include <AK/DeprecatedFlyString.h>
12
#include <AK/WeakPtr.h>
13
#include <LibJS/Bytecode/BasicBlock.h>
14
#include <LibJS/Forward.h>
15
#include <LibJS/Module.h>
16
#include <LibJS/Runtime/PrivateEnvironment.h>
17
#include <LibJS/Runtime/Value.h>
18
#include <LibJS/SourceRange.h>
19
20
namespace JS {
21
22
using ScriptOrModule = Variant<Empty, NonnullGCPtr<Script>, NonnullGCPtr<Module>>;
23
24
// 9.4 Execution Contexts, https://tc39.es/ecma262/#sec-execution-contexts
25
struct ExecutionContext {
26
    static NonnullOwnPtr<ExecutionContext> create();
27
    [[nodiscard]] NonnullOwnPtr<ExecutionContext> copy() const;
28
29
    ~ExecutionContext();
30
31
    void visit_edges(Cell::Visitor&);
32
33
private:
34
    friend class ExecutionContextAllocator;
35
36
    ExecutionContext();
37
38
public:
39
    void operator delete(void* ptr);
40
41
    GCPtr<FunctionObject> function;                // [[Function]]
42
    GCPtr<Realm> realm;                            // [[Realm]]
43
    ScriptOrModule script_or_module;               // [[ScriptOrModule]]
44
    GCPtr<Environment> lexical_environment;        // [[LexicalEnvironment]]
45
    GCPtr<Environment> variable_environment;       // [[VariableEnvironment]]
46
    GCPtr<PrivateEnvironment> private_environment; // [[PrivateEnvironment]]
47
48
    // Non-standard: This points at something that owns this ExecutionContext, in case it needs to be protected from GC.
49
    GCPtr<Cell> context_owner;
50
51
    Optional<size_t> program_counter;
52
    GCPtr<PrimitiveString> function_name;
53
    Value this_value;
54
55
    GCPtr<Bytecode::Executable> executable;
56
57
    // https://html.spec.whatwg.org/multipage/webappapis.html#skip-when-determining-incumbent-counter
58
    // FIXME: Move this out of LibJS (e.g. by using the CustomData concept), as it's used exclusively by LibWeb.
59
    size_t skip_when_determining_incumbent_counter { 0 };
60
61
    Value argument(size_t index) const
62
0
    {
63
0
        if (index >= arguments.size()) [[unlikely]]
64
0
            return js_undefined();
65
0
        return arguments[index];
66
0
    }
67
68
    Value& local(size_t index)
69
0
    {
70
0
        return registers_and_constants_and_locals[index];
71
0
    }
72
73
    u32 passed_argument_count { 0 };
74
    bool is_strict_mode { false };
75
76
    Vector<Value> arguments;
77
    Vector<Value> registers_and_constants_and_locals;
78
    Vector<Bytecode::UnwindInfo> unwind_contexts;
79
    Vector<Optional<size_t>> previously_scheduled_jumps;
80
    Vector<GCPtr<Environment>> saved_lexical_environments;
81
};
82
83
struct StackTraceElement {
84
    ExecutionContext* execution_context;
85
    Optional<UnrealizedSourceRange> source_range;
86
};
87
88
}