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 |