OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library dart2js.ir_builder_task; | 5 library dart2js.ir_builder_task; |
6 | 6 |
7 import '../closure.dart' as closurelib; | 7 import '../closure.dart' as closurelib; |
8 import '../closure.dart' hide ClosureScope; | 8 import '../closure.dart' hide ClosureScope; |
9 import '../common/names.dart' show | 9 import '../common/names.dart' show |
10 Names, | 10 Names, |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 with IrBuilderMixin<ast.Node>, | 115 with IrBuilderMixin<ast.Node>, |
116 SemanticSendResolvedMixin<ir.Primitive, dynamic>, | 116 SemanticSendResolvedMixin<ir.Primitive, dynamic>, |
117 SendResolverMixin, | 117 SendResolverMixin, |
118 ErrorBulkMixin<ir.Primitive, dynamic>, | 118 ErrorBulkMixin<ir.Primitive, dynamic>, |
119 BaseImplementationOfStaticsMixin<ir.Primitive, dynamic>, | 119 BaseImplementationOfStaticsMixin<ir.Primitive, dynamic>, |
120 BaseImplementationOfLocalsMixin<ir.Primitive, dynamic>, | 120 BaseImplementationOfLocalsMixin<ir.Primitive, dynamic>, |
121 BaseImplementationOfDynamicsMixin<ir.Primitive, dynamic>, | 121 BaseImplementationOfDynamicsMixin<ir.Primitive, dynamic>, |
122 BaseImplementationOfConstantsMixin<ir.Primitive, dynamic>, | 122 BaseImplementationOfConstantsMixin<ir.Primitive, dynamic>, |
123 BaseImplementationOfNewMixin<ir.Primitive, dynamic>, | 123 BaseImplementationOfNewMixin<ir.Primitive, dynamic>, |
124 BaseImplementationOfCompoundsMixin<ir.Primitive, dynamic>, | 124 BaseImplementationOfCompoundsMixin<ir.Primitive, dynamic>, |
| 125 BaseImplementationOfSetIfNullsMixin<ir.Primitive, dynamic>, |
125 BaseImplementationOfIndexCompoundsMixin<ir.Primitive, dynamic> | 126 BaseImplementationOfIndexCompoundsMixin<ir.Primitive, dynamic> |
126 implements SemanticSendVisitor<ir.Primitive, dynamic> { | 127 implements SemanticSendVisitor<ir.Primitive, dynamic> { |
127 final TreeElements elements; | 128 final TreeElements elements; |
128 final Compiler compiler; | 129 final Compiler compiler; |
129 final SourceInformationBuilder sourceInformationBuilder; | 130 final SourceInformationBuilder sourceInformationBuilder; |
130 | 131 |
131 /// A map from try statements in the source to analysis information about | 132 /// A map from try statements in the source to analysis information about |
132 /// them. | 133 /// them. |
133 /// | 134 /// |
134 /// The analysis information includes the set of variables that must be | 135 /// The analysis information includes the set of variables that must be |
(...skipping 1208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1343 elements.getOperatorTypeMaskInComplexSendSet(node); | 1344 elements.getOperatorTypeMaskInComplexSendSet(node); |
1344 SourceInformation operatorSourceInformation = | 1345 SourceInformation operatorSourceInformation = |
1345 sourceInformationBuilder.buildCall(node, node.assignmentOperator); | 1346 sourceInformationBuilder.buildCall(node, node.assignmentOperator); |
1346 ir.Primitive result = irBuilder.buildDynamicInvocation( | 1347 ir.Primitive result = irBuilder.buildDynamicInvocation( |
1347 value, operatorSelector, operatorTypeMask, arguments, | 1348 value, operatorSelector, operatorTypeMask, arguments, |
1348 sourceInformation: operatorSourceInformation); | 1349 sourceInformation: operatorSourceInformation); |
1349 setValue(result); | 1350 setValue(result); |
1350 return rhs.kind == CompoundKind.POSTFIX ? value : result; | 1351 return rhs.kind == CompoundKind.POSTFIX ? value : result; |
1351 } | 1352 } |
1352 | 1353 |
| 1354 ir.Primitive translateSetIfNull( |
| 1355 ast.SendSet node, |
| 1356 {ir.Primitive getValue(), |
| 1357 ast.Node rhs, |
| 1358 void setValue(ir.Primitive value)}) { |
| 1359 ir.Primitive value = getValue(); |
| 1360 // Unlike other compound operators if-null conditionally will not do the |
| 1361 // assignment operation. |
| 1362 return irBuilder.buildIfNull(value, nested(() { |
| 1363 ir.Primitive newValue = build(rhs); |
| 1364 setValue(newValue); |
| 1365 return newValue; |
| 1366 })); |
| 1367 } |
| 1368 |
1353 @override | 1369 @override |
1354 ir.Primitive handleDynamicSet( | 1370 ir.Primitive handleDynamicSet( |
1355 ast.SendSet node, | 1371 ast.SendSet node, |
1356 ast.Node receiver, | 1372 ast.Node receiver, |
1357 Name name, | 1373 Name name, |
1358 ast.Node rhs, | 1374 ast.Node rhs, |
1359 _) { | 1375 _) { |
1360 return irBuilder.buildDynamicSet( | 1376 return irBuilder.buildDynamicSet( |
1361 translateReceiver(receiver), | 1377 translateReceiver(receiver), |
1362 new Selector.setter(name), | 1378 new Selector.setter(name), |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1446 node, | 1462 node, |
1447 getValue: () { | 1463 getValue: () { |
1448 return buildConstantExpression(constant, | 1464 return buildConstantExpression(constant, |
1449 sourceInformationBuilder.buildGet(node)); | 1465 sourceInformationBuilder.buildGet(node)); |
1450 }, | 1466 }, |
1451 rhs: rhs, | 1467 rhs: rhs, |
1452 setValue: (value) {}); // The binary operator will throw before this. | 1468 setValue: (value) {}); // The binary operator will throw before this. |
1453 } | 1469 } |
1454 | 1470 |
1455 @override | 1471 @override |
| 1472 ir.Primitive handleTypeLiteralConstantSetIfNulls( |
| 1473 ast.SendSet node, |
| 1474 ConstantExpression constant, |
| 1475 ast.Node rhs, |
| 1476 _) { |
| 1477 // The type literal is never `null`. |
| 1478 return buildConstantExpression(constant, |
| 1479 sourceInformationBuilder.buildGet(node)); |
| 1480 } |
| 1481 |
| 1482 @override |
1456 ir.Primitive handleDynamicCompounds( | 1483 ir.Primitive handleDynamicCompounds( |
1457 ast.SendSet node, | 1484 ast.SendSet node, |
1458 ast.Node receiver, | 1485 ast.Node receiver, |
1459 Name name, | 1486 Name name, |
1460 CompoundRhs rhs, | 1487 CompoundRhs rhs, |
1461 arg) { | 1488 arg) { |
1462 ir.Primitive target = translateReceiver(receiver); | 1489 ir.Primitive target = translateReceiver(receiver); |
1463 ir.Primitive helper() { | 1490 ir.Primitive helper() { |
1464 return translateCompounds( | 1491 return translateCompounds( |
1465 node, | 1492 node, |
1466 getValue: () => irBuilder.buildDynamicGet( | 1493 getValue: () => irBuilder.buildDynamicGet( |
1467 target, | 1494 target, |
1468 new Selector.getter(name), | 1495 new Selector.getter(name), |
1469 elements.getGetterTypeMaskInComplexSendSet(node), | 1496 elements.getGetterTypeMaskInComplexSendSet(node), |
1470 sourceInformationBuilder.buildGet(node)), | 1497 sourceInformationBuilder.buildGet(node)), |
1471 rhs: rhs, | 1498 rhs: rhs, |
1472 setValue: (ir.Primitive result) { | 1499 setValue: (ir.Primitive result) { |
1473 irBuilder.buildDynamicSet( | 1500 irBuilder.buildDynamicSet( |
1474 target, | 1501 target, |
1475 new Selector.setter(name), | 1502 new Selector.setter(name), |
1476 elements.getTypeMask(node), | 1503 elements.getTypeMask(node), |
1477 result); | 1504 result); |
1478 }); | 1505 }); |
1479 } | 1506 } |
1480 return node.isConditional | 1507 return node.isConditional |
1481 ? irBuilder.buildIfNotNullSend(target, nested(helper)) | 1508 ? irBuilder.buildIfNotNullSend(target, nested(helper)) |
1482 : helper(); | 1509 : helper(); |
1483 } | 1510 } |
1484 | 1511 |
| 1512 @override |
| 1513 ir.Primitive handleDynamicSetIfNulls( |
| 1514 ast.Send node, |
| 1515 ast.Node receiver, |
| 1516 Name name, |
| 1517 ast.Node rhs, |
| 1518 _) { |
| 1519 ir.Primitive target = translateReceiver(receiver); |
| 1520 ir.Primitive helper() { |
| 1521 return translateSetIfNull( |
| 1522 node, |
| 1523 getValue: () => irBuilder.buildDynamicGet( |
| 1524 target, |
| 1525 new Selector.getter(name), |
| 1526 elements.getGetterTypeMaskInComplexSendSet(node), |
| 1527 sourceInformationBuilder.buildGet(node)), |
| 1528 rhs: rhs, |
| 1529 setValue: (ir.Primitive result) { |
| 1530 irBuilder.buildDynamicSet( |
| 1531 target, |
| 1532 new Selector.setter(name), |
| 1533 elements.getTypeMask(node), |
| 1534 result); |
| 1535 }); |
| 1536 } |
| 1537 return node.isConditional |
| 1538 ? irBuilder.buildIfNotNullSend(target, nested(helper)) |
| 1539 : helper(); |
| 1540 } |
| 1541 |
1485 ir.Primitive buildLocalNoSuchSetter(LocalElement local, ir.Primitive value) { | 1542 ir.Primitive buildLocalNoSuchSetter(LocalElement local, ir.Primitive value) { |
1486 Selector selector = new Selector.setter( | 1543 Selector selector = new Selector.setter( |
1487 new Name(local.name, local.library, isSetter: true)); | 1544 new Name(local.name, local.library, isSetter: true)); |
1488 return buildStaticNoSuchMethod(selector, [value]); | 1545 return buildStaticNoSuchMethod(selector, [value]); |
1489 } | 1546 } |
1490 | 1547 |
1491 @override | 1548 @override |
1492 ir.Primitive handleLocalCompounds( | 1549 ir.Primitive handleLocalCompounds( |
1493 ast.SendSet node, | 1550 ast.SendSet node, |
1494 LocalElement local, | 1551 LocalElement local, |
(...skipping 12 matching lines...) Expand all Loading... |
1507 rhs: rhs, | 1564 rhs: rhs, |
1508 setValue: (ir.Primitive result) { | 1565 setValue: (ir.Primitive result) { |
1509 if (isSetterValid) { | 1566 if (isSetterValid) { |
1510 irBuilder.buildLocalVariableSet(local, result); | 1567 irBuilder.buildLocalVariableSet(local, result); |
1511 } else { | 1568 } else { |
1512 return buildLocalNoSuchSetter(local, result); | 1569 return buildLocalNoSuchSetter(local, result); |
1513 } | 1570 } |
1514 }); | 1571 }); |
1515 } | 1572 } |
1516 | 1573 |
| 1574 @override |
| 1575 ir.Primitive handleLocalSetIfNulls( |
| 1576 ast.SendSet node, |
| 1577 LocalElement local, |
| 1578 ast.Node rhs, |
| 1579 _, |
| 1580 {bool isSetterValid}) { |
| 1581 return translateSetIfNull( |
| 1582 node, |
| 1583 getValue: () { |
| 1584 if (local.isFunction) { |
| 1585 return irBuilder.buildLocalFunctionGet(local); |
| 1586 } else { |
| 1587 return irBuilder.buildLocalVariableGet(local); |
| 1588 } |
| 1589 }, |
| 1590 rhs: rhs, |
| 1591 setValue: (ir.Primitive result) { |
| 1592 if (isSetterValid) { |
| 1593 irBuilder.buildLocalVariableSet(local, result); |
| 1594 } else { |
| 1595 return buildLocalNoSuchSetter(local, result); |
| 1596 } |
| 1597 }); |
| 1598 } |
| 1599 |
1517 ir.Primitive buildStaticNoSuchGetter(Element element) { | 1600 ir.Primitive buildStaticNoSuchGetter(Element element) { |
1518 return buildStaticNoSuchMethod( | 1601 return buildStaticNoSuchMethod( |
1519 new Selector.getter(new Name(element.name, element.library)), | 1602 new Selector.getter(new Name(element.name, element.library)), |
1520 const <ir.Primitive>[]); | 1603 const <ir.Primitive>[]); |
1521 } | 1604 } |
1522 | 1605 |
1523 ir.Primitive buildStaticNoSuchSetter(Element element, ir.Primitive value) { | 1606 ir.Primitive buildStaticNoSuchSetter(Element element, ir.Primitive value) { |
1524 return buildStaticNoSuchMethod( | 1607 return buildStaticNoSuchMethod( |
1525 new Selector.setter(new Name(element.name, element.library)), | 1608 new Selector.setter(new Name(element.name, element.library)), |
1526 <ir.Primitive>[value]); | 1609 <ir.Primitive>[value]); |
(...skipping 25 matching lines...) Expand all Loading... |
1552 } | 1635 } |
1553 }, | 1636 }, |
1554 rhs: rhs, | 1637 rhs: rhs, |
1555 setValue: (ir.Primitive result) { | 1638 setValue: (ir.Primitive result) { |
1556 switch (setterKind) { | 1639 switch (setterKind) { |
1557 case CompoundSetter.FIELD: | 1640 case CompoundSetter.FIELD: |
1558 return irBuilder.buildStaticFieldSet(setter, result); | 1641 return irBuilder.buildStaticFieldSet(setter, result); |
1559 case CompoundSetter.SETTER: | 1642 case CompoundSetter.SETTER: |
1560 return irBuilder.buildStaticSetterSet(setter, result); | 1643 return irBuilder.buildStaticSetterSet(setter, result); |
1561 case CompoundSetter.INVALID: | 1644 case CompoundSetter.INVALID: |
1562 // TODO(johnniwinther): Ensure [setter] is non null. | 1645 return buildStaticNoSuchSetter(setter, result); |
1563 return buildStaticNoSuchSetter( | |
1564 setter != null ? setter : getter, result); | |
1565 } | 1646 } |
1566 }); | 1647 }); |
1567 } | 1648 } |
| 1649 |
| 1650 @override |
| 1651 ir.Primitive handleStaticSetIfNulls( |
| 1652 ast.SendSet node, |
| 1653 Element getter, |
| 1654 CompoundGetter getterKind, |
| 1655 Element setter, |
| 1656 CompoundSetter setterKind, |
| 1657 ast.Node rhs, |
| 1658 _) { |
| 1659 return translateSetIfNull( |
| 1660 node, |
| 1661 getValue: () { |
| 1662 switch (getterKind) { |
| 1663 case CompoundGetter.FIELD: |
| 1664 SourceInformation src = sourceInformationBuilder.buildGet(node); |
| 1665 return irBuilder.buildStaticFieldGet(getter, src); |
| 1666 case CompoundGetter.GETTER: |
| 1667 return irBuilder.buildStaticGetterGet( |
| 1668 getter, sourceInformationBuilder.buildGet(node)); |
| 1669 case CompoundGetter.METHOD: |
| 1670 return irBuilder.buildStaticFunctionGet(getter); |
| 1671 case CompoundGetter.UNRESOLVED: |
| 1672 return buildStaticNoSuchGetter(getter); |
| 1673 } |
| 1674 }, |
| 1675 rhs: rhs, |
| 1676 setValue: (ir.Primitive result) { |
| 1677 switch (setterKind) { |
| 1678 case CompoundSetter.FIELD: |
| 1679 return irBuilder.buildStaticFieldSet(setter, result); |
| 1680 case CompoundSetter.SETTER: |
| 1681 return irBuilder.buildStaticSetterSet(setter, result); |
| 1682 case CompoundSetter.INVALID: |
| 1683 return buildStaticNoSuchSetter(setter, result); |
| 1684 } |
| 1685 }); |
| 1686 } |
1568 | 1687 |
1569 ir.Primitive buildSuperNoSuchGetter(Element element, TypeMask mask) { | 1688 ir.Primitive buildSuperNoSuchGetter(Element element, TypeMask mask) { |
1570 return buildInstanceNoSuchMethod( | 1689 return buildInstanceNoSuchMethod( |
1571 new Selector.getter(new Name(element.name, element.library)), | 1690 new Selector.getter(new Name(element.name, element.library)), |
1572 mask, | 1691 mask, |
1573 const <ir.Primitive>[]); | 1692 const <ir.Primitive>[]); |
1574 } | 1693 } |
1575 | 1694 |
1576 ir.Primitive buildSuperNoSuchSetter(Element element, | 1695 ir.Primitive buildSuperNoSuchSetter(Element element, |
1577 TypeMask mask, | 1696 TypeMask mask, |
(...skipping 18 matching lines...) Expand all Loading... |
1596 getValue: () { | 1715 getValue: () { |
1597 switch (getterKind) { | 1716 switch (getterKind) { |
1598 case CompoundGetter.FIELD: | 1717 case CompoundGetter.FIELD: |
1599 return irBuilder.buildSuperFieldGet(getter); | 1718 return irBuilder.buildSuperFieldGet(getter); |
1600 case CompoundGetter.GETTER: | 1719 case CompoundGetter.GETTER: |
1601 return irBuilder.buildSuperGetterGet( | 1720 return irBuilder.buildSuperGetterGet( |
1602 getter, sourceInformationBuilder.buildGet(node)); | 1721 getter, sourceInformationBuilder.buildGet(node)); |
1603 case CompoundGetter.METHOD: | 1722 case CompoundGetter.METHOD: |
1604 return irBuilder.buildSuperMethodGet(getter); | 1723 return irBuilder.buildSuperMethodGet(getter); |
1605 case CompoundGetter.UNRESOLVED: | 1724 case CompoundGetter.UNRESOLVED: |
1606 // TODO(johnniwinther): Ensure [getter] is not null. | |
1607 return buildSuperNoSuchGetter( | 1725 return buildSuperNoSuchGetter( |
1608 getter != null ? getter : setter, | 1726 getter, |
1609 elements.getGetterTypeMaskInComplexSendSet(node)); | 1727 elements.getGetterTypeMaskInComplexSendSet(node)); |
1610 } | 1728 } |
1611 }, | 1729 }, |
| 1730 rhs: rhs, |
| 1731 setValue: (ir.Primitive result) { |
| 1732 switch (setterKind) { |
| 1733 case CompoundSetter.FIELD: |
| 1734 return irBuilder.buildSuperFieldSet(setter, result); |
| 1735 case CompoundSetter.SETTER: |
| 1736 return irBuilder.buildSuperSetterSet(setter, result); |
| 1737 case CompoundSetter.INVALID: |
| 1738 return buildSuperNoSuchSetter( |
| 1739 setter, elements.getTypeMask(node), result); |
| 1740 } |
| 1741 }); |
| 1742 } |
| 1743 |
| 1744 @override |
| 1745 ir.Primitive handleSuperSetIfNulls( |
| 1746 ast.SendSet node, |
| 1747 Element getter, |
| 1748 CompoundGetter getterKind, |
| 1749 Element setter, |
| 1750 CompoundSetter setterKind, |
| 1751 ast.Node rhs, |
| 1752 _) { |
| 1753 return translateSetIfNull( |
| 1754 node, |
| 1755 getValue: () { |
| 1756 switch (getterKind) { |
| 1757 case CompoundGetter.FIELD: |
| 1758 return irBuilder.buildSuperFieldGet(getter); |
| 1759 case CompoundGetter.GETTER: |
| 1760 return irBuilder.buildSuperGetterGet( |
| 1761 getter, sourceInformationBuilder.buildGet(node)); |
| 1762 case CompoundGetter.METHOD: |
| 1763 return irBuilder.buildSuperMethodGet(getter); |
| 1764 case CompoundGetter.UNRESOLVED: |
| 1765 return buildSuperNoSuchGetter( |
| 1766 getter, |
| 1767 elements.getGetterTypeMaskInComplexSendSet(node)); |
| 1768 } |
| 1769 }, |
1612 rhs: rhs, | 1770 rhs: rhs, |
1613 setValue: (ir.Primitive result) { | 1771 setValue: (ir.Primitive result) { |
1614 switch (setterKind) { | 1772 switch (setterKind) { |
1615 case CompoundSetter.FIELD: | 1773 case CompoundSetter.FIELD: |
1616 return irBuilder.buildSuperFieldSet(setter, result); | 1774 return irBuilder.buildSuperFieldSet(setter, result); |
1617 case CompoundSetter.SETTER: | 1775 case CompoundSetter.SETTER: |
1618 return irBuilder.buildSuperSetterSet(setter, result); | 1776 return irBuilder.buildSuperSetterSet(setter, result); |
1619 case CompoundSetter.INVALID: | 1777 case CompoundSetter.INVALID: |
1620 return buildSuperNoSuchSetter( | 1778 return buildSuperNoSuchSetter( |
1621 setter, elements.getTypeMask(node), result); | 1779 setter, elements.getTypeMask(node), result); |
(...skipping 12 matching lines...) Expand all Loading... |
1634 getValue: () { | 1792 getValue: () { |
1635 return irBuilder.buildReifyTypeVariable( | 1793 return irBuilder.buildReifyTypeVariable( |
1636 typeVariable.type, | 1794 typeVariable.type, |
1637 sourceInformationBuilder.buildGet(node)); | 1795 sourceInformationBuilder.buildGet(node)); |
1638 }, | 1796 }, |
1639 rhs: rhs, | 1797 rhs: rhs, |
1640 setValue: (value) {}); // The binary operator will throw before this. | 1798 setValue: (value) {}); // The binary operator will throw before this. |
1641 } | 1799 } |
1642 | 1800 |
1643 @override | 1801 @override |
| 1802 ir.Primitive visitTypeVariableTypeLiteralSetIfNull( |
| 1803 ast.Send node, |
| 1804 TypeVariableElement element, |
| 1805 ast.Node rhs, |
| 1806 _) { |
| 1807 // The type variable is never `null`. |
| 1808 return translateTypeVariableTypeLiteral(element, |
| 1809 sourceInformationBuilder.buildGet(node)); |
| 1810 } |
| 1811 |
| 1812 @override |
1644 ir.Primitive handleIndexCompounds( | 1813 ir.Primitive handleIndexCompounds( |
1645 ast.SendSet node, | 1814 ast.SendSet node, |
1646 ast.Node receiver, | 1815 ast.Node receiver, |
1647 ast.Node index, | 1816 ast.Node index, |
1648 CompoundRhs rhs, | 1817 CompoundRhs rhs, |
1649 arg) { | 1818 arg) { |
1650 ir.Primitive target = visit(receiver); | 1819 ir.Primitive target = visit(receiver); |
1651 ir.Primitive indexValue = visit(index); | 1820 ir.Primitive indexValue = visit(index); |
1652 return translateCompounds( | 1821 return translateCompounds( |
1653 node, | 1822 node, |
(...skipping 1754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3408 if (compiler.backend.isForeign(function)) { | 3577 if (compiler.backend.isForeign(function)) { |
3409 return handleForeignCode(node, function, argumentList, callStructure); | 3578 return handleForeignCode(node, function, argumentList, callStructure); |
3410 } else { | 3579 } else { |
3411 return irBuilder.buildStaticFunctionInvocation(function, callStructure, | 3580 return irBuilder.buildStaticFunctionInvocation(function, callStructure, |
3412 translateStaticArguments(argumentList, function, callStructure), | 3581 translateStaticArguments(argumentList, function, callStructure), |
3413 sourceInformation: | 3582 sourceInformation: |
3414 sourceInformationBuilder.buildCall(node, node.selector)); | 3583 sourceInformationBuilder.buildCall(node, node.selector)); |
3415 } | 3584 } |
3416 } | 3585 } |
3417 } | 3586 } |
OLD | NEW |