| 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 class SsaCodeGeneratorTask extends CompilerTask { | 5 class SsaCodeGeneratorTask extends CompilerTask { |
| 6 | 6 |
| 7 final JavaScriptBackend backend; | 7 final JavaScriptBackend backend; |
| 8 | 8 |
| 9 SsaCodeGeneratorTask(JavaScriptBackend backend) | 9 SsaCodeGeneratorTask(JavaScriptBackend backend) |
| 10 : this.backend = backend, | 10 : this.backend = backend, |
| (...skipping 1510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1521 } else { | 1521 } else { |
| 1522 return defaultSelector; | 1522 return defaultSelector; |
| 1523 } | 1523 } |
| 1524 } | 1524 } |
| 1525 | 1525 |
| 1526 visitInvokeDynamicSetter(HInvokeDynamicSetter node) { | 1526 visitInvokeDynamicSetter(HInvokeDynamicSetter node) { |
| 1527 use(node.receiver); | 1527 use(node.receiver); |
| 1528 Selector setter = node.selector; | 1528 Selector setter = node.selector; |
| 1529 String name = backend.namer.setterName(setter.library, setter.name); | 1529 String name = backend.namer.setterName(setter.library, setter.name); |
| 1530 push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); | 1530 push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); |
| 1531 world.registerDynamicSetter( | 1531 Selector selector = getOptimizedSelectorFor(node, setter); |
| 1532 setter.name, getOptimizedSelectorFor(node, setter)); | 1532 world.registerDynamicSetter(setter.name, selector); |
| 1533 backend.addedDynamicSetter(selector, types[node.inputs[1]]); |
| 1533 } | 1534 } |
| 1534 | 1535 |
| 1535 visitInvokeDynamicGetter(HInvokeDynamicGetter node) { | 1536 visitInvokeDynamicGetter(HInvokeDynamicGetter node) { |
| 1536 use(node.receiver); | 1537 use(node.receiver); |
| 1537 Selector getter = node.selector; | 1538 Selector getter = node.selector; |
| 1538 String name = backend.namer.getterName(getter.library, getter.name); | 1539 String name = backend.namer.getterName(getter.library, getter.name); |
| 1539 push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); | 1540 push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); |
| 1540 world.registerDynamicGetter( | 1541 world.registerDynamicGetter( |
| 1541 getter.name, getOptimizedSelectorFor(node, getter)); | 1542 getter.name, getOptimizedSelectorFor(node, getter)); |
| 1542 } | 1543 } |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1631 if (value.guaranteedType.union(HType.NUMBER) == HType.NUMBER) return true; | 1632 if (value.guaranteedType.union(HType.NUMBER) == HType.NUMBER) return true; |
| 1632 if (value is HBinaryArithmetic) { | 1633 if (value is HBinaryArithmetic) { |
| 1633 return (isSimpleFieldNumberComputation(value.left, node) && | 1634 return (isSimpleFieldNumberComputation(value.left, node) && |
| 1634 isSimpleFieldNumberComputation(value.right, node)); | 1635 isSimpleFieldNumberComputation(value.right, node)); |
| 1635 } | 1636 } |
| 1636 if (value is HFieldGet) return value.element == node.element; | 1637 if (value is HFieldGet) return value.element == node.element; |
| 1637 return false; | 1638 return false; |
| 1638 } | 1639 } |
| 1639 | 1640 |
| 1640 visitFieldSet(HFieldSet node) { | 1641 visitFieldSet(HFieldSet node) { |
| 1641 if (work.element.isGenerativeConstructorBody() && | |
| 1642 node.element.isMember() && | |
| 1643 node.value.hasGuaranteedType() && | |
| 1644 node.block.dominates(currentGraph.exit)) { | |
| 1645 backend.updateFieldConstructorSetters(node.element, | |
| 1646 node.value.guaranteedType); | |
| 1647 } | |
| 1648 String name = backend.namer.getName(node.element); | 1642 String name = backend.namer.getName(node.element); |
| 1649 DartType type = types[node.receiver].computeType(compiler); | 1643 DartType type = types[node.receiver].computeType(compiler); |
| 1650 if (type != null) { | 1644 if (type != null) { |
| 1645 // Field setters in the generative constructor body are handled in a |
| 1646 // step "SsaConstructionFieldTypes" in the ssa optimizer. |
| 1651 if (!work.element.isGenerativeConstructorBody()) { | 1647 if (!work.element.isGenerativeConstructorBody()) { |
| 1652 world.registerFieldSetter( | 1648 world.registerFieldSetter( |
| 1653 node.element.name, node.element.getLibrary(), type); | 1649 node.element.name, node.element.getLibrary(), type); |
| 1654 } | 1650 backend.registerFieldSetter( |
| 1655 // Determine the types seen so far for the field. If only number | 1651 work.element, node.element, types[node.value]); |
| 1656 // types have been seen and the value of the field set is a | |
| 1657 // simple number computation only depending on that field, we | |
| 1658 // can safely keep the number type for the field. | |
| 1659 HType fieldSettersType = backend.fieldSettersTypeSoFar(node.element); | |
| 1660 HType initializersType = | |
| 1661 backend.typeFromInitializersSoFar(node.element); | |
| 1662 HType fieldType = fieldSettersType.union(initializersType); | |
| 1663 if (HType.NUMBER.union(fieldType) == HType.NUMBER && | |
| 1664 isSimpleFieldNumberComputation(node.value, node)) { | |
| 1665 backend.updateFieldSetters(node.element, HType.NUMBER); | |
| 1666 } else { | |
| 1667 backend.updateFieldSetters(node.element, types[node.value]); | |
| 1668 } | 1652 } |
| 1669 } | 1653 } |
| 1670 use(node.receiver); | 1654 use(node.receiver); |
| 1671 js.Expression receiver = pop(); | 1655 js.Expression receiver = pop(); |
| 1672 use(node.value); | 1656 use(node.value); |
| 1673 push(new js.Assignment(new js.PropertyAccess.field(receiver, name), pop()), | 1657 push(new js.Assignment(new js.PropertyAccess.field(receiver, name), pop()), |
| 1674 node); | 1658 node); |
| 1675 } | 1659 } |
| 1676 | 1660 |
| 1677 visitLocalGet(HLocalGet node) { | 1661 visitLocalGet(HLocalGet node) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1696 List<js.Expression> data = <js.Expression>[]; | 1680 List<js.Expression> data = <js.Expression>[]; |
| 1697 for (int i = 0; i < inputs.length; i++) { | 1681 for (int i = 0; i < inputs.length; i++) { |
| 1698 use(inputs[i]); | 1682 use(inputs[i]); |
| 1699 data.add(pop()); | 1683 data.add(pop()); |
| 1700 } | 1684 } |
| 1701 push(new js.LiteralExpression.withData(code, data), node); | 1685 push(new js.LiteralExpression.withData(code, data), node); |
| 1702 } | 1686 } |
| 1703 } | 1687 } |
| 1704 | 1688 |
| 1705 visitForeignNew(HForeignNew node) { | 1689 visitForeignNew(HForeignNew node) { |
| 1706 int j = 0; | |
| 1707 node.element.forEachInstanceField( | |
| 1708 includeBackendMembers: true, | |
| 1709 includeSuperMembers: true, | |
| 1710 f: (ClassElement enclosingClass, Element member) { | |
| 1711 backend.updateFieldInitializers(member, types[node.inputs[j]]); | |
| 1712 j++; | |
| 1713 }); | |
| 1714 String jsClassReference = backend.namer.isolateAccess(node.element); | 1690 String jsClassReference = backend.namer.isolateAccess(node.element); |
| 1715 List<HInstruction> inputs = node.inputs; | 1691 List<HInstruction> inputs = node.inputs; |
| 1716 // We can't use 'visitArguments', since our arguments start at input[0]. | 1692 // We can't use 'visitArguments', since our arguments start at input[0]. |
| 1717 List<js.Expression> arguments = <js.Expression>[]; | 1693 List<js.Expression> arguments = <js.Expression>[]; |
| 1718 for (int i = 0; i < inputs.length; i++) { | 1694 for (int i = 0; i < inputs.length; i++) { |
| 1719 use(inputs[i]); | 1695 use(inputs[i]); |
| 1720 arguments.add(pop()); | 1696 arguments.add(pop()); |
| 1721 } | 1697 } |
| 1722 // TODO(floitsch): jsClassReference is an Access. We shouldn't treat it | 1698 // TODO(floitsch): jsClassReference is an Access. We shouldn't treat it |
| 1723 // as if it was a string. | 1699 // as if it was a string. |
| (...skipping 1271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2995 if (leftType.canBeNull() && rightType.canBeNull()) { | 2971 if (leftType.canBeNull() && rightType.canBeNull()) { |
| 2996 if (left.isConstantNull() || right.isConstantNull() || | 2972 if (left.isConstantNull() || right.isConstantNull() || |
| 2997 (leftType.isPrimitive() && leftType == rightType)) { | 2973 (leftType.isPrimitive() && leftType == rightType)) { |
| 2998 return '=='; | 2974 return '=='; |
| 2999 } | 2975 } |
| 3000 return null; | 2976 return null; |
| 3001 } else { | 2977 } else { |
| 3002 return '==='; | 2978 return '==='; |
| 3003 } | 2979 } |
| 3004 } | 2980 } |
| OLD | NEW |