Chromium Code Reviews| 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()); |