| 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 1541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1552 // Split returns a List, so we make sure the backend knows the | 1552 // Split returns a List, so we make sure the backend knows the |
| 1553 // list class is instantiated. | 1553 // list class is instantiated. |
| 1554 world.registerInstantiatedClass(compiler.listClass); | 1554 world.registerInstantiatedClass(compiler.listClass); |
| 1555 } else if (target == backend.jsStringConcat) { | 1555 } else if (target == backend.jsStringConcat) { |
| 1556 push(new js.Binary('+', object, arguments[0]), node); | 1556 push(new js.Binary('+', object, arguments[0]), node); |
| 1557 return; | 1557 return; |
| 1558 } | 1558 } |
| 1559 } | 1559 } |
| 1560 | 1560 |
| 1561 if (methodName == null) { | 1561 if (methodName == null) { |
| 1562 methodName = backend.namer.instanceMethodInvocationName( | 1562 methodName = backend.namer.invocationName(node.selector); |
| 1563 node.selector.library, name, node.selector); | |
| 1564 bool inLoop = node.block.enclosingLoopHeader != null; | 1563 bool inLoop = node.block.enclosingLoopHeader != null; |
| 1565 | 1564 |
| 1566 Selector selector = getOptimizedSelectorFor(node, node.selector); | 1565 Selector selector = getOptimizedSelectorFor(node, node.selector); |
| 1567 if (node.isInterceptorCall) { | 1566 if (node.isInterceptorCall) { |
| 1568 backend.addInterceptedSelector(selector); | 1567 backend.addInterceptedSelector(selector); |
| 1569 } | 1568 } |
| 1570 // Register this invocation to collect the types used at all call sites. | 1569 // Register this invocation to collect the types used at all call sites. |
| 1571 backend.registerDynamicInvocation(node, selector, types); | 1570 backend.registerDynamicInvocation(node, selector, types); |
| 1572 | 1571 |
| 1573 // If we don't know what we're calling or if we are calling a getter, | 1572 // If we don't know what we're calling or if we are calling a getter, |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1612 !identical(receiverType.kind, TypeKind.MALFORMED_TYPE)) { | 1611 !identical(receiverType.kind, TypeKind.MALFORMED_TYPE)) { |
| 1613 return new TypedSelector(receiverType, defaultSelector); | 1612 return new TypedSelector(receiverType, defaultSelector); |
| 1614 } else { | 1613 } else { |
| 1615 return defaultSelector; | 1614 return defaultSelector; |
| 1616 } | 1615 } |
| 1617 } | 1616 } |
| 1618 | 1617 |
| 1619 visitInvokeDynamicSetter(HInvokeDynamicSetter node) { | 1618 visitInvokeDynamicSetter(HInvokeDynamicSetter node) { |
| 1620 use(node.receiver); | 1619 use(node.receiver); |
| 1621 Selector setter = node.selector; | 1620 Selector setter = node.selector; |
| 1622 String name = backend.namer.setterName(setter.library, setter.name); | 1621 String name = backend.namer.invocationName(setter); |
| 1623 push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); | 1622 push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); |
| 1624 Selector selector = getOptimizedSelectorFor(node, setter); | 1623 Selector selector = getOptimizedSelectorFor(node, setter); |
| 1625 world.registerDynamicSetter(setter.name, selector); | 1624 world.registerDynamicSetter(setter.name, selector); |
| 1626 HType valueType; | 1625 HType valueType; |
| 1627 if (node.isInterceptorCall) { | 1626 if (node.isInterceptorCall) { |
| 1628 valueType = types[node.inputs[2]]; | 1627 valueType = types[node.inputs[2]]; |
| 1629 backend.addInterceptedSelector(setter); | 1628 backend.addInterceptedSelector(setter); |
| 1630 } else { | 1629 } else { |
| 1631 valueType = types[node.inputs[1]]; | 1630 valueType = types[node.inputs[1]]; |
| 1632 } | 1631 } |
| 1633 backend.addedDynamicSetter(selector, valueType); | 1632 backend.addedDynamicSetter(selector, valueType); |
| 1634 } | 1633 } |
| 1635 | 1634 |
| 1636 visitInvokeDynamicGetter(HInvokeDynamicGetter node) { | 1635 visitInvokeDynamicGetter(HInvokeDynamicGetter node) { |
| 1637 use(node.receiver); | 1636 use(node.receiver); |
| 1638 Selector getter = node.selector; | 1637 Selector getter = node.selector; |
| 1639 String name = backend.namer.getterName(getter.library, getter.name); | 1638 String name = backend.namer.invocationName(getter); |
| 1640 push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); | 1639 push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); |
| 1641 world.registerDynamicGetter( | 1640 world.registerDynamicGetter( |
| 1642 getter.name, getOptimizedSelectorFor(node, getter)); | 1641 getter.name, getOptimizedSelectorFor(node, getter)); |
| 1643 if (node.isInterceptorCall) { | 1642 if (node.isInterceptorCall) { |
| 1644 backend.addInterceptedSelector(getter); | 1643 backend.addInterceptedSelector(getter); |
| 1645 } | 1644 } |
| 1646 world.registerInstantiatedClass(compiler.functionClass); | 1645 world.registerInstantiatedClass(compiler.functionClass); |
| 1647 } | 1646 } |
| 1648 | 1647 |
| 1649 visitInvokeClosure(HInvokeClosure node) { | 1648 visitInvokeClosure(HInvokeClosure node) { |
| 1649 Selector call = new Selector.callClosureFrom(node.selector); |
| 1650 use(node.receiver); | 1650 use(node.receiver); |
| 1651 push(jsPropertyCall(pop(), | 1651 push(jsPropertyCall(pop(), |
| 1652 backend.namer.closureInvocationName(node.selector), | 1652 backend.namer.invocationName(call), |
| 1653 visitArguments(node.inputs)), | 1653 visitArguments(node.inputs)), |
| 1654 node); | 1654 node); |
| 1655 Selector call = new Selector.callClosureFrom(node.selector); | |
| 1656 world.registerDynamicInvocation(call.name, call); | 1655 world.registerDynamicInvocation(call.name, call); |
| 1657 // A closure can also be invoked through [HInvokeDynamicMethod] by | 1656 // A closure can also be invoked through [HInvokeDynamicMethod] by |
| 1658 // explicitly calling the [:call:] method. Therefore, we must also | 1657 // explicitly calling the [:call:] method. Therefore, we must also |
| 1659 // register types here to let the backend invalidate wrong | 1658 // register types here to let the backend invalidate wrong |
| 1660 // optimizations. | 1659 // optimizations. |
| 1661 backend.registerDynamicInvocation(node, call, types); | 1660 backend.registerDynamicInvocation(node, call, types); |
| 1662 } | 1661 } |
| 1663 | 1662 |
| 1664 visitInvokeStatic(HInvokeStatic node) { | 1663 visitInvokeStatic(HInvokeStatic node) { |
| 1665 if (node.typeCode() == HInstruction.INVOKE_STATIC_TYPECODE) { | 1664 if (node.typeCode() == HInstruction.INVOKE_STATIC_TYPECODE) { |
| 1666 // Register this invocation to collect the types used at all call sites. | 1665 // Register this invocation to collect the types used at all call sites. |
| 1667 backend.registerStaticInvocation(node, types); | 1666 backend.registerStaticInvocation(node, types); |
| 1668 } | 1667 } |
| 1669 use(node.target); | 1668 use(node.target); |
| 1670 push(new js.Call(pop(), visitArguments(node.inputs)), node); | 1669 push(new js.Call(pop(), visitArguments(node.inputs)), node); |
| 1671 } | 1670 } |
| 1672 | 1671 |
| 1673 visitInvokeSuper(HInvokeSuper node) { | 1672 visitInvokeSuper(HInvokeSuper node) { |
| 1674 Element superMethod = node.element; | 1673 Element superMethod = node.element; |
| 1675 Element superClass = superMethod.getEnclosingClass(); | 1674 Element superClass = superMethod.getEnclosingClass(); |
| 1676 if (superMethod.kind == ElementKind.FIELD) { | 1675 if (superMethod.kind == ElementKind.FIELD) { |
| 1677 ClassElement currentClass = work.element.getEnclosingClass(); | 1676 ClassElement currentClass = work.element.getEnclosingClass(); |
| 1678 if (currentClass.isClosure()) { | 1677 if (currentClass.isClosure()) { |
| 1679 ClosureClassElement closure = currentClass; | 1678 ClosureClassElement closure = currentClass; |
| 1680 currentClass = closure.methodElement.getEnclosingClass(); | 1679 currentClass = closure.methodElement.getEnclosingClass(); |
| 1681 } | 1680 } |
| 1682 String fieldName; | 1681 String fieldName = currentClass.isShadowedByField(superMethod) |
| 1683 if (currentClass.isShadowedByField(superMethod)) { | 1682 ? backend.namer.shadowedFieldName(superMethod) |
| 1684 fieldName = backend.namer.shadowedFieldName(superMethod); | 1683 : backend.namer.instanceFieldName(superMethod); |
| 1685 } else { | |
| 1686 LibraryElement library = superMethod.getLibrary(); | |
| 1687 SourceString name = superMethod.name; | |
| 1688 fieldName = backend.namer.instanceFieldName(library, name); | |
| 1689 } | |
| 1690 use(node.inputs[1]); | 1684 use(node.inputs[1]); |
| 1691 js.PropertyAccess access = | 1685 js.PropertyAccess access = |
| 1692 new js.PropertyAccess.field(pop(), fieldName); | 1686 new js.PropertyAccess.field(pop(), fieldName); |
| 1693 if (node.isSetter) { | 1687 if (node.isSetter) { |
| 1694 use(node.value); | 1688 use(node.value); |
| 1695 push(new js.Assignment(access, pop()), node); | 1689 push(new js.Assignment(access, pop()), node); |
| 1696 } else { | 1690 } else { |
| 1697 push(access, node); | 1691 push(access, node); |
| 1698 } | 1692 } |
| 1699 } else { | 1693 } else { |
| 1700 String methodName; | 1694 String methodName = backend.namer.getName(superMethod); |
| 1701 if (superMethod.kind == ElementKind.FUNCTION || | |
| 1702 superMethod.kind == ElementKind.GENERATIVE_CONSTRUCTOR) { | |
| 1703 methodName = backend.namer.instanceMethodName(superMethod); | |
| 1704 } else if (superMethod.kind == ElementKind.GETTER) { | |
| 1705 methodName = | |
| 1706 backend.namer.getterName(currentLibrary, superMethod.name); | |
| 1707 } else { | |
| 1708 assert(superMethod.kind == ElementKind.SETTER); | |
| 1709 methodName = | |
| 1710 backend.namer.setterName(currentLibrary, superMethod.name); | |
| 1711 } | |
| 1712 String className = backend.namer.isolateAccess(superClass); | 1695 String className = backend.namer.isolateAccess(superClass); |
| 1713 js.VariableUse classReference = new js.VariableUse(className); | 1696 js.VariableUse classReference = new js.VariableUse(className); |
| 1714 js.PropertyAccess prototype = | 1697 js.PropertyAccess prototype = |
| 1715 new js.PropertyAccess.field(classReference, "prototype"); | 1698 new js.PropertyAccess.field(classReference, "prototype"); |
| 1716 js.PropertyAccess method = | 1699 js.PropertyAccess method = |
| 1717 new js.PropertyAccess.field(prototype, methodName); | 1700 new js.PropertyAccess.field(prototype, methodName); |
| 1718 push(jsPropertyCall(method, "call", visitArguments(node.inputs)), node); | 1701 push(jsPropertyCall(method, "call", visitArguments(node.inputs)), node); |
| 1719 } | 1702 } |
| 1720 world.registerStaticUse(superMethod); | 1703 world.registerStaticUse(superMethod); |
| 1721 } | 1704 } |
| (...skipping 1322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3044 if (leftType.canBeNull() && rightType.canBeNull()) { | 3027 if (leftType.canBeNull() && rightType.canBeNull()) { |
| 3045 if (left.isConstantNull() || right.isConstantNull() || | 3028 if (left.isConstantNull() || right.isConstantNull() || |
| 3046 (leftType.isPrimitive() && leftType == rightType)) { | 3029 (leftType.isPrimitive() && leftType == rightType)) { |
| 3047 return '=='; | 3030 return '=='; |
| 3048 } | 3031 } |
| 3049 return null; | 3032 return null; |
| 3050 } else { | 3033 } else { |
| 3051 return '==='; | 3034 return '==='; |
| 3052 } | 3035 } |
| 3053 } | 3036 } |
| OLD | NEW |