| 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 1512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1523 } | 1523 } |
| 1524 | 1524 |
| 1525 js.Call jsPropertyCall(js.Expression receiver, | 1525 js.Call jsPropertyCall(js.Expression receiver, |
| 1526 String fieldName, | 1526 String fieldName, |
| 1527 List<js.Expression> arguments) { | 1527 List<js.Expression> arguments) { |
| 1528 return new js.Call(new js.PropertyAccess.field(receiver, fieldName), | 1528 return new js.Call(new js.PropertyAccess.field(receiver, fieldName), |
| 1529 arguments); | 1529 arguments); |
| 1530 } | 1530 } |
| 1531 | 1531 |
| 1532 void visitInterceptor(HInterceptor node) { | 1532 void visitInterceptor(HInterceptor node) { |
| 1533 Element element = backend.getInterceptorMethod; | 1533 String name = |
| 1534 assert(element != null); | 1534 backend.registerSpecializedGetInterceptor(node.interceptedClasses); |
| 1535 world.registerStaticUse(element); | 1535 js.VariableUse interceptor = new js.VariableUse(name); |
| 1536 js.VariableUse interceptor = | |
| 1537 new js.VariableUse(backend.namer.isolateAccess(element)); | |
| 1538 use(node.receiver); | 1536 use(node.receiver); |
| 1539 List<js.Expression> arguments = <js.Expression>[pop()]; | 1537 List<js.Expression> arguments = <js.Expression>[pop()]; |
| 1540 push(new js.Call(interceptor, arguments), node); | 1538 push(new js.Call(interceptor, arguments), node); |
| 1541 } | 1539 } |
| 1542 | 1540 |
| 1543 visitInvokeDynamicMethod(HInvokeDynamicMethod node) { | 1541 visitInvokeDynamicMethod(HInvokeDynamicMethod node) { |
| 1544 use(node.receiver); | 1542 use(node.receiver); |
| 1545 js.Expression object = pop(); | 1543 js.Expression object = pop(); |
| 1546 SourceString name = node.selector.name; | 1544 SourceString name = node.selector.name; |
| 1547 String methodName; | 1545 String methodName; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1631 visitInvokeDynamicGetter(HInvokeDynamicGetter node) { | 1629 visitInvokeDynamicGetter(HInvokeDynamicGetter node) { |
| 1632 use(node.receiver); | 1630 use(node.receiver); |
| 1633 Selector getter = node.selector; | 1631 Selector getter = node.selector; |
| 1634 String name = backend.namer.getterName(getter.library, getter.name); | 1632 String name = backend.namer.getterName(getter.library, getter.name); |
| 1635 push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); | 1633 push(jsPropertyCall(pop(), name, visitArguments(node.inputs)), node); |
| 1636 world.registerDynamicGetter( | 1634 world.registerDynamicGetter( |
| 1637 getter.name, getOptimizedSelectorFor(node, getter)); | 1635 getter.name, getOptimizedSelectorFor(node, getter)); |
| 1638 if (node.isInterceptorCall) { | 1636 if (node.isInterceptorCall) { |
| 1639 backend.addInterceptedSelector(getter); | 1637 backend.addInterceptedSelector(getter); |
| 1640 } | 1638 } |
| 1639 world.registerInstantiatedClass(compiler.functionClass); |
| 1641 } | 1640 } |
| 1642 | 1641 |
| 1643 visitInvokeClosure(HInvokeClosure node) { | 1642 visitInvokeClosure(HInvokeClosure node) { |
| 1644 use(node.receiver); | 1643 use(node.receiver); |
| 1645 push(jsPropertyCall(pop(), | 1644 push(jsPropertyCall(pop(), |
| 1646 backend.namer.closureInvocationName(node.selector), | 1645 backend.namer.closureInvocationName(node.selector), |
| 1647 visitArguments(node.inputs)), | 1646 visitArguments(node.inputs)), |
| 1648 node); | 1647 node); |
| 1649 Selector call = new Selector.callClosureFrom(node.selector); | 1648 Selector call = new Selector.callClosureFrom(node.selector); |
| 1650 world.registerDynamicInvocation(call.name, call); | 1649 world.registerDynamicInvocation(call.name, call); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1774 } | 1773 } |
| 1775 pushStatement(new js.LiteralStatement(code), node); | 1774 pushStatement(new js.LiteralStatement(code), node); |
| 1776 } else { | 1775 } else { |
| 1777 List<js.Expression> data = <js.Expression>[]; | 1776 List<js.Expression> data = <js.Expression>[]; |
| 1778 for (int i = 0; i < inputs.length; i++) { | 1777 for (int i = 0; i < inputs.length; i++) { |
| 1779 use(inputs[i]); | 1778 use(inputs[i]); |
| 1780 data.add(pop()); | 1779 data.add(pop()); |
| 1781 } | 1780 } |
| 1782 push(new js.LiteralExpression.withData(code, data), node); | 1781 push(new js.LiteralExpression.withData(code, data), node); |
| 1783 } | 1782 } |
| 1783 DartType type = types[node].computeType(compiler); |
| 1784 if (type != null) { |
| 1785 world.registerInstantiatedClass(type.element); |
| 1786 } |
| 1784 // TODO(sra): Tell world.nativeEnqueuer about the types created here. | 1787 // TODO(sra): Tell world.nativeEnqueuer about the types created here. |
| 1785 } | 1788 } |
| 1786 | 1789 |
| 1787 visitForeignNew(HForeignNew node) { | 1790 visitForeignNew(HForeignNew node) { |
| 1788 visitedForeignCode = true; | 1791 visitedForeignCode = true; |
| 1789 String jsClassReference = backend.namer.isolateAccess(node.element); | 1792 String jsClassReference = backend.namer.isolateAccess(node.element); |
| 1790 List<HInstruction> inputs = node.inputs; | 1793 List<HInstruction> inputs = node.inputs; |
| 1791 // We can't use 'visitArguments', since our arguments start at input[0]. | 1794 // We can't use 'visitArguments', since our arguments start at input[0]. |
| 1792 List<js.Expression> arguments = <js.Expression>[]; | 1795 List<js.Expression> arguments = <js.Expression>[]; |
| 1793 for (int i = 0; i < inputs.length; i++) { | 1796 for (int i = 0; i < inputs.length; i++) { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1845 String name = namer.constantName(constant); | 1848 String name = namer.constantName(constant); |
| 1846 js.VariableUse currentIsolateUse = | 1849 js.VariableUse currentIsolateUse = |
| 1847 new js.VariableUse(backend.namer.CURRENT_ISOLATE); | 1850 new js.VariableUse(backend.namer.CURRENT_ISOLATE); |
| 1848 push(new js.PropertyAccess.field(currentIsolateUse, name)); | 1851 push(new js.PropertyAccess.field(currentIsolateUse, name)); |
| 1849 } | 1852 } |
| 1850 } | 1853 } |
| 1851 | 1854 |
| 1852 visitConstant(HConstant node) { | 1855 visitConstant(HConstant node) { |
| 1853 assert(isGenerateAtUseSite(node)); | 1856 assert(isGenerateAtUseSite(node)); |
| 1854 generateConstant(node.constant); | 1857 generateConstant(node.constant); |
| 1858 DartType type = node.constant.computeType(compiler); |
| 1859 world.registerInstantiatedClass(type.element); |
| 1855 } | 1860 } |
| 1856 | 1861 |
| 1857 visitLoopBranch(HLoopBranch node) { | 1862 visitLoopBranch(HLoopBranch node) { |
| 1858 if (subGraph != null && identical(node.block, subGraph.end)) { | 1863 if (subGraph != null && identical(node.block, subGraph.end)) { |
| 1859 // We are generating code for a loop condition. | 1864 // We are generating code for a loop condition. |
| 1860 // If doing this as part of a SubGraph traversal, the | 1865 // If doing this as part of a SubGraph traversal, the |
| 1861 // calling code will handle the control flow logic. | 1866 // calling code will handle the control flow logic. |
| 1862 | 1867 |
| 1863 // If we are generating the subgraph as an expression, the | 1868 // If we are generating the subgraph as an expression, the |
| 1864 // condition will be generated as the expression. | 1869 // condition will be generated as the expression. |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2078 void visitSwitch(HSwitch node) { | 2083 void visitSwitch(HSwitch node) { |
| 2079 // Switches are handled using [visitSwitchInfo]. | 2084 // Switches are handled using [visitSwitchInfo]. |
| 2080 } | 2085 } |
| 2081 | 2086 |
| 2082 void visitStatic(HStatic node) { | 2087 void visitStatic(HStatic node) { |
| 2083 // Check whether this static is used for anything else than as a target in | 2088 // Check whether this static is used for anything else than as a target in |
| 2084 // a static call. | 2089 // a static call. |
| 2085 node.usedBy.forEach((HInstruction instr) { | 2090 node.usedBy.forEach((HInstruction instr) { |
| 2086 if (instr is !HInvokeStatic) { | 2091 if (instr is !HInvokeStatic) { |
| 2087 backend.registerNonCallStaticUse(node); | 2092 backend.registerNonCallStaticUse(node); |
| 2088 } else if (!identical(instr.target, node)) { | 2093 if (node.element.isFunction()) { |
| 2094 world.registerInstantiatedClass(compiler.functionClass); |
| 2095 } |
| 2096 } else if (instr.target != node) { |
| 2089 backend.registerNonCallStaticUse(node); | 2097 backend.registerNonCallStaticUse(node); |
| 2090 } else { | |
| 2091 // If invoking the static is can still be passed as an argument as well | |
| 2092 // which will also be non call static use. | |
| 2093 for (int i = 1; i < node.inputs.length; i++) { | |
| 2094 if (identical(node.inputs, node)) { | |
| 2095 backend.registerNonCallStaticUse(node); | |
| 2096 break; | |
| 2097 } | |
| 2098 } | |
| 2099 } | 2098 } |
| 2100 }); | 2099 }); |
| 2101 world.registerStaticUse(node.element); | 2100 Element element = node.element; |
| 2101 world.registerStaticUse(element); |
| 2102 ClassElement cls = element.getEnclosingClass(); |
| 2103 if (element.isGenerativeConstructor() |
| 2104 || (element.isFactoryConstructor() && cls == compiler.listClass)) { |
| 2105 world.registerInstantiatedClass(cls); |
| 2106 } |
| 2102 push(new js.VariableUse(backend.namer.isolateAccess(node.element))); | 2107 push(new js.VariableUse(backend.namer.isolateAccess(node.element))); |
| 2103 } | 2108 } |
| 2104 | 2109 |
| 2105 void visitLazyStatic(HLazyStatic node) { | 2110 void visitLazyStatic(HLazyStatic node) { |
| 2106 Element element = node.element; | 2111 Element element = node.element; |
| 2107 world.registerStaticUse(element); | 2112 world.registerStaticUse(element); |
| 2108 String lazyGetter = backend.namer.isolateLazyInitializerAccess(element); | 2113 String lazyGetter = backend.namer.isolateLazyInitializerAccess(element); |
| 2109 js.VariableUse target = new js.VariableUse(lazyGetter); | 2114 js.VariableUse target = new js.VariableUse(lazyGetter); |
| 2110 js.Call call = new js.Call(target, <js.Expression>[]); | 2115 js.Call call = new js.Call(target, <js.Expression>[]); |
| 2111 push(call, node); | 2116 push(call, node); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2146 Element convertToString = compiler.findHelper(const SourceString("S")); | 2151 Element convertToString = compiler.findHelper(const SourceString("S")); |
| 2147 world.registerStaticUse(convertToString); | 2152 world.registerStaticUse(convertToString); |
| 2148 js.VariableUse variableUse = | 2153 js.VariableUse variableUse = |
| 2149 new js.VariableUse(backend.namer.isolateAccess(convertToString)); | 2154 new js.VariableUse(backend.namer.isolateAccess(convertToString)); |
| 2150 use(node); | 2155 use(node); |
| 2151 push(new js.Call(variableUse, <js.Expression>[pop()]), node); | 2156 push(new js.Call(variableUse, <js.Expression>[pop()]), node); |
| 2152 } | 2157 } |
| 2153 } | 2158 } |
| 2154 | 2159 |
| 2155 void visitLiteralList(HLiteralList node) { | 2160 void visitLiteralList(HLiteralList node) { |
| 2161 world.registerInstantiatedClass(compiler.listClass); |
| 2156 generateArrayLiteral(node); | 2162 generateArrayLiteral(node); |
| 2157 } | 2163 } |
| 2158 | 2164 |
| 2159 void generateArrayLiteral(HLiteralList node) { | 2165 void generateArrayLiteral(HLiteralList node) { |
| 2160 int len = node.inputs.length; | 2166 int len = node.inputs.length; |
| 2161 List<js.ArrayElement> elements = <js.ArrayElement>[]; | 2167 List<js.ArrayElement> elements = <js.ArrayElement>[]; |
| 2162 for (int i = 0; i < len; i++) { | 2168 for (int i = 0; i < len; i++) { |
| 2163 use(node.inputs[i]); | 2169 use(node.inputs[i]); |
| 2164 elements.add(new js.ArrayElement(i, pop())); | 2170 elements.add(new js.ArrayElement(i, pop())); |
| 2165 } | 2171 } |
| (...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3043 if (leftType.canBeNull() && rightType.canBeNull()) { | 3049 if (leftType.canBeNull() && rightType.canBeNull()) { |
| 3044 if (left.isConstantNull() || right.isConstantNull() || | 3050 if (left.isConstantNull() || right.isConstantNull() || |
| 3045 (leftType.isPrimitive() && leftType == rightType)) { | 3051 (leftType.isPrimitive() && leftType == rightType)) { |
| 3046 return '=='; | 3052 return '=='; |
| 3047 } | 3053 } |
| 3048 return null; | 3054 return null; |
| 3049 } else { | 3055 } else { |
| 3050 return '==='; | 3056 return '==='; |
| 3051 } | 3057 } |
| 3052 } | 3058 } |
| OLD | NEW |