Chromium Code Reviews| 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(); |
|
rmcilroy
2015/12/16 13:07:24
optional - can we remove the conditional here?
|
| } |
| @@ -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(); |
| } |