| 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 class SsaCodeGeneratorTask extends CompilerTask { | 5 class SsaCodeGeneratorTask extends CompilerTask { |
| 6 final JavaScriptBackend backend; | 6 final JavaScriptBackend backend; |
| 7 SsaCodeGeneratorTask(JavaScriptBackend backend) | 7 SsaCodeGeneratorTask(JavaScriptBackend backend) |
| 8 : this.backend = backend, | 8 : this.backend = backend, |
| 9 super(backend.compiler); | 9 super(backend.compiler); |
| 10 String get name() => 'SSA code generator'; | 10 String get name() => 'SSA code generator'; |
| 11 NativeEmitter get nativeEmitter() => backend.emitter.nativeEmitter; | 11 NativeEmitter get nativeEmitter() => backend.emitter.nativeEmitter; |
| 12 | 12 |
| 13 | 13 |
| 14 CodeBlock buildJavaScriptFunction(FunctionElement element, | 14 CodeBuffer buildJavaScriptFunction(FunctionElement element, |
| 15 String parameters, | 15 String parameters, |
| 16 String body) { | 16 String body) { |
| 17 String extraSpace = ""; | 17 String extraSpace = ""; |
| 18 // Members are emitted inside a JavaScript object literal. To line up the | 18 // Members are emitted inside a JavaScript object literal. To line up the |
| 19 // indentation we want the closing curly brace to be indented by one space. | 19 // indentation we want the closing curly brace to be indented by one space. |
| 20 // Example: | 20 // Example: |
| 21 // defineClass("A", "B", ... , { | 21 // defineClass("A", "B", ... , { |
| 22 // foo$1: function(..) { | 22 // foo$1: function(..) { |
| 23 // }, /* <========== indent by 1. */ | 23 // }, /* <========== indent by 1. */ |
| 24 // bar$2: function(..) { | 24 // bar$2: function(..) { |
| 25 // }, /* <========== indent by 1. */ | 25 // }, /* <========== indent by 1. */ |
| 26 // | 26 // |
| 27 // For static functions this is not necessary: | 27 // For static functions this is not necessary: |
| 28 // $.staticFun = function() { | 28 // $.staticFun = function() { |
| 29 // ... | 29 // ... |
| 30 // }; | 30 // }; |
| 31 if (element.isInstanceMember() || | 31 if (element.isInstanceMember() || |
| 32 element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) { | 32 element.kind == ElementKind.GENERATIVE_CONSTRUCTOR_BODY) { |
| 33 extraSpace = " "; | 33 extraSpace = " "; |
| 34 } | 34 } |
| 35 | 35 |
| 36 String code = 'function($parameters) {\n$body$extraSpace}'; | |
| 37 List<SourceMappingEntry> sourceMappings = new List<SourceMappingEntry>(); | |
| 38 SourceFile sourceFile = element.getCompilationUnit().script.file; | |
| 39 FunctionExpression expression = element.cachedNode; | 36 FunctionExpression expression = element.cachedNode; |
| 40 sourceMappings.add(new SourceMappingEntry( | 37 CodeBuffer buffer = new CodeBuffer(); |
| 41 sourceFile, expression.getBeginToken().charOffset, 0)); | 38 buffer.setSourceLocation(element, expression.getBeginToken()); |
| 42 sourceMappings.add(new SourceMappingEntry( | 39 buffer.add('function($parameters) {\n'); |
| 43 sourceFile, expression.getEndToken().charOffset, code.length - 1)); | 40 buffer.add(body); |
| 44 return new CodeBlock(code, sourceMappings); | 41 buffer.add(extraSpace); |
| 42 buffer.setSourceLocation(element, expression.getEndToken()); |
| 43 buffer.add('}'); |
| 44 return buffer; |
| 45 } | 45 } |
| 46 | 46 |
| 47 CodeBlock generateMethod(WorkItem work, HGraph graph) { | 47 CodeBuffer generateMethod(WorkItem work, HGraph graph) { |
| 48 return measure(() { | 48 return measure(() { |
| 49 compiler.tracer.traceGraph("codegen", graph); | 49 compiler.tracer.traceGraph("codegen", graph); |
| 50 Map<Element, String> parameterNames = getParameterNames(work); | 50 Map<Element, String> parameterNames = getParameterNames(work); |
| 51 parameterNames.forEach((element, name) { | 51 parameterNames.forEach((element, name) { |
| 52 compiler.enqueuer.codegen.addToWorkList(element); | 52 compiler.enqueuer.codegen.addToWorkList(element); |
| 53 }); | 53 }); |
| 54 String parameters = Strings.join(parameterNames.getValues(), ', '); | 54 String parameters = Strings.join(parameterNames.getValues(), ', '); |
| 55 SsaOptimizedCodeGenerator codegen = new SsaOptimizedCodeGenerator( | 55 SsaOptimizedCodeGenerator codegen = new SsaOptimizedCodeGenerator( |
| 56 backend, work, parameters, parameterNames); | 56 backend, work, parameters, parameterNames); |
| 57 codegen.visitGraph(graph); | 57 codegen.visitGraph(graph); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 71 native.generateMethodWithPrototypeCheckForElement( | 71 native.generateMethodWithPrototypeCheckForElement( |
| 72 compiler, buffer, element, '${codegen.buffer}', parameters); | 72 compiler, buffer, element, '${codegen.buffer}', parameters); |
| 73 code = buffer.toString(); | 73 code = buffer.toString(); |
| 74 } else { | 74 } else { |
| 75 code = codegen.buffer.toString(); | 75 code = codegen.buffer.toString(); |
| 76 } | 76 } |
| 77 return buildJavaScriptFunction(element, parameters, code); | 77 return buildJavaScriptFunction(element, parameters, code); |
| 78 }); | 78 }); |
| 79 } | 79 } |
| 80 | 80 |
| 81 CodeBlock generateBailoutMethod(WorkItem work, HGraph graph) { | 81 CodeBuffer generateBailoutMethod(WorkItem work, HGraph graph) { |
| 82 return measure(() { | 82 return measure(() { |
| 83 compiler.tracer.traceGraph("codegen-bailout", graph); | 83 compiler.tracer.traceGraph("codegen-bailout", graph); |
| 84 | 84 |
| 85 Map<Element, String> parameterNames = getParameterNames(work); | 85 Map<Element, String> parameterNames = getParameterNames(work); |
| 86 String parameters = Strings.join(parameterNames.getValues(), ', '); | 86 String parameters = Strings.join(parameterNames.getValues(), ', '); |
| 87 SsaUnoptimizedCodeGenerator codegen = new SsaUnoptimizedCodeGenerator( | 87 SsaUnoptimizedCodeGenerator codegen = new SsaUnoptimizedCodeGenerator( |
| 88 backend, work, parameters, parameterNames); | 88 backend, work, parameters, parameterNames); |
| 89 codegen.visitGraph(graph); | 89 codegen.visitGraph(graph); |
| 90 | 90 |
| 91 String body = '${codegen.setup}${codegen.buffer}'; | 91 String body = '${codegen.setup}${codegen.buffer}'; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 * expression, and that it only generates expressions of the form | 145 * expression, and that it only generates expressions of the form |
| 146 * variable = expression | 146 * variable = expression |
| 147 * which are also valid as parts of a "var" declaration. | 147 * which are also valid as parts of a "var" declaration. |
| 148 */ | 148 */ |
| 149 static final int TYPE_STATEMENT = 0; | 149 static final int TYPE_STATEMENT = 0; |
| 150 static final int TYPE_EXPRESSION = 1; | 150 static final int TYPE_EXPRESSION = 1; |
| 151 static final int TYPE_DECLARATION = 2; | 151 static final int TYPE_DECLARATION = 2; |
| 152 | 152 |
| 153 final JavaScriptBackend backend; | 153 final JavaScriptBackend backend; |
| 154 final WorkItem work; | 154 final WorkItem work; |
| 155 final StringBuffer buffer; | 155 final CodeBuffer buffer; |
| 156 final String parameters; | 156 final String parameters; |
| 157 | 157 |
| 158 final Set<HInstruction> generateAtUseSite; | 158 final Set<HInstruction> generateAtUseSite; |
| 159 final Set<HInstruction> controlFlowOperators; | 159 final Set<HInstruction> controlFlowOperators; |
| 160 final Map<Element, ElementAction> breakAction; | 160 final Map<Element, ElementAction> breakAction; |
| 161 final Map<Element, ElementAction> continueAction; | 161 final Map<Element, ElementAction> continueAction; |
| 162 final Map<Element, String> parameterNames; | 162 final Map<Element, String> parameterNames; |
| 163 | 163 |
| 164 /** | 164 /** |
| 165 * Contains the names of the instructions, as well as the parallel | 165 * Contains the names of the instructions, as well as the parallel |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 } | 244 } |
| 245 return hasNonBitOpUser(instruction, new Set<HPhi>()); | 245 return hasNonBitOpUser(instruction, new Set<HPhi>()); |
| 246 } | 246 } |
| 247 | 247 |
| 248 SsaCodeGenerator(this.backend, | 248 SsaCodeGenerator(this.backend, |
| 249 this.work, | 249 this.work, |
| 250 this.parameters, | 250 this.parameters, |
| 251 this.parameterNames) | 251 this.parameterNames) |
| 252 : declaredVariables = new Set<String>(), | 252 : declaredVariables = new Set<String>(), |
| 253 delayedVariableDeclarations = new Set<String>(), | 253 delayedVariableDeclarations = new Set<String>(), |
| 254 buffer = new StringBuffer(), | 254 buffer = new CodeBuffer(), |
| 255 generateAtUseSite = new Set<HInstruction>(), | 255 generateAtUseSite = new Set<HInstruction>(), |
| 256 controlFlowOperators = new Set<HInstruction>(), | 256 controlFlowOperators = new Set<HInstruction>(), |
| 257 breakAction = new Map<Element, ElementAction>(), | 257 breakAction = new Map<Element, ElementAction>(), |
| 258 continueAction = new Map<Element, ElementAction>(), | 258 continueAction = new Map<Element, ElementAction>(), |
| 259 unsignedShiftPrecedences = JSPrecedence.binary['>>>'] { | 259 unsignedShiftPrecedences = JSPrecedence.binary['>>>'] { |
| 260 } | 260 } |
| 261 | 261 |
| 262 abstract visitTypeGuard(HTypeGuard node); | 262 abstract visitTypeGuard(HTypeGuard node); |
| 263 | 263 |
| 264 abstract beginGraph(HGraph graph); | 264 abstract beginGraph(HGraph graph); |
| (...skipping 2559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2824 | 2824 |
| 2825 void startLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { | 2825 void startLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { |
| 2826 } | 2826 } |
| 2827 | 2827 |
| 2828 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { | 2828 void endLabeledBlock(HLabeledBlockInformation labeledBlockInfo) { |
| 2829 } | 2829 } |
| 2830 } | 2830 } |
| 2831 | 2831 |
| 2832 class SsaUnoptimizedCodeGenerator extends SsaCodeGenerator { | 2832 class SsaUnoptimizedCodeGenerator extends SsaCodeGenerator { |
| 2833 | 2833 |
| 2834 final StringBuffer setup; | 2834 final CodeBuffer setup; |
| 2835 final StringBuffer newParameters; | 2835 final CodeBuffer newParameters; |
| 2836 final List<String> labels; | 2836 final List<String> labels; |
| 2837 int labelId = 0; | 2837 int labelId = 0; |
| 2838 | 2838 |
| 2839 SsaBailoutPropagator propagator; | 2839 SsaBailoutPropagator propagator; |
| 2840 HInstruction savedFirstInstruction; | 2840 HInstruction savedFirstInstruction; |
| 2841 | 2841 |
| 2842 SsaUnoptimizedCodeGenerator(backend, work, parameters, parameterNames) | 2842 SsaUnoptimizedCodeGenerator(backend, work, parameters, parameterNames) |
| 2843 : super(backend, work, parameters, parameterNames), | 2843 : super(backend, work, parameters, parameterNames), |
| 2844 setup = new StringBuffer(), | 2844 setup = new CodeBuffer(), |
| 2845 newParameters = new StringBuffer(), | 2845 newParameters = new CodeBuffer(), |
| 2846 labels = <String>[]; | 2846 labels = <String>[]; |
| 2847 | 2847 |
| 2848 String pushLabel() { | 2848 String pushLabel() { |
| 2849 String label = 'L${labelId++}'; | 2849 String label = 'L${labelId++}'; |
| 2850 labels.addLast(label); | 2850 labels.addLast(label); |
| 2851 return label; | 2851 return label; |
| 2852 } | 2852 } |
| 2853 | 2853 |
| 2854 String popLabel() { | 2854 String popLabel() { |
| 2855 return labels.removeLast(); | 2855 return labels.removeLast(); |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3111 if (leftType.canBeNull() && rightType.canBeNull()) { | 3111 if (leftType.canBeNull() && rightType.canBeNull()) { |
| 3112 if (left.isConstantNull() || right.isConstantNull() || | 3112 if (left.isConstantNull() || right.isConstantNull() || |
| 3113 (leftType.isPrimitive() && leftType == rightType)) { | 3113 (leftType.isPrimitive() && leftType == rightType)) { |
| 3114 return '=='; | 3114 return '=='; |
| 3115 } | 3115 } |
| 3116 return null; | 3116 return null; |
| 3117 } else { | 3117 } else { |
| 3118 return '==='; | 3118 return '==='; |
| 3119 } | 3119 } |
| 3120 } | 3120 } |
| OLD | NEW |