| 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 | 
|---|