| 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 30 matching lines...) Expand all Loading... |
| 41 "Trace type check elimination at compile time."); | 41 "Trace type check elimination at compile time."); |
| 42 | 42 |
| 43 DECLARE_FLAG(int, optimization_counter_threshold); | 43 DECLARE_FLAG(int, optimization_counter_threshold); |
| 44 DECLARE_FLAG(bool, profile_vm); | 44 DECLARE_FLAG(bool, profile_vm); |
| 45 DECLARE_FLAG(bool, warn_on_javascript_compatibility); | 45 DECLARE_FLAG(bool, warn_on_javascript_compatibility); |
| 46 DECLARE_FLAG(bool, use_field_guards); | 46 DECLARE_FLAG(bool, use_field_guards); |
| 47 | 47 |
| 48 // Quick access to the locally defined zone() method. | 48 // Quick access to the locally defined zone() method. |
| 49 #define Z (zone()) | 49 #define Z (zone()) |
| 50 | 50 |
| 51 // Quick synthetic token position. |
| 52 #define ST(token_pos) Token::ToSynthetic(token_pos) |
| 53 |
| 51 // TODO(srdjan): Allow compiler to add constants as they are encountered in | 54 // TODO(srdjan): Allow compiler to add constants as they are encountered in |
| 52 // the compilation. | 55 // the compilation. |
| 53 const double kCommonDoubleConstants[] = | 56 const double kCommonDoubleConstants[] = |
| 54 {-1.0, -0.5, -0.1, 0.0, 0.1, 0.5, 1.0, 2.0, 4.0, 5.0, | 57 {-1.0, -0.5, -0.1, 0.0, 0.1, 0.5, 1.0, 2.0, 4.0, 5.0, |
| 55 10.0, 20.0, 30.0, 64.0, 255.0, NAN, | 58 10.0, 20.0, 30.0, 64.0, 255.0, NAN, |
| 56 // From dart:math | 59 // From dart:math |
| 57 2.718281828459045, 2.302585092994046, 0.6931471805599453, | 60 2.718281828459045, 2.302585092994046, 0.6931471805599453, |
| 58 1.4426950408889634, 0.4342944819032518, 3.1415926535897932, | 61 1.4426950408889634, 0.4342944819032518, 3.1415926535897932, |
| 59 0.7071067811865476, 1.4142135623730951}; | 62 0.7071067811865476, 1.4142135623730951}; |
| 60 | 63 |
| (...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 822 | 825 |
| 823 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) { | 826 PushArgumentInstr* EffectGraphVisitor::PushArgument(Value* value) { |
| 824 owner_->add_args_pushed(1); | 827 owner_->add_args_pushed(1); |
| 825 PushArgumentInstr* result = new(Z) PushArgumentInstr(value); | 828 PushArgumentInstr* result = new(Z) PushArgumentInstr(value); |
| 826 AddInstruction(result); | 829 AddInstruction(result); |
| 827 return result; | 830 return result; |
| 828 } | 831 } |
| 829 | 832 |
| 830 | 833 |
| 831 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local, | 834 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local, |
| 832 Value* value) { | 835 Value* value, |
| 836 intptr_t token_pos) { |
| 833 ASSERT(!local.is_captured()); | 837 ASSERT(!local.is_captured()); |
| 834 return new(Z) StoreLocalInstr(local, value); | 838 ASSERT(!Token::IsClassifying(token_pos)); |
| 839 return new(Z) StoreLocalInstr(local, value, ST(token_pos)); |
| 835 } | 840 } |
| 836 | 841 |
| 837 | 842 |
| 838 Definition* EffectGraphVisitor::BuildStoreExprTemp(Value* value) { | 843 Definition* EffectGraphVisitor::BuildStoreExprTemp(Value* value, |
| 844 intptr_t token_pos) { |
| 839 return BuildStoreTemp(*owner()->parsed_function().expression_temp_var(), | 845 return BuildStoreTemp(*owner()->parsed_function().expression_temp_var(), |
| 840 value); | 846 value, |
| 847 token_pos); |
| 841 } | 848 } |
| 842 | 849 |
| 843 | 850 |
| 844 Definition* EffectGraphVisitor::BuildLoadExprTemp() { | 851 Definition* EffectGraphVisitor::BuildLoadExprTemp(intptr_t token_pos) { |
| 845 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var()); | 852 ASSERT(!Token::IsClassifying(token_pos)); |
| 853 return BuildLoadLocal(*owner()->parsed_function().expression_temp_var(), |
| 854 token_pos); |
| 846 } | 855 } |
| 847 | 856 |
| 848 | 857 |
| 849 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local, | 858 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local, |
| 850 Value* value, | 859 Value* value, |
| 851 intptr_t token_pos) { | 860 intptr_t token_pos) { |
| 852 if (local.is_captured()) { | 861 if (local.is_captured()) { |
| 853 LocalVariable* tmp_var = EnterTempLocalScope(value); | 862 LocalVariable* tmp_var = EnterTempLocalScope(value, token_pos); |
| 854 intptr_t delta = | 863 intptr_t delta = |
| 855 owner()->context_level() - local.owner()->context_level(); | 864 owner()->context_level() - local.owner()->context_level(); |
| 856 ASSERT(delta >= 0); | 865 ASSERT(delta >= 0); |
| 857 Value* context = Bind(BuildCurrentContext(token_pos)); | 866 Value* context = Bind(BuildCurrentContext(token_pos)); |
| 858 while (delta-- > 0) { | 867 while (delta-- > 0) { |
| 859 context = Bind(new(Z) LoadFieldInstr( | 868 context = Bind(new(Z) LoadFieldInstr( |
| 860 context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()), | 869 context, Context::parent_offset(), Type::ZoneHandle(Z, Type::null()), |
| 861 token_pos)); | 870 token_pos)); |
| 862 } | 871 } |
| 863 Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var)); | 872 Value* tmp_val = Bind(new(Z) LoadLocalInstr(*tmp_var, token_pos)); |
| 864 StoreInstanceFieldInstr* store = | 873 StoreInstanceFieldInstr* store = |
| 865 new(Z) StoreInstanceFieldInstr(Context::variable_offset(local.index()), | 874 new(Z) StoreInstanceFieldInstr(Context::variable_offset(local.index()), |
| 866 context, | 875 context, |
| 867 tmp_val, | 876 tmp_val, |
| 868 kEmitStoreBarrier, | 877 kEmitStoreBarrier, |
| 869 token_pos); | 878 token_pos); |
| 870 Do(store); | 879 Do(store); |
| 871 return ExitTempLocalScope(tmp_var); | 880 return ExitTempLocalScope(tmp_var, token_pos); |
| 872 } else { | 881 } else { |
| 873 return new(Z) StoreLocalInstr(local, value, token_pos); | 882 return new(Z) StoreLocalInstr(local, value, token_pos); |
| 874 } | 883 } |
| 875 } | 884 } |
| 876 | 885 |
| 877 | 886 |
| 878 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local, | 887 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local, |
| 879 intptr_t token_pos) { | 888 intptr_t token_pos) { |
| 880 if (local.IsConst()) { | 889 if (local.IsConst()) { |
| 881 return new(Z) ConstantInstr(*local.ConstValue(), token_pos); | 890 return new(Z) ConstantInstr(*local.ConstValue(), token_pos); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 896 } else { | 905 } else { |
| 897 return new(Z) LoadLocalInstr(local, token_pos); | 906 return new(Z) LoadLocalInstr(local, token_pos); |
| 898 } | 907 } |
| 899 } | 908 } |
| 900 | 909 |
| 901 | 910 |
| 902 // Stores current context into the 'variable' | 911 // Stores current context into the 'variable' |
| 903 void EffectGraphVisitor::BuildSaveContext( | 912 void EffectGraphVisitor::BuildSaveContext( |
| 904 const LocalVariable& variable, | 913 const LocalVariable& variable, |
| 905 intptr_t token_pos) { | 914 intptr_t token_pos) { |
| 915 ASSERT(Token::IsSynthetic(token_pos) || Token::IsNoSource(token_pos)); |
| 906 Value* context = Bind(BuildCurrentContext(token_pos)); | 916 Value* context = Bind(BuildCurrentContext(token_pos)); |
| 907 Do(BuildStoreLocal(variable, context, token_pos)); | 917 Do(BuildStoreLocal(variable, context, token_pos)); |
| 908 } | 918 } |
| 909 | 919 |
| 910 | 920 |
| 911 // Loads context saved in 'context_variable' into the current context. | 921 // Loads context saved in 'context_variable' into the current context. |
| 912 void EffectGraphVisitor::BuildRestoreContext( | 922 void EffectGraphVisitor::BuildRestoreContext( |
| 913 const LocalVariable& variable, | 923 const LocalVariable& variable, |
| 914 intptr_t token_pos) { | 924 intptr_t token_pos) { |
| 915 Value* load_saved_context = Bind(BuildLoadLocal(variable, token_pos)); | 925 Value* load_saved_context = Bind(BuildLoadLocal(variable, token_pos)); |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1115 Append(for_value); | 1125 Append(for_value); |
| 1116 Value* return_value = for_value.value(); | 1126 Value* return_value = for_value.value(); |
| 1117 | 1127 |
| 1118 // Call to stub that checks whether the debugger is in single | 1128 // Call to stub that checks whether the debugger is in single |
| 1119 // step mode. This call must happen before the contexts are | 1129 // step mode. This call must happen before the contexts are |
| 1120 // unchained so that captured variables can be inspected. | 1130 // unchained so that captured variables can be inspected. |
| 1121 // No debugger check is done in native functions or for return | 1131 // No debugger check is done in native functions or for return |
| 1122 // statements for which there is no associated source position. | 1132 // statements for which there is no associated source position. |
| 1123 const Function& function = owner()->function(); | 1133 const Function& function = owner()->function(); |
| 1124 if (FLAG_support_debugger && | 1134 if (FLAG_support_debugger && |
| 1125 (node->token_pos() >= 0) && !function.is_native()) { | 1135 Token::IsDebugPause(node->token_pos()) && !function.is_native()) { |
| 1126 AddInstruction(new(Z) DebugStepCheckInstr(node->token_pos(), | 1136 AddInstruction(new(Z) DebugStepCheckInstr(node->token_pos(), |
| 1127 RawPcDescriptors::kRuntimeCall)); | 1137 RawPcDescriptors::kRuntimeCall)); |
| 1128 } | 1138 } |
| 1129 | 1139 |
| 1130 NestedContextAdjustment context_adjustment(owner(), owner()->context_level()); | 1140 NestedContextAdjustment context_adjustment(owner(), owner()->context_level()); |
| 1131 | 1141 |
| 1132 if (node->inlined_finally_list_length() > 0) { | 1142 if (node->inlined_finally_list_length() > 0) { |
| 1133 LocalVariable* temp = owner()->parsed_function().finally_return_temp_var(); | 1143 LocalVariable* temp = owner()->parsed_function().finally_return_temp_var(); |
| 1134 ASSERT(temp != NULL); | 1144 ASSERT(temp != NULL); |
| 1135 Do(BuildStoreLocal(*temp, return_value, node->token_pos())); | 1145 Do(BuildStoreLocal(*temp, return_value, node->token_pos())); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1170 // been inlined (call: :async_completer.complete(return_value)). These | 1180 // been inlined (call: :async_completer.complete(return_value)). These |
| 1171 // returns end up returning null in the end. | 1181 // returns end up returning null in the end. |
| 1172 // 2) "Continuation" returns that should not complete the completer but return | 1182 // 2) "Continuation" returns that should not complete the completer but return |
| 1173 // the value. | 1183 // the value. |
| 1174 // | 1184 // |
| 1175 // We distinguish those kinds of nodes via is_regular_return(). | 1185 // We distinguish those kinds of nodes via is_regular_return(). |
| 1176 // | 1186 // |
| 1177 if (function.IsAsyncClosure() && | 1187 if (function.IsAsyncClosure() && |
| 1178 (node->return_type() == ReturnNode::kRegular)) { | 1188 (node->return_type() == ReturnNode::kRegular)) { |
| 1179 // Temporary store the computed return value. | 1189 // Temporary store the computed return value. |
| 1180 Do(BuildStoreExprTemp(return_value)); | 1190 Do(BuildStoreExprTemp(return_value, node->token_pos())); |
| 1181 | 1191 |
| 1182 LocalVariable* rcv_var = | 1192 LocalVariable* rcv_var = |
| 1183 node->scope()->LookupVariable(Symbols::AsyncCompleter(), false); | 1193 node->scope()->LookupVariable(Symbols::AsyncCompleter(), false); |
| 1184 ASSERT(rcv_var != NULL && rcv_var->is_captured()); | 1194 ASSERT(rcv_var != NULL && rcv_var->is_captured()); |
| 1185 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1195 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1186 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); | 1196 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); |
| 1187 Value* rcv_value = Bind(BuildLoadLocal(*rcv_var, node->token_pos())); | 1197 Value* rcv_value = Bind(BuildLoadLocal(*rcv_var, node->token_pos())); |
| 1188 arguments->Add(PushArgument(rcv_value)); | 1198 arguments->Add(PushArgument(rcv_value)); |
| 1189 Value* returned_value = Bind(BuildLoadExprTemp()); | 1199 Value* returned_value = Bind(BuildLoadExprTemp(node->token_pos())); |
| 1190 arguments->Add(PushArgument(returned_value)); | 1200 arguments->Add(PushArgument(returned_value)); |
| 1191 InstanceCallInstr* call = new(Z) InstanceCallInstr( | 1201 InstanceCallInstr* call = new(Z) InstanceCallInstr( |
| 1192 node->token_pos(), | 1202 node->token_pos(), |
| 1193 Symbols::CompleterComplete(), | 1203 Symbols::CompleterComplete(), |
| 1194 Token::kILLEGAL, | 1204 Token::kILLEGAL, |
| 1195 arguments, | 1205 arguments, |
| 1196 Object::null_array(), | 1206 Object::null_array(), |
| 1197 1, | 1207 1, |
| 1198 owner()->ic_data_array()); | 1208 owner()->ic_data_array()); |
| 1199 Do(call); | 1209 Do(call); |
| 1200 | 1210 |
| 1201 // Rebind the return value for the actual return call to be null. | 1211 // Rebind the return value for the actual return call to be null. |
| 1202 return_value = BuildNullValue(); | 1212 return_value = BuildNullValue(node->token_pos()); |
| 1203 } | 1213 } |
| 1204 | 1214 |
| 1205 intptr_t current_context_level = owner()->context_level(); | 1215 intptr_t current_context_level = owner()->context_level(); |
| 1206 ASSERT(current_context_level >= 0); | 1216 ASSERT(current_context_level >= 0); |
| 1207 if (HasContextScope()) { | 1217 if (HasContextScope()) { |
| 1208 UnchainContexts(current_context_level); | 1218 UnchainContexts(current_context_level); |
| 1209 } | 1219 } |
| 1210 | 1220 |
| 1211 AddReturnExit(node->token_pos(), return_value); | 1221 AddReturnExit(node->token_pos(), return_value); |
| 1212 | 1222 |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1418 for_right.Bind(new(Z) AssertBooleanInstr(node->right()->token_pos(), | 1428 for_right.Bind(new(Z) AssertBooleanInstr(node->right()->token_pos(), |
| 1419 right_value)); | 1429 right_value)); |
| 1420 } | 1430 } |
| 1421 Value* constant_true = for_right.Bind(new(Z) ConstantInstr(Bool::True())); | 1431 Value* constant_true = for_right.Bind(new(Z) ConstantInstr(Bool::True())); |
| 1422 Value* compare = | 1432 Value* compare = |
| 1423 for_right.Bind(new(Z) StrictCompareInstr(node->token_pos(), | 1433 for_right.Bind(new(Z) StrictCompareInstr(node->token_pos(), |
| 1424 Token::kEQ_STRICT, | 1434 Token::kEQ_STRICT, |
| 1425 right_value, | 1435 right_value, |
| 1426 constant_true, | 1436 constant_true, |
| 1427 false)); // No number check. | 1437 false)); // No number check. |
| 1428 for_right.Do(BuildStoreExprTemp(compare)); | 1438 for_right.Do(BuildStoreExprTemp(compare, node->token_pos())); |
| 1429 | 1439 |
| 1430 if (node->kind() == Token::kAND) { | 1440 if (node->kind() == Token::kAND) { |
| 1431 ValueGraphVisitor for_false(owner()); | 1441 ValueGraphVisitor for_false(owner()); |
| 1432 Value* constant_false = | 1442 Value* constant_false = |
| 1433 for_false.Bind(new(Z) ConstantInstr(Bool::False())); | 1443 for_false.Bind(new(Z) ConstantInstr(Bool::False())); |
| 1434 for_false.Do(BuildStoreExprTemp(constant_false)); | 1444 for_false.Do(BuildStoreExprTemp(constant_false, node->token_pos())); |
| 1435 Join(for_test, for_right, for_false); | 1445 Join(for_test, for_right, for_false); |
| 1436 } else { | 1446 } else { |
| 1437 ASSERT(node->kind() == Token::kOR); | 1447 ASSERT(node->kind() == Token::kOR); |
| 1438 ValueGraphVisitor for_true(owner()); | 1448 ValueGraphVisitor for_true(owner()); |
| 1439 Value* constant_true = for_true.Bind(new(Z) ConstantInstr(Bool::True())); | 1449 Value* constant_true = for_true.Bind(new(Z) ConstantInstr(Bool::True())); |
| 1440 for_true.Do(BuildStoreExprTemp(constant_true)); | 1450 for_true.Do(BuildStoreExprTemp(constant_true, node->token_pos())); |
| 1441 Join(for_test, for_true, for_right); | 1451 Join(for_test, for_true, for_right); |
| 1442 } | 1452 } |
| 1443 ReturnDefinition(BuildLoadExprTemp()); | 1453 ReturnDefinition(BuildLoadExprTemp(node->token_pos())); |
| 1444 return; | 1454 return; |
| 1445 } | 1455 } |
| 1446 | 1456 |
| 1447 EffectGraphVisitor::VisitBinaryOpNode(node); | 1457 EffectGraphVisitor::VisitBinaryOpNode(node); |
| 1448 } | 1458 } |
| 1449 | 1459 |
| 1450 | 1460 |
| 1451 static const String& BinaryOpAndMaskName(BinaryOpNode* node) { | 1461 static const String& BinaryOpAndMaskName(BinaryOpNode* node) { |
| 1452 if (node->kind() == Token::kSHL) { | 1462 if (node->kind() == Token::kSHL) { |
| 1453 return Library::PrivateCoreLibName(Symbols::_leftShiftWithMask32()); | 1463 return Library::PrivateCoreLibName(Symbols::_leftShiftWithMask32()); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1497 | 1507 |
| 1498 | 1508 |
| 1499 void EffectGraphVisitor::BuildTypecheckPushArguments( | 1509 void EffectGraphVisitor::BuildTypecheckPushArguments( |
| 1500 intptr_t token_pos, | 1510 intptr_t token_pos, |
| 1501 PushArgumentInstr** push_instantiator_type_arguments_result) { | 1511 PushArgumentInstr** push_instantiator_type_arguments_result) { |
| 1502 const Class& instantiator_class = Class::Handle( | 1512 const Class& instantiator_class = Class::Handle( |
| 1503 Z, owner()->function().Owner()); | 1513 Z, owner()->function().Owner()); |
| 1504 // Since called only when type tested against is not instantiated. | 1514 // Since called only when type tested against is not instantiated. |
| 1505 ASSERT(instantiator_class.NumTypeParameters() > 0); | 1515 ASSERT(instantiator_class.NumTypeParameters() > 0); |
| 1506 Value* instantiator_type_arguments = NULL; | 1516 Value* instantiator_type_arguments = NULL; |
| 1507 Value* instantiator = BuildInstantiator(instantiator_class); | 1517 Value* instantiator = BuildInstantiator(token_pos, instantiator_class); |
| 1508 if (instantiator == NULL) { | 1518 if (instantiator == NULL) { |
| 1509 // No instantiator when inside factory. | 1519 // No instantiator when inside factory. |
| 1510 instantiator_type_arguments = | 1520 instantiator_type_arguments = |
| 1511 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 1521 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
| 1512 } else { | 1522 } else { |
| 1513 instantiator_type_arguments = BuildInstantiatorTypeArguments( | 1523 instantiator_type_arguments = BuildInstantiatorTypeArguments( |
| 1514 token_pos, instantiator_class, instantiator); | 1524 token_pos, instantiator_class, instantiator); |
| 1515 } | 1525 } |
| 1516 *push_instantiator_type_arguments_result = | 1526 *push_instantiator_type_arguments_result = |
| 1517 PushArgument(instantiator_type_arguments); | 1527 PushArgument(instantiator_type_arguments); |
| 1518 } | 1528 } |
| 1519 | 1529 |
| 1520 | 1530 |
| 1521 | 1531 |
| 1522 void EffectGraphVisitor::BuildTypecheckArguments( | 1532 void EffectGraphVisitor::BuildTypecheckArguments( |
| 1523 intptr_t token_pos, | 1533 intptr_t token_pos, |
| 1524 Value** instantiator_type_arguments_result) { | 1534 Value** instantiator_type_arguments_result) { |
| 1525 Value* instantiator = NULL; | 1535 Value* instantiator = NULL; |
| 1526 Value* instantiator_type_arguments = NULL; | 1536 Value* instantiator_type_arguments = NULL; |
| 1527 const Class& instantiator_class = Class::Handle( | 1537 const Class& instantiator_class = Class::Handle( |
| 1528 Z, owner()->function().Owner()); | 1538 Z, owner()->function().Owner()); |
| 1529 // Since called only when type tested against is not instantiated. | 1539 // Since called only when type tested against is not instantiated. |
| 1530 ASSERT(instantiator_class.NumTypeParameters() > 0); | 1540 ASSERT(instantiator_class.NumTypeParameters() > 0); |
| 1531 instantiator = BuildInstantiator(instantiator_class); | 1541 instantiator = BuildInstantiator(token_pos, instantiator_class); |
| 1532 if (instantiator == NULL) { | 1542 if (instantiator == NULL) { |
| 1533 // No instantiator when inside factory. | 1543 // No instantiator when inside factory. |
| 1534 instantiator_type_arguments = | 1544 instantiator_type_arguments = |
| 1535 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 1545 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
| 1536 } else { | 1546 } else { |
| 1537 instantiator_type_arguments = BuildInstantiatorTypeArguments( | 1547 instantiator_type_arguments = BuildInstantiatorTypeArguments( |
| 1538 token_pos, instantiator_class, instantiator); | 1548 token_pos, instantiator_class, instantiator); |
| 1539 } | 1549 } |
| 1540 *instantiator_type_arguments_result = instantiator_type_arguments; | 1550 *instantiator_type_arguments_result = instantiator_type_arguments; |
| 1541 } | 1551 } |
| 1542 | 1552 |
| 1543 | 1553 |
| 1544 Value* EffectGraphVisitor::BuildNullValue() { | 1554 Value* EffectGraphVisitor::BuildNullValue(intptr_t token_pos) { |
| 1545 return Bind(new(Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()))); | 1555 return Bind(new(Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()), |
| 1556 token_pos)); |
| 1546 } | 1557 } |
| 1547 | 1558 |
| 1548 | 1559 |
| 1549 // Used for testing incoming arguments. | 1560 // Used for testing incoming arguments. |
| 1550 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( | 1561 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( |
| 1551 intptr_t token_pos, | 1562 intptr_t token_pos, |
| 1552 Value* value, | 1563 Value* value, |
| 1553 const AbstractType& dst_type, | 1564 const AbstractType& dst_type, |
| 1554 const String& dst_name) { | 1565 const String& dst_name) { |
| 1555 // Build the type check computation. | 1566 // Build the type check computation. |
| 1556 Value* instantiator_type_arguments = NULL; | 1567 Value* instantiator_type_arguments = NULL; |
| 1557 if (dst_type.IsInstantiated()) { | 1568 if (dst_type.IsInstantiated()) { |
| 1558 instantiator_type_arguments = BuildNullValue(); | 1569 instantiator_type_arguments = BuildNullValue(token_pos); |
| 1559 } else { | 1570 } else { |
| 1560 BuildTypecheckArguments(token_pos, &instantiator_type_arguments); | 1571 BuildTypecheckArguments(token_pos, &instantiator_type_arguments); |
| 1561 } | 1572 } |
| 1562 | 1573 |
| 1563 const intptr_t deopt_id = Thread::Current()->GetNextDeoptId(); | 1574 const intptr_t deopt_id = Thread::Current()->GetNextDeoptId(); |
| 1564 return new(Z) AssertAssignableInstr(token_pos, | 1575 return new(Z) AssertAssignableInstr(token_pos, |
| 1565 value, | 1576 value, |
| 1566 instantiator_type_arguments, | 1577 instantiator_type_arguments, |
| 1567 dst_type, | 1578 dst_type, |
| 1568 dst_name, | 1579 dst_name, |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1659 kNumArgsChecked, | 1670 kNumArgsChecked, |
| 1660 owner()->ic_data_array()); | 1671 owner()->ic_data_array()); |
| 1661 ReturnDefinition(call); | 1672 ReturnDefinition(call); |
| 1662 return; | 1673 return; |
| 1663 } | 1674 } |
| 1664 } | 1675 } |
| 1665 | 1676 |
| 1666 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); | 1677 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); |
| 1667 PushArgumentInstr* push_type_args = NULL; | 1678 PushArgumentInstr* push_type_args = NULL; |
| 1668 if (type.IsInstantiated()) { | 1679 if (type.IsInstantiated()) { |
| 1669 push_type_args = PushArgument(BuildNullValue()); | 1680 push_type_args = PushArgument(BuildNullValue(node->token_pos())); |
| 1670 } else { | 1681 } else { |
| 1671 BuildTypecheckPushArguments(node->token_pos(), &push_type_args); | 1682 BuildTypecheckPushArguments(node->token_pos(), &push_type_args); |
| 1672 } | 1683 } |
| 1673 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1684 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1674 new(Z) ZoneGrowableArray<PushArgumentInstr*>(4); | 1685 new(Z) ZoneGrowableArray<PushArgumentInstr*>(4); |
| 1675 arguments->Add(push_left); | 1686 arguments->Add(push_left); |
| 1676 arguments->Add(push_type_args); | 1687 arguments->Add(push_type_args); |
| 1677 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); | 1688 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); |
| 1678 Value* type_const = Bind(new(Z) ConstantInstr(type)); | 1689 Value* type_const = Bind(new(Z) ConstantInstr(type)); |
| 1679 arguments->Add(PushArgument(type_const)); | 1690 arguments->Add(PushArgument(type_const)); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1711 // Do not skip type check if javascript compatibility warning is required. | 1722 // Do not skip type check if javascript compatibility warning is required. |
| 1712 if (!FLAG_warn_on_javascript_compatibility || | 1723 if (!FLAG_warn_on_javascript_compatibility || |
| 1713 !owner()->WarnOnJSIntegralNumTypeTest(node->left(), type)) { | 1724 !owner()->WarnOnJSIntegralNumTypeTest(node->left(), type)) { |
| 1714 ReturnValue(for_value.value()); | 1725 ReturnValue(for_value.value()); |
| 1715 return; | 1726 return; |
| 1716 } | 1727 } |
| 1717 } | 1728 } |
| 1718 PushArgumentInstr* push_left = PushArgument(for_value.value()); | 1729 PushArgumentInstr* push_left = PushArgument(for_value.value()); |
| 1719 PushArgumentInstr* push_type_args = NULL; | 1730 PushArgumentInstr* push_type_args = NULL; |
| 1720 if (type.IsInstantiated()) { | 1731 if (type.IsInstantiated()) { |
| 1721 push_type_args = PushArgument(BuildNullValue()); | 1732 push_type_args = PushArgument(BuildNullValue(node->token_pos())); |
| 1722 } else { | 1733 } else { |
| 1723 BuildTypecheckPushArguments(node->token_pos(), &push_type_args); | 1734 BuildTypecheckPushArguments(node->token_pos(), &push_type_args); |
| 1724 } | 1735 } |
| 1725 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1736 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 1726 new(Z) ZoneGrowableArray<PushArgumentInstr*>(3); | 1737 new(Z) ZoneGrowableArray<PushArgumentInstr*>(3); |
| 1727 arguments->Add(push_left); | 1738 arguments->Add(push_left); |
| 1728 arguments->Add(push_type_args); | 1739 arguments->Add(push_type_args); |
| 1729 Value* type_arg = Bind(new(Z) ConstantInstr(type)); | 1740 Value* type_arg = Bind(new(Z) ConstantInstr(type)); |
| 1730 arguments->Add(PushArgument(type_arg)); | 1741 arguments->Add(PushArgument(type_arg)); |
| 1731 const intptr_t kNumArgsChecked = 1; | 1742 const intptr_t kNumArgsChecked = 1; |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1910 } | 1921 } |
| 1911 | 1922 |
| 1912 | 1923 |
| 1913 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { | 1924 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) { |
| 1914 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); | 1925 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); |
| 1915 node->condition()->Visit(&for_test); | 1926 node->condition()->Visit(&for_test); |
| 1916 | 1927 |
| 1917 ValueGraphVisitor for_true(owner()); | 1928 ValueGraphVisitor for_true(owner()); |
| 1918 node->true_expr()->Visit(&for_true); | 1929 node->true_expr()->Visit(&for_true); |
| 1919 ASSERT(for_true.is_open()); | 1930 ASSERT(for_true.is_open()); |
| 1920 for_true.Do(BuildStoreExprTemp(for_true.value())); | 1931 for_true.Do(BuildStoreExprTemp(for_true.value(), |
| 1932 node->true_expr()->token_pos())); |
| 1921 | 1933 |
| 1922 ValueGraphVisitor for_false(owner()); | 1934 ValueGraphVisitor for_false(owner()); |
| 1923 node->false_expr()->Visit(&for_false); | 1935 node->false_expr()->Visit(&for_false); |
| 1924 ASSERT(for_false.is_open()); | 1936 ASSERT(for_false.is_open()); |
| 1925 for_false.Do(BuildStoreExprTemp(for_false.value())); | 1937 for_false.Do(BuildStoreExprTemp(for_false.value(), |
| 1938 node->false_expr()->token_pos())); |
| 1926 | 1939 |
| 1927 Join(for_test, for_true, for_false); | 1940 Join(for_test, for_true, for_false); |
| 1928 ReturnDefinition(BuildLoadExprTemp()); | 1941 ReturnDefinition(BuildLoadExprTemp(node->token_pos())); |
| 1929 } | 1942 } |
| 1930 | 1943 |
| 1931 | 1944 |
| 1932 // <Statement> ::= If { condition: <Expression> | 1945 // <Statement> ::= If { condition: <Expression> |
| 1933 // true_branch: <Sequence> | 1946 // true_branch: <Sequence> |
| 1934 // false_branch: <Sequence> } | 1947 // false_branch: <Sequence> } |
| 1935 void EffectGraphVisitor::VisitIfNode(IfNode* node) { | 1948 void EffectGraphVisitor::VisitIfNode(IfNode* node) { |
| 1936 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); | 1949 TestGraphVisitor for_test(owner(), node->condition()->token_pos()); |
| 1937 node->condition()->Visit(&for_test); | 1950 node->condition()->Visit(&for_test); |
| 1938 | 1951 |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2266 void EffectGraphVisitor::VisitAwaitNode(AwaitNode* node) { | 2279 void EffectGraphVisitor::VisitAwaitNode(AwaitNode* node) { |
| 2267 // Await nodes are temporary during parsing. | 2280 // Await nodes are temporary during parsing. |
| 2268 UNREACHABLE(); | 2281 UNREACHABLE(); |
| 2269 } | 2282 } |
| 2270 | 2283 |
| 2271 | 2284 |
| 2272 void EffectGraphVisitor::VisitAwaitMarkerNode(AwaitMarkerNode* node) { | 2285 void EffectGraphVisitor::VisitAwaitMarkerNode(AwaitMarkerNode* node) { |
| 2273 // We need to create a new await state which involves: | 2286 // We need to create a new await state which involves: |
| 2274 // * Increase the jump counter. Sanity check against the list of targets. | 2287 // * Increase the jump counter. Sanity check against the list of targets. |
| 2275 // * Save the current context for resuming. | 2288 // * Save the current context for resuming. |
| 2289 ASSERT(Token::IsSynthetic(node->token_pos()) || |
| 2290 Token::IsNoSource(node->token_pos())); |
| 2276 ASSERT(node->async_scope() != NULL); | 2291 ASSERT(node->async_scope() != NULL); |
| 2277 ASSERT(node->await_scope() != NULL); | 2292 ASSERT(node->await_scope() != NULL); |
| 2278 LocalVariable* jump_var = node->async_scope()->LookupVariable( | 2293 LocalVariable* jump_var = node->async_scope()->LookupVariable( |
| 2279 Symbols::AwaitJumpVar(), false); | 2294 Symbols::AwaitJumpVar(), false); |
| 2280 LocalVariable* ctx_var = node->async_scope()->LookupVariable( | 2295 LocalVariable* ctx_var = node->async_scope()->LookupVariable( |
| 2281 Symbols::AwaitContextVar(), false); | 2296 Symbols::AwaitContextVar(), false); |
| 2282 ASSERT((jump_var != NULL) && jump_var->is_captured()); | 2297 ASSERT((jump_var != NULL) && jump_var->is_captured()); |
| 2283 ASSERT((ctx_var != NULL) && ctx_var->is_captured()); | 2298 ASSERT((ctx_var != NULL) && ctx_var->is_captured()); |
| 2284 const intptr_t jump_count = owner()->next_await_counter(); | 2299 const intptr_t jump_count = owner()->next_await_counter(); |
| 2285 ASSERT(jump_count >= 0); | 2300 ASSERT(jump_count >= 0); |
| 2286 // Sanity check that we always add a JoinEntryInstr before adding a new | 2301 // Sanity check that we always add a JoinEntryInstr before adding a new |
| 2287 // state. | 2302 // state. |
| 2288 ASSERT(jump_count == owner()->await_joins()->length()); | 2303 ASSERT(jump_count == owner()->await_joins()->length()); |
| 2289 // Store the counter in :await_jump_var. | 2304 // Store the counter in :await_jump_var. |
| 2290 Value* jump_val = Bind(new(Z) ConstantInstr( | 2305 Value* jump_val = Bind(new(Z) ConstantInstr( |
| 2291 Smi::ZoneHandle(Z, Smi::New(jump_count)))); | 2306 Smi::ZoneHandle(Z, Smi::New(jump_count)), node->token_pos())); |
| 2292 Do(BuildStoreLocal(*jump_var, jump_val)); | 2307 Do(BuildStoreLocal(*jump_var, jump_val, node->token_pos())); |
| 2293 // Save the current context for resuming. | 2308 // Save the current context for resuming. |
| 2294 BuildSaveContext(*ctx_var, node->token_pos()); | 2309 BuildSaveContext(*ctx_var, node->token_pos()); |
| 2295 } | 2310 } |
| 2296 | 2311 |
| 2297 | 2312 |
| 2298 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const { | 2313 intptr_t EffectGraphVisitor::GetCurrentTempLocalIndex() const { |
| 2299 return kFirstLocalSlotFromFp | 2314 return kFirstLocalSlotFromFp |
| 2300 - owner()->num_stack_locals() | 2315 - owner()->num_stack_locals() |
| 2301 - owner()->num_copied_params() | 2316 - owner()->num_copied_params() |
| 2302 - owner()->args_pushed() | 2317 - owner()->args_pushed() |
| 2303 - owner()->temp_count() + 1; | 2318 - owner()->temp_count() + 1; |
| 2304 } | 2319 } |
| 2305 | 2320 |
| 2306 | 2321 |
| 2307 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) { | 2322 LocalVariable* EffectGraphVisitor::EnterTempLocalScope( |
| 2323 Value* value, intptr_t token_pos) { |
| 2308 Do(new(Z) PushTempInstr(value)); | 2324 Do(new(Z) PushTempInstr(value)); |
| 2309 owner()->AllocateTemp(); | 2325 owner()->AllocateTemp(); |
| 2310 | 2326 |
| 2311 ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1)); | 2327 ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1)); |
| 2312 intptr_t index = GetCurrentTempLocalIndex(); | 2328 intptr_t index = GetCurrentTempLocalIndex(); |
| 2313 char name[64]; | 2329 char name[64]; |
| 2314 OS::SNPrint(name, 64, ":tmp_local%" Pd, index); | 2330 OS::SNPrint(name, 64, ":tmp_local%" Pd, index); |
| 2315 LocalVariable* var = | 2331 LocalVariable* var = |
| 2316 new(Z) LocalVariable(Scanner::kNoSourcePos, | 2332 new(Z) LocalVariable(Token::kNoSourcePos, |
| 2317 String::ZoneHandle(Z, Symbols::New(name)), | 2333 String::ZoneHandle(Z, Symbols::New(name)), |
| 2318 *value->Type()->ToAbstractType()); | 2334 *value->Type()->ToAbstractType()); |
| 2319 var->set_index(index); | 2335 var->set_index(index); |
| 2320 return var; | 2336 return var; |
| 2321 } | 2337 } |
| 2322 | 2338 |
| 2323 | 2339 |
| 2324 Definition* EffectGraphVisitor::ExitTempLocalScope(LocalVariable* var) { | 2340 Definition* EffectGraphVisitor::ExitTempLocalScope( |
| 2325 Value* tmp = Bind(new(Z) LoadLocalInstr(*var)); | 2341 LocalVariable* var, intptr_t token_pos) { |
| 2342 Value* tmp = Bind(new(Z) LoadLocalInstr(*var, token_pos)); |
| 2326 owner()->DeallocateTemps(1); | 2343 owner()->DeallocateTemps(1); |
| 2327 ASSERT(GetCurrentTempLocalIndex() == var->index()); | 2344 ASSERT(GetCurrentTempLocalIndex() == var->index()); |
| 2328 return new(Z) DropTempsInstr(1, tmp); | 2345 return new(Z) DropTempsInstr(1, tmp); |
| 2329 } | 2346 } |
| 2330 | 2347 |
| 2331 | 2348 |
| 2332 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) { | 2349 void EffectGraphVisitor::BuildLetTempExpressions(LetNode* node) { |
| 2333 intptr_t num_temps = node->num_temps(); | 2350 intptr_t num_temps = node->num_temps(); |
| 2334 for (intptr_t i = 0; i < num_temps; ++i) { | 2351 for (intptr_t i = 0; i < num_temps; ++i) { |
| 2335 ValueGraphVisitor for_value(owner()); | 2352 ValueGraphVisitor for_value(owner()); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2393 TypeArguments::ZoneHandle(Z, node->type().arguments()); | 2410 TypeArguments::ZoneHandle(Z, node->type().arguments()); |
| 2394 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), | 2411 Value* element_type = BuildInstantiatedTypeArguments(node->token_pos(), |
| 2395 type_args); | 2412 type_args); |
| 2396 Value* num_elements = | 2413 Value* num_elements = |
| 2397 Bind(new(Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(node->length())))); | 2414 Bind(new(Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(node->length())))); |
| 2398 CreateArrayInstr* create = new(Z) CreateArrayInstr(node->token_pos(), | 2415 CreateArrayInstr* create = new(Z) CreateArrayInstr(node->token_pos(), |
| 2399 element_type, | 2416 element_type, |
| 2400 num_elements); | 2417 num_elements); |
| 2401 Value* array_val = Bind(create); | 2418 Value* array_val = Bind(create); |
| 2402 | 2419 |
| 2403 { LocalVariable* tmp_var = EnterTempLocalScope(array_val); | 2420 { LocalVariable* tmp_var = EnterTempLocalScope(array_val, node->token_pos()); |
| 2404 const intptr_t class_id = kArrayCid; | 2421 const intptr_t class_id = kArrayCid; |
| 2405 const intptr_t deopt_id = Thread::kNoDeoptId; | 2422 const intptr_t deopt_id = Thread::kNoDeoptId; |
| 2406 for (int i = 0; i < node->length(); ++i) { | 2423 for (int i = 0; i < node->length(); ++i) { |
| 2407 Value* array = Bind(new(Z) LoadLocalInstr(*tmp_var)); | 2424 Value* array = Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); |
| 2408 Value* index = | 2425 Value* index = |
| 2409 Bind(new(Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(i)))); | 2426 Bind(new(Z) ConstantInstr(Smi::ZoneHandle(Z, Smi::New(i)), |
| 2427 node->token_pos())); |
| 2410 ValueGraphVisitor for_value(owner()); | 2428 ValueGraphVisitor for_value(owner()); |
| 2411 node->ElementAt(i)->Visit(&for_value); | 2429 node->ElementAt(i)->Visit(&for_value); |
| 2412 Append(for_value); | 2430 Append(for_value); |
| 2413 // No store barrier needed for constants. | 2431 // No store barrier needed for constants. |
| 2414 const StoreBarrierType emit_store_barrier = | 2432 const StoreBarrierType emit_store_barrier = |
| 2415 for_value.value()->BindsToConstant() | 2433 for_value.value()->BindsToConstant() |
| 2416 ? kNoStoreBarrier | 2434 ? kNoStoreBarrier |
| 2417 : kEmitStoreBarrier; | 2435 : kEmitStoreBarrier; |
| 2418 const intptr_t index_scale = Instance::ElementSizeFor(class_id); | 2436 const intptr_t index_scale = Instance::ElementSizeFor(class_id); |
| 2419 StoreIndexedInstr* store = new(Z) StoreIndexedInstr( | 2437 StoreIndexedInstr* store = new(Z) StoreIndexedInstr( |
| 2420 array, index, for_value.value(), emit_store_barrier, | 2438 array, index, for_value.value(), emit_store_barrier, |
| 2421 index_scale, class_id, deopt_id, node->token_pos()); | 2439 index_scale, class_id, deopt_id, node->token_pos()); |
| 2422 Do(store); | 2440 Do(store); |
| 2423 } | 2441 } |
| 2424 ReturnDefinition(ExitTempLocalScope(tmp_var)); | 2442 ReturnDefinition(ExitTempLocalScope(tmp_var, node->token_pos())); |
| 2425 } | 2443 } |
| 2426 } | 2444 } |
| 2427 | 2445 |
| 2428 | 2446 |
| 2429 void EffectGraphVisitor::VisitStringInterpolateNode( | 2447 void EffectGraphVisitor::VisitStringInterpolateNode( |
| 2430 StringInterpolateNode* node) { | 2448 StringInterpolateNode* node) { |
| 2431 ValueGraphVisitor for_argument(owner()); | 2449 ValueGraphVisitor for_argument(owner()); |
| 2432 ArrayNode* arguments = node->value(); | 2450 ArrayNode* arguments = node->value(); |
| 2433 if (arguments->length() == 1) { | 2451 if (arguments->length() == 1) { |
| 2434 ZoneGrowableArray<PushArgumentInstr*>* values = | 2452 ZoneGrowableArray<PushArgumentInstr*>* values = |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2520 instantiator_class, | 2538 instantiator_class, |
| 2521 NULL); | 2539 NULL); |
| 2522 arguments->Add(PushArgument(type_arguments)); | 2540 arguments->Add(PushArgument(type_arguments)); |
| 2523 } | 2541 } |
| 2524 AllocateObjectInstr* alloc = new(Z) AllocateObjectInstr(node->token_pos(), | 2542 AllocateObjectInstr* alloc = new(Z) AllocateObjectInstr(node->token_pos(), |
| 2525 cls, | 2543 cls, |
| 2526 arguments); | 2544 arguments); |
| 2527 alloc->set_closure_function(function); | 2545 alloc->set_closure_function(function); |
| 2528 | 2546 |
| 2529 Value* closure_val = Bind(alloc); | 2547 Value* closure_val = Bind(alloc); |
| 2530 { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val); | 2548 { LocalVariable* closure_tmp_var = |
| 2549 EnterTempLocalScope(closure_val, node->token_pos()); |
| 2531 // Store function. | 2550 // Store function. |
| 2532 Value* closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var)); | 2551 Value* closure_tmp_val = |
| 2552 Bind(new(Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); |
| 2533 Value* func_val = | 2553 Value* func_val = |
| 2534 Bind(new(Z) ConstantInstr(Function::ZoneHandle(Z, function.raw()))); | 2554 Bind(new(Z) ConstantInstr(Function::ZoneHandle(Z, function.raw()))); |
| 2535 Do(new(Z) StoreInstanceFieldInstr(Closure::function_offset(), | 2555 Do(new(Z) StoreInstanceFieldInstr(Closure::function_offset(), |
| 2536 closure_tmp_val, | 2556 closure_tmp_val, |
| 2537 func_val, | 2557 func_val, |
| 2538 kEmitStoreBarrier, | 2558 kEmitStoreBarrier, |
| 2539 node->token_pos())); | 2559 node->token_pos())); |
| 2540 if (is_implicit) { | 2560 if (is_implicit) { |
| 2541 // Create new context containing the receiver. | 2561 // Create new context containing the receiver. |
| 2542 const intptr_t kNumContextVariables = 1; // The receiver. | 2562 const intptr_t kNumContextVariables = 1; // The receiver. |
| 2543 Value* allocated_context = | 2563 Value* allocated_context = |
| 2544 Bind(new(Z) AllocateContextInstr(node->token_pos(), | 2564 Bind(new(Z) AllocateContextInstr(node->token_pos(), |
| 2545 kNumContextVariables)); | 2565 kNumContextVariables)); |
| 2546 { LocalVariable* context_tmp_var = EnterTempLocalScope(allocated_context); | 2566 { LocalVariable* context_tmp_var = |
| 2567 EnterTempLocalScope(allocated_context, node->token_pos()); |
| 2547 // Store receiver in context. | 2568 // Store receiver in context. |
| 2548 Value* context_tmp_val = Bind(new(Z) LoadLocalInstr(*context_tmp_var)); | 2569 Value* context_tmp_val = |
| 2570 Bind(new(Z) LoadLocalInstr(*context_tmp_var, node->token_pos())); |
| 2549 ValueGraphVisitor for_receiver(owner()); | 2571 ValueGraphVisitor for_receiver(owner()); |
| 2550 node->receiver()->Visit(&for_receiver); | 2572 node->receiver()->Visit(&for_receiver); |
| 2551 Append(for_receiver); | 2573 Append(for_receiver); |
| 2552 Value* receiver = for_receiver.value(); | 2574 Value* receiver = for_receiver.value(); |
| 2553 Do(new(Z) StoreInstanceFieldInstr(Context::variable_offset(0), | 2575 Do(new(Z) StoreInstanceFieldInstr(Context::variable_offset(0), |
| 2554 context_tmp_val, | 2576 context_tmp_val, |
| 2555 receiver, | 2577 receiver, |
| 2556 kEmitStoreBarrier, | 2578 kEmitStoreBarrier, |
| 2557 node->token_pos())); | 2579 node->token_pos())); |
| 2558 // Store new context in closure. | 2580 // Store new context in closure. |
| 2559 closure_tmp_val = Bind(new(Z) LoadLocalInstr(*closure_tmp_var)); | 2581 closure_tmp_val = |
| 2560 context_tmp_val = Bind(new(Z) LoadLocalInstr(*context_tmp_var)); | 2582 Bind(new(Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); |
| 2583 context_tmp_val = |
| 2584 Bind(new(Z) LoadLocalInstr(*context_tmp_var, node->token_pos())); |
| 2561 Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(), | 2585 Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(), |
| 2562 closure_tmp_val, | 2586 closure_tmp_val, |
| 2563 context_tmp_val, | 2587 context_tmp_val, |
| 2564 kEmitStoreBarrier, | 2588 kEmitStoreBarrier, |
| 2565 node->token_pos())); | 2589 node->token_pos())); |
| 2566 Do(ExitTempLocalScope(context_tmp_var)); | 2590 Do(ExitTempLocalScope(context_tmp_var, node->token_pos())); |
| 2567 } | 2591 } |
| 2568 } else { | 2592 } else { |
| 2569 // Store current context in closure. | 2593 // Store current context in closure. |
| 2570 closure_tmp_val = Bind( | 2594 closure_tmp_val = Bind( |
| 2571 new(Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); | 2595 new(Z) LoadLocalInstr(*closure_tmp_var, node->token_pos())); |
| 2572 Value* context = Bind(BuildCurrentContext(node->token_pos())); | 2596 Value* context = Bind(BuildCurrentContext(node->token_pos())); |
| 2573 Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(), | 2597 Do(new(Z) StoreInstanceFieldInstr(Closure::context_offset(), |
| 2574 closure_tmp_val, | 2598 closure_tmp_val, |
| 2575 context, | 2599 context, |
| 2576 kEmitStoreBarrier, | 2600 kEmitStoreBarrier, |
| 2577 node->token_pos())); | 2601 node->token_pos())); |
| 2578 } | 2602 } |
| 2579 ReturnDefinition(ExitTempLocalScope(closure_tmp_var)); | 2603 ReturnDefinition(ExitTempLocalScope(closure_tmp_var, node->token_pos())); |
| 2580 } | 2604 } |
| 2581 } | 2605 } |
| 2582 | 2606 |
| 2583 | 2607 |
| 2584 void EffectGraphVisitor::BuildPushArguments( | 2608 void EffectGraphVisitor::BuildPushArguments( |
| 2585 const ArgumentListNode& node, | 2609 const ArgumentListNode& node, |
| 2586 ZoneGrowableArray<PushArgumentInstr*>* values) { | 2610 ZoneGrowableArray<PushArgumentInstr*>* values) { |
| 2587 for (intptr_t i = 0; i < node.length(); ++i) { | 2611 for (intptr_t i = 0; i < node.length(); ++i) { |
| 2588 ValueGraphVisitor for_argument(owner()); | 2612 ValueGraphVisitor for_argument(owner()); |
| 2589 node.NodeAt(i)->Visit(&for_argument); | 2613 node.NodeAt(i)->Visit(&for_argument); |
| 2590 Append(for_argument); | 2614 Append(for_argument); |
| 2591 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); | 2615 PushArgumentInstr* push_arg = PushArgument(for_argument.value()); |
| 2592 values->Add(push_arg); | 2616 values->Add(push_arg); |
| 2593 } | 2617 } |
| 2594 } | 2618 } |
| 2595 | 2619 |
| 2596 | 2620 |
| 2597 void EffectGraphVisitor::BuildInstanceCallConditional(InstanceCallNode* node) { | 2621 void EffectGraphVisitor::BuildInstanceCallConditional(InstanceCallNode* node) { |
| 2622 const intptr_t token_pos = node->token_pos(); |
| 2598 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); | 2623 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); |
| 2599 LoadLocalNode* load_temp = | 2624 LoadLocalNode* load_temp = new(Z) LoadLocalNode(token_pos, temp_var); |
| 2600 new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var); | |
| 2601 | 2625 |
| 2602 LiteralNode* null_constant = | 2626 LiteralNode* null_constant = |
| 2603 new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance()); | 2627 new(Z) LiteralNode(ST(token_pos), Object::null_instance()); |
| 2604 ComparisonNode* check_is_null = | 2628 ComparisonNode* check_is_null = |
| 2605 new(Z) ComparisonNode(Scanner::kNoSourcePos, | 2629 new(Z) ComparisonNode(ST(token_pos), |
| 2606 Token::kEQ, | 2630 Token::kEQ, |
| 2607 load_temp, | 2631 load_temp, |
| 2608 null_constant); | 2632 null_constant); |
| 2609 TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos); | 2633 TestGraphVisitor for_test(owner(), ST(token_pos)); |
| 2610 check_is_null->Visit(&for_test); | 2634 check_is_null->Visit(&for_test); |
| 2611 | 2635 |
| 2612 EffectGraphVisitor for_true(owner()); | 2636 EffectGraphVisitor for_true(owner()); |
| 2613 EffectGraphVisitor for_false(owner()); | 2637 EffectGraphVisitor for_false(owner()); |
| 2614 | 2638 |
| 2615 StoreLocalNode* store_null = | 2639 StoreLocalNode* store_null = |
| 2616 new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, null_constant); | 2640 new(Z) StoreLocalNode(ST(token_pos), temp_var, null_constant); |
| 2617 store_null->Visit(&for_true); | 2641 store_null->Visit(&for_true); |
| 2618 | 2642 |
| 2619 InstanceCallNode* call = | 2643 InstanceCallNode* call = |
| 2620 new(Z) InstanceCallNode(node->token_pos(), | 2644 new(Z) InstanceCallNode(token_pos, |
| 2621 load_temp, | 2645 load_temp, |
| 2622 node->function_name(), | 2646 node->function_name(), |
| 2623 node->arguments()); | 2647 node->arguments()); |
| 2624 StoreLocalNode* store_result = | 2648 StoreLocalNode* store_result = |
| 2625 new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, call); | 2649 new(Z) StoreLocalNode(ST(token_pos), temp_var, call); |
| 2626 store_result->Visit(&for_false); | 2650 store_result->Visit(&for_false); |
| 2627 | 2651 |
| 2628 Join(for_test, for_true, for_false); | 2652 Join(for_test, for_true, for_false); |
| 2629 } | 2653 } |
| 2630 | 2654 |
| 2631 | 2655 |
| 2632 void ValueGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { | 2656 void ValueGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
| 2633 if (node->is_conditional()) { | 2657 if (node->is_conditional()) { |
| 2634 ValueGraphVisitor for_receiver(owner()); | 2658 ValueGraphVisitor for_receiver(owner()); |
| 2635 node->receiver()->Visit(&for_receiver); | 2659 node->receiver()->Visit(&for_receiver); |
| 2636 Append(for_receiver); | 2660 Append(for_receiver); |
| 2637 Do(BuildStoreExprTemp(for_receiver.value())); | 2661 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos())); |
| 2638 BuildInstanceCallConditional(node); | 2662 BuildInstanceCallConditional(node); |
| 2639 ReturnDefinition(BuildLoadExprTemp()); | 2663 ReturnDefinition(BuildLoadExprTemp(node->token_pos())); |
| 2640 } else { | 2664 } else { |
| 2641 EffectGraphVisitor::VisitInstanceCallNode(node); | 2665 EffectGraphVisitor::VisitInstanceCallNode(node); |
| 2642 } | 2666 } |
| 2643 } | 2667 } |
| 2644 | 2668 |
| 2645 | 2669 |
| 2646 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { | 2670 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) { |
| 2647 ValueGraphVisitor for_receiver(owner()); | 2671 ValueGraphVisitor for_receiver(owner()); |
| 2648 node->receiver()->Visit(&for_receiver); | 2672 node->receiver()->Visit(&for_receiver); |
| 2649 Append(for_receiver); | 2673 Append(for_receiver); |
| 2650 if (node->is_conditional()) { | 2674 if (node->is_conditional()) { |
| 2651 Do(BuildStoreExprTemp(for_receiver.value())); | 2675 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos())); |
| 2652 BuildInstanceCallConditional(node); | 2676 BuildInstanceCallConditional(node); |
| 2653 } else { | 2677 } else { |
| 2654 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 2678 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 2655 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2679 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2656 new(Z) ZoneGrowableArray<PushArgumentInstr*>( | 2680 new(Z) ZoneGrowableArray<PushArgumentInstr*>( |
| 2657 node->arguments()->length() + 1); | 2681 node->arguments()->length() + 1); |
| 2658 arguments->Add(push_receiver); | 2682 arguments->Add(push_receiver); |
| 2659 | 2683 |
| 2660 BuildPushArguments(*node->arguments(), arguments); | 2684 BuildPushArguments(*node->arguments(), arguments); |
| 2661 InstanceCallInstr* call = new(Z) InstanceCallInstr( | 2685 InstanceCallInstr* call = new(Z) InstanceCallInstr( |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2723 ReturnDefinition(call); | 2747 ReturnDefinition(call); |
| 2724 } | 2748 } |
| 2725 | 2749 |
| 2726 | 2750 |
| 2727 void EffectGraphVisitor::BuildClosureCall( | 2751 void EffectGraphVisitor::BuildClosureCall( |
| 2728 ClosureCallNode* node, bool result_needed) { | 2752 ClosureCallNode* node, bool result_needed) { |
| 2729 ValueGraphVisitor for_closure(owner()); | 2753 ValueGraphVisitor for_closure(owner()); |
| 2730 node->closure()->Visit(&for_closure); | 2754 node->closure()->Visit(&for_closure); |
| 2731 Append(for_closure); | 2755 Append(for_closure); |
| 2732 | 2756 |
| 2733 LocalVariable* tmp_var = EnterTempLocalScope(for_closure.value()); | 2757 LocalVariable* tmp_var = |
| 2758 EnterTempLocalScope(for_closure.value(), node->token_pos()); |
| 2734 | 2759 |
| 2735 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 2760 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 2736 new(Z) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); | 2761 new(Z) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length()); |
| 2737 Value* closure_val = Bind(new(Z) LoadLocalInstr(*tmp_var)); | 2762 Value* closure_val = Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); |
| 2738 PushArgumentInstr* push_closure = PushArgument(closure_val); | 2763 PushArgumentInstr* push_closure = PushArgument(closure_val); |
| 2739 arguments->Add(push_closure); | 2764 arguments->Add(push_closure); |
| 2740 BuildPushArguments(*node->arguments(), arguments); | 2765 BuildPushArguments(*node->arguments(), arguments); |
| 2741 | 2766 |
| 2742 closure_val = Bind(new(Z) LoadLocalInstr(*tmp_var)); | 2767 closure_val = Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); |
| 2743 LoadFieldInstr* function_load = new(Z) LoadFieldInstr( | 2768 LoadFieldInstr* function_load = new(Z) LoadFieldInstr( |
| 2744 closure_val, | 2769 closure_val, |
| 2745 Closure::function_offset(), | 2770 Closure::function_offset(), |
| 2746 AbstractType::ZoneHandle(Z, AbstractType::null()), | 2771 AbstractType::ZoneHandle(Z, AbstractType::null()), |
| 2747 node->token_pos()); | 2772 node->token_pos()); |
| 2748 function_load->set_is_immutable(true); | 2773 function_load->set_is_immutable(true); |
| 2749 Value* function_val = Bind(function_load); | 2774 Value* function_val = Bind(function_load); |
| 2750 | 2775 |
| 2751 Definition* closure_call = | 2776 Definition* closure_call = |
| 2752 new(Z) ClosureCallInstr(function_val, node, arguments); | 2777 new(Z) ClosureCallInstr(function_val, node, arguments); |
| 2753 if (result_needed) { | 2778 if (result_needed) { |
| 2754 Value* result = Bind(closure_call); | 2779 Value* result = Bind(closure_call); |
| 2755 Do(new(Z) StoreLocalInstr(*tmp_var, result)); | 2780 Do(new(Z) StoreLocalInstr(*tmp_var, result, ST(node->token_pos()))); |
| 2756 } else { | 2781 } else { |
| 2757 Do(closure_call); | 2782 Do(closure_call); |
| 2758 } | 2783 } |
| 2759 ReturnDefinition(ExitTempLocalScope(tmp_var)); | 2784 ReturnDefinition(ExitTempLocalScope(tmp_var, node->token_pos())); |
| 2760 } | 2785 } |
| 2761 | 2786 |
| 2762 | 2787 |
| 2763 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 2788 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 2764 BuildClosureCall(node, false); | 2789 BuildClosureCall(node, false); |
| 2765 } | 2790 } |
| 2766 | 2791 |
| 2767 | 2792 |
| 2768 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { | 2793 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) { |
| 2769 BuildClosureCall(node, true); | 2794 BuildClosureCall(node, true); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2879 // t_n+1 <- ctor-arg | 2904 // t_n+1 <- ctor-arg |
| 2880 // t_n+2... <- constructor arguments start here | 2905 // t_n+2... <- constructor arguments start here |
| 2881 // StaticCall(constructor, t_n+1, t_n+2, ...) | 2906 // StaticCall(constructor, t_n+1, t_n+2, ...) |
| 2882 // No need to preserve allocated value (simpler than in ValueGraphVisitor). | 2907 // No need to preserve allocated value (simpler than in ValueGraphVisitor). |
| 2883 Value* allocated_value = BuildObjectAllocation(node); | 2908 Value* allocated_value = BuildObjectAllocation(node); |
| 2884 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); | 2909 PushArgumentInstr* push_allocated_value = PushArgument(allocated_value); |
| 2885 BuildConstructorCall(node, push_allocated_value); | 2910 BuildConstructorCall(node, push_allocated_value); |
| 2886 } | 2911 } |
| 2887 | 2912 |
| 2888 | 2913 |
| 2889 Value* EffectGraphVisitor::BuildInstantiator(const Class& instantiator_class) { | 2914 Value* EffectGraphVisitor::BuildInstantiator(intptr_t token_pos, |
| 2915 const Class& instantiator_class) { |
| 2890 ASSERT(instantiator_class.NumTypeParameters() > 0); | 2916 ASSERT(instantiator_class.NumTypeParameters() > 0); |
| 2891 Function& outer_function = Function::Handle(Z, owner()->function().raw()); | 2917 Function& outer_function = Function::Handle(Z, owner()->function().raw()); |
| 2892 while (outer_function.IsLocalFunction()) { | 2918 while (outer_function.IsLocalFunction()) { |
| 2893 outer_function = outer_function.parent_function(); | 2919 outer_function = outer_function.parent_function(); |
| 2894 } | 2920 } |
| 2895 if (outer_function.IsFactory()) { | 2921 if (outer_function.IsFactory()) { |
| 2896 return NULL; | 2922 return NULL; |
| 2897 } | 2923 } |
| 2898 | 2924 |
| 2899 LocalVariable* instantiator = owner()->parsed_function().instantiator(); | 2925 LocalVariable* instantiator = owner()->parsed_function().instantiator(); |
| 2900 ASSERT(instantiator != NULL); | 2926 ASSERT(instantiator != NULL); |
| 2901 Value* result = Bind(BuildLoadLocal(*instantiator)); | 2927 Value* result = Bind(BuildLoadLocal(*instantiator, token_pos)); |
| 2902 return result; | 2928 return result; |
| 2903 } | 2929 } |
| 2904 | 2930 |
| 2905 | 2931 |
| 2906 // 'expression_temp_var' may not be used inside this method if 'instantiator' | 2932 // 'expression_temp_var' may not be used inside this method if 'instantiator' |
| 2907 // is not NULL. | 2933 // is not NULL. |
| 2908 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( | 2934 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments( |
| 2909 intptr_t token_pos, | 2935 intptr_t token_pos, |
| 2910 const Class& instantiator_class, | 2936 const Class& instantiator_class, |
| 2911 Value* instantiator) { | 2937 Value* instantiator) { |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2927 Function& outer_function = Function::Handle(Z, owner()->function().raw()); | 2953 Function& outer_function = Function::Handle(Z, owner()->function().raw()); |
| 2928 while (outer_function.IsLocalFunction()) { | 2954 while (outer_function.IsLocalFunction()) { |
| 2929 outer_function = outer_function.parent_function(); | 2955 outer_function = outer_function.parent_function(); |
| 2930 } | 2956 } |
| 2931 if (outer_function.IsFactory()) { | 2957 if (outer_function.IsFactory()) { |
| 2932 // No instantiator for factories. | 2958 // No instantiator for factories. |
| 2933 ASSERT(instantiator == NULL); | 2959 ASSERT(instantiator == NULL); |
| 2934 LocalVariable* instantiator_var = | 2960 LocalVariable* instantiator_var = |
| 2935 owner()->parsed_function().instantiator(); | 2961 owner()->parsed_function().instantiator(); |
| 2936 ASSERT(instantiator_var != NULL); | 2962 ASSERT(instantiator_var != NULL); |
| 2937 return Bind(BuildLoadLocal(*instantiator_var)); | 2963 return Bind(BuildLoadLocal(*instantiator_var, token_pos)); |
| 2938 } | 2964 } |
| 2939 if (instantiator == NULL) { | 2965 if (instantiator == NULL) { |
| 2940 instantiator = BuildInstantiator(instantiator_class); | 2966 instantiator = BuildInstantiator(token_pos, instantiator_class); |
| 2941 } | 2967 } |
| 2942 // The instantiator is the receiver of the caller, which is not a factory. | 2968 // The instantiator is the receiver of the caller, which is not a factory. |
| 2943 // The receiver cannot be null; extract its TypeArguments object. | 2969 // The receiver cannot be null; extract its TypeArguments object. |
| 2944 // Note that in the factory case, the instantiator is the first parameter | 2970 // Note that in the factory case, the instantiator is the first parameter |
| 2945 // of the factory, i.e. already a TypeArguments object. | 2971 // of the factory, i.e. already a TypeArguments object. |
| 2946 intptr_t type_arguments_field_offset = | 2972 intptr_t type_arguments_field_offset = |
| 2947 instantiator_class.type_arguments_field_offset(); | 2973 instantiator_class.type_arguments_field_offset(); |
| 2948 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); | 2974 ASSERT(type_arguments_field_offset != Class::kNoTypeArguments); |
| 2949 | 2975 |
| 2950 return Bind(new(Z) LoadFieldInstr( | 2976 return Bind(new(Z) LoadFieldInstr( |
| 2951 instantiator, | 2977 instantiator, |
| 2952 type_arguments_field_offset, | 2978 type_arguments_field_offset, |
| 2953 Type::ZoneHandle(Z, Type::null()), // Not an instance, no type. | 2979 Type::ZoneHandle(Z, Type::null()), // Not an instance, no type. |
| 2954 Scanner::kNoSourcePos)); | 2980 token_pos)); |
| 2955 } | 2981 } |
| 2956 | 2982 |
| 2957 | 2983 |
| 2958 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( | 2984 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments( |
| 2959 intptr_t token_pos, | 2985 intptr_t token_pos, |
| 2960 const TypeArguments& type_arguments) { | 2986 const TypeArguments& type_arguments) { |
| 2961 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { | 2987 if (type_arguments.IsNull() || type_arguments.IsInstantiated()) { |
| 2962 return Bind(new(Z) ConstantInstr(type_arguments)); | 2988 return Bind(new(Z) ConstantInstr(type_arguments)); |
| 2963 } | 2989 } |
| 2964 // The type arguments are uninstantiated. | 2990 // The type arguments are uninstantiated. |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2988 | 3014 |
| 2989 // t_n contains the allocated and initialized object. | 3015 // t_n contains the allocated and initialized object. |
| 2990 // t_n <- AllocateObject(class) | 3016 // t_n <- AllocateObject(class) |
| 2991 // t_n <- StoreLocal(temp, t_n); | 3017 // t_n <- StoreLocal(temp, t_n); |
| 2992 // t_n+1 <- ctor-arg | 3018 // t_n+1 <- ctor-arg |
| 2993 // t_n+2... <- constructor arguments start here | 3019 // t_n+2... <- constructor arguments start here |
| 2994 // StaticCall(constructor, t_n, t_n+1, ...) | 3020 // StaticCall(constructor, t_n, t_n+1, ...) |
| 2995 // tn <- LoadLocal(temp) | 3021 // tn <- LoadLocal(temp) |
| 2996 | 3022 |
| 2997 Value* allocate = BuildObjectAllocation(node); | 3023 Value* allocate = BuildObjectAllocation(node); |
| 2998 { LocalVariable* tmp_var = EnterTempLocalScope(allocate); | 3024 { LocalVariable* tmp_var = EnterTempLocalScope(allocate, node->token_pos()); |
| 2999 Value* allocated_tmp = Bind(new(Z) LoadLocalInstr(*tmp_var)); | 3025 Value* allocated_tmp = |
| 3026 Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); |
| 3000 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp); | 3027 PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp); |
| 3001 BuildConstructorCall(node, push_allocated_value); | 3028 BuildConstructorCall(node, push_allocated_value); |
| 3002 ReturnDefinition(ExitTempLocalScope(tmp_var)); | 3029 ReturnDefinition(ExitTempLocalScope(tmp_var, node->token_pos())); |
| 3003 } | 3030 } |
| 3004 } | 3031 } |
| 3005 | 3032 |
| 3006 | 3033 |
| 3007 | 3034 |
| 3008 void EffectGraphVisitor::BuildInstanceGetterConditional( | 3035 void EffectGraphVisitor::BuildInstanceGetterConditional( |
| 3009 InstanceGetterNode* node) { | 3036 InstanceGetterNode* node) { |
| 3037 const intptr_t token_pos = node->token_pos(); |
| 3010 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); | 3038 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); |
| 3011 LoadLocalNode* load_temp = | 3039 LoadLocalNode* load_temp = new(Z) LoadLocalNode(token_pos, temp_var); |
| 3012 new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var); | |
| 3013 | 3040 |
| 3014 LiteralNode* null_constant = | 3041 LiteralNode* null_constant = |
| 3015 new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance()); | 3042 new(Z) LiteralNode(ST(token_pos), Object::null_instance()); |
| 3016 ComparisonNode* check_is_null = | 3043 ComparisonNode* check_is_null = |
| 3017 new(Z) ComparisonNode(Scanner::kNoSourcePos, | 3044 new(Z) ComparisonNode(ST(token_pos), |
| 3018 Token::kEQ, | 3045 Token::kEQ, |
| 3019 load_temp, | 3046 load_temp, |
| 3020 null_constant); | 3047 null_constant); |
| 3021 TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos); | 3048 TestGraphVisitor for_test(owner(), ST(token_pos)); |
| 3022 check_is_null->Visit(&for_test); | 3049 check_is_null->Visit(&for_test); |
| 3023 | 3050 |
| 3024 EffectGraphVisitor for_true(owner()); | 3051 EffectGraphVisitor for_true(owner()); |
| 3025 EffectGraphVisitor for_false(owner()); | 3052 EffectGraphVisitor for_false(owner()); |
| 3026 | 3053 |
| 3027 StoreLocalNode* store_null = | 3054 StoreLocalNode* store_null = |
| 3028 new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, null_constant); | 3055 new(Z) StoreLocalNode(ST(token_pos), temp_var, null_constant); |
| 3029 store_null->Visit(&for_true); | 3056 store_null->Visit(&for_true); |
| 3030 | 3057 |
| 3031 InstanceGetterNode* getter = | 3058 InstanceGetterNode* getter = new(Z) InstanceGetterNode(token_pos, |
| 3032 new(Z) InstanceGetterNode(node->token_pos(), | 3059 load_temp, |
| 3033 load_temp, | 3060 node->field_name()); |
| 3034 node->field_name()); | |
| 3035 StoreLocalNode* store_getter = | 3061 StoreLocalNode* store_getter = |
| 3036 new(Z) StoreLocalNode(Scanner::kNoSourcePos, temp_var, getter); | 3062 new(Z) StoreLocalNode(ST(token_pos), temp_var, getter); |
| 3037 store_getter->Visit(&for_false); | 3063 store_getter->Visit(&for_false); |
| 3038 | 3064 |
| 3039 Join(for_test, for_true, for_false); | 3065 Join(for_test, for_true, for_false); |
| 3040 } | 3066 } |
| 3041 | 3067 |
| 3042 | 3068 |
| 3043 void ValueGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { | 3069 void ValueGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 3044 if (node->is_conditional()) { | 3070 if (node->is_conditional()) { |
| 3045 ValueGraphVisitor for_receiver(owner()); | 3071 ValueGraphVisitor for_receiver(owner()); |
| 3046 node->receiver()->Visit(&for_receiver); | 3072 node->receiver()->Visit(&for_receiver); |
| 3047 Append(for_receiver); | 3073 Append(for_receiver); |
| 3048 Do(BuildStoreExprTemp(for_receiver.value())); | 3074 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos())); |
| 3049 BuildInstanceGetterConditional(node); | 3075 BuildInstanceGetterConditional(node); |
| 3050 ReturnDefinition(BuildLoadExprTemp()); | 3076 ReturnDefinition(BuildLoadExprTemp(node->token_pos())); |
| 3051 } else { | 3077 } else { |
| 3052 EffectGraphVisitor::VisitInstanceGetterNode(node); | 3078 EffectGraphVisitor::VisitInstanceGetterNode(node); |
| 3053 } | 3079 } |
| 3054 } | 3080 } |
| 3055 | 3081 |
| 3056 | 3082 |
| 3057 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { | 3083 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) { |
| 3058 ValueGraphVisitor for_receiver(owner()); | 3084 ValueGraphVisitor for_receiver(owner()); |
| 3059 node->receiver()->Visit(&for_receiver); | 3085 node->receiver()->Visit(&for_receiver); |
| 3060 Append(for_receiver); | 3086 Append(for_receiver); |
| 3061 if (node->is_conditional()) { | 3087 if (node->is_conditional()) { |
| 3062 Do(BuildStoreExprTemp(for_receiver.value())); | 3088 Do(BuildStoreExprTemp(for_receiver.value(), node->token_pos())); |
| 3063 BuildInstanceGetterConditional(node); | 3089 BuildInstanceGetterConditional(node); |
| 3064 } else { | 3090 } else { |
| 3065 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); | 3091 PushArgumentInstr* push_receiver = PushArgument(for_receiver.value()); |
| 3066 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 3092 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 3067 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1); | 3093 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1); |
| 3068 arguments->Add(push_receiver); | 3094 arguments->Add(push_receiver); |
| 3069 const String& name = | 3095 const String& name = |
| 3070 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name())); | 3096 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name())); |
| 3071 InstanceCallInstr* call = new(Z) InstanceCallInstr( | 3097 InstanceCallInstr* call = new(Z) InstanceCallInstr( |
| 3072 node->token_pos(), | 3098 node->token_pos(), |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3088 node->receiver()->Visit(&for_receiver); | 3114 node->receiver()->Visit(&for_receiver); |
| 3089 Append(for_receiver); | 3115 Append(for_receiver); |
| 3090 arguments->Add(PushArgument(for_receiver.value())); | 3116 arguments->Add(PushArgument(for_receiver.value())); |
| 3091 | 3117 |
| 3092 ValueGraphVisitor for_value(owner()); | 3118 ValueGraphVisitor for_value(owner()); |
| 3093 node->value()->Visit(&for_value); | 3119 node->value()->Visit(&for_value); |
| 3094 Append(for_value); | 3120 Append(for_value); |
| 3095 | 3121 |
| 3096 Value* value = NULL; | 3122 Value* value = NULL; |
| 3097 if (result_is_needed) { | 3123 if (result_is_needed) { |
| 3098 value = Bind(BuildStoreExprTemp(for_value.value())); | 3124 value = Bind(BuildStoreExprTemp(for_value.value(), node->token_pos())); |
| 3099 } else { | 3125 } else { |
| 3100 value = for_value.value(); | 3126 value = for_value.value(); |
| 3101 } | 3127 } |
| 3102 arguments->Add(PushArgument(value)); | 3128 arguments->Add(PushArgument(value)); |
| 3103 } | 3129 } |
| 3104 | 3130 |
| 3105 | 3131 |
| 3106 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { | 3132 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 3133 const intptr_t token_pos = node->token_pos(); |
| 3107 if (node->is_conditional()) { | 3134 if (node->is_conditional()) { |
| 3108 ValueGraphVisitor for_receiver(owner()); | 3135 ValueGraphVisitor for_receiver(owner()); |
| 3109 node->receiver()->Visit(&for_receiver); | 3136 node->receiver()->Visit(&for_receiver); |
| 3110 Append(for_receiver); | 3137 Append(for_receiver); |
| 3111 Do(BuildStoreExprTemp(for_receiver.value())); | 3138 Do(BuildStoreExprTemp(for_receiver.value(), token_pos)); |
| 3112 | 3139 |
| 3113 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); | 3140 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); |
| 3114 LoadLocalNode* load_temp = | 3141 LoadLocalNode* load_temp = |
| 3115 new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var); | 3142 new(Z) LoadLocalNode(ST(token_pos), temp_var); |
| 3116 LiteralNode* null_constant = | 3143 LiteralNode* null_constant = |
| 3117 new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance()); | 3144 new(Z) LiteralNode(ST(token_pos), Object::null_instance()); |
| 3118 ComparisonNode* check_is_null = | 3145 ComparisonNode* check_is_null = |
| 3119 new(Z) ComparisonNode(Scanner::kNoSourcePos, | 3146 new(Z) ComparisonNode(ST(token_pos), |
| 3120 Token::kEQ, | 3147 Token::kEQ, |
| 3121 load_temp, | 3148 load_temp, |
| 3122 null_constant); | 3149 null_constant); |
| 3123 TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos); | 3150 TestGraphVisitor for_test(owner(), ST(token_pos)); |
| 3124 check_is_null->Visit(&for_test); | 3151 check_is_null->Visit(&for_test); |
| 3125 | 3152 |
| 3126 EffectGraphVisitor for_true(owner()); | 3153 EffectGraphVisitor for_true(owner()); |
| 3127 EffectGraphVisitor for_false(owner()); | 3154 EffectGraphVisitor for_false(owner()); |
| 3128 | 3155 |
| 3129 InstanceSetterNode* setter = | 3156 InstanceSetterNode* setter = |
| 3130 new(Z) InstanceSetterNode(node->token_pos(), | 3157 new(Z) InstanceSetterNode(token_pos, |
| 3131 load_temp, | 3158 load_temp, |
| 3132 node->field_name(), | 3159 node->field_name(), |
| 3133 node->value()); | 3160 node->value()); |
| 3134 setter->Visit(&for_false); | 3161 setter->Visit(&for_false); |
| 3135 Join(for_test, for_true, for_false); | 3162 Join(for_test, for_true, for_false); |
| 3136 return; | 3163 return; |
| 3137 } | 3164 } |
| 3138 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 3165 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 3139 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); | 3166 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); |
| 3140 BuildInstanceSetterArguments(node, arguments, kResultNotNeeded); | 3167 BuildInstanceSetterArguments(node, arguments, kResultNotNeeded); |
| 3141 const String& name = | 3168 const String& name = |
| 3142 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name())); | 3169 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name())); |
| 3143 const intptr_t kNumArgsChecked = 1; // Do not check value type. | 3170 const intptr_t kNumArgsChecked = 1; // Do not check value type. |
| 3144 InstanceCallInstr* call = new(Z) InstanceCallInstr(node->token_pos(), | 3171 InstanceCallInstr* call = new(Z) InstanceCallInstr(token_pos, |
| 3145 name, | 3172 name, |
| 3146 Token::kSET, | 3173 Token::kSET, |
| 3147 arguments, | 3174 arguments, |
| 3148 Object::null_array(), | 3175 Object::null_array(), |
| 3149 kNumArgsChecked, | 3176 kNumArgsChecked, |
| 3150 owner()->ic_data_array()); | 3177 owner()->ic_data_array()); |
| 3151 ReturnDefinition(call); | 3178 ReturnDefinition(call); |
| 3152 } | 3179 } |
| 3153 | 3180 |
| 3154 | 3181 |
| 3155 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { | 3182 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) { |
| 3183 const intptr_t token_pos = node->token_pos(); |
| 3156 if (node->is_conditional()) { | 3184 if (node->is_conditional()) { |
| 3157 ValueGraphVisitor for_receiver(owner()); | 3185 ValueGraphVisitor for_receiver(owner()); |
| 3158 node->receiver()->Visit(&for_receiver); | 3186 node->receiver()->Visit(&for_receiver); |
| 3159 Append(for_receiver); | 3187 Append(for_receiver); |
| 3160 Do(BuildStoreExprTemp(for_receiver.value())); | 3188 Do(BuildStoreExprTemp(for_receiver.value(), token_pos)); |
| 3161 | 3189 |
| 3162 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); | 3190 LocalVariable* temp_var = owner()->parsed_function().expression_temp_var(); |
| 3163 LoadLocalNode* load_temp = | 3191 LoadLocalNode* load_temp = |
| 3164 new(Z) LoadLocalNode(Scanner::kNoSourcePos, temp_var); | 3192 new(Z) LoadLocalNode(ST(token_pos), temp_var); |
| 3165 LiteralNode* null_constant = | 3193 LiteralNode* null_constant = |
| 3166 new(Z) LiteralNode(Scanner::kNoSourcePos, Object::null_instance()); | 3194 new(Z) LiteralNode(ST(token_pos), Object::null_instance()); |
| 3167 ComparisonNode* check_is_null = | 3195 ComparisonNode* check_is_null = |
| 3168 new(Z) ComparisonNode(Scanner::kNoSourcePos, | 3196 new(Z) ComparisonNode(ST(token_pos), |
| 3169 Token::kEQ, | 3197 Token::kEQ, |
| 3170 load_temp, | 3198 load_temp, |
| 3171 null_constant); | 3199 null_constant); |
| 3172 TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos); | 3200 TestGraphVisitor for_test(owner(), ST(token_pos)); |
| 3173 check_is_null->Visit(&for_test); | 3201 check_is_null->Visit(&for_test); |
| 3174 | 3202 |
| 3175 ValueGraphVisitor for_true(owner()); | 3203 ValueGraphVisitor for_true(owner()); |
| 3176 null_constant->Visit(&for_true); | 3204 null_constant->Visit(&for_true); |
| 3177 for_true.Do(BuildStoreExprTemp(for_true.value())); | 3205 for_true.Do(BuildStoreExprTemp(for_true.value(), token_pos)); |
| 3178 | 3206 |
| 3179 ValueGraphVisitor for_false(owner()); | 3207 ValueGraphVisitor for_false(owner()); |
| 3180 InstanceSetterNode* setter = | 3208 InstanceSetterNode* setter = |
| 3181 new(Z) InstanceSetterNode(node->token_pos(), | 3209 new(Z) InstanceSetterNode(token_pos, |
| 3182 load_temp, | 3210 load_temp, |
| 3183 node->field_name(), | 3211 node->field_name(), |
| 3184 node->value()); | 3212 node->value()); |
| 3185 setter->Visit(&for_false); | 3213 setter->Visit(&for_false); |
| 3186 for_false.Do(BuildStoreExprTemp(for_false.value())); | 3214 for_false.Do(BuildStoreExprTemp(for_false.value(), token_pos)); |
| 3187 | 3215 |
| 3188 Join(for_test, for_true, for_false); | 3216 Join(for_test, for_true, for_false); |
| 3189 ReturnDefinition(BuildLoadExprTemp()); | 3217 ReturnDefinition(BuildLoadExprTemp(token_pos)); |
| 3190 return; | 3218 return; |
| 3191 } | 3219 } |
| 3192 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 3220 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 3193 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); | 3221 new(Z) ZoneGrowableArray<PushArgumentInstr*>(2); |
| 3194 BuildInstanceSetterArguments(node, arguments, kResultNeeded); | 3222 BuildInstanceSetterArguments(node, arguments, kResultNeeded); |
| 3195 const String& name = | 3223 const String& name = |
| 3196 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name())); | 3224 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name())); |
| 3197 const intptr_t kNumArgsChecked = 1; // Do not check value type. | 3225 const intptr_t kNumArgsChecked = 1; // Do not check value type. |
| 3198 Do(new(Z) InstanceCallInstr(node->token_pos(), | 3226 Do(new(Z) InstanceCallInstr(token_pos, |
| 3199 name, | 3227 name, |
| 3200 Token::kSET, | 3228 Token::kSET, |
| 3201 arguments, | 3229 arguments, |
| 3202 Object::null_array(), | 3230 Object::null_array(), |
| 3203 kNumArgsChecked, | 3231 kNumArgsChecked, |
| 3204 owner()->ic_data_array())); | 3232 owner()->ic_data_array())); |
| 3205 ReturnDefinition(BuildLoadExprTemp()); | 3233 ReturnDefinition(BuildLoadExprTemp(token_pos)); |
| 3206 } | 3234 } |
| 3207 | 3235 |
| 3208 | 3236 |
| 3209 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { | 3237 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) { |
| 3210 const String& getter_name = | 3238 const String& getter_name = |
| 3211 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name())); | 3239 String::ZoneHandle(Z, Field::GetterSymbol(node->field_name())); |
| 3212 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 3240 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 3213 new(Z) ZoneGrowableArray<PushArgumentInstr*>(); | 3241 new(Z) ZoneGrowableArray<PushArgumentInstr*>(); |
| 3214 Function& getter_function = Function::ZoneHandle(Z, Function::null()); | 3242 Function& getter_function = Function::ZoneHandle(Z, Function::null()); |
| 3215 if (node->is_super_getter()) { | 3243 if (node->is_super_getter()) { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3277 ReturnDefinition(call); | 3305 ReturnDefinition(call); |
| 3278 } | 3306 } |
| 3279 | 3307 |
| 3280 | 3308 |
| 3281 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, | 3309 void EffectGraphVisitor::BuildStaticSetter(StaticSetterNode* node, |
| 3282 bool result_is_needed) { | 3310 bool result_is_needed) { |
| 3283 const String& setter_name = | 3311 const String& setter_name = |
| 3284 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name())); | 3312 String::ZoneHandle(Z, Field::SetterSymbol(node->field_name())); |
| 3285 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 3313 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 3286 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1); | 3314 new(Z) ZoneGrowableArray<PushArgumentInstr*>(1); |
| 3315 const intptr_t token_pos = node->token_pos(); |
| 3287 // A super setter is an instance setter whose setter function is | 3316 // A super setter is an instance setter whose setter function is |
| 3288 // resolved at compile time (in the caller instance getter's super class). | 3317 // resolved at compile time (in the caller instance getter's super class). |
| 3289 // Unlike a static getter, a super getter has a receiver parameter. | 3318 // Unlike a static getter, a super getter has a receiver parameter. |
| 3290 const bool is_super_setter = (node->receiver() != NULL); | 3319 const bool is_super_setter = (node->receiver() != NULL); |
| 3291 const Function& setter_function = node->function(); | 3320 const Function& setter_function = node->function(); |
| 3292 StaticCallInstr* call; | 3321 StaticCallInstr* call; |
| 3293 if (setter_function.IsNull()) { | 3322 if (setter_function.IsNull()) { |
| 3294 if (is_super_setter) { | 3323 if (is_super_setter) { |
| 3295 ASSERT(node->receiver() != NULL); | 3324 ASSERT(node->receiver() != NULL); |
| 3296 // Resolve and call noSuchMethod. | 3325 // Resolve and call noSuchMethod. |
| 3297 ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos()); | 3326 ArgumentListNode* arguments = new(Z) ArgumentListNode(token_pos); |
| 3298 arguments->Add(node->receiver()); | 3327 arguments->Add(node->receiver()); |
| 3299 arguments->Add(node->value()); | 3328 arguments->Add(node->value()); |
| 3300 call = BuildStaticNoSuchMethodCall( | 3329 call = BuildStaticNoSuchMethodCall( |
| 3301 node->cls(), | 3330 node->cls(), |
| 3302 node->receiver(), | 3331 node->receiver(), |
| 3303 setter_name, | 3332 setter_name, |
| 3304 arguments, | 3333 arguments, |
| 3305 result_is_needed, // Save last arg if result is needed. | 3334 result_is_needed, // Save last arg if result is needed. |
| 3306 true); // Super invocation. | 3335 true); // Super invocation. |
| 3307 } else { | 3336 } else { |
| 3308 // Throw a NoSuchMethodError. | 3337 // Throw a NoSuchMethodError. |
| 3309 ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos()); | 3338 ArgumentListNode* arguments = new(Z) ArgumentListNode(token_pos); |
| 3310 arguments->Add(node->value()); | 3339 arguments->Add(node->value()); |
| 3311 call = BuildThrowNoSuchMethodError( | 3340 call = BuildThrowNoSuchMethodError( |
| 3312 node->token_pos(), | 3341 token_pos, |
| 3313 node->cls(), | 3342 node->cls(), |
| 3314 setter_name, | 3343 setter_name, |
| 3315 arguments, // Argument is the value passed to the setter. | 3344 arguments, // Argument is the value passed to the setter. |
| 3316 InvocationMirror::EncodeType( | 3345 InvocationMirror::EncodeType( |
| 3317 node->cls().IsTopLevel() ? | 3346 node->cls().IsTopLevel() ? |
| 3318 InvocationMirror::kTopLevel : | 3347 InvocationMirror::kTopLevel : |
| 3319 InvocationMirror::kStatic, | 3348 InvocationMirror::kStatic, |
| 3320 InvocationMirror::kSetter)); | 3349 InvocationMirror::kSetter)); |
| 3321 } | 3350 } |
| 3322 } else { | 3351 } else { |
| 3323 if (is_super_setter) { | 3352 if (is_super_setter) { |
| 3324 // Add receiver of instance getter. | 3353 // Add receiver of instance getter. |
| 3325 ValueGraphVisitor for_receiver(owner()); | 3354 ValueGraphVisitor for_receiver(owner()); |
| 3326 node->receiver()->Visit(&for_receiver); | 3355 node->receiver()->Visit(&for_receiver); |
| 3327 Append(for_receiver); | 3356 Append(for_receiver); |
| 3328 arguments->Add(PushArgument(for_receiver.value())); | 3357 arguments->Add(PushArgument(for_receiver.value())); |
| 3329 } | 3358 } |
| 3330 ValueGraphVisitor for_value(owner()); | 3359 ValueGraphVisitor for_value(owner()); |
| 3331 node->value()->Visit(&for_value); | 3360 node->value()->Visit(&for_value); |
| 3332 Append(for_value); | 3361 Append(for_value); |
| 3333 Value* value = NULL; | 3362 Value* value = NULL; |
| 3334 if (result_is_needed) { | 3363 if (result_is_needed) { |
| 3335 value = Bind(BuildStoreExprTemp(for_value.value())); | 3364 value = Bind(BuildStoreExprTemp(for_value.value(), token_pos)); |
| 3336 } else { | 3365 } else { |
| 3337 value = for_value.value(); | 3366 value = for_value.value(); |
| 3338 } | 3367 } |
| 3339 arguments->Add(PushArgument(value)); | 3368 arguments->Add(PushArgument(value)); |
| 3340 | 3369 |
| 3341 call = new(Z) StaticCallInstr(node->token_pos(), | 3370 call = new(Z) StaticCallInstr(token_pos, |
| 3342 setter_function, | 3371 setter_function, |
| 3343 Object::null_array(), // No names. | 3372 Object::null_array(), // No names. |
| 3344 arguments, | 3373 arguments, |
| 3345 owner()->ic_data_array()); | 3374 owner()->ic_data_array()); |
| 3346 } | 3375 } |
| 3347 if (result_is_needed) { | 3376 if (result_is_needed) { |
| 3348 Do(call); | 3377 Do(call); |
| 3349 ReturnDefinition(BuildLoadExprTemp()); | 3378 ReturnDefinition(BuildLoadExprTemp(token_pos)); |
| 3350 } else { | 3379 } else { |
| 3351 ReturnDefinition(call); | 3380 ReturnDefinition(call); |
| 3352 } | 3381 } |
| 3353 } | 3382 } |
| 3354 | 3383 |
| 3355 | 3384 |
| 3356 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { | 3385 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) { |
| 3357 BuildStaticSetter(node, false); // Result not needed. | 3386 BuildStaticSetter(node, false); // Result not needed. |
| 3358 } | 3387 } |
| 3359 | 3388 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3375 return TypedData::length_offset(); | 3404 return TypedData::length_offset(); |
| 3376 case MethodRecognizer::kGrowableArrayLength: | 3405 case MethodRecognizer::kGrowableArrayLength: |
| 3377 return GrowableObjectArray::length_offset(); | 3406 return GrowableObjectArray::length_offset(); |
| 3378 default: | 3407 default: |
| 3379 UNREACHABLE(); | 3408 UNREACHABLE(); |
| 3380 return 0; | 3409 return 0; |
| 3381 } | 3410 } |
| 3382 } | 3411 } |
| 3383 | 3412 |
| 3384 | 3413 |
| 3385 LoadLocalInstr* EffectGraphVisitor::BuildLoadThisVar(LocalScope* scope) { | 3414 LoadLocalInstr* EffectGraphVisitor::BuildLoadThisVar( |
| 3415 LocalScope* scope, intptr_t token_pos) { |
| 3386 LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(), | 3416 LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(), |
| 3387 true); // Test only. | 3417 true); // Test only. |
| 3388 return new(Z) LoadLocalInstr(*receiver_var); | 3418 return new(Z) LoadLocalInstr(*receiver_var, token_pos); |
| 3389 } | 3419 } |
| 3390 | 3420 |
| 3391 | 3421 |
| 3392 LoadFieldInstr* EffectGraphVisitor::BuildNativeGetter( | 3422 LoadFieldInstr* EffectGraphVisitor::BuildNativeGetter( |
| 3393 NativeBodyNode* node, | 3423 NativeBodyNode* node, |
| 3394 MethodRecognizer::Kind kind, | 3424 MethodRecognizer::Kind kind, |
| 3395 intptr_t offset, | 3425 intptr_t offset, |
| 3396 const Type& type, | 3426 const Type& type, |
| 3397 intptr_t class_id) { | 3427 intptr_t class_id) { |
| 3398 Value* receiver = Bind(BuildLoadThisVar(node->scope())); | 3428 Value* receiver = Bind(BuildLoadThisVar(node->scope(), node->token_pos())); |
| 3399 LoadFieldInstr* load = new(Z) LoadFieldInstr(receiver, | 3429 LoadFieldInstr* load = new(Z) LoadFieldInstr(receiver, |
| 3400 offset, | 3430 offset, |
| 3401 type, | 3431 type, |
| 3402 node->token_pos()); | 3432 node->token_pos()); |
| 3403 load->set_result_cid(class_id); | 3433 load->set_result_cid(class_id); |
| 3404 load->set_recognized_kind(kind); | 3434 load->set_recognized_kind(kind); |
| 3405 return load; | 3435 return load; |
| 3406 } | 3436 } |
| 3407 | 3437 |
| 3408 | 3438 |
| 3409 ConstantInstr* EffectGraphVisitor::DoNativeSetterStoreValue( | 3439 ConstantInstr* EffectGraphVisitor::DoNativeSetterStoreValue( |
| 3410 NativeBodyNode* node, | 3440 NativeBodyNode* node, |
| 3411 intptr_t offset, | 3441 intptr_t offset, |
| 3412 StoreBarrierType emit_store_barrier) { | 3442 StoreBarrierType emit_store_barrier) { |
| 3413 Value* receiver = Bind(BuildLoadThisVar(node->scope())); | 3443 Value* receiver = Bind(BuildLoadThisVar(node->scope(), node->token_pos())); |
| 3414 LocalVariable* value_var = | 3444 LocalVariable* value_var = |
| 3415 node->scope()->LookupVariable(Symbols::Value(), true); | 3445 node->scope()->LookupVariable(Symbols::Value(), true); |
| 3416 Value* value = Bind(new(Z) LoadLocalInstr(*value_var)); | 3446 Value* value = Bind(new(Z) LoadLocalInstr(*value_var, node->token_pos())); |
| 3417 StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr( | 3447 StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr( |
| 3418 offset, | 3448 offset, |
| 3419 receiver, | 3449 receiver, |
| 3420 value, | 3450 value, |
| 3421 emit_store_barrier, | 3451 emit_store_barrier, |
| 3422 node->token_pos()); | 3452 node->token_pos()); |
| 3423 Do(store); | 3453 Do(store); |
| 3424 return new(Z) ConstantInstr(Object::ZoneHandle(Z, Object::null())); | 3454 return new(Z) ConstantInstr(Object::ZoneHandle(Z, Object::null())); |
| 3425 } | 3455 } |
| 3426 | 3456 |
| 3427 | 3457 |
| 3428 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { | 3458 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) { |
| 3429 const Function& function = owner()->function(); | 3459 const Function& function = owner()->function(); |
| 3460 const intptr_t token_pos = node->token_pos(); |
| 3430 if (!function.IsClosureFunction()) { | 3461 if (!function.IsClosureFunction()) { |
| 3431 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function); | 3462 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function); |
| 3432 switch (kind) { | 3463 switch (kind) { |
| 3433 case MethodRecognizer::kObjectEquals: { | 3464 case MethodRecognizer::kObjectEquals: { |
| 3434 Value* receiver = Bind(BuildLoadThisVar(node->scope())); | 3465 Value* receiver = Bind(BuildLoadThisVar(node->scope(), token_pos)); |
| 3435 LocalVariable* other_var = | 3466 LocalVariable* other_var = |
| 3436 node->scope()->LookupVariable(Symbols::Other(), | 3467 node->scope()->LookupVariable(Symbols::Other(), |
| 3437 true); // Test only. | 3468 true); // Test only. |
| 3438 Value* other = Bind(new(Z) LoadLocalInstr(*other_var)); | 3469 Value* other = Bind(new(Z) LoadLocalInstr(*other_var, token_pos)); |
| 3439 // Receiver is not a number because numbers override equality. | 3470 // Receiver is not a number because numbers override equality. |
| 3440 const bool kNoNumberCheck = false; | 3471 const bool kNoNumberCheck = false; |
| 3441 StrictCompareInstr* compare = | 3472 StrictCompareInstr* compare = |
| 3442 new(Z) StrictCompareInstr(node->token_pos(), | 3473 new(Z) StrictCompareInstr(token_pos, |
| 3443 Token::kEQ_STRICT, | 3474 Token::kEQ_STRICT, |
| 3444 receiver, | 3475 receiver, |
| 3445 other, | 3476 other, |
| 3446 kNoNumberCheck); | 3477 kNoNumberCheck); |
| 3447 return ReturnDefinition(compare); | 3478 return ReturnDefinition(compare); |
| 3448 } | 3479 } |
| 3449 case MethodRecognizer::kStringBaseLength: | 3480 case MethodRecognizer::kStringBaseLength: |
| 3450 case MethodRecognizer::kStringBaseIsEmpty: { | 3481 case MethodRecognizer::kStringBaseIsEmpty: { |
| 3451 // Treat length loads as mutable (i.e. affected by side effects) to | 3482 // Treat length loads as mutable (i.e. affected by side effects) to |
| 3452 // avoid hoisting them since we can't hoist the preceding class-check. | 3483 // avoid hoisting them since we can't hoist the preceding class-check. |
| 3453 // This is because of externalization of strings that affects their | 3484 // This is because of externalization of strings that affects their |
| 3454 // class-id. | 3485 // class-id. |
| 3455 LoadFieldInstr* load = BuildNativeGetter( | 3486 LoadFieldInstr* load = BuildNativeGetter( |
| 3456 node, MethodRecognizer::kStringBaseLength, String::length_offset(), | 3487 node, MethodRecognizer::kStringBaseLength, String::length_offset(), |
| 3457 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); | 3488 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); |
| 3458 if (kind == MethodRecognizer::kStringBaseLength) { | 3489 if (kind == MethodRecognizer::kStringBaseLength) { |
| 3459 return ReturnDefinition(load); | 3490 return ReturnDefinition(load); |
| 3460 } | 3491 } |
| 3461 ASSERT(kind == MethodRecognizer::kStringBaseIsEmpty); | 3492 ASSERT(kind == MethodRecognizer::kStringBaseIsEmpty); |
| 3462 Value* zero_val = Bind(new(Z) ConstantInstr( | 3493 Value* zero_val = Bind(new(Z) ConstantInstr( |
| 3463 Smi::ZoneHandle(Z, Smi::New(0)))); | 3494 Smi::ZoneHandle(Z, Smi::New(0)))); |
| 3464 Value* load_val = Bind(load); | 3495 Value* load_val = Bind(load); |
| 3465 StrictCompareInstr* compare = | 3496 StrictCompareInstr* compare = |
| 3466 new(Z) StrictCompareInstr(node->token_pos(), | 3497 new(Z) StrictCompareInstr(token_pos, |
| 3467 Token::kEQ_STRICT, | 3498 Token::kEQ_STRICT, |
| 3468 load_val, | 3499 load_val, |
| 3469 zero_val, | 3500 zero_val, |
| 3470 false); // No number check. | 3501 false); // No number check. |
| 3471 return ReturnDefinition(compare); | 3502 return ReturnDefinition(compare); |
| 3472 } | 3503 } |
| 3473 case MethodRecognizer::kGrowableArrayLength: | 3504 case MethodRecognizer::kGrowableArrayLength: |
| 3474 case MethodRecognizer::kObjectArrayLength: | 3505 case MethodRecognizer::kObjectArrayLength: |
| 3475 case MethodRecognizer::kImmutableArrayLength: | 3506 case MethodRecognizer::kImmutableArrayLength: |
| 3476 case MethodRecognizer::kTypedDataLength: { | 3507 case MethodRecognizer::kTypedDataLength: { |
| 3477 LoadFieldInstr* load = BuildNativeGetter( | 3508 LoadFieldInstr* load = BuildNativeGetter( |
| 3478 node, kind, OffsetForLengthGetter(kind), | 3509 node, kind, OffsetForLengthGetter(kind), |
| 3479 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); | 3510 Type::ZoneHandle(Z, Type::SmiType()), kSmiCid); |
| 3480 load->set_is_immutable(kind != MethodRecognizer::kGrowableArrayLength); | 3511 load->set_is_immutable(kind != MethodRecognizer::kGrowableArrayLength); |
| 3481 return ReturnDefinition(load); | 3512 return ReturnDefinition(load); |
| 3482 } | 3513 } |
| 3483 case MethodRecognizer::kClassIDgetID: { | 3514 case MethodRecognizer::kClassIDgetID: { |
| 3484 LocalVariable* value_var = | 3515 LocalVariable* value_var = |
| 3485 node->scope()->LookupVariable(Symbols::Value(), true); | 3516 node->scope()->LookupVariable(Symbols::Value(), true); |
| 3486 Value* value = Bind(new(Z) LoadLocalInstr(*value_var)); | 3517 Value* value = Bind(new(Z) LoadLocalInstr(*value_var, token_pos)); |
| 3487 LoadClassIdInstr* load = new(Z) LoadClassIdInstr(value); | 3518 LoadClassIdInstr* load = new(Z) LoadClassIdInstr(value); |
| 3488 return ReturnDefinition(load); | 3519 return ReturnDefinition(load); |
| 3489 } | 3520 } |
| 3490 case MethodRecognizer::kGrowableArrayCapacity: { | 3521 case MethodRecognizer::kGrowableArrayCapacity: { |
| 3491 Value* receiver = Bind(BuildLoadThisVar(node->scope())); | 3522 Value* receiver = Bind(BuildLoadThisVar(node->scope(), token_pos)); |
| 3492 LoadFieldInstr* data_load = new(Z) LoadFieldInstr( | 3523 LoadFieldInstr* data_load = new(Z) LoadFieldInstr( |
| 3493 receiver, | 3524 receiver, |
| 3494 Array::data_offset(), | 3525 Array::data_offset(), |
| 3495 Object::dynamic_type(), | 3526 Object::dynamic_type(), |
| 3496 node->token_pos()); | 3527 node->token_pos()); |
| 3497 data_load->set_result_cid(kArrayCid); | 3528 data_load->set_result_cid(kArrayCid); |
| 3498 Value* data = Bind(data_load); | 3529 Value* data = Bind(data_load); |
| 3499 LoadFieldInstr* length_load = new(Z) LoadFieldInstr( | 3530 LoadFieldInstr* length_load = new(Z) LoadFieldInstr( |
| 3500 data, | 3531 data, |
| 3501 Array::length_offset(), | 3532 Array::length_offset(), |
| 3502 Type::ZoneHandle(Z, Type::SmiType()), | 3533 Type::ZoneHandle(Z, Type::SmiType()), |
| 3503 node->token_pos()); | 3534 node->token_pos()); |
| 3504 length_load->set_result_cid(kSmiCid); | 3535 length_load->set_result_cid(kSmiCid); |
| 3505 length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength); | 3536 length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength); |
| 3506 return ReturnDefinition(length_load); | 3537 return ReturnDefinition(length_load); |
| 3507 } | 3538 } |
| 3508 case MethodRecognizer::kObjectArrayAllocate: { | 3539 case MethodRecognizer::kObjectArrayAllocate: { |
| 3509 LocalVariable* type_args_parameter = | 3540 LocalVariable* type_args_parameter = |
| 3510 node->scope()->LookupVariable(Symbols::TypeArgumentsParameter(), | 3541 node->scope()->LookupVariable(Symbols::TypeArgumentsParameter(), |
| 3511 true); | 3542 true); |
| 3512 Value* element_type = Bind(new(Z) LoadLocalInstr(*type_args_parameter)); | 3543 Value* element_type = |
| 3544 Bind(new(Z) LoadLocalInstr(*type_args_parameter, token_pos)); |
| 3513 LocalVariable* length_parameter = | 3545 LocalVariable* length_parameter = |
| 3514 node->scope()->LookupVariable(Symbols::Length(), true); | 3546 node->scope()->LookupVariable(Symbols::Length(), true); |
| 3515 Value* length = Bind(new(Z) LoadLocalInstr(*length_parameter)); | 3547 Value* length = |
| 3548 Bind(new(Z) LoadLocalInstr(*length_parameter, token_pos)); |
| 3516 CreateArrayInstr* create_array = | 3549 CreateArrayInstr* create_array = |
| 3517 new CreateArrayInstr(node->token_pos(), element_type, length); | 3550 new CreateArrayInstr(token_pos, element_type, length); |
| 3518 return ReturnDefinition(create_array); | 3551 return ReturnDefinition(create_array); |
| 3519 } | 3552 } |
| 3520 case MethodRecognizer::kBigint_getDigits: { | 3553 case MethodRecognizer::kBigint_getDigits: { |
| 3521 return ReturnDefinition(BuildNativeGetter( | 3554 return ReturnDefinition(BuildNativeGetter( |
| 3522 node, kind, Bigint::digits_offset(), | 3555 node, kind, Bigint::digits_offset(), |
| 3523 Object::dynamic_type(), | 3556 Object::dynamic_type(), |
| 3524 kTypedDataUint32ArrayCid)); | 3557 kTypedDataUint32ArrayCid)); |
| 3525 } | 3558 } |
| 3526 case MethodRecognizer::kBigint_getUsed: { | 3559 case MethodRecognizer::kBigint_getUsed: { |
| 3527 return ReturnDefinition(BuildNativeGetter( | 3560 return ReturnDefinition(BuildNativeGetter( |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3620 // If the right hand side is an expression that does not contain | 3653 // If the right hand side is an expression that does not contain |
| 3621 // a safe point for the debugger to stop, add an explicit stub | 3654 // a safe point for the debugger to stop, add an explicit stub |
| 3622 // call. Exception: don't do this when assigning to or from internal | 3655 // call. Exception: don't do this when assigning to or from internal |
| 3623 // variables, or for generated code that has no source position. | 3656 // variables, or for generated code that has no source position. |
| 3624 if (FLAG_support_debugger) { | 3657 if (FLAG_support_debugger) { |
| 3625 if ((node->value()->IsLiteralNode() || | 3658 if ((node->value()->IsLiteralNode() || |
| 3626 (node->value()->IsLoadLocalNode() && | 3659 (node->value()->IsLoadLocalNode() && |
| 3627 !node->value()->AsLoadLocalNode()->local().IsInternal()) || | 3660 !node->value()->AsLoadLocalNode()->local().IsInternal()) || |
| 3628 node->value()->IsClosureNode()) && | 3661 node->value()->IsClosureNode()) && |
| 3629 !node->local().IsInternal() && | 3662 !node->local().IsInternal() && |
| 3630 (node->token_pos() >= 0)) { | 3663 Token::IsDebugPause(node->token_pos())) { |
| 3631 AddInstruction(new(Z) DebugStepCheckInstr( | 3664 AddInstruction(new(Z) DebugStepCheckInstr( |
| 3632 node->token_pos(), RawPcDescriptors::kRuntimeCall)); | 3665 node->token_pos(), RawPcDescriptors::kRuntimeCall)); |
| 3633 } | 3666 } |
| 3634 } | 3667 } |
| 3635 | 3668 |
| 3636 ValueGraphVisitor for_value(owner()); | 3669 ValueGraphVisitor for_value(owner()); |
| 3637 node->value()->Visit(&for_value); | 3670 node->value()->Visit(&for_value); |
| 3638 Append(for_value); | 3671 Append(for_value); |
| 3639 Value* store_value = for_value.value(); | 3672 Value* store_value = for_value.value(); |
| 3640 if (Isolate::Current()->flags().type_checks()) { | 3673 if (Isolate::Current()->flags().type_checks()) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3666 load->set_result_cid(node->field().guarded_cid()); | 3699 load->set_result_cid(node->field().guarded_cid()); |
| 3667 } | 3700 } |
| 3668 FlowGraph::AddToGuardedFields(owner()->guarded_fields(), &node->field()); | 3701 FlowGraph::AddToGuardedFields(owner()->guarded_fields(), &node->field()); |
| 3669 } | 3702 } |
| 3670 ReturnDefinition(load); | 3703 ReturnDefinition(load); |
| 3671 } | 3704 } |
| 3672 | 3705 |
| 3673 | 3706 |
| 3674 void EffectGraphVisitor::VisitStoreInstanceFieldNode( | 3707 void EffectGraphVisitor::VisitStoreInstanceFieldNode( |
| 3675 StoreInstanceFieldNode* node) { | 3708 StoreInstanceFieldNode* node) { |
| 3709 const intptr_t token_pos = node->token_pos(); |
| 3676 ValueGraphVisitor for_instance(owner()); | 3710 ValueGraphVisitor for_instance(owner()); |
| 3677 node->instance()->Visit(&for_instance); | 3711 node->instance()->Visit(&for_instance); |
| 3678 Append(for_instance); | 3712 Append(for_instance); |
| 3679 ValueGraphVisitor for_value(owner()); | 3713 ValueGraphVisitor for_value(owner()); |
| 3680 node->value()->Visit(&for_value); | 3714 node->value()->Visit(&for_value); |
| 3681 Append(for_value); | 3715 Append(for_value); |
| 3682 Value* store_value = for_value.value(); | 3716 Value* store_value = for_value.value(); |
| 3683 if (Isolate::Current()->flags().type_checks()) { | 3717 if (Isolate::Current()->flags().type_checks()) { |
| 3684 const AbstractType& type = | 3718 const AbstractType& type = |
| 3685 AbstractType::ZoneHandle(Z, node->field().type()); | 3719 AbstractType::ZoneHandle(Z, node->field().type()); |
| 3686 const String& dst_name = String::ZoneHandle(Z, node->field().name()); | 3720 const String& dst_name = String::ZoneHandle(Z, node->field().name()); |
| 3687 store_value = BuildAssignableValue(node->value()->token_pos(), | 3721 store_value = BuildAssignableValue(node->value()->token_pos(), |
| 3688 store_value, | 3722 store_value, |
| 3689 type, | 3723 type, |
| 3690 dst_name); | 3724 dst_name); |
| 3691 } | 3725 } |
| 3692 | 3726 |
| 3693 if (FLAG_use_field_guards) { | 3727 if (FLAG_use_field_guards) { |
| 3694 store_value = Bind(BuildStoreExprTemp(store_value)); | 3728 store_value = Bind(BuildStoreExprTemp(store_value, token_pos)); |
| 3695 GuardFieldClassInstr* guard_field_class = | 3729 GuardFieldClassInstr* guard_field_class = |
| 3696 new(Z) GuardFieldClassInstr(store_value, | 3730 new(Z) GuardFieldClassInstr(store_value, |
| 3697 node->field(), | 3731 node->field(), |
| 3698 thread()->GetNextDeoptId()); | 3732 thread()->GetNextDeoptId()); |
| 3699 AddInstruction(guard_field_class); | 3733 AddInstruction(guard_field_class); |
| 3700 store_value = Bind(BuildLoadExprTemp()); | 3734 store_value = Bind(BuildLoadExprTemp(token_pos)); |
| 3701 GuardFieldLengthInstr* guard_field_length = | 3735 GuardFieldLengthInstr* guard_field_length = |
| 3702 new(Z) GuardFieldLengthInstr(store_value, | 3736 new(Z) GuardFieldLengthInstr(store_value, |
| 3703 node->field(), | 3737 node->field(), |
| 3704 thread()->GetNextDeoptId()); | 3738 thread()->GetNextDeoptId()); |
| 3705 AddInstruction(guard_field_length); | 3739 AddInstruction(guard_field_length); |
| 3706 store_value = Bind(BuildLoadExprTemp()); | 3740 store_value = Bind(BuildLoadExprTemp(token_pos)); |
| 3707 } | 3741 } |
| 3708 StoreInstanceFieldInstr* store = | 3742 StoreInstanceFieldInstr* store = |
| 3709 new(Z) StoreInstanceFieldInstr(node->field(), | 3743 new(Z) StoreInstanceFieldInstr(node->field(), |
| 3710 for_instance.value(), | 3744 for_instance.value(), |
| 3711 store_value, | 3745 store_value, |
| 3712 kEmitStoreBarrier, | 3746 kEmitStoreBarrier, |
| 3713 node->token_pos()); | 3747 token_pos); |
| 3714 // Maybe initializing unboxed store. | 3748 // Maybe initializing unboxed store. |
| 3715 store->set_is_potential_unboxed_initialization(true); | 3749 store->set_is_potential_unboxed_initialization(true); |
| 3716 ReturnDefinition(store); | 3750 ReturnDefinition(store); |
| 3717 } | 3751 } |
| 3718 | 3752 |
| 3719 | 3753 |
| 3720 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { | 3754 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) { |
| 3721 const intptr_t token_pos = node->token_pos(); | 3755 const intptr_t token_pos = node->token_pos(); |
| 3722 if (node->field().is_const()) { | 3756 if (node->field().is_const()) { |
| 3723 ASSERT(node->field().StaticValue() != Object::sentinel().raw()); | 3757 ASSERT(node->field().StaticValue() != Object::sentinel().raw()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3736 | 3770 |
| 3737 Definition* EffectGraphVisitor::BuildStoreStaticField( | 3771 Definition* EffectGraphVisitor::BuildStoreStaticField( |
| 3738 StoreStaticFieldNode* node, | 3772 StoreStaticFieldNode* node, |
| 3739 bool result_is_needed, | 3773 bool result_is_needed, |
| 3740 intptr_t token_pos) { | 3774 intptr_t token_pos) { |
| 3741 ValueGraphVisitor for_value(owner()); | 3775 ValueGraphVisitor for_value(owner()); |
| 3742 node->value()->Visit(&for_value); | 3776 node->value()->Visit(&for_value); |
| 3743 Append(for_value); | 3777 Append(for_value); |
| 3744 Value* store_value = NULL; | 3778 Value* store_value = NULL; |
| 3745 if (result_is_needed) { | 3779 if (result_is_needed) { |
| 3746 store_value = Bind(BuildStoreExprTemp(for_value.value())); | 3780 store_value = Bind(BuildStoreExprTemp(for_value.value(), token_pos)); |
| 3747 } else { | 3781 } else { |
| 3748 store_value = for_value.value(); | 3782 store_value = for_value.value(); |
| 3749 } | 3783 } |
| 3750 StoreStaticFieldInstr* store = | 3784 StoreStaticFieldInstr* store = |
| 3751 new(Z) StoreStaticFieldInstr(node->field(), store_value, token_pos); | 3785 new(Z) StoreStaticFieldInstr(node->field(), store_value, token_pos); |
| 3752 | 3786 |
| 3753 if (result_is_needed) { | 3787 if (result_is_needed) { |
| 3754 Do(store); | 3788 Do(store); |
| 3755 return BuildLoadExprTemp(); | 3789 return BuildLoadExprTemp(token_pos); |
| 3756 } else { | 3790 } else { |
| 3757 return store; | 3791 return store; |
| 3758 } | 3792 } |
| 3759 } | 3793 } |
| 3760 | 3794 |
| 3761 | 3795 |
| 3762 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { | 3796 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) { |
| 3763 ReturnDefinition( | 3797 ReturnDefinition( |
| 3764 BuildStoreStaticField(node, kResultNotNeeded, node->token_pos())); | 3798 BuildStoreStaticField(node, kResultNotNeeded, node->token_pos())); |
| 3765 } | 3799 } |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3828 owner()->ic_data_array()); | 3862 owner()->ic_data_array()); |
| 3829 ReturnDefinition(load); | 3863 ReturnDefinition(load); |
| 3830 } | 3864 } |
| 3831 } | 3865 } |
| 3832 | 3866 |
| 3833 | 3867 |
| 3834 Definition* EffectGraphVisitor::BuildStoreIndexedValues( | 3868 Definition* EffectGraphVisitor::BuildStoreIndexedValues( |
| 3835 StoreIndexedNode* node, | 3869 StoreIndexedNode* node, |
| 3836 bool result_is_needed) { | 3870 bool result_is_needed) { |
| 3837 Function* super_function = NULL; | 3871 Function* super_function = NULL; |
| 3872 const intptr_t token_pos = node->token_pos(); |
| 3838 if (node->IsSuperStore()) { | 3873 if (node->IsSuperStore()) { |
| 3839 // Resolve the store indexed operator in the super class. | 3874 // Resolve the store indexed operator in the super class. |
| 3840 super_function = &Function::ZoneHandle( | 3875 super_function = &Function::ZoneHandle( |
| 3841 Z, Resolver::ResolveDynamicAnyArgs(node->super_class(), | 3876 Z, Resolver::ResolveDynamicAnyArgs(node->super_class(), |
| 3842 Symbols::AssignIndexToken())); | 3877 Symbols::AssignIndexToken())); |
| 3843 if (super_function->IsNull()) { | 3878 if (super_function->IsNull()) { |
| 3844 // Could not resolve super operator. Generate call noSuchMethod() of the | 3879 // Could not resolve super operator. Generate call noSuchMethod() of the |
| 3845 // super class instead. | 3880 // super class instead. |
| 3846 ArgumentListNode* arguments = new(Z) ArgumentListNode(node->token_pos()); | 3881 ArgumentListNode* arguments = new(Z) ArgumentListNode(token_pos); |
| 3847 arguments->Add(node->array()); | 3882 arguments->Add(node->array()); |
| 3848 arguments->Add(node->index_expr()); | 3883 arguments->Add(node->index_expr()); |
| 3849 arguments->Add(node->value()); | 3884 arguments->Add(node->value()); |
| 3850 StaticCallInstr* call = BuildStaticNoSuchMethodCall( | 3885 StaticCallInstr* call = BuildStaticNoSuchMethodCall( |
| 3851 node->super_class(), | 3886 node->super_class(), |
| 3852 node->array(), | 3887 node->array(), |
| 3853 Symbols::AssignIndexToken(), | 3888 Symbols::AssignIndexToken(), |
| 3854 arguments, | 3889 arguments, |
| 3855 result_is_needed, // Save last arg if result is needed. | 3890 result_is_needed, // Save last arg if result is needed. |
| 3856 true); // Super invocation. | 3891 true); // Super invocation. |
| 3857 if (result_is_needed) { | 3892 if (result_is_needed) { |
| 3858 Do(call); | 3893 Do(call); |
| 3859 // BuildStaticNoSuchMethodCall stores the value in expression_temp. | 3894 // BuildStaticNoSuchMethodCall stores the value in expression_temp. |
| 3860 return BuildLoadExprTemp(); | 3895 return BuildLoadExprTemp(token_pos); |
| 3861 } else { | 3896 } else { |
| 3862 return call; | 3897 return call; |
| 3863 } | 3898 } |
| 3864 } | 3899 } |
| 3865 } | 3900 } |
| 3866 | 3901 |
| 3867 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 3902 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
| 3868 new(Z) ZoneGrowableArray<PushArgumentInstr*>(3); | 3903 new(Z) ZoneGrowableArray<PushArgumentInstr*>(3); |
| 3869 ValueGraphVisitor for_array(owner()); | 3904 ValueGraphVisitor for_array(owner()); |
| 3870 node->array()->Visit(&for_array); | 3905 node->array()->Visit(&for_array); |
| 3871 Append(for_array); | 3906 Append(for_array); |
| 3872 arguments->Add(PushArgument(for_array.value())); | 3907 arguments->Add(PushArgument(for_array.value())); |
| 3873 | 3908 |
| 3874 ValueGraphVisitor for_index(owner()); | 3909 ValueGraphVisitor for_index(owner()); |
| 3875 node->index_expr()->Visit(&for_index); | 3910 node->index_expr()->Visit(&for_index); |
| 3876 Append(for_index); | 3911 Append(for_index); |
| 3877 arguments->Add(PushArgument(for_index.value())); | 3912 arguments->Add(PushArgument(for_index.value())); |
| 3878 | 3913 |
| 3879 ValueGraphVisitor for_value(owner()); | 3914 ValueGraphVisitor for_value(owner()); |
| 3880 node->value()->Visit(&for_value); | 3915 node->value()->Visit(&for_value); |
| 3881 Append(for_value); | 3916 Append(for_value); |
| 3882 Value* value = NULL; | 3917 Value* value = NULL; |
| 3883 if (result_is_needed) { | 3918 if (result_is_needed) { |
| 3884 value = Bind(BuildStoreExprTemp(for_value.value())); | 3919 value = Bind(BuildStoreExprTemp(for_value.value(), token_pos)); |
| 3885 } else { | 3920 } else { |
| 3886 value = for_value.value(); | 3921 value = for_value.value(); |
| 3887 } | 3922 } |
| 3888 arguments->Add(PushArgument(value)); | 3923 arguments->Add(PushArgument(value)); |
| 3889 | 3924 |
| 3890 if (super_function != NULL) { | 3925 if (super_function != NULL) { |
| 3891 // Generate static call to super operator []=. | 3926 // Generate static call to super operator []=. |
| 3892 | 3927 |
| 3893 StaticCallInstr* store = | 3928 StaticCallInstr* store = |
| 3894 new(Z) StaticCallInstr(node->token_pos(), | 3929 new(Z) StaticCallInstr(token_pos, |
| 3895 *super_function, | 3930 *super_function, |
| 3896 Object::null_array(), | 3931 Object::null_array(), |
| 3897 arguments, | 3932 arguments, |
| 3898 owner()->ic_data_array()); | 3933 owner()->ic_data_array()); |
| 3899 if (result_is_needed) { | 3934 if (result_is_needed) { |
| 3900 Do(store); | 3935 Do(store); |
| 3901 return BuildLoadExprTemp(); | 3936 return BuildLoadExprTemp(token_pos); |
| 3902 } else { | 3937 } else { |
| 3903 return store; | 3938 return store; |
| 3904 } | 3939 } |
| 3905 } else { | 3940 } else { |
| 3906 // Generate dynamic call to operator []=. | 3941 // Generate dynamic call to operator []=. |
| 3907 const intptr_t checked_argument_count = 2; // Do not check for value type. | 3942 const intptr_t checked_argument_count = 2; // Do not check for value type. |
| 3908 const String& name = | 3943 const String& name = |
| 3909 String::ZoneHandle(Z, Symbols::New(Token::Str(Token::kASSIGN_INDEX))); | 3944 String::ZoneHandle(Z, Symbols::New(Token::Str(Token::kASSIGN_INDEX))); |
| 3910 InstanceCallInstr* store = | 3945 InstanceCallInstr* store = |
| 3911 new(Z) InstanceCallInstr(node->token_pos(), | 3946 new(Z) InstanceCallInstr(token_pos, |
| 3912 name, | 3947 name, |
| 3913 Token::kASSIGN_INDEX, | 3948 Token::kASSIGN_INDEX, |
| 3914 arguments, | 3949 arguments, |
| 3915 Object::null_array(), | 3950 Object::null_array(), |
| 3916 checked_argument_count, | 3951 checked_argument_count, |
| 3917 owner()->ic_data_array()); | 3952 owner()->ic_data_array()); |
| 3918 if (result_is_needed) { | 3953 if (result_is_needed) { |
| 3919 Do(store); | 3954 Do(store); |
| 3920 return BuildLoadExprTemp(); | 3955 return BuildLoadExprTemp(token_pos); |
| 3921 } else { | 3956 } else { |
| 3922 return store; | 3957 return store; |
| 3923 } | 3958 } |
| 3924 } | 3959 } |
| 3925 } | 3960 } |
| 3926 | 3961 |
| 3927 | 3962 |
| 3928 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { | 3963 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) { |
| 3929 ReturnDefinition(BuildStoreIndexedValues(node, kResultNotNeeded)); | 3964 ReturnDefinition(BuildStoreIndexedValues(node, kResultNotNeeded)); |
| 3930 } | 3965 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4001 ASSERT((node->label() == NULL) || !is_top_level_sequence); | 4036 ASSERT((node->label() == NULL) || !is_top_level_sequence); |
| 4002 NestedBlock nested_block(owner(), node); | 4037 NestedBlock nested_block(owner(), node); |
| 4003 | 4038 |
| 4004 if (num_context_variables > 0) { | 4039 if (num_context_variables > 0) { |
| 4005 // The local scope declares variables that are captured. | 4040 // The local scope declares variables that are captured. |
| 4006 // Allocate and chain a new context (Except don't chain when at the function | 4041 // Allocate and chain a new context (Except don't chain when at the function |
| 4007 // entry if the function does not capture any variables from outer scopes). | 4042 // entry if the function does not capture any variables from outer scopes). |
| 4008 Value* allocated_context = | 4043 Value* allocated_context = |
| 4009 Bind(new(Z) AllocateContextInstr(node->token_pos(), | 4044 Bind(new(Z) AllocateContextInstr(node->token_pos(), |
| 4010 num_context_variables)); | 4045 num_context_variables)); |
| 4011 { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context); | 4046 { LocalVariable* tmp_var = |
| 4047 EnterTempLocalScope(allocated_context, node->token_pos()); |
| 4012 if (!is_top_level_sequence || HasContextScope()) { | 4048 if (!is_top_level_sequence || HasContextScope()) { |
| 4013 ASSERT(is_top_level_sequence || | 4049 ASSERT(is_top_level_sequence || |
| 4014 (nested_block.ContextLevel() == | 4050 (nested_block.ContextLevel() == |
| 4015 nested_block.outer()->ContextLevel() + 1)); | 4051 nested_block.outer()->ContextLevel() + 1)); |
| 4016 Value* tmp_val = Bind( | 4052 Value* tmp_val = Bind( |
| 4017 new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); | 4053 new(Z) LoadLocalInstr(*tmp_var, node->token_pos())); |
| 4018 Value* parent_context = Bind(BuildCurrentContext(node->token_pos())); | 4054 Value* parent_context = Bind(BuildCurrentContext(node->token_pos())); |
| 4019 Do(new(Z) StoreInstanceFieldInstr(Context::parent_offset(), | 4055 Do(new(Z) StoreInstanceFieldInstr(Context::parent_offset(), |
| 4020 tmp_val, | 4056 tmp_val, |
| 4021 parent_context, | 4057 parent_context, |
| 4022 kEmitStoreBarrier, | 4058 kEmitStoreBarrier, |
| 4023 node->token_pos())); | 4059 node->token_pos())); |
| 4024 } | 4060 } |
| 4025 Do(BuildStoreContext( | 4061 Do(BuildStoreContext( |
| 4026 Bind(ExitTempLocalScope(tmp_var)), | 4062 Bind(ExitTempLocalScope(tmp_var, node->token_pos())), |
| 4027 node->token_pos())); | 4063 node->token_pos())); |
| 4028 } | 4064 } |
| 4029 | 4065 |
| 4030 // If this node_sequence is the body of the function being compiled, copy | 4066 // If this node_sequence is the body of the function being compiled, copy |
| 4031 // the captured parameters from the frame into the context. | 4067 // the captured parameters from the frame into the context. |
| 4032 if (is_top_level_sequence) { | 4068 if (is_top_level_sequence) { |
| 4033 ASSERT(scope->context_level() == 1); | 4069 ASSERT(scope->context_level() == 1); |
| 4034 const int num_params = function.NumParameters(); | 4070 const int num_params = function.NumParameters(); |
| 4035 int param_frame_index = (num_params == function.num_fixed_parameters()) ? | 4071 int param_frame_index = (num_params == function.num_fixed_parameters()) ? |
| 4036 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp; | 4072 (kParamEndSlotFromFp + num_params) : kFirstLocalSlotFromFp; |
| 4037 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { | 4073 for (int pos = 0; pos < num_params; param_frame_index--, pos++) { |
| 4038 const LocalVariable& parameter = *scope->VariableAt(pos); | 4074 const LocalVariable& parameter = *scope->VariableAt(pos); |
| 4039 ASSERT(parameter.owner() == scope); | 4075 ASSERT(parameter.owner() == scope); |
| 4040 if (parameter.is_captured()) { | 4076 if (parameter.is_captured()) { |
| 4041 // Create a temporary local describing the original position. | 4077 // Create a temporary local describing the original position. |
| 4042 const String& temp_name = Symbols::TempParam(); | 4078 const String& temp_name = Symbols::TempParam(); |
| 4043 LocalVariable* temp_local = new(Z) LocalVariable( | 4079 LocalVariable* temp_local = new(Z) LocalVariable( |
| 4044 Scanner::kNoSourcePos, // Token index. | 4080 Token::kNoSourcePos, // Token index. |
| 4045 temp_name, | 4081 temp_name, |
| 4046 Object::dynamic_type()); // Type. | 4082 Object::dynamic_type()); // Type. |
| 4047 temp_local->set_index(param_frame_index); | 4083 temp_local->set_index(param_frame_index); |
| 4048 | 4084 |
| 4049 // Mark this local as captured parameter so that the optimizer | 4085 // Mark this local as captured parameter so that the optimizer |
| 4050 // correctly handles these when compiling try-catch: Captured | 4086 // correctly handles these when compiling try-catch: Captured |
| 4051 // parameters are not in the stack environment, therefore they | 4087 // parameters are not in the stack environment, therefore they |
| 4052 // must be skipped when emitting sync-code in try-blocks. | 4088 // must be skipped when emitting sync-code in try-blocks. |
| 4053 temp_local->set_is_captured_parameter(true); | 4089 temp_local->set_is_captured_parameter(true); |
| 4054 | 4090 |
| 4055 // Copy parameter from local frame to current context. | 4091 // Copy parameter from local frame to current context. |
| 4056 Value* load = Bind(BuildLoadLocal(*temp_local)); | 4092 Value* load = Bind(BuildLoadLocal(*temp_local, node->token_pos())); |
| 4057 Do(BuildStoreLocal(parameter, load)); | 4093 Do(BuildStoreLocal(parameter, load, ST(node->token_pos()))); |
| 4058 // Write NULL to the source location to detect buggy accesses and | 4094 // Write NULL to the source location to detect buggy accesses and |
| 4059 // allow GC of passed value if it gets overwritten by a new value in | 4095 // allow GC of passed value if it gets overwritten by a new value in |
| 4060 // the function. | 4096 // the function. |
| 4061 Value* null_constant = Bind(new(Z) ConstantInstr( | 4097 Value* null_constant = Bind(new(Z) ConstantInstr( |
| 4062 Object::ZoneHandle(Z, Object::null()))); | 4098 Object::ZoneHandle(Z, Object::null()))); |
| 4063 Do(BuildStoreLocal(*temp_local, null_constant)); | 4099 Do(BuildStoreLocal(*temp_local, |
| 4100 null_constant, |
| 4101 ST(node->token_pos()))); |
| 4064 } | 4102 } |
| 4065 } | 4103 } |
| 4066 } | 4104 } |
| 4067 } | 4105 } |
| 4068 | 4106 |
| 4069 if (FLAG_support_debugger && | 4107 if (FLAG_support_debugger && |
| 4070 is_top_level_sequence && | 4108 is_top_level_sequence && |
| 4071 function.is_debuggable()) { | 4109 function.is_debuggable()) { |
| 4072 // Place a debug check at method entry to ensure breaking on a method always | 4110 // Place a debug check at method entry to ensure breaking on a method always |
| 4073 // happens, even if there are no assignments/calls/runtimecalls in the first | 4111 // happens, even if there are no assignments/calls/runtimecalls in the first |
| 4074 // basic block. Place this check at the last parameter to ensure parameters | 4112 // basic block. Place this check at the last parameter to ensure parameters |
| 4075 // are in scope in the debugger at method entry. | 4113 // are in scope in the debugger at method entry. |
| 4076 const int num_params = function.NumParameters(); | 4114 const int num_params = function.NumParameters(); |
| 4077 intptr_t check_pos = Scanner::kNoSourcePos; | 4115 intptr_t check_pos = Token::kNoSourcePos; |
| 4078 if (num_params > 0) { | 4116 if (num_params > 0) { |
| 4079 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); | 4117 const LocalVariable& parameter = *scope->VariableAt(num_params - 1); |
| 4080 check_pos = parameter.token_pos(); | 4118 check_pos = parameter.token_pos(); |
| 4081 } | 4119 } |
| 4082 if (check_pos < 0) { | 4120 if (!Token::IsDebugPause(check_pos)) { |
| 4083 // No parameters or synthetic parameters. | 4121 // No parameters or synthetic parameters. |
| 4084 check_pos = node->token_pos(); | 4122 check_pos = node->token_pos(); |
| 4085 ASSERT(check_pos >= 0); | 4123 ASSERT(Token::IsDebugPause(check_pos)); |
| 4086 } | 4124 } |
| 4087 AddInstruction(new(Z) DebugStepCheckInstr(check_pos, | 4125 AddInstruction(new(Z) DebugStepCheckInstr(check_pos, |
| 4088 RawPcDescriptors::kRuntimeCall)); | 4126 RawPcDescriptors::kRuntimeCall)); |
| 4089 } | 4127 } |
| 4090 | 4128 |
| 4091 // This check may be deleted if the generated code is leaf. | 4129 // This check may be deleted if the generated code is leaf. |
| 4092 // Native functions don't need a stack check at entry. | 4130 // Native functions don't need a stack check at entry. |
| 4093 if (is_top_level_sequence && !function.is_native()) { | 4131 if (is_top_level_sequence && !function.is_native()) { |
| 4094 // Always allocate CheckOverflowInstr so that deopt-ids match regardless | 4132 // Always allocate CheckOverflowInstr so that deopt-ids match regardless |
| 4095 // if we inline or not. | 4133 // if we inline or not. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 4115 // Skip type checking of receiver for instance functions and constructors. | 4153 // Skip type checking of receiver for instance functions and constructors. |
| 4116 pos = 1; | 4154 pos = 1; |
| 4117 } | 4155 } |
| 4118 while (pos < num_params) { | 4156 while (pos < num_params) { |
| 4119 const LocalVariable& parameter = *scope->VariableAt(pos); | 4157 const LocalVariable& parameter = *scope->VariableAt(pos); |
| 4120 ASSERT(parameter.owner() == scope); | 4158 ASSERT(parameter.owner() == scope); |
| 4121 if (!CanSkipTypeCheck(parameter.token_pos(), | 4159 if (!CanSkipTypeCheck(parameter.token_pos(), |
| 4122 NULL, | 4160 NULL, |
| 4123 parameter.type(), | 4161 parameter.type(), |
| 4124 parameter.name())) { | 4162 parameter.name())) { |
| 4125 Value* parameter_value = Bind(BuildLoadLocal(parameter)); | 4163 Value* parameter_value = |
| 4164 Bind(BuildLoadLocal(parameter, parameter.token_pos())); |
| 4126 Do(BuildAssertAssignable(parameter.token_pos(), | 4165 Do(BuildAssertAssignable(parameter.token_pos(), |
| 4127 parameter_value, | 4166 parameter_value, |
| 4128 parameter.type(), | 4167 parameter.type(), |
| 4129 parameter.name())); | 4168 parameter.name())); |
| 4130 } | 4169 } |
| 4131 pos++; | 4170 pos++; |
| 4132 } | 4171 } |
| 4133 } | 4172 } |
| 4134 | 4173 |
| 4135 // Continuation part: | 4174 // Continuation part: |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4174 LocalScope* top_scope = node->scope(); | 4213 LocalScope* top_scope = node->scope(); |
| 4175 LocalVariable* jump_var = top_scope->LookupVariable( | 4214 LocalVariable* jump_var = top_scope->LookupVariable( |
| 4176 Symbols::AwaitJumpVar(), false); | 4215 Symbols::AwaitJumpVar(), false); |
| 4177 ASSERT(jump_var != NULL && jump_var->is_captured()); | 4216 ASSERT(jump_var != NULL && jump_var->is_captured()); |
| 4178 Instruction* saved_entry = entry_; | 4217 Instruction* saved_entry = entry_; |
| 4179 Instruction* saved_exit = exit_; | 4218 Instruction* saved_exit = exit_; |
| 4180 entry_ = NULL; | 4219 entry_ = NULL; |
| 4181 exit_ = NULL; | 4220 exit_ = NULL; |
| 4182 | 4221 |
| 4183 LoadLocalNode* load_jump_count = | 4222 LoadLocalNode* load_jump_count = |
| 4184 new(Z) LoadLocalNode(Scanner::kNoSourcePos, jump_var); | 4223 new(Z) LoadLocalNode(node->token_pos(), jump_var); |
| 4185 ComparisonNode* check_jump_count; | 4224 ComparisonNode* check_jump_count; |
| 4186 const intptr_t num_await_states = owner()->await_joins()->length(); | 4225 const intptr_t num_await_states = owner()->await_joins()->length(); |
| 4187 | 4226 |
| 4188 LocalVariable* old_context = top_scope->LookupVariable( | 4227 LocalVariable* old_context = top_scope->LookupVariable( |
| 4189 Symbols::AwaitContextVar(), false); | 4228 Symbols::AwaitContextVar(), false); |
| 4190 for (intptr_t i = 0; i < num_await_states; i++) { | 4229 for (intptr_t i = 0; i < num_await_states; i++) { |
| 4191 check_jump_count = new(Z) ComparisonNode( | 4230 check_jump_count = new(Z) ComparisonNode( |
| 4192 Scanner::kNoSourcePos, | 4231 ST(node->token_pos()), |
| 4193 Token::kEQ, | 4232 Token::kEQ, |
| 4194 load_jump_count, | 4233 load_jump_count, |
| 4195 new(Z) LiteralNode( | 4234 new(Z) LiteralNode( |
| 4196 Scanner::kNoSourcePos, Smi::ZoneHandle(Z, Smi::New(i)))); | 4235 ST(node->token_pos()), Smi::ZoneHandle(Z, Smi::New(i)))); |
| 4197 TestGraphVisitor for_test(owner(), Scanner::kNoSourcePos); | 4236 TestGraphVisitor for_test(owner(), ST(node->token_pos())); |
| 4198 check_jump_count->Visit(&for_test); | 4237 check_jump_count->Visit(&for_test); |
| 4199 EffectGraphVisitor for_true(owner()); | 4238 EffectGraphVisitor for_true(owner()); |
| 4200 EffectGraphVisitor for_false(owner()); | 4239 EffectGraphVisitor for_false(owner()); |
| 4201 | 4240 |
| 4202 // Build async jump or sync yield jump. | 4241 // Build async jump or sync yield jump. |
| 4203 ASSERT(function.IsAsyncClosure() || | 4242 ASSERT(function.IsAsyncClosure() || |
| 4204 function.IsAsyncGenClosure() || | 4243 function.IsAsyncGenClosure() || |
| 4205 function.IsSyncGenClosure()); | 4244 function.IsSyncGenClosure()); |
| 4206 | 4245 |
| 4207 // Restore the saved continuation context, i.e. the context that was | 4246 // Restore the saved continuation context, i.e. the context that was |
| 4208 // saved into :await_ctx_var before the closure suspended. | 4247 // saved into :await_ctx_var before the closure suspended. |
| 4209 for_true.BuildRestoreContext(*old_context, Scanner::kNoSourcePos); | 4248 for_true.BuildRestoreContext(*old_context, ST(node->token_pos())); |
| 4210 | 4249 |
| 4211 // Goto saved join. | 4250 // Goto saved join. |
| 4212 for_true.Goto((*owner()->await_joins())[i]); | 4251 for_true.Goto((*owner()->await_joins())[i]); |
| 4213 | 4252 |
| 4214 Join(for_test, for_true, for_false); | 4253 Join(for_test, for_true, for_false); |
| 4215 if (i == 0) { | 4254 if (i == 0) { |
| 4216 // Manually link up the preamble start. | 4255 // Manually link up the preamble start. |
| 4217 preamble_start->previous()->set_next(for_test.entry()); | 4256 preamble_start->previous()->set_next(for_test.entry()); |
| 4218 for_test.entry()->set_previous(preamble_start->previous()); | 4257 for_test.entry()->set_previous(preamble_start->previous()); |
| 4219 } | 4258 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4257 | 4296 |
| 4258 | 4297 |
| 4259 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { | 4298 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) { |
| 4260 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); | 4299 InlineBailout("EffectGraphVisitor::VisitTryCatchNode (exception)"); |
| 4261 const intptr_t original_handler_index = owner()->try_index(); | 4300 const intptr_t original_handler_index = owner()->try_index(); |
| 4262 const intptr_t try_handler_index = node->try_index(); | 4301 const intptr_t try_handler_index = node->try_index(); |
| 4263 ASSERT(try_handler_index != original_handler_index); | 4302 ASSERT(try_handler_index != original_handler_index); |
| 4264 owner()->set_try_index(try_handler_index); | 4303 owner()->set_try_index(try_handler_index); |
| 4265 | 4304 |
| 4266 // Preserve current context into local variable ':saved_try_context_var'. | 4305 // Preserve current context into local variable ':saved_try_context_var'. |
| 4267 BuildSaveContext(node->context_var(), node->token_pos()); | 4306 BuildSaveContext(node->context_var(), ST(node->token_pos())); |
| 4268 | 4307 |
| 4269 EffectGraphVisitor for_try(owner()); | 4308 EffectGraphVisitor for_try(owner()); |
| 4270 node->try_block()->Visit(&for_try); | 4309 node->try_block()->Visit(&for_try); |
| 4271 | 4310 |
| 4272 if (for_try.is_open()) { | 4311 if (for_try.is_open()) { |
| 4273 JoinEntryInstr* after_try = | 4312 JoinEntryInstr* after_try = |
| 4274 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), | 4313 new(Z) JoinEntryInstr(owner()->AllocateBlockId(), |
| 4275 original_handler_index); | 4314 original_handler_index); |
| 4276 for_try.Goto(after_try); | 4315 for_try.Goto(after_try); |
| 4277 for_try.exit_ = after_try; | 4316 for_try.exit_ = after_try; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4334 // Create a handler for the code in the catch block, containing the | 4373 // Create a handler for the code in the catch block, containing the |
| 4335 // code in the finally block. | 4374 // code in the finally block. |
| 4336 owner()->set_try_index(original_handler_index); | 4375 owner()->set_try_index(original_handler_index); |
| 4337 EffectGraphVisitor for_finally(owner()); | 4376 EffectGraphVisitor for_finally(owner()); |
| 4338 for_finally.BuildRestoreContext(catch_block->context_var(), | 4377 for_finally.BuildRestoreContext(catch_block->context_var(), |
| 4339 finally_block->token_pos()); | 4378 finally_block->token_pos()); |
| 4340 | 4379 |
| 4341 node->rethrow_clause()->Visit(&for_finally); | 4380 node->rethrow_clause()->Visit(&for_finally); |
| 4342 if (for_finally.is_open()) { | 4381 if (for_finally.is_open()) { |
| 4343 // Rethrow the exception. Manually build the graph for rethrow. | 4382 // Rethrow the exception. Manually build the graph for rethrow. |
| 4344 Value* exception = for_finally.Bind( | 4383 Value* exception = for_finally.Bind(for_finally.BuildLoadLocal( |
| 4345 for_finally.BuildLoadLocal(catch_block->rethrow_exception_var())); | 4384 catch_block->rethrow_exception_var(), finally_block->token_pos())); |
| 4346 for_finally.PushArgument(exception); | 4385 for_finally.PushArgument(exception); |
| 4347 Value* stacktrace = for_finally.Bind( | 4386 Value* stacktrace = for_finally.Bind(for_finally.BuildLoadLocal( |
| 4348 for_finally.BuildLoadLocal(catch_block->rethrow_stacktrace_var())); | 4387 catch_block->rethrow_stacktrace_var(), finally_block->token_pos())); |
| 4349 for_finally.PushArgument(stacktrace); | 4388 for_finally.PushArgument(stacktrace); |
| 4350 for_finally.AddInstruction( | 4389 for_finally.AddInstruction( |
| 4351 new(Z) ReThrowInstr(catch_block->token_pos(), catch_handler_index)); | 4390 new(Z) ReThrowInstr(catch_block->token_pos(), catch_handler_index)); |
| 4352 for_finally.CloseFragment(); | 4391 for_finally.CloseFragment(); |
| 4353 } | 4392 } |
| 4354 ASSERT(!for_finally.is_open()); | 4393 ASSERT(!for_finally.is_open()); |
| 4355 | 4394 |
| 4356 const Array& types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld)); | 4395 const Array& types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld)); |
| 4357 types.SetAt(0, Object::dynamic_type()); | 4396 types.SetAt(0, Object::dynamic_type()); |
| 4358 CatchBlockEntryInstr* finally_entry = | 4397 CatchBlockEntryInstr* finally_entry = |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4622 Script::Handle(function.script()), | 4661 Script::Handle(function.script()), |
| 4623 function.token_pos(), | 4662 function.token_pos(), |
| 4624 Report::AtLocation, | 4663 Report::AtLocation, |
| 4625 "FlowGraphBuilder Bailout: %s %s", | 4664 "FlowGraphBuilder Bailout: %s %s", |
| 4626 String::Handle(function.name()).ToCString(), | 4665 String::Handle(function.name()).ToCString(), |
| 4627 reason); | 4666 reason); |
| 4628 UNREACHABLE(); | 4667 UNREACHABLE(); |
| 4629 } | 4668 } |
| 4630 | 4669 |
| 4631 } // namespace dart | 4670 } // namespace dart |
| OLD | NEW |