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 dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
6 | 6 |
7 const USE_NEW_EMITTER = const bool.fromEnvironment("dart2js.use.new.emitter"); | 7 const USE_NEW_EMITTER = const bool.fromEnvironment("dart2js.use.new.emitter"); |
8 | 8 |
9 /** | 9 /** |
10 * Generates the code for all used classes in the program. Static fields (even | 10 * Generates the code for all used classes in the program. Static fields (even |
11 * in classes) are ignored, since they can be treated as non-class elements. | 11 * in classes) are ignored, since they can be treated as non-class elements. |
12 * | 12 * |
13 * The code for the containing (used) methods must exist in the [:universe:]. | 13 * The code for the containing (used) methods must exist in the [:universe:]. |
14 */ | 14 */ |
15 class CodeEmitterTask extends CompilerTask { | 15 class CodeEmitterTask extends CompilerTask { |
16 // TODO(floitsch): the code-emitter task should not need a namer. | 16 // TODO(floitsch): the code-emitter task should not need a namer. |
17 final Namer namer; | 17 final Namer namer; |
18 final TypeTestEmitter typeTestEmitter = new TypeTestEmitter(); | 18 final TypeTestEmitter typeTestEmitter = new TypeTestEmitter(); |
19 NativeEmitter nativeEmitter; | 19 NativeEmitter nativeEmitter; |
20 OldEmitter oldEmitter; | 20 OldEmitter oldEmitter; |
21 Emitter emitter; | 21 Emitter emitter; |
22 | 22 |
23 final Set<ClassElement> neededClasses = new Set<ClassElement>(); | 23 final Set<ClassElement> neededClasses = new Set<ClassElement>(); |
24 final Map<OutputUnit, List<ClassElement>> outputClassLists = | 24 final Map<OutputUnit, List<ClassElement>> outputClassLists = |
25 new Map<OutputUnit, List<ClassElement>>(); | 25 new Map<OutputUnit, List<ClassElement>>(); |
26 final Map<OutputUnit, List<Constant>> outputConstantLists = | 26 final Map<OutputUnit, List<ConstantValue>> outputConstantLists = |
27 new Map<OutputUnit, List<Constant>>(); | 27 new Map<OutputUnit, List<ConstantValue>>(); |
28 final List<ClassElement> nativeClasses = <ClassElement>[]; | 28 final List<ClassElement> nativeClasses = <ClassElement>[]; |
29 | 29 |
30 /// Records if a type variable is read dynamically for type tests. | 30 /// Records if a type variable is read dynamically for type tests. |
31 final Set<TypeVariableElement> readTypeVariables = | 31 final Set<TypeVariableElement> readTypeVariables = |
32 new Set<TypeVariableElement>(); | 32 new Set<TypeVariableElement>(); |
33 | 33 |
34 // TODO(ngeoffray): remove this field. | 34 // TODO(ngeoffray): remove this field. |
35 Set<ClassElement> instantiatedClasses; | 35 Set<ClassElement> instantiatedClasses; |
36 List<TypedefElement> typedefsNeededForReflection; | 36 List<TypedefElement> typedefsNeededForReflection; |
37 | 37 |
(...skipping 11 matching lines...) Expand all Loading... |
49 // TODO(18886): Remove this call (and the show in the import) once the | 49 // TODO(18886): Remove this call (and the show in the import) once the |
50 // memory-leak in the VM is fixed. | 50 // memory-leak in the VM is fixed. |
51 templateManager.clear(); | 51 templateManager.clear(); |
52 } | 52 } |
53 | 53 |
54 | 54 |
55 jsAst.Expression generateEmbeddedGlobalAccess(String global) { | 55 jsAst.Expression generateEmbeddedGlobalAccess(String global) { |
56 return emitter.generateEmbeddedGlobalAccess(global); | 56 return emitter.generateEmbeddedGlobalAccess(global); |
57 } | 57 } |
58 | 58 |
59 jsAst.Expression constantReference(Constant value) { | 59 jsAst.Expression constantReference(ConstantValue value) { |
60 return emitter.constantReference(value); | 60 return emitter.constantReference(value); |
61 } | 61 } |
62 | 62 |
63 Set<ClassElement> interceptorsReferencedFromConstants() { | 63 Set<ClassElement> interceptorsReferencedFromConstants() { |
64 Set<ClassElement> classes = new Set<ClassElement>(); | 64 Set<ClassElement> classes = new Set<ClassElement>(); |
65 JavaScriptConstantCompiler handler = backend.constants; | 65 JavaScriptConstantCompiler handler = backend.constants; |
66 List<Constant> constants = handler.getConstantsForEmission(); | 66 List<ConstantValue> constants = handler.getConstantsForEmission(); |
67 for (Constant constant in constants) { | 67 for (ConstantValue constant in constants) { |
68 if (constant is InterceptorConstant) { | 68 if (constant is InterceptorConstantValue) { |
69 InterceptorConstant interceptorConstant = constant; | 69 InterceptorConstantValue interceptorConstant = constant; |
70 classes.add(interceptorConstant.dispatchedType.element); | 70 classes.add(interceptorConstant.dispatchedType.element); |
71 } | 71 } |
72 } | 72 } |
73 return classes; | 73 return classes; |
74 } | 74 } |
75 | 75 |
76 /** | 76 /** |
77 * Return a function that returns true if its argument is a class | 77 * Return a function that returns true if its argument is a class |
78 * that needs to be emitted. | 78 * that needs to be emitted. |
79 */ | 79 */ |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 unneededClasses.add(backend.jsPositiveIntClass); | 114 unneededClasses.add(backend.jsPositiveIntClass); |
115 | 115 |
116 return (ClassElement cls) => !unneededClasses.contains(cls); | 116 return (ClassElement cls) => !unneededClasses.contains(cls); |
117 } | 117 } |
118 | 118 |
119 /** | 119 /** |
120 * Compute all the constants that must be emitted. | 120 * Compute all the constants that must be emitted. |
121 */ | 121 */ |
122 void computeNeededConstants() { | 122 void computeNeededConstants() { |
123 JavaScriptConstantCompiler handler = backend.constants; | 123 JavaScriptConstantCompiler handler = backend.constants; |
124 List<Constant> constants = handler.getConstantsForEmission( | 124 List<ConstantValue> constants = handler.getConstantsForEmission( |
125 compiler.hasIncrementalSupport ? null : emitter.compareConstants); | 125 compiler.hasIncrementalSupport ? null : emitter.compareConstants); |
126 for (Constant constant in constants) { | 126 for (ConstantValue constant in constants) { |
127 if (emitter.isConstantInlinedOrAlreadyEmitted(constant)) continue; | 127 if (emitter.isConstantInlinedOrAlreadyEmitted(constant)) continue; |
128 OutputUnit constantUnit = | 128 OutputUnit constantUnit = |
129 compiler.deferredLoadTask.outputUnitForConstant(constant); | 129 compiler.deferredLoadTask.outputUnitForConstant(constant); |
130 if (constantUnit == null) { | 130 if (constantUnit == null) { |
131 // The back-end introduces some constants, like "InterceptorConstant" or | 131 // The back-end introduces some constants, like "InterceptorConstant" or |
132 // some list constants. They are emitted in the main output-unit. | 132 // some list constants. They are emitted in the main output-unit. |
133 // TODO(sigurdm): We should track those constants. | 133 // TODO(sigurdm): We should track those constants. |
134 constantUnit = compiler.deferredLoadTask.mainOutputUnit; | 134 constantUnit = compiler.deferredLoadTask.mainOutputUnit; |
135 } | 135 } |
136 outputConstantLists.putIfAbsent(constantUnit, () => new List<Constant>()) | 136 outputConstantLists.putIfAbsent(constantUnit, () => new List<ConstantValue
>()) |
137 .add(constant); | 137 .add(constant); |
138 } | 138 } |
139 } | 139 } |
140 | 140 |
141 /// Compute all the classes and typedefs that must be emitted. | 141 /// Compute all the classes and typedefs that must be emitted. |
142 void computeNeededDeclarations() { | 142 void computeNeededDeclarations() { |
143 // Compute needed typedefs. | 143 // Compute needed typedefs. |
144 typedefsNeededForReflection = Elements.sortedByPosition( | 144 typedefsNeededForReflection = Elements.sortedByPosition( |
145 compiler.world.allTypedefs | 145 compiler.world.allTypedefs |
146 .where(backend.isAccessibleByReflection) | 146 .where(backend.isAccessibleByReflection) |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 | 269 |
270 void registerReadTypeVariable(TypeVariableElement element) { | 270 void registerReadTypeVariable(TypeVariableElement element) { |
271 readTypeVariables.add(element); | 271 readTypeVariables.add(element); |
272 } | 272 } |
273 } | 273 } |
274 | 274 |
275 abstract class Emitter { | 275 abstract class Emitter { |
276 void emitProgram(); | 276 void emitProgram(); |
277 | 277 |
278 jsAst.Expression generateEmbeddedGlobalAccess(String global); | 278 jsAst.Expression generateEmbeddedGlobalAccess(String global); |
279 jsAst.Expression constantReference(Constant value); | 279 jsAst.Expression constantReference(ConstantValue value); |
280 | 280 |
281 int compareConstants(Constant a, Constant b); | 281 int compareConstants(ConstantValue a, ConstantValue b); |
282 bool isConstantInlinedOrAlreadyEmitted(Constant constant); | 282 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant); |
283 | 283 |
284 void invalidateCaches(); | 284 void invalidateCaches(); |
285 } | 285 } |
OLD | NEW |