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_; |
}; |