Index: runtime/vm/flow_graph_builder.cc |
=================================================================== |
--- runtime/vm/flow_graph_builder.cc (revision 25871) |
+++ runtime/vm/flow_graph_builder.cc (working copy) |
@@ -3298,11 +3298,7 @@ |
void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { |
InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); |
- // NOTE: The implicit variables ':saved_context', ':exception_var' |
- // and ':stacktrace_var' can never be captured variables. |
// Restores CTX from local variable ':saved_context'. |
- AddInstruction( |
- new CatchEntryInstr(node->exception_var(), node->stacktrace_var())); |
BuildRestoreContext(node->context_var()); |
EffectGraphVisitor for_catch(owner(), temp_index()); |
@@ -3343,67 +3339,74 @@ |
CatchClauseNode* catch_block = node->catch_block(); |
SequenceNode* finally_block = node->finally_block(); |
- if (catch_block != NULL) { |
- // If there is a finally block, it is the handler for code in the catch |
- // block. |
- intptr_t catch_handler_index = (finally_block == NULL) |
- ? original_handler_index |
- : catch_block->catch_handler_index(); |
- owner()->set_try_index(catch_handler_index); |
- EffectGraphVisitor for_catch(owner(), temp_index()); |
- catch_block->Visit(&for_catch); |
- CatchBlockEntryInstr* catch_entry = |
- new CatchBlockEntryInstr(owner()->AllocateBlockId(), |
- catch_handler_index, |
- catch_block->handler_types(), |
- try_handler_index); |
- owner()->AddCatchEntry(catch_entry); |
- ASSERT(!for_catch.is_open()); |
- AppendFragment(catch_entry, for_catch); |
- if (node->end_catch_label() != NULL) { |
- JoinEntryInstr* join = node->end_catch_label()->join_for_continue(); |
- if (join != NULL) { |
- if (is_open()) Goto(join); |
- exit_ = join; |
- } |
- } |
+ // If there is a finally block, it is the handler for code in the catch |
+ // block. |
+ intptr_t catch_handler_index = (finally_block == NULL) |
srdjan
2013/08/07 18:46:17
const
Florian Schneider
2013/08/08 07:39:57
Done.
|
+ ? original_handler_index |
+ : catch_block->catch_handler_index(); |
- if (finally_block != NULL) { |
- // Create a handler for the code in the catch block, containing the |
- // code in the finally block. |
- owner()->set_try_index(original_handler_index); |
- EffectGraphVisitor for_finally(owner(), temp_index()); |
- for_finally.AddInstruction( |
- new CatchEntryInstr(catch_block->exception_var(), |
- catch_block->stacktrace_var())); |
- for_finally.BuildRestoreContext(catch_block->context_var()); |
+ owner()->set_try_index(catch_handler_index); |
+ EffectGraphVisitor for_catch(owner(), temp_index()); |
+ catch_block->Visit(&for_catch); |
- finally_block->Visit(&for_finally); |
- if (for_finally.is_open()) { |
- // Rethrow the exception. Manually build the graph for rethrow. |
- Value* exception = for_finally.Bind( |
- for_finally.BuildLoadLocal(catch_block->exception_var())); |
- for_finally.PushArgument(exception); |
- Value* stacktrace = for_finally.Bind( |
- for_finally.BuildLoadLocal(catch_block->stacktrace_var())); |
- for_finally.PushArgument(stacktrace); |
- for_finally.AddInstruction(new ReThrowInstr(catch_block->token_pos())); |
- for_finally.CloseFragment(); |
- } |
- ASSERT(!for_finally.is_open()); |
+ // NOTE: The implicit variables ':saved_context', ':exception_var' |
+ // and ':stacktrace_var' can never be captured variables. |
+ ASSERT(!catch_block->exception_var().is_captured()); |
+ ASSERT(!catch_block->stacktrace_var().is_captured()); |
- const Array& types = Array::ZoneHandle(Array::New(1, Heap::kOld)); |
- types.SetAt(0, Type::Handle(Type::DynamicType())); |
- CatchBlockEntryInstr* finally_entry = |
- new CatchBlockEntryInstr(owner()->AllocateBlockId(), |
- original_handler_index, |
- types, |
- catch_handler_index); |
- owner()->AddCatchEntry(finally_entry); |
- AppendFragment(finally_entry, for_finally); |
+ CatchBlockEntryInstr* catch_entry = |
+ new CatchBlockEntryInstr(owner()->AllocateBlockId(), |
+ catch_handler_index, |
+ catch_block->handler_types(), |
+ try_handler_index, |
+ catch_block->exception_var(), |
+ catch_block->stacktrace_var()); |
+ owner()->AddCatchEntry(catch_entry); |
+ ASSERT(!for_catch.is_open()); |
+ AppendFragment(catch_entry, for_catch); |
+ if (node->end_catch_label() != NULL) { |
+ JoinEntryInstr* join = node->end_catch_label()->join_for_continue(); |
+ if (join != NULL) { |
+ if (is_open()) Goto(join); |
+ exit_ = join; |
} |
} |
+ |
+ if (finally_block != NULL) { |
+ // Create a handler for the code in the catch block, containing the |
+ // code in the finally block. |
+ owner()->set_try_index(original_handler_index); |
+ EffectGraphVisitor for_finally(owner(), temp_index()); |
+ for_finally.BuildRestoreContext(catch_block->context_var()); |
+ |
+ finally_block->Visit(&for_finally); |
+ if (for_finally.is_open()) { |
+ // Rethrow the exception. Manually build the graph for rethrow. |
+ Value* exception = for_finally.Bind( |
+ for_finally.BuildLoadLocal(catch_block->exception_var())); |
+ for_finally.PushArgument(exception); |
+ Value* stacktrace = for_finally.Bind( |
+ for_finally.BuildLoadLocal(catch_block->stacktrace_var())); |
+ for_finally.PushArgument(stacktrace); |
+ for_finally.AddInstruction(new ReThrowInstr(catch_block->token_pos())); |
+ for_finally.CloseFragment(); |
+ } |
+ ASSERT(!for_finally.is_open()); |
+ |
+ const Array& types = Array::ZoneHandle(Array::New(1, Heap::kOld)); |
+ types.SetAt(0, Type::Handle(Type::DynamicType())); |
+ CatchBlockEntryInstr* finally_entry = |
+ new CatchBlockEntryInstr(owner()->AllocateBlockId(), |
+ original_handler_index, |
+ types, |
+ catch_handler_index, |
+ catch_block->exception_var(), |
+ catch_block->stacktrace_var()); |
+ owner()->AddCatchEntry(finally_entry); |
+ AppendFragment(finally_entry, for_finally); |
+ } |
+ |
// Generate code for the finally block if one exists. |
if ((finally_block != NULL) && is_open()) { |
EffectGraphVisitor for_finally_block(owner(), temp_index()); |