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