Chromium Code Reviews| Index: runtime/vm/kernel_to_il.cc |
| diff --git a/runtime/vm/kernel_to_il.cc b/runtime/vm/kernel_to_il.cc |
| index 02f54379e86e50ca0231e41aa207ddafc84e2afb..d194dfb81d9bf3ed9f1e31530a19c335ea4f017b 100644 |
| --- a/runtime/vm/kernel_to_il.cc |
| +++ b/runtime/vm/kernel_to_il.cc |
| @@ -845,7 +845,8 @@ class TryFinallyBlock { |
| // Finalizers are executed outside of the try block hence |
| // try depth of finalizers are one less than current try |
| // depth. |
| - try_depth_(builder->try_depth_ - 1) { |
| + try_depth_(builder->try_depth_ - 1), |
| + try_index_(builder_->CurrentTryIndex()) { |
| builder_->try_finally_block_ = this; |
| } |
| ~TryFinallyBlock() { builder_->try_finally_block_ = outer_; } |
| @@ -853,6 +854,7 @@ class TryFinallyBlock { |
| Statement* finalizer() const { return finalizer_; } |
| intptr_t context_depth() const { return context_depth_; } |
| intptr_t try_depth() const { return try_depth_; } |
| + intptr_t try_index() const { return try_depth_; } |
|
Kevin Millikin (Google)
2016/11/09 12:30:02
return try_index_
kustermann
2016/11/11 19:41:35
Thanks for catching this! I've modified the test t
|
| TryFinallyBlock* outer() const { return outer_; } |
| private: |
| @@ -861,6 +863,7 @@ class TryFinallyBlock { |
| Statement* const finalizer_; |
| const intptr_t context_depth_; |
| const intptr_t try_depth_; |
| + const intptr_t try_index_; |
| }; |
| @@ -876,7 +879,8 @@ class TryCatchBlock { |
| } |
| ~TryCatchBlock() { builder_->try_catch_block_ = outer_; } |
| - intptr_t TryIndex() { return try_index_; } |
| + intptr_t try_index() { return try_index_; } |
| + TryCatchBlock* outer() const { return outer_; } |
| private: |
| FlowGraphBuilder* builder_; |
| @@ -1844,6 +1848,7 @@ FlowGraphBuilder::~FlowGraphBuilder() {} |
| Fragment FlowGraphBuilder::TranslateFinallyFinalizers( |
| TryFinallyBlock* outer_finally, intptr_t target_context_depth) { |
| TryFinallyBlock* const saved_block = try_finally_block_; |
| + TryCatchBlock* const saved_try_catch_block = try_catch_block_; |
| const intptr_t saved_depth = context_depth_; |
| const intptr_t saved_try_depth = try_depth_; |
| @@ -1862,6 +1867,22 @@ Fragment FlowGraphBuilder::TranslateFinallyFinalizers( |
| Statement* finalizer = try_finally_block_->finalizer(); |
| try_finally_block_ = try_finally_block_->outer(); |
| + // The to-be-translated finalizer has to have the correct try-index (namely |
| + // the one outside the try-finally block). |
| + bool changed_try_index = false; |
| + intptr_t target_try_index = try_finally_block_ == NULL |
| + ? CatchClauseNode::kInvalidTryIndex |
| + : try_finally_block_->try_index(); |
| + while (CurrentTryIndex() != target_try_index) { |
| + try_catch_block_ = try_catch_block_->outer(); |
| + changed_try_index = true; |
| + } |
| + if (changed_try_index) { |
| + JoinEntryInstr* entry = BuildJoinEntry(); |
| + instructions += Goto(entry); |
| + instructions = Fragment(instructions.entry, entry); |
| + } |
| + |
| // This will potentially have exceptional cases as described in |
| // [VisitTryFinally] and will handle them. |
| instructions += TranslateStatement(finalizer); |
| @@ -1872,13 +1893,14 @@ Fragment FlowGraphBuilder::TranslateFinallyFinalizers( |
| } |
| if (instructions.is_open() && target_context_depth != -1) { |
| - // A target context depth of -1 indicates that we the code after this |
| + // A target context depth of -1 indicates that the code after this |
| // will not care about the context chain so we can leave it any way we |
| // want after the last finalizer. That is used when returning. |
| instructions += AdjustContextTo(target_context_depth); |
| } |
| try_finally_block_ = saved_block; |
| + try_catch_block_ = saved_try_catch_block; |
| context_depth_ = saved_depth; |
| try_depth_ = saved_try_depth; |
| @@ -2659,7 +2681,7 @@ intptr_t FlowGraphBuilder::CurrentTryIndex() { |
| if (try_catch_block_ == NULL) { |
| return CatchClauseNode::kInvalidTryIndex; |
| } else { |
| - return try_catch_block_->TryIndex(); |
| + return try_catch_block_->try_index(); |
| } |
| } |
| @@ -5420,8 +5442,8 @@ void FlowGraphBuilder::VisitTryFinally(TryFinally* node) { |
| // Fill in the body of the try. |
| ++try_depth_; |
| { |
| - TryCatchBlock tcb(this, try_handler_index); |
| TryFinallyBlock tfb(this, node->finalizer()); |
| + TryCatchBlock tcb(this, try_handler_index); |
| try_body += TranslateStatement(node->body()); |
| } |
| --try_depth_; |