Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(797)

Unified Diff: runtime/vm/kernel_to_il.cc

Issue 2487183002: VM: [Kernel] Ensure we have the correct try-index when translating finally blocks (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/kernel/unsorted/try_finally_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_;
« no previous file with comments | « no previous file | tests/kernel/unsorted/try_finally_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698