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