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 |