| 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/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 847 | 847 |
| 848 | 848 |
| 849 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local, | 849 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local, |
| 850 Value* value, | 850 Value* value, |
| 851 intptr_t token_pos) { | 851 intptr_t token_pos) { |
| 852 if (local.is_captured()) { | 852 if (local.is_captured()) { |
| 853 LocalVariable* tmp_var = EnterTempLocalScope(value); | 853 LocalVariable* tmp_var = EnterTempLocalScope(value); |
| 854 intptr_t delta = | 854 intptr_t delta = |
| 855 owner()->context_level() - local.owner()->context_level(); | 855 owner()->context_level() - local.owner()->context_level(); |
| 856 ASSERT(delta >= 0); | 856 ASSERT(delta >= 0); |
| 857 Value* context = Bind(BuildCurrentContext()); | 857 Value* context = Bind(BuildCurrentContext(token_pos)); |
| 858 while (delta-- > 0) { | 858 while (delta-- > 0) { |
| 859 context = Bind(new(Z) LoadFieldInstr( | 859 context = Bind(new(Z) LoadFieldInstr( |
| 860 context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()), | 860 context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()), |
| 861 token_pos)); | 861 token_pos)); |
| 862 } | 862 } |
| 863 Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var)); | 863 Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var)); |
| 864 StoreInstanceFieldInstr* store = | 864 StoreInstanceFieldInstr* store = |
| 865 new(Z) StoreInstanceFieldInstr(Context::variable_offset(local.index()), | 865 new(Z) StoreInstanceFieldInstr(Context::variable_offset(local.index()), |
| 866 context, | 866 context, |
| 867 tmp_val, | 867 tmp_val, |
| 868 kEmitStoreBarrier, | 868 kEmitStoreBarrier, |
| 869 token_pos); | 869 token_pos); |
| 870 Do(store); | 870 Do(store); |
| 871 return ExitTempLocalScope(tmp_var); | 871 return ExitTempLocalScope(tmp_var); |
| 872 } else { | 872 } else { |
| 873 return new(Z) StoreLocalInstr(local, value, token_pos); | 873 return new(Z) StoreLocalInstr(local, value, token_pos); |
| 874 } | 874 } |
| 875 } | 875 } |
| 876 | 876 |
| 877 | 877 |
| 878 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local, | 878 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local, |
| 879 intptr_t token_pos) { | 879 intptr_t token_pos) { |
| 880 if (local.IsConst()) { | 880 if (local.IsConst()) { |
| 881 return new(Z) ConstantInstr(*local.ConstValue(), token_pos); | 881 return new(Z) ConstantInstr(*local.ConstValue(), token_pos); |
| 882 } else if (local.is_captured()) { | 882 } else if (local.is_captured()) { |
| 883 intptr_t delta = | 883 intptr_t delta = |
| 884 owner()->context_level() - local.owner()->context_level(); | 884 owner()->context_level() - local.owner()->context_level(); |
| 885 ASSERT(delta >= 0); | 885 ASSERT(delta >= 0); |
| 886 Value* context = Bind(BuildCurrentContext()); | 886 Value* context = Bind(BuildCurrentContext(token_pos)); |
| 887 while (delta-- > 0) { | 887 while (delta-- > 0) { |
| 888 context = Bind(new(Z) LoadFieldInstr( | 888 context = Bind(new(Z) LoadFieldInstr( |
| 889 context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()), | 889 context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()), |
| 890 token_pos)); | 890 token_pos)); |
| 891 } | 891 } |
| 892 return new(Z) LoadFieldInstr(context, | 892 return new(Z) LoadFieldInstr(context, |
| 893 Context::variable_offset(local.index()), | 893 Context::variable_offset(local.index()), |
| 894 local.type(), | 894 local.type(), |
| 895 token_pos); | 895 token_pos); |
| 896 } else { | 896 } else { |
| 897 return new(Z) LoadLocalInstr(local, token_pos); | 897 return new(Z) LoadLocalInstr(local, token_pos); |
| 898 } | 898 } |
| 899 } | 899 } |
| 900 | 900 |
| 901 | 901 |
| 902 // Stores current context into the 'variable' | 902 // Stores current context into the 'variable' |
| 903 void EffectGraphVisitor::BuildSaveContext(const LocalVariable& variable) { | 903 void EffectGraphVisitor::BuildSaveContext( |
| 904 Value* context = Bind(BuildCurrentContext()); | 904 const LocalVariable& variable, |
| 905 Do(BuildStoreLocal(variable, context)); | 905 intptr_t token_pos) { |
| 906 Value* context = Bind(BuildCurrentContext(token_pos)); |
| 907 Do(BuildStoreLocal(variable, context, token_pos)); |
| 906 } | 908 } |
| 907 | 909 |
| 908 | 910 |
| 909 // Loads context saved in 'context_variable' into the current context. | 911 // Loads context saved in 'context_variable' into the current context. |
| 910 void EffectGraphVisitor::BuildRestoreContext(const LocalVariable& variable) { | 912 void EffectGraphVisitor::BuildRestoreContext( |
| 911 Value* load_saved_context = Bind(BuildLoadLocal(variable)); | 913 const LocalVariable& variable, |
| 912 Do(BuildStoreContext(load_saved_context)); | 914 intptr_t token_pos) { |
| 915 Value* load_saved_context = Bind(BuildLoadLocal(variable, token_pos)); |
| 916 Do(BuildStoreContext(load_saved_context, token_pos)); |
| 913 } | 917 } |
| 914 | 918 |
| 915 | 919 |
| 916 Definition* EffectGraphVisitor::BuildStoreContext(Value* value) { | 920 Definition* EffectGraphVisitor::BuildStoreContext( |
| 921 Value* value, intptr_t token_pos) { |
| 917 return new(Z) StoreLocalInstr( | 922 return new(Z) StoreLocalInstr( |
| 918 *owner()->parsed_function().current_context_var(), value); | 923 *owner()->parsed_function().current_context_var(), value, token_pos); |
| 919 } | 924 } |
| 920 | 925 |
| 921 | 926 |
| 922 Definition* EffectGraphVisitor::BuildCurrentContext() { | 927 Definition* EffectGraphVisitor::BuildCurrentContext(intptr_t token_pos) { |
| 923 return new(Z) LoadLocalInstr( | 928 return new(Z) LoadLocalInstr( |
| 924 *owner()->parsed_function().current_context_var()); | 929 *owner()->parsed_function().current_context_var(), |
| 930 token_pos); |
| 925 } | 931 } |
| 926 | 932 |
| 927 | 933 |
| 928 void TestGraphVisitor::ConnectBranchesTo( | 934 void TestGraphVisitor::ConnectBranchesTo( |
| 929 const GrowableArray<TargetEntryInstr**>& branches, | 935 const GrowableArray<TargetEntryInstr**>& branches, |
| 930 JoinEntryInstr* join) const { | 936 JoinEntryInstr* join) const { |
| 931 ASSERT(!branches.is_empty()); | 937 ASSERT(!branches.is_empty()); |
| 932 for (intptr_t i = 0; i < branches.length(); i++) { | 938 for (intptr_t i = 0; i < branches.length(); i++) { |
| 933 TargetEntryInstr* target = | 939 TargetEntryInstr* target = |
| 934 new(Z) TargetEntryInstr(owner()->AllocateBlockId(), | 940 new(Z) TargetEntryInstr(owner()->AllocateBlockId(), |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1119 (node->token_pos() >= 0) && !function.is_native()) { | 1125 (node->token_pos() >= 0) && !function.is_native()) { |
| 1120 AddInstruction(new(Z) DebugStepCheckInstr(node->token_pos(), | 1126 AddInstruction(new(Z) DebugStepCheckInstr(node->token_pos(), |
| 1121 RawPcDescriptors::kRuntimeCall)); | 1127 RawPcDescriptors::kRuntimeCall)); |
| 1122 } | 1128 } |
| 1123 | 1129 |
| 1124 NestedContextAdjustment context_adjustment(owner(), owner()->context_level()); | 1130 NestedContextAdjustment context_adjustment(owner(), owner()->context_level()); |
| 1125 | 1131 |
| 1126 if (node->inlined_finally_list_length() > 0) { | 1132 if (node->inlined_finally_list_length() > 0) { |
| 1127 LocalVariable* temp = owner()->parsed_function().finally_return_temp_var(); | 1133 LocalVariable* temp = owner()->parsed_function().finally_return_temp_var(); |
| 1128 ASSERT(temp != NULL); | 1134 ASSERT(temp != NULL); |
| 1129 Do(BuildStoreLocal(*temp, return_value)); | 1135 Do(BuildStoreLocal(*temp, return_value, node->token_pos())); |
| 1130 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { | 1136 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) { |
| 1131 InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)"); | 1137 InlineBailout("EffectGraphVisitor::VisitReturnNode (exception)"); |
| 1132 EffectGraphVisitor for_effect(owner()); | 1138 EffectGraphVisitor for_effect(owner()); |
| 1133 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); | 1139 node->InlinedFinallyNodeAt(i)->Visit(&for_effect); |
| 1134 Append(for_effect); | 1140 Append(for_effect); |
| 1135 if (!is_open()) { | 1141 if (!is_open()) { |
| 1136 return; | 1142 return; |
| 1137 } | 1143 } |
| 1138 } | 1144 } |
| 1139 return_value = Bind(BuildLoadLocal(*temp)); | 1145 return_value = Bind(BuildLoadLocal(*temp, node->token_pos())); |
| 1140 } | 1146 } |
| 1141 | 1147 |
| 1142 if (Isolate::Current()->flags().type_checks()) { | 1148 if (Isolate::Current()->flags().type_checks()) { |
| 1143 const bool is_implicit_dynamic_getter = | 1149 const bool is_implicit_dynamic_getter = |
| 1144 (!function.is_static() && | 1150 (!function.is_static() && |
| 1145 ((function.kind() == RawFunction::kImplicitGetter) || | 1151 ((function.kind() == RawFunction::kImplicitGetter) || |
| 1146 (function.kind() == RawFunction::kImplicitStaticFinalGetter))); | 1152 (function.kind() == RawFunction::kImplicitStaticFinalGetter))); |
| 1147 // Implicit getters do not need a type check at return, unless they compute | 1153 // Implicit getters do not need a type check at return, unless they compute |
| 1148 // the initial value of a static field. | 1154 // the initial value of a static field. |
| 1149 // The body of a constructor cannot modify the type of the | 1155 // The body of a constructor cannot modify the type of the |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1171 if (function.IsAsyncClosure() && | 1177 if (function.IsAsyncClosure() && |
| 1172 (node->return_type() == ReturnNode::kRegular)) { | 1178 (node->return_type() == ReturnNode::kRegular)) { |
| 1173 // Temporary store the computed return value. | 1179 // Temporary store the computed return value. |
| 1174 Do(BuildStoreExprTemp(return_value)); | 1180 Do(BuildStoreExprTemp(return_value)); |
| 1175 | 1181 |
| 1176 LocalVariable* rcv_var = | 1182 LocalVariable* rcv_var = |
| 1177 node->scope()->LookupVariable(Symbols::AsyncCompleter(), false); | 1183 node->scope()->LookupVariable(Symbols::AsyncCompleter(), false); |
| 1178 ASSERT(rcv_var != NULL && rcv_var->is_captured()); | 1184 ASSERT(rcv_var != NULL && rcv_var->is_captured()); |
| 1179 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1185 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1180 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); | 1186 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1181 Value* rcv_value = Bind(BuildLoadLocal(*rcv_var)); | 1187 Value* rcv_value = Bind(BuildLoadLocal(*rcv_var, node->token_pos())); |
| 1182 arguments->Add(PushArgument(rcv_value)); | 1188 arguments->Add(PushArgument(rcv_value)); |
| 1183 Value* returned_value = Bind(BuildLoadExprTemp()); | 1189 Value* returned_value = Bind(BuildLoadExprTemp()); |
| 1184 arguments->Add(PushArgument(returned_value)); | 1190 arguments->Add(PushArgument(returned_value)); |
| 1185 InstanceCallInstr* call = new(Z) InstanceCallInstr( | 1191 InstanceCallInstr* call = new(Z) InstanceCallInstr( |
| 1186 Scanner::kNoSourcePos, | 1192 node->token_pos(), |
| 1187 Symbols::CompleterComplete(), | 1193 Symbols::CompleterComplete(), |
| 1188 Token::kILLEGAL, | 1194 Token::kILLEGAL, |
| 1189 arguments, | 1195 arguments, |
| 1190 Object::null_array(), | 1196 Object::null_array(), |
| 1191 1, | 1197 1, |
| 1192 owner()->ic_data_array()); | 1198 owner()->ic_data_array()); |
| 1193 Do(call); | 1199 Do(call); |
| 1194 | 1200 |
| 1195 // Rebind the return value for the actual return call to be null. | 1201 // Rebind the return value for the actual return call to be null. |
| 1196 return_value = BuildNullValue(); | 1202 return_value = BuildNullValue(); |
| (...skipping 1081 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2278 const intptr_t jump_count = owner()->next_await_counter(); | 2284 const intptr_t jump_count = owner()->next_await_counter(); |
| 2279 ASSERT(jump_count >= 0); | 2285 ASSERT(jump_count >= 0); |
| 2280 // Sanity check that we always add a JoinEntryInstr before adding a new | 2286 // Sanity check that we always add a JoinEntryInstr before adding a new |
| 2281 // state. | 2287 // state. |
| 2282 ASSERT(jump_count == owner()->await_joins()->length()); | 2288 ASSERT(jump_count == owner()->await_joins()->length()); |
| 2283 // Store the counter in :await_jump_var. | 2289 // Store the counter in :await_jump_var. |
| 2284 Value* jump_val = Bind(new(Z) ConstantInstr( | 2290 Value* jump_val = Bind(new(Z) ConstantInstr( |
| 2285 Smi::ZoneHandle(Z, Smi::New(jump_count)))); | 2291 Smi::ZoneHandle(Z, Smi::New(jump_count)))); |
| 2286 Do(BuildStoreLocal(*jump_var, jump_val)); | 2292 Do(BuildStoreLocal(*jump_var, jump_val)); |
| 2287 // Save the current context for resuming. | 2293 // Save the current context for resuming. |
| 2288 BuildSaveContext(*ctx_var); | 2294 BuildSaveContext(*ctx_var, node->token_pos()); |
| 2289 } | 2295 } |
| 2290 | 2296 |
| 2291 | 2297 |
| 2292 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const { | 2298 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const { |
| 2293 return kFirstLocalSlotFromFp | 2299 return kFirstLocalSlotFromFp |
| 2294 - owner()->num_stack_locals() | 2300 - owner()->num_stack_locals() |
| 2295 - owner()->num_copied_params() | 2301 - owner()->num_copied_params() |
| 2296 - owner()->args_pushed() | 2302 - owner()->args_pushed() |
| 2297 - owner()->temp_count() + 1; | 2303 - owner()->temp_count() + 1; |
| 2298 } | 2304 } |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2554 context_tmp_val = Bind(new(Z) LoadLocalInstr(*context_tmp_var)); | 2560 context_tmp_val = Bind(new(Z) LoadLocalInstr(*context_tmp_var)); |
| 2555 Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(), | 2561 Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(), |
| 2556 closure_tmp_val, | 2562 closure_tmp_val, |
| 2557 context_tmp_val, | 2563 context_tmp_val, |
| 2558 kEmitStoreBarrier, | 2564 kEmitStoreBarrier, |
| 2559 node->token_pos())); | 2565 node->token_pos())); |
| 2560 Do(ExitTempLocalScope(context_tmp_var)); | 2566 Do(ExitTempLocalScope(context_tmp_var)); |
| 2561 } | 2567 } |
| 2562 } else { | 2568 } else { |
| 2563 // Store current context in closure. | 2569 // Store current context in closure. |
| 2564 closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var)); | 2570 closure_tmp_val = Bind( |
| 2565 Value* context = Bind(BuildCurrentContext()); | 2571 new(Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); |
| 2572 Value* context = Bind(BuildCurrentContext(node->token_pos())); |
| 2566 Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(), | 2573 Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(), |
| 2567 closure_tmp_val, | 2574 closure_tmp_val, |
| 2568 context, | 2575 context, |
| 2569 kEmitStoreBarrier, | 2576 kEmitStoreBarrier, |
| 2570 node->token_pos())); | 2577 node->token_pos())); |
| 2571 } | 2578 } |
| 2572 ReturnDefinition(ExitTempLocalScope(closure_tmp_var)); | 2579 ReturnDefinition(ExitTempLocalScope(closure_tmp_var)); |
| 2573 } | 2580 } |
| 2574 } | 2581 } |
| 2575 | 2582 |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2763 } | 2770 } |
| 2764 | 2771 |
| 2765 | 2772 |
| 2766 void EffectGraphVisitor::VisitInitStaticFieldNode(InitStaticFieldNode* node) { | 2773 void EffectGraphVisitor::VisitInitStaticFieldNode(InitStaticFieldNode* node) { |
| 2767 Value* field = Bind(new(Z) ConstantInstr(node->field())); | 2774 Value* field = Bind(new(Z) ConstantInstr(node->field())); |
| 2768 AddInstruction(new(Z) InitStaticFieldInstr(field, node->field())); | 2775 AddInstruction(new(Z) InitStaticFieldInstr(field, node->field())); |
| 2769 } | 2776 } |
| 2770 | 2777 |
| 2771 | 2778 |
| 2772 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { | 2779 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) { |
| 2773 Value* context = Bind(BuildCurrentContext()); | 2780 Value* context = Bind(BuildCurrentContext(node->token_pos())); |
| 2774 Value* clone = Bind(new(Z) CloneContextInstr(node->token_pos(), context)); | 2781 Value* clone = Bind(new(Z) CloneContextInstr(node->token_pos(), context)); |
| 2775 Do(BuildStoreContext(clone)); | 2782 Do(BuildStoreContext(clone, node->token_pos())); |
| 2776 } | 2783 } |
| 2777 | 2784 |
| 2778 | 2785 |
| 2779 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) { | 2786 Value* EffectGraphVisitor::BuildObjectAllocation(ConstructorCallNode* node) { |
| 2780 const Class& cls = Class::ZoneHandle(Z, node->constructor().Owner()); | 2787 const Class& cls = Class::ZoneHandle(Z, node->constructor().Owner()); |
| 2781 const bool cls_is_parameterized = cls.NumTypeArguments() > 0; | 2788 const bool cls_is_parameterized = cls.NumTypeArguments() > 0; |
| 2782 | 2789 |
| 2783 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = | 2790 ZoneGrowableArray<PushArgumentInstr*>* allocate_arguments = |
| 2784 new(Z) ZoneGrowableArray<PushArgumentInstr*>( | 2791 new(Z) ZoneGrowableArray<PushArgumentInstr*>( |
| 2785 cls_is_parameterized ? 1 : 0); | 2792 cls_is_parameterized ? 1 : 0); |
| (...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3929 | 3936 |
| 3930 | 3937 |
| 3931 bool EffectGraphVisitor::HasContextScope() const { | 3938 bool EffectGraphVisitor::HasContextScope() const { |
| 3932 const ContextScope& context_scope = ContextScope::Handle( | 3939 const ContextScope& context_scope = ContextScope::Handle( |
| 3933 owner()->function().context_scope()); | 3940 owner()->function().context_scope()); |
| 3934 return !context_scope.IsNull() && (context_scope.num_variables() > 0); | 3941 return !context_scope.IsNull() && (context_scope.num_variables() > 0); |
| 3935 } | 3942 } |
| 3936 | 3943 |
| 3937 | 3944 |
| 3938 void EffectGraphVisitor::UnchainContexts(intptr_t n) { | 3945 void EffectGraphVisitor::UnchainContexts(intptr_t n) { |
| 3946 // TODO(johnmccutchan): Pass this in. |
| 3947 const intptr_t token_pos = ClassifyingTokenPositions::kContext; |
| 3939 if (n > 0) { | 3948 if (n > 0) { |
| 3940 Value* context = Bind(BuildCurrentContext()); | 3949 Value* context = Bind(BuildCurrentContext(token_pos)); |
| 3941 while (n-- > 0) { | 3950 while (n-- > 0) { |
| 3942 context = Bind( | 3951 context = Bind( |
| 3943 new(Z) LoadFieldInstr(context, | 3952 new(Z) LoadFieldInstr(context, |
| 3944 Context::parent_offset(), | 3953 Context::parent_offset(), |
| 3945 // Not an instance, no type. | 3954 // Not an instance, no type. |
| 3946 Type::ZoneHandle(Z, Type::null()), | 3955 Type::ZoneHandle(Z, Type::null()), |
| 3947 Scanner::kNoSourcePos)); | 3956 token_pos)); |
| 3948 } | 3957 } |
| 3949 Do(BuildStoreContext(context)); | 3958 Do(BuildStoreContext(context, token_pos)); |
| 3950 } | 3959 } |
| 3951 } | 3960 } |
| 3952 | 3961 |
| 3953 | 3962 |
| 3954 void EffectGraphVisitor::AdjustContextLevel(LocalScope* target_scope) { | 3963 void EffectGraphVisitor::AdjustContextLevel(LocalScope* target_scope) { |
| 3955 ASSERT(target_scope != NULL); | 3964 ASSERT(target_scope != NULL); |
| 3956 intptr_t target_context_level = 0; | 3965 intptr_t target_context_level = 0; |
| 3957 if (target_scope->num_context_variables() > 0) { | 3966 if (target_scope->num_context_variables() > 0) { |
| 3958 // The scope of the target label allocates a context, therefore its outer | 3967 // The scope of the target label allocates a context, therefore its outer |
| 3959 // scope is at a lower context level. | 3968 // scope is at a lower context level. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3997 // Allocate and chain a new context (Except don't chain when at the function | 4006 // Allocate and chain a new context (Except don't chain when at the function |
| 3998 // entry if the function does not capture any variables from outer scopes). | 4007 // entry if the function does not capture any variables from outer scopes). |
| 3999 Value* allocated_context = | 4008 Value* allocated_context = |
| 4000 Bind(new(Z) AllocateContextInstr(node->token_pos(), | 4009 Bind(new(Z) AllocateContextInstr(node->token_pos(), |
| 4001 num_context_variables)); | 4010 num_context_variables)); |
| 4002 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context); | 4011 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context); |
| 4003 if (!is_top_level_sequence || HasContextScope()) { | 4012 if (!is_top_level_sequence || HasContextScope()) { |
| 4004 ASSERT(is_top_level_sequence || | 4013 ASSERT(is_top_level_sequence || |
| 4005 (nested_block.ContextLevel() == | 4014 (nested_block.ContextLevel() == |
| 4006 nested_block.outer()->ContextLevel() + 1)); | 4015 nested_block.outer()->ContextLevel() + 1)); |
| 4007 Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var)); | 4016 Value* tmp_val = Bind( |
| 4008 Value* parent_context = Bind(BuildCurrentContext()); | 4017 new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); |
| 4018 Value* parent_context = Bind(BuildCurrentContext(node->token_pos())); |
| 4009 Do(new(Z) StoreInstanceFieldInstr(Context::parent_offset(), | 4019 Do(new(Z) StoreInstanceFieldInstr(Context::parent_offset(), |
| 4010 tmp_val, | 4020 tmp_val, |
| 4011 parent_context, | 4021 parent_context, |
| 4012 kEmitStoreBarrier, | 4022 kEmitStoreBarrier, |
| 4013 Scanner::kNoSourcePos)); | 4023 node->token_pos())); |
| 4014 } | 4024 } |
| 4015 Do(BuildStoreContext(Bind(ExitTempLocalScope(tmp_var)))); | 4025 Do(BuildStoreContext( |
| 4026 Bind(ExitTempLocalScope(tmp_var)), |
| 4027 node->token_pos())); |
| 4016 } | 4028 } |
| 4017 | 4029 |
| 4018 // If this node_sequence is the body of the function being compiled, copy | 4030 // If this node_sequence is the body of the function being compiled, copy |
| 4019 // the captured parameters from the frame into the context. | 4031 // the captured parameters from the frame into the context. |
| 4020 if (is_top_level_sequence) { | 4032 if (is_top_level_sequence) { |
| 4021 ASSERT(scope->context_level() == 1); | 4033 ASSERT(scope->context_level() == 1); |
| 4022 const int num_params = function.NumParameters(); | 4034 const int num_params = function.NumParameters(); |
| 4023 int param_frame_index = (num_params == function.num_fixed_parameters()) ? | 4035 int param_frame_index = (num_params == function.num_fixed_parameters()) ? |
| 4024 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp; | 4036 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp; |
| 4025 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { | 4037 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4187 EffectGraphVisitor for_true(owner()); | 4199 EffectGraphVisitor for_true(owner()); |
| 4188 EffectGraphVisitor for_false(owner()); | 4200 EffectGraphVisitor for_false(owner()); |
| 4189 | 4201 |
| 4190 // Build async jump or sync yield jump. | 4202 // Build async jump or sync yield jump. |
| 4191 ASSERT(function.IsAsyncClosure() || | 4203 ASSERT(function.IsAsyncClosure() || |
| 4192 function.IsAsyncGenClosure() || | 4204 function.IsAsyncGenClosure() || |
| 4193 function.IsSyncGenClosure()); | 4205 function.IsSyncGenClosure()); |
| 4194 | 4206 |
| 4195 // Restore the saved continuation context, i.e. the context that was | 4207 // Restore the saved continuation context, i.e. the context that was |
| 4196 // saved into :await_ctx_var before the closure suspended. | 4208 // saved into :await_ctx_var before the closure suspended. |
| 4197 for_true.BuildRestoreContext(*old_context); | 4209 for_true.BuildRestoreContext(*old_context, Scanner::kNoSourcePos); |
| 4198 | 4210 |
| 4199 // Goto saved join. | 4211 // Goto saved join. |
| 4200 for_true.Goto((*owner()->await_joins())[i]); | 4212 for_true.Goto((*owner()->await_joins())[i]); |
| 4201 | 4213 |
| 4202 Join(for_test, for_true, for_false); | 4214 Join(for_test, for_true, for_false); |
| 4203 if (i == 0) { | 4215 if (i == 0) { |
| 4204 // Manually link up the preamble start. | 4216 // Manually link up the preamble start. |
| 4205 preamble_start->previous()->set_next(for_test.entry()); | 4217 preamble_start->previous()->set_next(for_test.entry()); |
| 4206 for_test.entry()->set_previous(preamble_start->previous()); | 4218 for_test.entry()->set_previous(preamble_start->previous()); |
| 4207 } | 4219 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 4229 if (nested_block.break_target() != NULL) { | 4241 if (nested_block.break_target() != NULL) { |
| 4230 if (is_open()) Goto(nested_block.break_target()); | 4242 if (is_open()) Goto(nested_block.break_target()); |
| 4231 exit_ = nested_block.break_target(); | 4243 exit_ = nested_block.break_target(); |
| 4232 } | 4244 } |
| 4233 } | 4245 } |
| 4234 | 4246 |
| 4235 | 4247 |
| 4236 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { | 4248 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) { |
| 4237 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); | 4249 InlineBailout("EffectGraphVisitor::VisitCatchClauseNode (exception)"); |
| 4238 // Restores current context from local variable ':saved_try_context_var'. | 4250 // Restores current context from local variable ':saved_try_context_var'. |
| 4239 BuildRestoreContext(node->context_var()); | 4251 BuildRestoreContext(node->context_var(), node->token_pos()); |
| 4240 | 4252 |
| 4241 EffectGraphVisitor for_catch(owner()); | 4253 EffectGraphVisitor for_catch(owner()); |
| 4242 node->VisitChildren(&for_catch); | 4254 node->VisitChildren(&for_catch); |
| 4243 Append(for_catch); | 4255 Append(for_catch); |
| 4244 } | 4256 } |
| 4245 | 4257 |
| 4246 | 4258 |
| 4247 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { | 4259 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { |
| 4248 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); | 4260 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); |
| 4249 const intptr_t original_handler_index = owner()->try_index(); | 4261 const intptr_t original_handler_index = owner()->try_index(); |
| 4250 const intptr_t try_handler_index = node->try_index(); | 4262 const intptr_t try_handler_index = node->try_index(); |
| 4251 ASSERT(try_handler_index != original_handler_index); | 4263 ASSERT(try_handler_index != original_handler_index); |
| 4252 owner()->set_try_index(try_handler_index); | 4264 owner()->set_try_index(try_handler_index); |
| 4253 | 4265 |
| 4254 // Preserve current context into local variable ':saved_try_context_var'. | 4266 // Preserve current context into local variable ':saved_try_context_var'. |
| 4255 BuildSaveContext(node->context_var()); | 4267 BuildSaveContext(node->context_var(), node->token_pos()); |
| 4256 | 4268 |
| 4257 EffectGraphVisitor for_try(owner()); | 4269 EffectGraphVisitor for_try(owner()); |
| 4258 node->try_block()->Visit(&for_try); | 4270 node->try_block()->Visit(&for_try); |
| 4259 | 4271 |
| 4260 if (for_try.is_open()) { | 4272 if (for_try.is_open()) { |
| 4261 JoinEntryInstr* after_try = | 4273 JoinEntryInstr* after_try = |
| 4262 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), | 4274 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), |
| 4263 original_handler_index); | 4275 original_handler_index); |
| 4264 for_try.Goto(after_try); | 4276 for_try.Goto(after_try); |
| 4265 for_try.exit_ = after_try; | 4277 for_try.exit_ = after_try; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4316 if (is_open()) Goto(join); | 4328 if (is_open()) Goto(join); |
| 4317 exit_ = join; | 4329 exit_ = join; |
| 4318 } | 4330 } |
| 4319 | 4331 |
| 4320 if (finally_block != NULL) { | 4332 if (finally_block != NULL) { |
| 4321 ASSERT(node->rethrow_clause() != NULL); | 4333 ASSERT(node->rethrow_clause() != NULL); |
| 4322 // Create a handler for the code in the catch block, containing the | 4334 // Create a handler for the code in the catch block, containing the |
| 4323 // code in the finally block. | 4335 // code in the finally block. |
| 4324 owner()->set_try_index(original_handler_index); | 4336 owner()->set_try_index(original_handler_index); |
| 4325 EffectGraphVisitor for_finally(owner()); | 4337 EffectGraphVisitor for_finally(owner()); |
| 4326 for_finally.BuildRestoreContext(catch_block->context_var()); | 4338 for_finally.BuildRestoreContext(catch_block->context_var(), |
| 4339 finally_block->token_pos()); |
| 4327 | 4340 |
| 4328 node->rethrow_clause()->Visit(&for_finally); | 4341 node->rethrow_clause()->Visit(&for_finally); |
| 4329 if (for_finally.is_open()) { | 4342 if (for_finally.is_open()) { |
| 4330 // Rethrow the exception. Manually build the graph for rethrow. | 4343 // Rethrow the exception. Manually build the graph for rethrow. |
| 4331 Value* exception = for_finally.Bind( | 4344 Value* exception = for_finally.Bind( |
| 4332 for_finally.BuildLoadLocal(catch_block->rethrow_exception_var())); | 4345 for_finally.BuildLoadLocal(catch_block->rethrow_exception_var())); |
| 4333 for_finally.PushArgument(exception); | 4346 for_finally.PushArgument(exception); |
| 4334 Value* stacktrace = for_finally.Bind( | 4347 Value* stacktrace = for_finally.Bind( |
| 4335 for_finally.BuildLoadLocal(catch_block->rethrow_stacktrace_var())); | 4348 for_finally.BuildLoadLocal(catch_block->rethrow_stacktrace_var())); |
| 4336 for_finally.PushArgument(stacktrace); | 4349 for_finally.PushArgument(stacktrace); |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4608 Report::MessageF(Report::kBailout, | 4621 Report::MessageF(Report::kBailout, |
| 4609 Script::Handle(function.script()), | 4622 Script::Handle(function.script()), |
| 4610 function.token_pos(), | 4623 function.token_pos(), |
| 4611 "FlowGraphBuilder Bailout: %s %s", | 4624 "FlowGraphBuilder Bailout: %s %s", |
| 4612 String::Handle(function.name()).ToCString(), | 4625 String::Handle(function.name()).ToCString(), |
| 4613 reason); | 4626 reason); |
| 4614 UNREACHABLE(); | 4627 UNREACHABLE(); |
| 4615 } | 4628 } |
| 4616 | 4629 |
| 4617 } // namespace dart | 4630 } // namespace dart |
| OLD | NEW |