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