| 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 |