| 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 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 class SsaCodeGeneratorTask extends CompilerTask { | 7 class SsaCodeGeneratorTask extends CompilerTask { |
| 8 | 8 |
| 9 final JavaScriptBackend backend; | 9 final JavaScriptBackend backend; |
| 10 | 10 |
| (...skipping 1549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1560 Selector defaultSelector) { | 1560 Selector defaultSelector) { |
| 1561 // If [JSInvocationMirror.invokeOn] has been called, we must not create a | 1561 // If [JSInvocationMirror.invokeOn] has been called, we must not create a |
| 1562 // typed selector based on the receiver type. | 1562 // typed selector based on the receiver type. |
| 1563 if (node.element == null && // Invocation is not exact. | 1563 if (node.element == null && // Invocation is not exact. |
| 1564 backend.compiler.enabledInvokeOn) { | 1564 backend.compiler.enabledInvokeOn) { |
| 1565 return defaultSelector; | 1565 return defaultSelector; |
| 1566 } | 1566 } |
| 1567 int receiverIndex = node.isInterceptorCall ? 1 : 0; | 1567 int receiverIndex = node.isInterceptorCall ? 1 : 0; |
| 1568 HType receiverHType = types[node.inputs[receiverIndex]]; | 1568 HType receiverHType = types[node.inputs[receiverIndex]]; |
| 1569 DartType receiverType = receiverHType.computeType(compiler); | 1569 DartType receiverType = receiverHType.computeType(compiler); |
| 1570 if (receiverType != null && | 1570 if (receiverType != null && !receiverType.isMalformed) { |
| 1571 !identical(receiverType.kind, TypeKind.MALFORMED_TYPE)) { | 1571 if (receiverHType.isExact()) { |
| 1572 return new TypedSelector(receiverType, defaultSelector); | 1572 return new TypedSelector.exact(receiverType, defaultSelector); |
| 1573 } else if (receiverHType.isInterfaceType()) { |
| 1574 return new TypedSelector.subtype(receiverType, defaultSelector); |
| 1575 } else { |
| 1576 return new TypedSelector.subclass(receiverType, defaultSelector); |
| 1577 } |
| 1573 } else { | 1578 } else { |
| 1574 return defaultSelector; | 1579 return defaultSelector; |
| 1575 } | 1580 } |
| 1576 } | 1581 } |
| 1577 | 1582 |
| 1578 void registerInvoke(HInvokeDynamic node) { | 1583 void registerInvoke(HInvokeDynamic node) { |
| 1579 bool inLoop = node.block.enclosingLoopHeader != null; | 1584 bool inLoop = node.block.enclosingLoopHeader != null; |
| 1580 SourceString name = node.selector.name; | 1585 SourceString name = node.selector.name; |
| 1581 if (inLoop) { | 1586 if (inLoop) { |
| 1582 Element target = node.element; | 1587 Element target = node.element; |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1702 new js.PropertyAccess.field(classReference, "prototype"); | 1707 new js.PropertyAccess.field(classReference, "prototype"); |
| 1703 js.PropertyAccess method = | 1708 js.PropertyAccess method = |
| 1704 new js.PropertyAccess.field(prototype, methodName); | 1709 new js.PropertyAccess.field(prototype, methodName); |
| 1705 push(jsPropertyCall(method, "call", visitArguments(node.inputs)), node); | 1710 push(jsPropertyCall(method, "call", visitArguments(node.inputs)), node); |
| 1706 } | 1711 } |
| 1707 world.registerStaticUse(superMethod); | 1712 world.registerStaticUse(superMethod); |
| 1708 } | 1713 } |
| 1709 | 1714 |
| 1710 visitFieldGet(HFieldGet node) { | 1715 visitFieldGet(HFieldGet node) { |
| 1711 use(node.receiver); | 1716 use(node.receiver); |
| 1712 if (node.element == backend.jsArrayLength | 1717 Element element = node.element; |
| 1713 || node.element == backend.jsStringLength) { | 1718 if (element == backend.jsArrayLength || element == backend.jsStringLength) { |
| 1714 // We're accessing a native JavaScript property called 'length' | 1719 // We're accessing a native JavaScript property called 'length' |
| 1715 // on a JS String or a JS array. Therefore, the name of that | 1720 // on a JS String or a JS array. Therefore, the name of that |
| 1716 // property should not be mangled. | 1721 // property should not be mangled. |
| 1717 push(new js.PropertyAccess.field(pop(), 'length'), node); | 1722 push(new js.PropertyAccess.field(pop(), 'length'), node); |
| 1718 } else { | 1723 } else { |
| 1719 String name = _fieldPropertyName(node.element); | 1724 String name = _fieldPropertyName(element); |
| 1720 push(new js.PropertyAccess.field(pop(), name), node); | 1725 push(new js.PropertyAccess.field(pop(), name), node); |
| 1721 HType receiverHType = types[node.receiver]; | 1726 DartType type = types[node.receiver].computeType(compiler); |
| 1722 DartType type = receiverHType.computeType(compiler); | |
| 1723 if (type != null && !identical(type.kind, TypeKind.MALFORMED_TYPE)) { | 1727 if (type != null && !identical(type.kind, TypeKind.MALFORMED_TYPE)) { |
| 1724 world.registerFieldGetter( | 1728 world.registerFieldGetter(element); |
| 1725 node.element.name, node.element.getLibrary(), type); | |
| 1726 } | 1729 } |
| 1727 } | 1730 } |
| 1728 } | 1731 } |
| 1729 | 1732 |
| 1730 visitFieldSet(HFieldSet node) { | 1733 visitFieldSet(HFieldSet node) { |
| 1731 String name = _fieldPropertyName(node.element); | 1734 Element element = node.element; |
| 1735 String name = _fieldPropertyName(element); |
| 1732 DartType type = types[node.receiver].computeType(compiler); | 1736 DartType type = types[node.receiver].computeType(compiler); |
| 1733 if (type != null && !identical(type.kind, TypeKind.MALFORMED_TYPE)) { | 1737 if (type != null && !identical(type.kind, TypeKind.MALFORMED_TYPE)) { |
| 1734 // Field setters in the generative constructor body are handled in a | 1738 // Field setters in the generative constructor body are handled in a |
| 1735 // step "SsaConstructionFieldTypes" in the ssa optimizer. | 1739 // step "SsaConstructionFieldTypes" in the ssa optimizer. |
| 1736 if (!work.element.isGenerativeConstructorBody()) { | 1740 if (!work.element.isGenerativeConstructorBody()) { |
| 1737 world.registerFieldSetter( | 1741 world.registerFieldSetter(element); |
| 1738 node.element.name, node.element.getLibrary(), type); | 1742 backend.registerFieldSetter(work.element, element, types[node.value]); |
| 1739 backend.registerFieldSetter( | |
| 1740 work.element, node.element, types[node.value]); | |
| 1741 } | 1743 } |
| 1742 } | 1744 } |
| 1743 use(node.receiver); | 1745 use(node.receiver); |
| 1744 js.Expression receiver = pop(); | 1746 js.Expression receiver = pop(); |
| 1745 use(node.value); | 1747 use(node.value); |
| 1746 push(new js.Assignment(new js.PropertyAccess.field(receiver, name), pop()), | 1748 push(new js.Assignment(new js.PropertyAccess.field(receiver, name), pop()), |
| 1747 node); | 1749 node); |
| 1748 } | 1750 } |
| 1749 | 1751 |
| 1750 String _fieldPropertyName(Element element) => element.hasFixedBackendName() | 1752 String _fieldPropertyName(Element element) => element.hasFixedBackendName() |
| (...skipping 1246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2997 if (leftType.canBeNull() && rightType.canBeNull()) { | 2999 if (leftType.canBeNull() && rightType.canBeNull()) { |
| 2998 if (left.isConstantNull() || right.isConstantNull() || | 3000 if (left.isConstantNull() || right.isConstantNull() || |
| 2999 (leftType.isPrimitive() && leftType == rightType)) { | 3001 (leftType.isPrimitive() && leftType == rightType)) { |
| 3000 return '=='; | 3002 return '=='; |
| 3001 } | 3003 } |
| 3002 return null; | 3004 return null; |
| 3003 } else { | 3005 } else { |
| 3004 return '==='; | 3006 return '==='; |
| 3005 } | 3007 } |
| 3006 } | 3008 } |
| OLD | NEW |