| 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 1654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1665 // 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. |
| 1666 backend.registerStaticInvocation(node, types); | 1666 backend.registerStaticInvocation(node, types); |
| 1667 } | 1667 } |
| 1668 use(node.target); | 1668 use(node.target); |
| 1669 push(new js.Call(pop(), visitArguments(node.inputs)), node); | 1669 push(new js.Call(pop(), visitArguments(node.inputs)), node); |
| 1670 } | 1670 } |
| 1671 | 1671 |
| 1672 visitInvokeSuper(HInvokeSuper node) { | 1672 visitInvokeSuper(HInvokeSuper node) { |
| 1673 Element superMethod = node.element; | 1673 Element superMethod = node.element; |
| 1674 Element superClass = superMethod.getEnclosingClass(); | 1674 Element superClass = superMethod.getEnclosingClass(); |
| 1675 if (superMethod.isField()) { | 1675 if (superMethod.kind == ElementKind.FIELD) { |
| 1676 ClassElement currentClass = work.element.getEnclosingClass(); | 1676 ClassElement currentClass = work.element.getEnclosingClass(); |
| 1677 if (currentClass.isClosure()) { | 1677 if (currentClass.isClosure()) { |
| 1678 ClosureClassElement closure = currentClass; | 1678 ClosureClassElement closure = currentClass; |
| 1679 currentClass = closure.methodElement.getEnclosingClass(); | 1679 currentClass = closure.methodElement.getEnclosingClass(); |
| 1680 } | 1680 } |
| 1681 String fieldName; | 1681 String fieldName; |
| 1682 if (currentClass.isShadowedByField(superMethod)) { | 1682 if (currentClass.isShadowedByField(superMethod)) { |
| 1683 fieldName = backend.namer.shadowedFieldName(superMethod); | 1683 fieldName = backend.namer.shadowedFieldName(superMethod); |
| 1684 } else { | 1684 } else { |
| 1685 LibraryElement library = superMethod.getLibrary(); | 1685 LibraryElement library = superMethod.getLibrary(); |
| 1686 SourceString name = superMethod.name; | 1686 SourceString name = superMethod.name; |
| 1687 fieldName = backend.namer.instanceFieldName(library, name); | 1687 fieldName = backend.namer.instanceFieldName(library, name); |
| 1688 } | 1688 } |
| 1689 use(node.inputs[1]); | 1689 use(node.inputs[1]); |
| 1690 js.PropertyAccess access = | 1690 js.PropertyAccess access = |
| 1691 new js.PropertyAccess.field(pop(), fieldName); | 1691 new js.PropertyAccess.field(pop(), fieldName); |
| 1692 if (node.isSendSet) { | 1692 if (node.isSetter) { |
| 1693 use(node.value); | 1693 use(node.value); |
| 1694 push(new js.Assignment(access, pop()), node); | 1694 push(new js.Assignment(access, pop()), node); |
| 1695 } else { | 1695 } else { |
| 1696 push(access, node); | 1696 push(access, node); |
| 1697 } | 1697 } |
| 1698 } else { | 1698 } else { |
| 1699 bool isPropertyAccess = false; | |
| 1700 String methodName; | 1699 String methodName; |
| 1701 if (superMethod.isGetter()) { | 1700 if (superMethod.kind == ElementKind.FUNCTION || |
| 1701 superMethod.kind == ElementKind.GENERATIVE_CONSTRUCTOR) { |
| 1702 methodName = backend.namer.instanceMethodName(superMethod); |
| 1703 } else if (superMethod.kind == ElementKind.GETTER) { |
| 1702 methodName = | 1704 methodName = |
| 1703 backend.namer.getterName(currentLibrary, superMethod.name); | 1705 backend.namer.getterName(currentLibrary, superMethod.name); |
| 1704 } else if (node.isSendSet || superMethod.isSetter()) { | 1706 } else { |
| 1707 assert(superMethod.kind == ElementKind.SETTER); |
| 1705 methodName = | 1708 methodName = |
| 1706 backend.namer.setterName(currentLibrary, superMethod.name); | 1709 backend.namer.setterName(currentLibrary, superMethod.name); |
| 1707 } else if (superMethod.isFunction() || | |
| 1708 superMethod.isGenerativeConstructor()) { | |
| 1709 if (node.isPropertyAccess) { | |
| 1710 methodName = | |
| 1711 backend.namer.getterName(currentLibrary, superMethod.name); | |
| 1712 isPropertyAccess = true; | |
| 1713 } else { | |
| 1714 methodName = backend.namer.instanceMethodName(superMethod); | |
| 1715 } | |
| 1716 } | 1710 } |
| 1717 String className = backend.namer.isolateAccess(superClass); | 1711 String className = backend.namer.isolateAccess(superClass); |
| 1718 js.VariableUse classReference = new js.VariableUse(className); | 1712 js.VariableUse classReference = new js.VariableUse(className); |
| 1719 js.PropertyAccess prototype = | 1713 js.PropertyAccess prototype = |
| 1720 new js.PropertyAccess.field(classReference, "prototype"); | 1714 new js.PropertyAccess.field(classReference, "prototype"); |
| 1721 if (isPropertyAccess) { | 1715 js.PropertyAccess method = |
| 1722 // Property access of a function. Obtain the bound closure instead of | 1716 new js.PropertyAccess.field(prototype, methodName); |
| 1723 // invoking the function. | 1717 push(jsPropertyCall(method, "call", visitArguments(node.inputs)), node); |
| 1724 push(jsPropertyCall(prototype, methodName, | |
| 1725 visitArguments(node.inputs)), node); | |
| 1726 } else { | |
| 1727 js.PropertyAccess method = | |
| 1728 new js.PropertyAccess.field(prototype, methodName); | |
| 1729 push(jsPropertyCall(method, "call", visitArguments(node.inputs)), node); | |
| 1730 } | |
| 1731 } | 1718 } |
| 1732 world.registerStaticUse(superMethod); | 1719 world.registerStaticUse(superMethod); |
| 1733 } | 1720 } |
| 1734 | 1721 |
| 1735 visitFieldGet(HFieldGet node) { | 1722 visitFieldGet(HFieldGet node) { |
| 1736 use(node.receiver); | 1723 use(node.receiver); |
| 1737 if (node.element == backend.jsArrayLength | 1724 if (node.element == backend.jsArrayLength |
| 1738 || node.element == backend.jsStringLength) { | 1725 || node.element == backend.jsStringLength) { |
| 1739 // We're accessing a native JavaScript property called 'length' | 1726 // We're accessing a native JavaScript property called 'length' |
| 1740 // on a JS String or a JS array. Therefore, the name of that | 1727 // on a JS String or a JS array. Therefore, the name of that |
| (...skipping 1315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3056 if (leftType.canBeNull() && rightType.canBeNull()) { | 3043 if (leftType.canBeNull() && rightType.canBeNull()) { |
| 3057 if (left.isConstantNull() || right.isConstantNull() || | 3044 if (left.isConstantNull() || right.isConstantNull() || |
| 3058 (leftType.isPrimitive() && leftType == rightType)) { | 3045 (leftType.isPrimitive() && leftType == rightType)) { |
| 3059 return '=='; | 3046 return '=='; |
| 3060 } | 3047 } |
| 3061 return null; | 3048 return null; |
| 3062 } else { | 3049 } else { |
| 3063 return '==='; | 3050 return '==='; |
| 3064 } | 3051 } |
| 3065 } | 3052 } |
| OLD | NEW |