/* * Copyright (c) 2020-2021, Andreas Kling * Copyright (c) 2020-2021, Linus Groh * Copyright (c) 2022, Luke Wilde * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include namespace JS { using ScriptOrModule = Variant, NonnullGCPtr>; // 9.4 Execution Contexts, https://tc39.es/ecma262/#sec-execution-contexts struct ExecutionContext { static NonnullOwnPtr create(Heap&); [[nodiscard]] NonnullOwnPtr copy() const; ~ExecutionContext(); void visit_edges(Cell::Visitor&); static FlatPtr realm_offset() { return OFFSET_OF(ExecutionContext, realm); } static FlatPtr lexical_environment_offset() { return OFFSET_OF(ExecutionContext, lexical_environment); } static FlatPtr variable_environment_offset() { return OFFSET_OF(ExecutionContext, variable_environment); } private: ExecutionContext(Heap&); IntrusiveListNode m_list_node; public: Heap& m_heap; using List = IntrusiveList<&ExecutionContext::m_list_node>; GCPtr function; // [[Function]] GCPtr realm; // [[Realm]] ScriptOrModule script_or_module; // [[ScriptOrModule]] GCPtr lexical_environment; // [[LexicalEnvironment]] GCPtr variable_environment; // [[VariableEnvironment]] GCPtr private_environment; // [[PrivateEnvironment]] // Non-standard: This points at something that owns this ExecutionContext, in case it needs to be protected from GC. GCPtr context_owner; Optional instruction_stream_iterator; GCPtr function_name; Value this_value; bool is_strict_mode { false }; GCPtr executable; // https://html.spec.whatwg.org/multipage/webappapis.html#skip-when-determining-incumbent-counter // FIXME: Move this out of LibJS (e.g. by using the CustomData concept), as it's used exclusively by LibWeb. size_t skip_when_determining_incumbent_counter { 0 }; Value argument(size_t index) const { if (index >= arguments.size()) [[unlikely]] return js_undefined(); return arguments[index]; } Value& local(size_t index) { return locals[index]; } Vector arguments; Vector locals; }; struct StackTraceElement { ExecutionContext* execution_context; Optional source_range; }; }