diff options
-rw-r--r-- | Libraries/LibJS/AST.cpp | 10 | ||||
-rw-r--r-- | Libraries/LibJS/AST.h | 4 | ||||
-rw-r--r-- | Libraries/LibJS/Interpreter.cpp | 4 | ||||
-rw-r--r-- | Libraries/LibJS/Interpreter.h | 2 |
4 files changed, 17 insertions, 3 deletions
diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp index abfccf1f14..2b6ede9ba0 100644 --- a/Libraries/LibJS/AST.cpp +++ b/Libraries/LibJS/AST.cpp @@ -95,6 +95,13 @@ Value WhileStatement::execute(Interpreter& interpreter) const Value ForStatement::execute(Interpreter& interpreter) const { + OwnPtr<BlockStatement> wrapper; + + if (m_init->is_variable_declaration() && static_cast<const VariableDeclaration*>(m_init.ptr())->declaration_type() != DeclarationType::Var) { + wrapper = make<BlockStatement>(); + interpreter.enter_scope(*wrapper, {}, ScopeType::Block); + } + Value last_value = js_undefined(); if (m_init) @@ -114,6 +121,9 @@ Value ForStatement::execute(Interpreter& interpreter) const } } + if (wrapper) + interpreter.exit_scope(*wrapper); + return last_value; } diff --git a/Libraries/LibJS/AST.h b/Libraries/LibJS/AST.h index 2d2bceba31..f2ec48a393 100644 --- a/Libraries/LibJS/AST.h +++ b/Libraries/LibJS/AST.h @@ -50,6 +50,8 @@ private: }; class Statement : public ASTNode { +public: + virtual bool is_variable_declaration() const { return false; } }; class ErrorStatement final : public Statement { @@ -480,7 +482,9 @@ public: { } + virtual bool is_variable_declaration() const override { return true; } const Identifier& name() const { return *m_name; } + DeclarationType declaration_type() const { return m_declaration_type; } virtual Value execute(Interpreter&) const override; virtual void dump(int indent) const override; diff --git a/Libraries/LibJS/Interpreter.cpp b/Libraries/LibJS/Interpreter.cpp index 99049a36c4..dfbaa35ebb 100644 --- a/Libraries/LibJS/Interpreter.cpp +++ b/Libraries/LibJS/Interpreter.cpp @@ -68,8 +68,8 @@ void Interpreter::enter_scope(const ScopeNode& scope_node, Vector<Argument> argu void Interpreter::exit_scope(const ScopeNode& scope_node) { - ASSERT(&m_scope_stack.last().scope_node == &scope_node); - m_scope_stack.take_last(); + while (&m_scope_stack.last().scope_node != &scope_node) + m_scope_stack.take_last(); } void Interpreter::do_return() diff --git a/Libraries/LibJS/Interpreter.h b/Libraries/LibJS/Interpreter.h index 9164e286b3..61b584c068 100644 --- a/Libraries/LibJS/Interpreter.h +++ b/Libraries/LibJS/Interpreter.h @@ -76,10 +76,10 @@ public: void collect_roots(Badge<Heap>, HashTable<Cell*>&); -private: void enter_scope(const ScopeNode&, Vector<Argument>, ScopeType); void exit_scope(const ScopeNode&); +private: Heap m_heap; Vector<ScopeFrame> m_scope_stack; |