summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Libraries/LibJS/AST.cpp10
-rw-r--r--Libraries/LibJS/AST.h4
-rw-r--r--Libraries/LibJS/Interpreter.cpp4
-rw-r--r--Libraries/LibJS/Interpreter.h2
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;