diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index 838b93e86de..ba297a4a433 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -59,19 +59,20 @@ class InterpreterNodeScope { public: InterpreterNodeScope(Interpreter& interpreter, const ASTNode& node) : m_interpreter(interpreter) - , m_node(node) + , m_chain_node { nullptr, node } { - m_interpreter.enter_node(m_node); + m_interpreter.vm().call_frame().current_node = &node; + m_interpreter.push_ast_node(m_chain_node); } ~InterpreterNodeScope() { - m_interpreter.exit_node(m_node); + m_interpreter.pop_ast_node(); } private: Interpreter& m_interpreter; - const ASTNode& m_node; + ExecutingASTNodeChain m_chain_node; }; String ASTNode::class_name() const @@ -2169,8 +2170,7 @@ void SequenceExpression::dump(int indent) const Value SequenceExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const { - interpreter.enter_node(*this); - ScopeGuard exit_node { [&] { interpreter.exit_node(*this); } }; + InterpreterNodeScope node_scope { interpreter, *this }; Value last_value; for (auto& expression : m_expressions) { diff --git a/Userland/Libraries/LibJS/Interpreter.cpp b/Userland/Libraries/LibJS/Interpreter.cpp index 5750ecb129a..4518a5b41a7 100644 --- a/Userland/Libraries/LibJS/Interpreter.cpp +++ b/Userland/Libraries/LibJS/Interpreter.cpp @@ -143,17 +143,6 @@ void Interpreter::exit_scope(const ScopeNode& scope_node) vm().unwind(ScopeType::None); } -void Interpreter::enter_node(const ASTNode& node) -{ - vm().call_frame().current_node = &node; - push_ast_node(node); -} - -void Interpreter::exit_node(const ASTNode&) -{ - pop_ast_node(); -} - void Interpreter::push_scope(ScopeFrame frame) { m_scope_stack.append(move(frame)); diff --git a/Userland/Libraries/LibJS/Interpreter.h b/Userland/Libraries/LibJS/Interpreter.h index a2b801cefa5..d9bea8e63a8 100644 --- a/Userland/Libraries/LibJS/Interpreter.h +++ b/Userland/Libraries/LibJS/Interpreter.h @@ -44,6 +44,11 @@ namespace JS { +struct ExecutingASTNodeChain { + ExecutingASTNodeChain* previous { nullptr }; + const ASTNode& node; +}; + class Interpreter : public Weakable { public: template @@ -77,14 +82,21 @@ public: void enter_scope(const ScopeNode&, ScopeType, GlobalObject&); void exit_scope(const ScopeNode&); - void enter_node(const ASTNode&); - void exit_node(const ASTNode&); + void push_ast_node(ExecutingASTNodeChain& chain_node) + { + chain_node.previous = m_ast_node_chain; + m_ast_node_chain = &chain_node; + } - void push_ast_node(const ASTNode& node) { m_ast_nodes.append(&node); } - void pop_ast_node() { m_ast_nodes.take_last(); } + void pop_ast_node() + { + VERIFY(m_ast_node_chain); + m_ast_node_chain = m_ast_node_chain->previous; + } - const ASTNode* current_node() const { return !m_ast_nodes.is_empty() ? m_ast_nodes.last() : nullptr; } - const Vector& node_stack() const { return m_ast_nodes; } + const ASTNode* current_node() const { return m_ast_node_chain ? &m_ast_node_chain->node : nullptr; } + ExecutingASTNodeChain* executing_ast_node_chain() { return m_ast_node_chain; } + const ExecutingASTNodeChain* executing_ast_node_chain() const { return m_ast_node_chain; } Value execute_statement(GlobalObject&, const Statement&, ScopeType = ScopeType::Block); @@ -94,7 +106,7 @@ private: void push_scope(ScopeFrame frame); Vector m_scope_stack; - Vector m_ast_nodes; + ExecutingASTNodeChain* m_ast_node_chain { nullptr }; NonnullRefPtr m_vm; diff --git a/Userland/Libraries/LibJS/Runtime/Exception.cpp b/Userland/Libraries/LibJS/Runtime/Exception.cpp index f8f0f0c4c89..5a2c90900ec 100644 --- a/Userland/Libraries/LibJS/Runtime/Exception.cpp +++ b/Userland/Libraries/LibJS/Runtime/Exception.cpp @@ -45,11 +45,8 @@ Exception::Exception(Value value) } if (auto* interpreter = vm.interpreter_if_exists()) { - auto& node_stack = interpreter->node_stack(); - for (ssize_t i = node_stack.size() - 1; i >= 0; --i) { - auto* node = node_stack[i]; - VERIFY(node); - m_source_ranges.append(node->source_range()); + for (auto* node_chain = interpreter->executing_ast_node_chain(); node_chain; node_chain = node_chain->previous) { + m_source_ranges.append(node_chain->node.source_range()); } } }