Index: src/interpreter/bytecode-generator.cc |
diff --git a/src/interpreter/bytecode-generator.cc b/src/interpreter/bytecode-generator.cc |
index 22972537abcbccb0e72a702ba07e9e4eb12a011a..7ce271c0db096b61d3dee32e562e535d8c23055c 100644 |
--- a/src/interpreter/bytecode-generator.cc |
+++ b/src/interpreter/bytecode-generator.cc |
@@ -104,65 +104,65 @@ class BytecodeGenerator::ControlScope BASE_EMBEDDED { |
}; |
-// Scoped class for enabling 'break' and 'continue' in iteration |
-// constructs, e.g. do...while, while..., for... |
-class BytecodeGenerator::ControlScopeForIteration |
+// Scoped class for enabling break inside blocks and switch blocks. |
+class BytecodeGenerator::ControlScopeForBreakable final |
: public BytecodeGenerator::ControlScope { |
public: |
- ControlScopeForIteration(BytecodeGenerator* generator, |
- IterationStatement* statement, |
- LoopBuilder* loop_builder) |
+ ControlScopeForBreakable(BytecodeGenerator* generator, |
+ BreakableStatement* statement, |
+ BreakableControlFlowBuilder* control_builder) |
: ControlScope(generator), |
statement_(statement), |
- loop_builder_(loop_builder) {} |
+ control_builder_(control_builder) {} |
protected: |
virtual bool Execute(Command command, Statement* statement) { |
if (statement != statement_) return false; |
switch (command) { |
case CMD_BREAK: |
- loop_builder_->Break(); |
+ control_builder_->Break(); |
return true; |
case CMD_CONTINUE: |
- loop_builder_->Continue(); |
- return true; |
+ break; |
} |
return false; |
} |
private: |
Statement* statement_; |
- LoopBuilder* loop_builder_; |
+ BreakableControlFlowBuilder* control_builder_; |
}; |
-// Scoped class for enabling 'break' in switch statements. |
-class BytecodeGenerator::ControlScopeForSwitch |
+// Scoped class for enabling 'break' and 'continue' in iteration |
+// constructs, e.g. do...while, while..., for... |
+class BytecodeGenerator::ControlScopeForIteration final |
: public BytecodeGenerator::ControlScope { |
public: |
- ControlScopeForSwitch(BytecodeGenerator* generator, |
- SwitchStatement* statement, |
- SwitchBuilder* switch_builder) |
+ ControlScopeForIteration(BytecodeGenerator* generator, |
+ IterationStatement* statement, |
+ LoopBuilder* loop_builder) |
: ControlScope(generator), |
statement_(statement), |
- switch_builder_(switch_builder) {} |
+ loop_builder_(loop_builder) {} |
protected: |
virtual bool Execute(Command command, Statement* statement) { |
if (statement != statement_) return false; |
switch (command) { |
case CMD_BREAK: |
- switch_builder_->Break(); |
+ loop_builder_->Break(); |
return true; |
case CMD_CONTINUE: |
- break; |
+ loop_builder_->Continue(); |
+ return true; |
} |
return false; |
} |
private: |
Statement* statement_; |
- SwitchBuilder* switch_builder_; |
+ LoopBuilder* loop_builder_; |
}; |
@@ -484,6 +484,9 @@ void BytecodeGenerator::MakeBytecodeBody() { |
void BytecodeGenerator::VisitBlock(Block* stmt) { |
+ BlockBuilder block_builder(this->builder()); |
+ ControlScopeForBreakable execution_control(this, stmt, &block_builder); |
+ |
if (stmt->scope() == NULL) { |
// Visit statements in the same scope, no declarations. |
VisitStatements(stmt->statements()); |
@@ -499,6 +502,7 @@ void BytecodeGenerator::VisitBlock(Block* stmt) { |
VisitStatements(stmt->statements()); |
} |
} |
+ if (stmt->labels() != nullptr) block_builder.EndBlock(); |
} |
@@ -685,7 +689,7 @@ void BytecodeGenerator::VisitWithStatement(WithStatement* stmt) { |
void BytecodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { |
ZoneList<CaseClause*>* clauses = stmt->cases(); |
SwitchBuilder switch_builder(builder(), clauses->length()); |
- ControlScopeForSwitch scope(this, stmt, &switch_builder); |
+ ControlScopeForBreakable scope(this, stmt, &switch_builder); |
int default_index = -1; |
// Keep the switch value in a register until a case matches. |
@@ -753,7 +757,7 @@ void BytecodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { |
VisitForAccumulatorValue(stmt->cond()); |
loop_builder.JumpToHeaderIfTrue(); |
} |
- loop_builder.LoopEnd(); |
+ loop_builder.EndLoop(); |
} |
@@ -773,7 +777,7 @@ void BytecodeGenerator::VisitWhileStatement(WhileStatement* stmt) { |
} |
Visit(stmt->body()); |
loop_builder.JumpToHeader(); |
- loop_builder.LoopEnd(); |
+ loop_builder.EndLoop(); |
} |
@@ -802,7 +806,7 @@ void BytecodeGenerator::VisitForStatement(ForStatement* stmt) { |
Visit(stmt->next()); |
} |
loop_builder.JumpToHeader(); |
- loop_builder.LoopEnd(); |
+ loop_builder.EndLoop(); |
} |
@@ -894,7 +898,7 @@ void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
builder()->LoadAccumulatorWithRegister(index).CountOperation( |
Token::Value::ADD, language_mode_strength()); |
loop_builder.JumpToHeader(); |
- loop_builder.LoopEnd(); |
+ loop_builder.EndLoop(); |
} |