Chromium Code Reviews| Index: src/compiler/ast-graph-builder.cc |
| diff --git a/src/compiler/ast-graph-builder.cc b/src/compiler/ast-graph-builder.cc |
| index b8b0f4360ae60a86ea3c8cc3c85b278413e13de0..7e14fb7527311f8e95b0fa009052e225d99dd428 100644 |
| --- a/src/compiler/ast-graph-builder.cc |
| +++ b/src/compiler/ast-graph-builder.cc |
| @@ -206,7 +206,6 @@ class AstGraphBuilder::ControlScope BASE_EMBEDDED { |
| int stack_height_; |
| }; |
| - |
| // Helper class for a try-finally control scope. It can record intercepted |
| // control-flow commands that cause entry into a finally-block, and re-apply |
| // them after again leaving that block. Special tokens are used to identify |
| @@ -214,7 +213,10 @@ class AstGraphBuilder::ControlScope BASE_EMBEDDED { |
| class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject { |
| public: |
| explicit DeferredCommands(AstGraphBuilder* owner) |
| - : owner_(owner), deferred_(owner->local_zone()) {} |
| + : owner_(owner), |
| + deferred_(owner->local_zone()), |
| + return_token_(nullptr), |
| + throw_token_(nullptr) {} |
| // One recorded control-flow command. |
| struct Entry { |
| @@ -226,7 +228,24 @@ class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject { |
| // Records a control-flow command while entering the finally-block. This also |
| // generates a new dispatch token that identifies one particular path. |
| Node* RecordCommand(Command cmd, Statement* stmt, Node* value) { |
| - Node* token = NewPathTokenForDeferredCommand(); |
| + Node* token = nullptr; |
| + switch (cmd) { |
| + case CMD_BREAK: |
| + case CMD_CONTINUE: |
| + token = WrapToken(dispenser_.GetBreakContinueToken()); |
| + break; |
| + case CMD_THROW: |
| + if (throw_token_) return throw_token_; |
| + token = WrapToken(TokenDispenserForFinally::kThrowToken); |
| + throw_token_ = token; |
| + break; |
| + case CMD_RETURN: |
| + if (return_token_) return return_token_; |
| + token = WrapToken(TokenDispenserForFinally::kReturnToken); |
| + return_token_ = token; |
| + break; |
| + } |
| + DCHECK_NOT_NULL(token); |
| deferred_.push_back({cmd, stmt, token}); |
| return token; |
| } |
| @@ -255,11 +274,12 @@ class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject { |
| } |
| protected: |
| - Node* NewPathTokenForDeferredCommand() { |
| - return owner_->jsgraph()->Constant(static_cast<int>(deferred_.size())); |
| + Node* WrapToken(int token_id) { |
|
Michael Starzinger
2016/02/05 13:44:57
nit: Can we call this "NewPathToken" instead? Beca
Jarin
2016/02/05 13:55:07
Done.
|
| + return owner_->jsgraph()->Constant(token_id); |
| } |
| Node* NewPathTokenForImplicitFallThrough() { |
| - return owner_->jsgraph()->Constant(-1); |
| + return owner_->jsgraph()->Constant( |
|
Michael Starzinger
2016/02/05 13:44:57
nit: "return WrapToken(TokenDispenserForFinally::k
Jarin
2016/02/05 13:55:08
Done.
|
| + TokenDispenserForFinally::kFallThroughToken); |
| } |
| Node* NewPathDispatchCondition(Node* t1, Node* t2) { |
| // TODO(mstarzinger): This should be machine()->WordEqual(), but our Phi |
| @@ -268,8 +288,11 @@ class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject { |
| } |
| private: |
| + TokenDispenserForFinally dispenser_; |
| AstGraphBuilder* owner_; |
| ZoneVector<Entry> deferred_; |
| + Node* return_token_; |
| + Node* throw_token_; |
| }; |