| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
| 9 #include "vm/bit_vector.h" | 9 #include "vm/bit_vector.h" |
| 10 #include "vm/code_descriptors.h" | 10 #include "vm/code_descriptors.h" |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 | 535 |
| 536 | 536 |
| 537 Definition* EffectGraphVisitor::BuildLoadExprTemp() { | 537 Definition* EffectGraphVisitor::BuildLoadExprTemp() { |
| 538 return BuildLoadLocal(*owner()->parsed_function()->expression_temp_var()); | 538 return BuildLoadLocal(*owner()->parsed_function()->expression_temp_var()); |
| 539 } | 539 } |
| 540 | 540 |
| 541 | 541 |
| 542 Definition* EffectGraphVisitor::BuildStoreLocal( | 542 Definition* EffectGraphVisitor::BuildStoreLocal( |
| 543 const LocalVariable& local, Value* value, bool result_is_needed) { | 543 const LocalVariable& local, Value* value, bool result_is_needed) { |
| 544 if (local.is_captured()) { | 544 if (local.is_captured()) { |
| 545 InlineBailout("EffectGraphVisitor::BuildStoreLocal (context)"); | |
| 546 if (result_is_needed) { | 545 if (result_is_needed) { |
| 547 value = Bind(BuildStoreExprTemp(value)); | 546 value = Bind(BuildStoreExprTemp(value)); |
| 548 } | 547 } |
| 549 | 548 |
| 550 intptr_t delta = | 549 intptr_t delta = |
| 551 owner()->context_level() - local.owner()->context_level(); | 550 owner()->context_level() - local.owner()->context_level(); |
| 552 ASSERT(delta >= 0); | 551 ASSERT(delta >= 0); |
| 553 Value* context = Bind(new CurrentContextInstr()); | 552 Value* context = Bind(new CurrentContextInstr()); |
| 554 while (delta-- > 0) { | 553 while (delta-- > 0) { |
| 555 context = Bind(new LoadFieldInstr( | 554 context = Bind(new LoadFieldInstr( |
| (...skipping 12 matching lines...) Expand all Loading... |
| 568 return store; | 567 return store; |
| 569 } | 568 } |
| 570 } else { | 569 } else { |
| 571 return new StoreLocalInstr(local, value); | 570 return new StoreLocalInstr(local, value); |
| 572 } | 571 } |
| 573 } | 572 } |
| 574 | 573 |
| 575 | 574 |
| 576 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { | 575 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local) { |
| 577 if (local.is_captured()) { | 576 if (local.is_captured()) { |
| 578 InlineBailout("EffectGraphVisitor::BuildLoadLocal (context)"); | |
| 579 intptr_t delta = | 577 intptr_t delta = |
| 580 owner()->context_level() - local.owner()->context_level(); | 578 owner()->context_level() - local.owner()->context_level(); |
| 581 ASSERT(delta >= 0); | 579 ASSERT(delta >= 0); |
| 582 Value* context = Bind(new CurrentContextInstr()); | 580 Value* context = Bind(new CurrentContextInstr()); |
| 583 while (delta-- > 0) { | 581 while (delta-- > 0) { |
| 584 context = Bind(new LoadFieldInstr( | 582 context = Bind(new LoadFieldInstr( |
| 585 context, Context::parent_offset(), Type::ZoneHandle())); | 583 context, Context::parent_offset(), Type::ZoneHandle())); |
| 586 } | 584 } |
| 587 return new LoadFieldInstr(context, | 585 return new LoadFieldInstr(context, |
| 588 Context::variable_offset(local.index()), | 586 Context::variable_offset(local.index()), |
| 589 local.type()); | 587 local.type()); |
| 590 } else { | 588 } else { |
| 591 return new LoadLocalInstr(local); | 589 return new LoadLocalInstr(local); |
| 592 } | 590 } |
| 593 } | 591 } |
| 594 | 592 |
| 595 | 593 |
| 596 // Stores current context into the 'variable' | 594 // Stores current context into the 'variable' |
| 597 void EffectGraphVisitor::BuildStoreContext(const LocalVariable& variable) { | 595 void EffectGraphVisitor::BuildSaveContext(const LocalVariable& variable) { |
| 598 Value* context = Bind(new CurrentContextInstr()); | 596 Value* context = Bind(new CurrentContextInstr()); |
| 599 Do(BuildStoreLocal(variable, context, kResultNotNeeded)); | 597 Do(BuildStoreLocal(variable, context, kResultNotNeeded)); |
| 600 } | 598 } |
| 601 | 599 |
| 602 | 600 |
| 603 // Loads context saved in 'context_variable' into the current context. | 601 // Loads context saved in 'context_variable' into the current context. |
| 604 void EffectGraphVisitor::BuildLoadContext(const LocalVariable& variable) { | 602 void EffectGraphVisitor::BuildRestoreContext(const LocalVariable& variable) { |
| 605 Value* load_saved_context = Bind(BuildLoadLocal(variable)); | 603 Value* load_saved_context = Bind(BuildLoadLocal(variable)); |
| 606 AddInstruction(new StoreContextInstr(load_saved_context)); | 604 AddInstruction(new StoreContextInstr(load_saved_context)); |
| 607 } | 605 } |
| 608 | 606 |
| 609 | 607 |
| 610 void TestGraphVisitor::ConnectBranchesTo( | 608 void TestGraphVisitor::ConnectBranchesTo( |
| 611 const GrowableArray<TargetEntryInstr**>& branches, | 609 const GrowableArray<TargetEntryInstr**>& branches, |
| 612 JoinEntryInstr* join) const { | 610 JoinEntryInstr* join) const { |
| 613 ASSERT(!branches.is_empty()); | 611 ASSERT(!branches.is_empty()); |
| 614 for (intptr_t i = 0; i < branches.length(); i++) { | 612 for (intptr_t i = 0; i < branches.length(); i++) { |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 816 return_value, | 814 return_value, |
| 817 dst_type, | 815 dst_type, |
| 818 Symbols::FunctionResult()); | 816 Symbols::FunctionResult()); |
| 819 } | 817 } |
| 820 } | 818 } |
| 821 | 819 |
| 822 intptr_t current_context_level = owner()->context_level(); | 820 intptr_t current_context_level = owner()->context_level(); |
| 823 ASSERT(current_context_level >= 0); | 821 ASSERT(current_context_level >= 0); |
| 824 if (owner()->parsed_function()->saved_entry_context_var() != NULL) { | 822 if (owner()->parsed_function()->saved_entry_context_var() != NULL) { |
| 825 // CTX on entry was saved, but not linked as context parent. | 823 // CTX on entry was saved, but not linked as context parent. |
| 826 BuildLoadContext(*owner()->parsed_function()->saved_entry_context_var()); | 824 BuildRestoreContext(*owner()->parsed_function()->saved_entry_context_var()); |
| 827 } else { | 825 } else { |
| 828 while (current_context_level-- > 0) { | 826 while (current_context_level-- > 0) { |
| 829 UnchainContext(); | 827 UnchainContext(); |
| 830 } | 828 } |
| 831 } | 829 } |
| 832 | 830 |
| 833 AddReturnExit(node->token_pos(), return_value); | 831 AddReturnExit(node->token_pos(), return_value); |
| 834 } | 832 } |
| 835 | 833 |
| 836 | 834 |
| (...skipping 1294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2131 Append(for_closure); | 2129 Append(for_closure); |
| 2132 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); | 2130 PushArgumentInstr* push_closure = PushArgument(for_closure.value()); |
| 2133 | 2131 |
| 2134 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2132 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2135 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 2133 new ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 2136 arguments->Add(push_closure); | 2134 arguments->Add(push_closure); |
| 2137 BuildPushArguments(*node->arguments(), arguments); | 2135 BuildPushArguments(*node->arguments(), arguments); |
| 2138 | 2136 |
| 2139 // Save context around the call. | 2137 // Save context around the call. |
| 2140 ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL); | 2138 ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL); |
| 2141 BuildStoreContext(*owner()->parsed_function()->saved_current_context_var()); | 2139 BuildSaveContext(*owner()->parsed_function()->saved_current_context_var()); |
| 2142 return new ClosureCallInstr(node, arguments); | 2140 return new ClosureCallInstr(node, arguments); |
| 2143 } | 2141 } |
| 2144 | 2142 |
| 2145 | 2143 |
| 2146 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 2144 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 2147 Do(BuildClosureCall(node)); | 2145 Do(BuildClosureCall(node)); |
| 2148 // Restore context from saved location. | 2146 // Restore context from saved location. |
| 2149 ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL); | 2147 ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL); |
| 2150 BuildLoadContext(*owner()->parsed_function()->saved_current_context_var()); | 2148 BuildRestoreContext(*owner()->parsed_function()->saved_current_context_var()); |
| 2151 } | 2149 } |
| 2152 | 2150 |
| 2153 | 2151 |
| 2154 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 2152 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 2155 Value* result = Bind(BuildClosureCall(node)); | 2153 Value* result = Bind(BuildClosureCall(node)); |
| 2156 // Restore context from temp. | 2154 // Restore context from temp. |
| 2157 ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL); | 2155 ASSERT(owner()->parsed_function()->saved_current_context_var() != NULL); |
| 2158 BuildLoadContext(*owner()->parsed_function()->saved_current_context_var()); | 2156 BuildRestoreContext(*owner()->parsed_function()->saved_current_context_var()); |
| 2159 ReturnValue(result); | 2157 ReturnValue(result); |
| 2160 } | 2158 } |
| 2161 | 2159 |
| 2162 | 2160 |
| 2163 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { | 2161 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
| 2164 InlineBailout("EffectGraphVisitor::VisitCloneContextNode (context)"); | |
| 2165 Value* context = Bind(new CurrentContextInstr()); | 2162 Value* context = Bind(new CurrentContextInstr()); |
| 2166 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); | 2163 Value* clone = Bind(new CloneContextInstr(node->token_pos(), context)); |
| 2167 AddInstruction(new StoreContextInstr(clone)); | 2164 AddInstruction(new StoreContextInstr(clone)); |
| 2168 } | 2165 } |
| 2169 | 2166 |
| 2170 | 2167 |
| 2171 Value* EffectGraphVisitor::BuildObjectAllocation( | 2168 Value* EffectGraphVisitor::BuildObjectAllocation( |
| 2172 ConstructorCallNode* node) { | 2169 ConstructorCallNode* node) { |
| 2173 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); | 2170 const Class& cls = Class::ZoneHandle(node->constructor().Owner()); |
| 2174 const bool requires_type_arguments = cls.HasTypeArguments(); | 2171 const bool requires_type_arguments = cls.HasTypeArguments(); |
| (...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3061 } | 3058 } |
| 3062 | 3059 |
| 3063 | 3060 |
| 3064 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { | 3061 bool EffectGraphVisitor::MustSaveRestoreContext(SequenceNode* node) const { |
| 3065 return (node == owner()->parsed_function()->node_sequence()) && | 3062 return (node == owner()->parsed_function()->node_sequence()) && |
| 3066 (owner()->parsed_function()->saved_entry_context_var() != NULL); | 3063 (owner()->parsed_function()->saved_entry_context_var() != NULL); |
| 3067 } | 3064 } |
| 3068 | 3065 |
| 3069 | 3066 |
| 3070 void EffectGraphVisitor::UnchainContext() { | 3067 void EffectGraphVisitor::UnchainContext() { |
| 3071 InlineBailout("EffectGraphVisitor::UnchainContext (context)"); | |
| 3072 Value* context = Bind(new CurrentContextInstr()); | 3068 Value* context = Bind(new CurrentContextInstr()); |
| 3073 Value* parent = Bind( | 3069 Value* parent = Bind( |
| 3074 new LoadFieldInstr(context, | 3070 new LoadFieldInstr(context, |
| 3075 Context::parent_offset(), | 3071 Context::parent_offset(), |
| 3076 Type::ZoneHandle())); // Not an instance, no type. | 3072 Type::ZoneHandle())); // Not an instance, no type. |
| 3077 AddInstruction(new StoreContextInstr(parent)); | 3073 AddInstruction(new StoreContextInstr(parent)); |
| 3078 } | 3074 } |
| 3079 | 3075 |
| 3080 | 3076 |
| 3081 // <Statement> ::= Sequence { scope: LocalScope | 3077 // <Statement> ::= Sequence { scope: LocalScope |
| 3082 // nodes: <Statement>* | 3078 // nodes: <Statement>* |
| 3083 // label: SourceLabel } | 3079 // label: SourceLabel } |
| 3084 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { | 3080 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) { |
| 3085 LocalScope* scope = node->scope(); | 3081 LocalScope* scope = node->scope(); |
| 3086 const intptr_t num_context_variables = | 3082 const intptr_t num_context_variables = |
| 3087 (scope != NULL) ? scope->num_context_variables() : 0; | 3083 (scope != NULL) ? scope->num_context_variables() : 0; |
| 3088 int previous_context_level = owner()->context_level(); | 3084 int previous_context_level = owner()->context_level(); |
| 3089 if (num_context_variables > 0) { | 3085 if (num_context_variables > 0) { |
| 3090 InlineBailout("EffectGraphVisitor::VisitSequenceNode (context)"); | |
| 3091 // The loop local scope declares variables that are captured. | 3086 // The loop local scope declares variables that are captured. |
| 3092 // Allocate and chain a new context. | 3087 // Allocate and chain a new context. |
| 3093 // Allocate context computation (uses current CTX) | 3088 // Allocate context computation (uses current CTX) |
| 3094 Value* allocated_context = | 3089 Value* allocated_context = |
| 3095 Bind(new AllocateContextInstr(node->token_pos(), | 3090 Bind(new AllocateContextInstr(node->token_pos(), |
| 3096 num_context_variables)); | 3091 num_context_variables)); |
| 3097 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context); | 3092 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context); |
| 3098 // If this node_sequence is the body of the function being compiled, and | 3093 // If this node_sequence is the body of the function being compiled, and |
| 3099 // if this function allocates context variables, but none of its enclosing | 3094 // if this function allocates context variables, but none of its enclosing |
| 3100 // functions do, the context on entry is not linked as parent of the | 3095 // functions do, the context on entry is not linked as parent of the |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3198 Append(for_effect); | 3193 Append(for_effect); |
| 3199 if (!is_open()) { | 3194 if (!is_open()) { |
| 3200 // E.g., because of a JumpNode. | 3195 // E.g., because of a JumpNode. |
| 3201 break; | 3196 break; |
| 3202 } | 3197 } |
| 3203 } | 3198 } |
| 3204 | 3199 |
| 3205 if (is_open()) { | 3200 if (is_open()) { |
| 3206 if (MustSaveRestoreContext(node)) { | 3201 if (MustSaveRestoreContext(node)) { |
| 3207 ASSERT(num_context_variables > 0); | 3202 ASSERT(num_context_variables > 0); |
| 3208 BuildLoadContext(*owner()->parsed_function()->saved_entry_context_var()); | 3203 BuildRestoreContext( |
| 3204 *owner()->parsed_function()->saved_entry_context_var()); |
| 3209 } else if (num_context_variables > 0) { | 3205 } else if (num_context_variables > 0) { |
| 3210 UnchainContext(); | 3206 UnchainContext(); |
| 3211 } | 3207 } |
| 3212 } | 3208 } |
| 3213 | 3209 |
| 3214 // No continue on sequence allowed. | 3210 // No continue on sequence allowed. |
| 3215 ASSERT((node->label() == NULL) || | 3211 ASSERT((node->label() == NULL) || |
| 3216 (node->label()->join_for_continue() == NULL)); | 3212 (node->label()->join_for_continue() == NULL)); |
| 3217 // If this node sequence is labeled, a break out of the sequence will have | 3213 // If this node sequence is labeled, a break out of the sequence will have |
| 3218 // taken care of unchaining the context. | 3214 // taken care of unchaining the context. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3229 } | 3225 } |
| 3230 | 3226 |
| 3231 | 3227 |
| 3232 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { | 3228 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { |
| 3233 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); | 3229 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); |
| 3234 // NOTE: The implicit variables ':saved_context', ':exception_var' | 3230 // NOTE: The implicit variables ':saved_context', ':exception_var' |
| 3235 // and ':stacktrace_var' can never be captured variables. | 3231 // and ':stacktrace_var' can never be captured variables. |
| 3236 // Restores CTX from local variable ':saved_context'. | 3232 // Restores CTX from local variable ':saved_context'. |
| 3237 AddInstruction( | 3233 AddInstruction( |
| 3238 new CatchEntryInstr(node->exception_var(), node->stacktrace_var())); | 3234 new CatchEntryInstr(node->exception_var(), node->stacktrace_var())); |
| 3239 BuildLoadContext(node->context_var()); | 3235 BuildRestoreContext(node->context_var()); |
| 3240 | 3236 |
| 3241 EffectGraphVisitor for_catch(owner(), temp_index()); | 3237 EffectGraphVisitor for_catch(owner(), temp_index()); |
| 3242 node->VisitChildren(&for_catch); | 3238 node->VisitChildren(&for_catch); |
| 3243 Append(for_catch); | 3239 Append(for_catch); |
| 3244 } | 3240 } |
| 3245 | 3241 |
| 3246 | 3242 |
| 3247 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { | 3243 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { |
| 3248 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); | 3244 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); |
| 3249 intptr_t original_handler_index = owner()->try_index(); | 3245 intptr_t original_handler_index = owner()->try_index(); |
| 3250 intptr_t try_handler_index = owner()->AllocateTryIndex(); | 3246 intptr_t try_handler_index = owner()->AllocateTryIndex(); |
| 3251 owner()->set_try_index(try_handler_index); | 3247 owner()->set_try_index(try_handler_index); |
| 3252 | 3248 |
| 3253 // Preserve CTX into local variable '%saved_context'. | 3249 // Preserve CTX into local variable '%saved_context'. |
| 3254 BuildStoreContext(node->context_var()); | 3250 BuildSaveContext(node->context_var()); |
| 3255 | 3251 |
| 3256 EffectGraphVisitor for_try(owner(), temp_index()); | 3252 EffectGraphVisitor for_try(owner(), temp_index()); |
| 3257 node->try_block()->Visit(&for_try); | 3253 node->try_block()->Visit(&for_try); |
| 3258 | 3254 |
| 3259 if (for_try.is_open()) { | 3255 if (for_try.is_open()) { |
| 3260 JoinEntryInstr* after_try = | 3256 JoinEntryInstr* after_try = |
| 3261 new JoinEntryInstr(owner()->AllocateBlockId(), original_handler_index); | 3257 new JoinEntryInstr(owner()->AllocateBlockId(), original_handler_index); |
| 3262 for_try.Goto(after_try); | 3258 for_try.Goto(after_try); |
| 3263 for_try.exit_ = after_try; | 3259 for_try.exit_ = after_try; |
| 3264 } | 3260 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3301 } | 3297 } |
| 3302 | 3298 |
| 3303 if (finally_block != NULL) { | 3299 if (finally_block != NULL) { |
| 3304 // Create a handler for the code in the catch block, containing the | 3300 // Create a handler for the code in the catch block, containing the |
| 3305 // code in the finally block. | 3301 // code in the finally block. |
| 3306 owner()->set_try_index(original_handler_index); | 3302 owner()->set_try_index(original_handler_index); |
| 3307 EffectGraphVisitor for_finally(owner(), temp_index()); | 3303 EffectGraphVisitor for_finally(owner(), temp_index()); |
| 3308 for_finally.AddInstruction( | 3304 for_finally.AddInstruction( |
| 3309 new CatchEntryInstr(catch_block->exception_var(), | 3305 new CatchEntryInstr(catch_block->exception_var(), |
| 3310 catch_block->stacktrace_var())); | 3306 catch_block->stacktrace_var())); |
| 3311 for_finally.BuildLoadContext(catch_block->context_var()); | 3307 for_finally.BuildRestoreContext(catch_block->context_var()); |
| 3312 | 3308 |
| 3313 finally_block->Visit(&for_finally); | 3309 finally_block->Visit(&for_finally); |
| 3314 if (for_finally.is_open()) { | 3310 if (for_finally.is_open()) { |
| 3315 // Rethrow the exception. Manually build the graph for rethrow. | 3311 // Rethrow the exception. Manually build the graph for rethrow. |
| 3316 Value* exception = for_finally.Bind( | 3312 Value* exception = for_finally.Bind( |
| 3317 for_finally.BuildLoadLocal(catch_block->exception_var())); | 3313 for_finally.BuildLoadLocal(catch_block->exception_var())); |
| 3318 for_finally.PushArgument(exception); | 3314 for_finally.PushArgument(exception); |
| 3319 Value* stacktrace = for_finally.Bind( | 3315 Value* stacktrace = for_finally.Bind( |
| 3320 for_finally.BuildLoadLocal(catch_block->stacktrace_var())); | 3316 for_finally.BuildLoadLocal(catch_block->stacktrace_var())); |
| 3321 for_finally.PushArgument(stacktrace); | 3317 for_finally.PushArgument(stacktrace); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3471 | 3467 |
| 3472 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { | 3468 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { |
| 3473 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode (exception)"); | 3469 InlineBailout("EffectGraphVisitor::VisitInlinedFinallyNode (exception)"); |
| 3474 const intptr_t try_index = owner()->try_index(); | 3470 const intptr_t try_index = owner()->try_index(); |
| 3475 if (try_index >= 0) { | 3471 if (try_index >= 0) { |
| 3476 // We are about to generate code for an inlined finally block. Exceptions | 3472 // We are about to generate code for an inlined finally block. Exceptions |
| 3477 // thrown in this block of code should be treated as though they are | 3473 // thrown in this block of code should be treated as though they are |
| 3478 // thrown not from the current try block but the outer try block if any. | 3474 // thrown not from the current try block but the outer try block if any. |
| 3479 owner()->set_try_index((try_index - 1)); | 3475 owner()->set_try_index((try_index - 1)); |
| 3480 } | 3476 } |
| 3481 BuildLoadContext(node->context_var()); | 3477 BuildRestoreContext(node->context_var()); |
| 3482 | 3478 |
| 3483 JoinEntryInstr* finally_entry = | 3479 JoinEntryInstr* finally_entry = |
| 3484 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); | 3480 new JoinEntryInstr(owner()->AllocateBlockId(), owner()->try_index()); |
| 3485 EffectGraphVisitor for_finally_block(owner(), temp_index()); | 3481 EffectGraphVisitor for_finally_block(owner(), temp_index()); |
| 3486 node->finally_block()->Visit(&for_finally_block); | 3482 node->finally_block()->Visit(&for_finally_block); |
| 3487 | 3483 |
| 3488 if (try_index >= 0) { | 3484 if (try_index >= 0) { |
| 3489 owner()->set_try_index(try_index); | 3485 owner()->set_try_index(try_index); |
| 3490 } | 3486 } |
| 3491 | 3487 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3554 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 3550 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 3555 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 3551 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 3556 OS::SNPrint(chars, len, kFormat, function_name, reason); | 3552 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 3557 const Error& error = Error::Handle( | 3553 const Error& error = Error::Handle( |
| 3558 LanguageError::New(String::Handle(String::New(chars)))); | 3554 LanguageError::New(String::Handle(String::New(chars)))); |
| 3559 Isolate::Current()->long_jump_base()->Jump(1, error); | 3555 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 3560 } | 3556 } |
| 3561 | 3557 |
| 3562 | 3558 |
| 3563 } // namespace dart | 3559 } // namespace dart |
| OLD | NEW |