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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 CodeBuffer generateMethod(WorkItem work, HGraph graph) { | 66 CodeBuffer generateMethod(WorkItem work, HGraph graph) { |
67 return measure(() { | 67 return measure(() { |
68 compiler.tracer.traceGraph("codegen", graph); | 68 compiler.tracer.traceGraph("codegen", graph); |
69 SsaOptimizedCodeGenerator codegen = | 69 SsaOptimizedCodeGenerator codegen = |
70 new SsaOptimizedCodeGenerator(backend, work); | 70 new SsaOptimizedCodeGenerator(backend, work); |
71 codegen.visitGraph(graph); | 71 codegen.visitGraph(graph); |
72 | 72 |
73 FunctionElement element = work.element; | 73 FunctionElement element = work.element; |
74 js.Block body; | 74 js.Block body; |
75 ClassElement enclosingClass = element.getEnclosingClass(); | 75 ClassElement enclosingClass = element.getEnclosingClass(); |
76 bool allowVariableMinification = !codegen.visitedForeignCode; | 76 bool allowVariableMinification = !codegen.inhibitVariableMinification; |
77 | 77 |
78 if (element.isInstanceMember() | 78 if (element.isInstanceMember() |
79 && enclosingClass.isNative() | 79 && enclosingClass.isNative() |
80 && native.isOverriddenMethod( | 80 && native.isOverriddenMethod( |
81 element, enclosingClass, nativeEmitter)) { | 81 element, enclosingClass, nativeEmitter)) { |
82 // Record that this method is overridden. In case of optional | 82 // Record that this method is overridden. In case of optional |
83 // arguments, the emitter will generate stubs to handle them, | 83 // arguments, the emitter will generate stubs to handle them, |
84 // and needs to know if the method is overridden. | 84 // and needs to know if the method is overridden. |
85 nativeEmitter.overriddenMethods.add(element); | 85 nativeEmitter.overriddenMethods.add(element); |
86 StringBuffer buffer = new StringBuffer(); | 86 StringBuffer buffer = new StringBuffer(); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 static const int TYPE_STATEMENT = 0; | 156 static const int TYPE_STATEMENT = 0; |
157 static const int TYPE_EXPRESSION = 1; | 157 static const int TYPE_EXPRESSION = 1; |
158 static const int TYPE_DECLARATION = 2; | 158 static const int TYPE_DECLARATION = 2; |
159 | 159 |
160 /** | 160 /** |
161 * Whether we are currently generating expressions instead of statements. | 161 * Whether we are currently generating expressions instead of statements. |
162 * This includes declarations, which are generated as expressions. | 162 * This includes declarations, which are generated as expressions. |
163 */ | 163 */ |
164 bool isGeneratingExpression = false; | 164 bool isGeneratingExpression = false; |
165 | 165 |
166 bool visitedForeignCode = false; | 166 bool inhibitVariableMinification = false; |
167 | 167 |
168 final JavaScriptBackend backend; | 168 final JavaScriptBackend backend; |
169 final WorkItem work; | 169 final WorkItem work; |
170 final HTypeMap types; | 170 final HTypeMap types; |
171 | 171 |
172 final Set<HInstruction> generateAtUseSite; | 172 final Set<HInstruction> generateAtUseSite; |
173 final Set<HInstruction> controlFlowOperators; | 173 final Set<HInstruction> controlFlowOperators; |
174 final Map<Element, ElementAction> breakAction; | 174 final Map<Element, ElementAction> breakAction; |
175 final Map<Element, ElementAction> continueAction; | 175 final Map<Element, ElementAction> continueAction; |
176 final Map<Element, String> parameterNames; | 176 final Map<Element, String> parameterNames; |
(...skipping 1594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1771 visitLocalGet(HLocalGet node) { | 1771 visitLocalGet(HLocalGet node) { |
1772 use(node.receiver); | 1772 use(node.receiver); |
1773 } | 1773 } |
1774 | 1774 |
1775 visitLocalSet(HLocalSet node) { | 1775 visitLocalSet(HLocalSet node) { |
1776 use(node.value); | 1776 use(node.value); |
1777 assignVariable(variableNames.getName(node.receiver), pop()); | 1777 assignVariable(variableNames.getName(node.receiver), pop()); |
1778 } | 1778 } |
1779 | 1779 |
1780 visitForeign(HForeign node) { | 1780 visitForeign(HForeign node) { |
1781 visitedForeignCode = true; | 1781 // TODO(sra): We could be a lot more picky about when to inhibit renaming of |
| 1782 // locals - most JS strings don't contain free variables, or contain safe |
| 1783 // ones like 'Object'. JS strings like "#.length" and "#[#]" are perfectly |
| 1784 // safe for variable renaming. |
| 1785 inhibitVariableMinification = true; |
1782 String code = node.code.slowToString(); | 1786 String code = node.code.slowToString(); |
1783 List<HInstruction> inputs = node.inputs; | 1787 List<HInstruction> inputs = node.inputs; |
1784 if (node.isJsStatement(types)) { | 1788 if (node.isJsStatement(types)) { |
1785 if (!inputs.isEmpty) { | 1789 if (!inputs.isEmpty) { |
1786 compiler.internalError("foreign statement with inputs: $code", | 1790 compiler.internalError("foreign statement with inputs: $code", |
1787 instruction: node); | 1791 instruction: node); |
1788 } | 1792 } |
1789 pushStatement(new js.LiteralStatement(code), node); | 1793 pushStatement(new js.LiteralStatement(code), node); |
1790 } else { | 1794 } else { |
1791 List<js.Expression> data = <js.Expression>[]; | 1795 List<js.Expression> data = <js.Expression>[]; |
1792 for (int i = 0; i < inputs.length; i++) { | 1796 for (int i = 0; i < inputs.length; i++) { |
1793 use(inputs[i]); | 1797 use(inputs[i]); |
1794 data.add(pop()); | 1798 data.add(pop()); |
1795 } | 1799 } |
1796 push(new js.LiteralExpression.withData(code, data), node); | 1800 push(new js.LiteralExpression.withData(code, data), node); |
1797 } | 1801 } |
1798 DartType type = types[node].computeType(compiler); | 1802 DartType type = types[node].computeType(compiler); |
1799 if (type != null) { | 1803 if (type != null) { |
1800 world.registerInstantiatedClass(type.element); | 1804 world.registerInstantiatedClass(type.element); |
1801 } | 1805 } |
1802 // TODO(sra): Tell world.nativeEnqueuer about the types created here. | 1806 // TODO(sra): Tell world.nativeEnqueuer about the types created here. |
1803 } | 1807 } |
1804 | 1808 |
1805 visitForeignNew(HForeignNew node) { | 1809 visitForeignNew(HForeignNew node) { |
1806 visitedForeignCode = true; | |
1807 String jsClassReference = backend.namer.isolateAccess(node.element); | 1810 String jsClassReference = backend.namer.isolateAccess(node.element); |
1808 List<HInstruction> inputs = node.inputs; | 1811 List<HInstruction> inputs = node.inputs; |
1809 // We can't use 'visitArguments', since our arguments start at input[0]. | 1812 // We can't use 'visitArguments', since our arguments start at input[0]. |
1810 List<js.Expression> arguments = <js.Expression>[]; | 1813 List<js.Expression> arguments = <js.Expression>[]; |
1811 for (int i = 0; i < inputs.length; i++) { | 1814 for (int i = 0; i < inputs.length; i++) { |
1812 use(inputs[i]); | 1815 use(inputs[i]); |
1813 arguments.add(pop()); | 1816 arguments.add(pop()); |
1814 } | 1817 } |
1815 // TODO(floitsch): jsClassReference is an Access. We shouldn't treat it | 1818 // TODO(floitsch): jsClassReference is an Access. We shouldn't treat it |
1816 // as if it was a string. | 1819 // as if it was a string. |
(...skipping 1239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3056 if (leftType.canBeNull() && rightType.canBeNull()) { | 3059 if (leftType.canBeNull() && rightType.canBeNull()) { |
3057 if (left.isConstantNull() || right.isConstantNull() || | 3060 if (left.isConstantNull() || right.isConstantNull() || |
3058 (leftType.isPrimitive() && leftType == rightType)) { | 3061 (leftType.isPrimitive() && leftType == rightType)) { |
3059 return '=='; | 3062 return '=='; |
3060 } | 3063 } |
3061 return null; | 3064 return null; |
3062 } else { | 3065 } else { |
3063 return '==='; | 3066 return '==='; |
3064 } | 3067 } |
3065 } | 3068 } |
OLD | NEW |