| 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..bcc7fa7d0540fa44a5df1403e42e22d85b3eb2b4 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 = NewPathToken(dispenser_.GetBreakContinueToken());
|
| + break;
|
| + case CMD_THROW:
|
| + if (throw_token_) return throw_token_;
|
| + token = NewPathToken(TokenDispenserForFinally::kThrowToken);
|
| + throw_token_ = token;
|
| + break;
|
| + case CMD_RETURN:
|
| + if (return_token_) return return_token_;
|
| + token = NewPathToken(TokenDispenserForFinally::kReturnToken);
|
| + return_token_ = token;
|
| + break;
|
| + }
|
| + DCHECK_NOT_NULL(token);
|
| deferred_.push_back({cmd, stmt, token});
|
| return token;
|
| }
|
| @@ -255,11 +274,11 @@ class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject {
|
| }
|
|
|
| protected:
|
| - Node* NewPathTokenForDeferredCommand() {
|
| - return owner_->jsgraph()->Constant(static_cast<int>(deferred_.size()));
|
| + Node* NewPathToken(int token_id) {
|
| + return owner_->jsgraph()->Constant(token_id);
|
| }
|
| Node* NewPathTokenForImplicitFallThrough() {
|
| - return owner_->jsgraph()->Constant(-1);
|
| + return NewPathToken(TokenDispenserForFinally::kFallThroughToken);
|
| }
|
| Node* NewPathDispatchCondition(Node* t1, Node* t2) {
|
| // TODO(mstarzinger): This should be machine()->WordEqual(), but our Phi
|
| @@ -268,8 +287,11 @@ class AstGraphBuilder::ControlScope::DeferredCommands : public ZoneObject {
|
| }
|
|
|
| private:
|
| + TokenDispenserForFinally dispenser_;
|
| AstGraphBuilder* owner_;
|
| ZoneVector<Entry> deferred_;
|
| + Node* return_token_;
|
| + Node* throw_token_;
|
| };
|
|
|
|
|
| @@ -1487,7 +1509,7 @@ void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
|
| // The result value, dispatch token and message is expected on the operand
|
| // stack (this is in sync with FullCodeGenerator::EnterFinallyBlock).
|
| Node* message = NewNode(javascript()->LoadMessage());
|
| - environment()->Push(token); // TODO(mstarzinger): Cook token!
|
| + environment()->Push(token);
|
| environment()->Push(result);
|
| environment()->Push(message);
|
|
|
| @@ -1503,7 +1525,7 @@ void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
|
| // stack (this is in sync with FullCodeGenerator::ExitFinallyBlock).
|
| message = environment()->Pop();
|
| result = environment()->Pop();
|
| - token = environment()->Pop(); // TODO(mstarzinger): Uncook token!
|
| + token = environment()->Pop();
|
| NewNode(javascript()->StoreMessage(), message);
|
|
|
| // Dynamic dispatch after the finally-block.
|
|
|