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 1451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1462 arguments, | 1462 arguments, |
1463 Object::null_array(), | 1463 Object::null_array(), |
1464 kNumArgsChecked, | 1464 kNumArgsChecked, |
1465 owner()->ic_data_array()); | 1465 owner()->ic_data_array()); |
1466 ReturnDefinition(call); | 1466 ReturnDefinition(call); |
1467 } | 1467 } |
1468 | 1468 |
1469 | 1469 |
1470 void EffectGraphVisitor::BuildTypecheckPushArguments( | 1470 void EffectGraphVisitor::BuildTypecheckPushArguments( |
1471 intptr_t token_pos, | 1471 intptr_t token_pos, |
1472 PushArgumentInstr** push_instantiator_result, | |
1473 PushArgumentInstr** push_instantiator_type_arguments_result) { | 1472 PushArgumentInstr** push_instantiator_type_arguments_result) { |
1474 const Class& instantiator_class = Class::Handle( | 1473 const Class& instantiator_class = Class::Handle( |
1475 Z, owner()->function().Owner()); | 1474 Z, owner()->function().Owner()); |
1476 // Since called only when type tested against is not instantiated. | 1475 // Since called only when type tested against is not instantiated. |
1477 ASSERT(instantiator_class.NumTypeParameters() > 0); | 1476 ASSERT(instantiator_class.NumTypeParameters() > 0); |
1478 Value* instantiator_type_arguments = NULL; | 1477 Value* instantiator_type_arguments = NULL; |
1479 Value* instantiator = BuildInstantiator(instantiator_class); | 1478 Value* instantiator = BuildInstantiator(instantiator_class); |
1480 if (instantiator == NULL) { | 1479 if (instantiator == NULL) { |
1481 // No instantiator when inside factory. | 1480 // No instantiator when inside factory. |
1482 *push_instantiator_result = PushArgument(BuildNullValue()); | |
1483 instantiator_type_arguments = | 1481 instantiator_type_arguments = |
1484 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 1482 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
1485 } else { | 1483 } else { |
1486 instantiator = Bind(BuildStoreExprTemp(instantiator)); | 1484 instantiator_type_arguments = BuildInstantiatorTypeArguments( |
1487 *push_instantiator_result = PushArgument(instantiator); | 1485 token_pos, instantiator_class, instantiator); |
1488 Value* loaded = Bind(BuildLoadExprTemp()); | |
1489 instantiator_type_arguments = | |
1490 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded); | |
1491 } | 1486 } |
1492 *push_instantiator_type_arguments_result = | 1487 *push_instantiator_type_arguments_result = |
1493 PushArgument(instantiator_type_arguments); | 1488 PushArgument(instantiator_type_arguments); |
1494 } | 1489 } |
1495 | 1490 |
1496 | 1491 |
1497 | 1492 |
1498 void EffectGraphVisitor::BuildTypecheckArguments( | 1493 void EffectGraphVisitor::BuildTypecheckArguments( |
1499 intptr_t token_pos, | 1494 intptr_t token_pos, |
1500 Value** instantiator_result, | |
1501 Value** instantiator_type_arguments_result) { | 1495 Value** instantiator_type_arguments_result) { |
1502 Value* instantiator = NULL; | 1496 Value* instantiator = NULL; |
1503 Value* instantiator_type_arguments = NULL; | 1497 Value* instantiator_type_arguments = NULL; |
1504 const Class& instantiator_class = Class::Handle( | 1498 const Class& instantiator_class = Class::Handle( |
1505 Z, owner()->function().Owner()); | 1499 Z, owner()->function().Owner()); |
1506 // Since called only when type tested against is not instantiated. | 1500 // Since called only when type tested against is not instantiated. |
1507 ASSERT(instantiator_class.NumTypeParameters() > 0); | 1501 ASSERT(instantiator_class.NumTypeParameters() > 0); |
1508 instantiator = BuildInstantiator(instantiator_class); | 1502 instantiator = BuildInstantiator(instantiator_class); |
1509 if (instantiator == NULL) { | 1503 if (instantiator == NULL) { |
1510 // No instantiator when inside factory. | 1504 // No instantiator when inside factory. |
1511 instantiator = BuildNullValue(); | |
1512 instantiator_type_arguments = | 1505 instantiator_type_arguments = |
1513 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); | 1506 BuildInstantiatorTypeArguments(token_pos, instantiator_class, NULL); |
1514 } else { | 1507 } else { |
1515 // Preserve instantiator. | 1508 instantiator_type_arguments = BuildInstantiatorTypeArguments( |
1516 instantiator = Bind(BuildStoreExprTemp(instantiator)); | 1509 token_pos, instantiator_class, instantiator); |
1517 Value* loaded = Bind(BuildLoadExprTemp()); | |
1518 instantiator_type_arguments = | |
1519 BuildInstantiatorTypeArguments(token_pos, instantiator_class, loaded); | |
1520 } | 1510 } |
1521 *instantiator_result = instantiator; | |
1522 *instantiator_type_arguments_result = instantiator_type_arguments; | 1511 *instantiator_type_arguments_result = instantiator_type_arguments; |
1523 } | 1512 } |
1524 | 1513 |
1525 | 1514 |
1526 Value* EffectGraphVisitor::BuildNullValue() { | 1515 Value* EffectGraphVisitor::BuildNullValue() { |
1527 return Bind(new(Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()))); | 1516 return Bind(new(Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()))); |
1528 } | 1517 } |
1529 | 1518 |
1530 | 1519 |
1531 // Used for testing incoming arguments. | 1520 // Used for testing incoming arguments. |
1532 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( | 1521 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable( |
1533 intptr_t token_pos, | 1522 intptr_t token_pos, |
1534 Value* value, | 1523 Value* value, |
1535 const AbstractType& dst_type, | 1524 const AbstractType& dst_type, |
1536 const String& dst_name) { | 1525 const String& dst_name) { |
1537 // Build the type check computation. | 1526 // Build the type check computation. |
1538 Value* instantiator = NULL; | |
1539 Value* instantiator_type_arguments = NULL; | 1527 Value* instantiator_type_arguments = NULL; |
1540 if (dst_type.IsInstantiated()) { | 1528 if (dst_type.IsInstantiated()) { |
1541 instantiator = BuildNullValue(); | |
1542 instantiator_type_arguments = BuildNullValue(); | 1529 instantiator_type_arguments = BuildNullValue(); |
1543 } else { | 1530 } else { |
1544 BuildTypecheckArguments(token_pos, | 1531 BuildTypecheckArguments(token_pos, &instantiator_type_arguments); |
1545 &instantiator, | |
1546 &instantiator_type_arguments); | |
1547 } | 1532 } |
1548 | 1533 |
1549 const intptr_t deopt_id = Thread::Current()->GetNextDeoptId(); | 1534 const intptr_t deopt_id = Thread::Current()->GetNextDeoptId(); |
1550 return new(Z) AssertAssignableInstr(token_pos, | 1535 return new(Z) AssertAssignableInstr(token_pos, |
1551 value, | 1536 value, |
1552 instantiator, | |
1553 instantiator_type_arguments, | 1537 instantiator_type_arguments, |
1554 dst_type, | 1538 dst_type, |
1555 dst_name, | 1539 dst_name, |
1556 deopt_id); | 1540 deopt_id); |
1557 } | 1541 } |
1558 | 1542 |
1559 | 1543 |
1560 // Used for type casts and to test assignments. | 1544 // Used for type casts and to test assignments. |
1561 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos, | 1545 Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos, |
1562 Value* value, | 1546 Value* value, |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1644 arguments, | 1628 arguments, |
1645 Object::null_array(), // No argument names. | 1629 Object::null_array(), // No argument names. |
1646 kNumArgsChecked, | 1630 kNumArgsChecked, |
1647 owner()->ic_data_array()); | 1631 owner()->ic_data_array()); |
1648 ReturnDefinition(call); | 1632 ReturnDefinition(call); |
1649 return; | 1633 return; |
1650 } | 1634 } |
1651 } | 1635 } |
1652 | 1636 |
1653 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); | 1637 PushArgumentInstr* push_left = PushArgument(for_left_value.value()); |
1654 PushArgumentInstr* push_instantiator = NULL; | |
1655 PushArgumentInstr* push_type_args = NULL; | 1638 PushArgumentInstr* push_type_args = NULL; |
1656 if (type.IsInstantiated()) { | 1639 if (type.IsInstantiated()) { |
1657 push_instantiator = PushArgument(BuildNullValue()); | |
1658 push_type_args = PushArgument(BuildNullValue()); | 1640 push_type_args = PushArgument(BuildNullValue()); |
1659 } else { | 1641 } else { |
1660 BuildTypecheckPushArguments(node->token_pos(), | 1642 BuildTypecheckPushArguments(node->token_pos(), &push_type_args); |
1661 &push_instantiator, | |
1662 &push_type_args); | |
1663 } | 1643 } |
1664 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1644 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
1665 new(Z) ZoneGrowableArray<PushArgumentInstr*>(5); | 1645 new(Z) ZoneGrowableArray<PushArgumentInstr*>(4); |
1666 arguments->Add(push_left); | 1646 arguments->Add(push_left); |
1667 arguments->Add(push_instantiator); | |
1668 arguments->Add(push_type_args); | 1647 arguments->Add(push_type_args); |
1669 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); | 1648 ASSERT(!node->right()->AsTypeNode()->type().IsNull()); |
1670 Value* type_const = Bind(new(Z) ConstantInstr(type)); | 1649 Value* type_const = Bind(new(Z) ConstantInstr(type)); |
1671 arguments->Add(PushArgument(type_const)); | 1650 arguments->Add(PushArgument(type_const)); |
1672 const Bool& negate = Bool::Get(node->kind() == Token::kISNOT); | 1651 const Bool& negate = Bool::Get(node->kind() == Token::kISNOT); |
1673 Value* negate_arg = Bind(new(Z) ConstantInstr(negate)); | 1652 Value* negate_arg = Bind(new(Z) ConstantInstr(negate)); |
1674 arguments->Add(PushArgument(negate_arg)); | 1653 arguments->Add(PushArgument(negate_arg)); |
1675 const intptr_t kNumArgsChecked = 1; | 1654 const intptr_t kNumArgsChecked = 1; |
1676 InstanceCallInstr* call = new(Z) InstanceCallInstr( | 1655 InstanceCallInstr* call = new(Z) InstanceCallInstr( |
1677 node->token_pos(), | 1656 node->token_pos(), |
(...skipping 23 matching lines...) Expand all Loading... |
1701 dst_name)) { | 1680 dst_name)) { |
1702 // Check for javascript compatibility. | 1681 // Check for javascript compatibility. |
1703 // Do not skip type check if javascript compatibility warning is required. | 1682 // Do not skip type check if javascript compatibility warning is required. |
1704 if (!FLAG_warn_on_javascript_compatibility || | 1683 if (!FLAG_warn_on_javascript_compatibility || |
1705 !owner()->WarnOnJSIntegralNumTypeTest(node->left(), type)) { | 1684 !owner()->WarnOnJSIntegralNumTypeTest(node->left(), type)) { |
1706 ReturnValue(for_value.value()); | 1685 ReturnValue(for_value.value()); |
1707 return; | 1686 return; |
1708 } | 1687 } |
1709 } | 1688 } |
1710 PushArgumentInstr* push_left = PushArgument(for_value.value()); | 1689 PushArgumentInstr* push_left = PushArgument(for_value.value()); |
1711 PushArgumentInstr* push_instantiator = NULL; | |
1712 PushArgumentInstr* push_type_args = NULL; | 1690 PushArgumentInstr* push_type_args = NULL; |
1713 if (type.IsInstantiated()) { | 1691 if (type.IsInstantiated()) { |
1714 push_instantiator = PushArgument(BuildNullValue()); | |
1715 push_type_args = PushArgument(BuildNullValue()); | 1692 push_type_args = PushArgument(BuildNullValue()); |
1716 } else { | 1693 } else { |
1717 BuildTypecheckPushArguments(node->token_pos(), | 1694 BuildTypecheckPushArguments(node->token_pos(), &push_type_args); |
1718 &push_instantiator, | |
1719 &push_type_args); | |
1720 } | 1695 } |
1721 ZoneGrowableArray<PushArgumentInstr*>* arguments = | 1696 ZoneGrowableArray<PushArgumentInstr*>* arguments = |
1722 new(Z) ZoneGrowableArray<PushArgumentInstr*>(4); | 1697 new(Z) ZoneGrowableArray<PushArgumentInstr*>(3); |
1723 arguments->Add(push_left); | 1698 arguments->Add(push_left); |
1724 arguments->Add(push_instantiator); | |
1725 arguments->Add(push_type_args); | 1699 arguments->Add(push_type_args); |
1726 Value* type_arg = Bind(new(Z) ConstantInstr(type)); | 1700 Value* type_arg = Bind(new(Z) ConstantInstr(type)); |
1727 arguments->Add(PushArgument(type_arg)); | 1701 arguments->Add(PushArgument(type_arg)); |
1728 const intptr_t kNumArgsChecked = 1; | 1702 const intptr_t kNumArgsChecked = 1; |
1729 InstanceCallInstr* call = new(Z) InstanceCallInstr( | 1703 InstanceCallInstr* call = new(Z) InstanceCallInstr( |
1730 node->token_pos(), | 1704 node->token_pos(), |
1731 Library::PrivateCoreLibName(Symbols::_as()), | 1705 Library::PrivateCoreLibName(Symbols::_as()), |
1732 node->kind(), | 1706 node->kind(), |
1733 arguments, | 1707 arguments, |
1734 Object::null_array(), // No argument names. | 1708 Object::null_array(), // No argument names. |
1735 kNumArgsChecked, | 1709 kNumArgsChecked, |
1736 owner()->ic_data_array()); | 1710 owner()->ic_data_array()); |
1737 ReturnDefinition(call); | 1711 ReturnDefinition(call); |
1738 } | 1712 } |
1739 | 1713 |
1740 | 1714 |
1741 StrictCompareInstr* EffectGraphVisitor::BuildStrictCompare(AstNode* left, | 1715 StrictCompareInstr* EffectGraphVisitor::BuildStrictCompare(AstNode* left, |
1742 AstNode* right, | 1716 AstNode* right, |
1743 Token::Kind kind, | 1717 Token::Kind kind, |
1744 intptr_t token_pos) { | 1718 intptr_t token_pos) { |
1745 ValueGraphVisitor for_left_value(owner()); | 1719 ValueGraphVisitor for_left_value(owner()); |
1746 left->Visit(&for_left_value); | 1720 left->Visit(&for_left_value); |
1747 Append(for_left_value); | 1721 Append(for_left_value); |
1748 ValueGraphVisitor for_right_value(owner()); | 1722 ValueGraphVisitor for_right_value(owner()); |
1749 right->Visit(&for_right_value); | 1723 right->Visit(&for_right_value); |
1750 Append(for_right_value); | 1724 Append(for_right_value); |
1751 StrictCompareInstr* comp = new(Z) StrictCompareInstr(token_pos, | 1725 StrictCompareInstr* comp = new(Z) StrictCompareInstr(token_pos, |
1752 kind, | 1726 kind, |
1753 for_left_value.value(), | 1727 for_left_value.value(), |
1754 for_right_value.value(), | 1728 for_right_value.value(), |
1755 true); // Number check. | 1729 true); // Number check. |
1756 return comp; | 1730 return comp; |
1757 } | 1731 } |
1758 | 1732 |
1759 | 1733 |
1760 // <Expression> :: Comparison { kind: Token::Kind | 1734 // <Expression> :: Comparison { kind: Token::Kind |
1761 // left: <Expression> | 1735 // left: <Expression> |
1762 // right: <Expression> } | 1736 // right: <Expression> } |
1763 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { | 1737 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) { |
1764 if (Token::IsTypeTestOperator(node->kind())) { | 1738 if (Token::IsTypeTestOperator(node->kind())) { |
1765 BuildTypeTest(node); | 1739 BuildTypeTest(node); |
(...skipping 2840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4606 Report::MessageF(Report::kBailout, | 4580 Report::MessageF(Report::kBailout, |
4607 Script::Handle(function.script()), | 4581 Script::Handle(function.script()), |
4608 function.token_pos(), | 4582 function.token_pos(), |
4609 "FlowGraphBuilder Bailout: %s %s", | 4583 "FlowGraphBuilder Bailout: %s %s", |
4610 String::Handle(function.name()).ToCString(), | 4584 String::Handle(function.name()).ToCString(), |
4611 reason); | 4585 reason); |
4612 UNREACHABLE(); | 4586 UNREACHABLE(); |
4613 } | 4587 } |
4614 | 4588 |
4615 } // namespace dart | 4589 } // namespace dart |
OLD | NEW |