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 library dart2js.common.codegen; | 5 library dart2js.common.codegen; |
6 | 6 |
7 import '../common.dart'; | 7 import '../common.dart'; |
8 import '../compiler.dart' show | 8 import '../compiler.dart' show Compiler; |
9 Compiler; | 9 import '../constants/values.dart' show ConstantValue; |
10 import '../constants/values.dart' show | 10 import '../dart_types.dart' show DartType, InterfaceType; |
11 ConstantValue; | 11 import '../elements/elements.dart' |
12 import '../dart_types.dart' show | 12 show |
13 DartType, | 13 AstElement, |
14 InterfaceType; | 14 ClassElement, |
15 import '../elements/elements.dart' show | 15 Element, |
16 AstElement, | 16 FunctionElement, |
17 ClassElement, | 17 LocalFunctionElement; |
18 Element, | 18 import '../enqueue.dart' show CodegenEnqueuer; |
19 FunctionElement, | 19 import '../resolution/tree_elements.dart' show TreeElements; |
20 LocalFunctionElement; | 20 import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse; |
21 import '../enqueue.dart' show | 21 import '../universe/world_impact.dart' |
22 CodegenEnqueuer; | 22 show WorldImpact, WorldImpactBuilder, WorldImpactVisitor; |
23 import '../resolution/tree_elements.dart' show | 23 import '../util/util.dart' show Pair, Setlet; |
24 TreeElements; | 24 import 'registry.dart' show Registry, EagerRegistry; |
25 import '../universe/use.dart' show | 25 import 'work.dart' show ItemCompilationContext, WorkItem; |
26 DynamicUse, | |
27 StaticUse, | |
28 TypeUse; | |
29 import '../universe/world_impact.dart' show | |
30 WorldImpact, | |
31 WorldImpactBuilder, | |
32 WorldImpactVisitor; | |
33 import '../util/util.dart' show | |
34 Pair, | |
35 Setlet; | |
36 import 'registry.dart' show | |
37 Registry, | |
38 EagerRegistry; | |
39 import 'work.dart' show | |
40 ItemCompilationContext, | |
41 WorkItem; | |
42 | 26 |
43 class CodegenImpact extends WorldImpact { | 27 class CodegenImpact extends WorldImpact { |
44 const CodegenImpact(); | 28 const CodegenImpact(); |
45 | 29 |
46 // TODO(johnniwinther): Remove this. | 30 // TODO(johnniwinther): Remove this. |
47 Registry get registry => null; | 31 Registry get registry => null; |
48 | 32 |
49 Iterable<ConstantValue> get compileTimeConstants => const <ConstantValue>[]; | 33 Iterable<ConstantValue> get compileTimeConstants => const <ConstantValue>[]; |
50 | 34 |
51 Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks { | 35 Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks { |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
87 | 71 |
88 void registerCompileTimeConstant(ConstantValue constant) { | 72 void registerCompileTimeConstant(ConstantValue constant) { |
89 if (_compileTimeConstants == null) { | 73 if (_compileTimeConstants == null) { |
90 _compileTimeConstants = new Setlet<ConstantValue>(); | 74 _compileTimeConstants = new Setlet<ConstantValue>(); |
91 } | 75 } |
92 _compileTimeConstants.add(constant); | 76 _compileTimeConstants.add(constant); |
93 } | 77 } |
94 | 78 |
95 Iterable<ConstantValue> get compileTimeConstants { | 79 Iterable<ConstantValue> get compileTimeConstants { |
96 return _compileTimeConstants != null | 80 return _compileTimeConstants != null |
97 ? _compileTimeConstants : const <ConstantValue>[]; | 81 ? _compileTimeConstants |
| 82 : const <ConstantValue>[]; |
98 } | 83 } |
99 | 84 |
100 void registerTypeVariableBoundsSubtypeCheck(DartType subtype, | 85 void registerTypeVariableBoundsSubtypeCheck( |
101 DartType supertype) { | 86 DartType subtype, DartType supertype) { |
102 if (_typeVariableBoundsSubtypeChecks == null) { | 87 if (_typeVariableBoundsSubtypeChecks == null) { |
103 _typeVariableBoundsSubtypeChecks = new Setlet<Pair<DartType, DartType>>(); | 88 _typeVariableBoundsSubtypeChecks = new Setlet<Pair<DartType, DartType>>(); |
104 } | 89 } |
105 _typeVariableBoundsSubtypeChecks.add( | 90 _typeVariableBoundsSubtypeChecks |
106 new Pair<DartType, DartType>(subtype, supertype)); | 91 .add(new Pair<DartType, DartType>(subtype, supertype)); |
107 } | 92 } |
108 | 93 |
109 Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks { | 94 Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks { |
110 return _typeVariableBoundsSubtypeChecks != null | 95 return _typeVariableBoundsSubtypeChecks != null |
111 ? _typeVariableBoundsSubtypeChecks : const <Pair<DartType, DartType>>[]; | 96 ? _typeVariableBoundsSubtypeChecks |
| 97 : const <Pair<DartType, DartType>>[]; |
112 } | 98 } |
113 | 99 |
114 void registerConstSymbol(String name) { | 100 void registerConstSymbol(String name) { |
115 if (_constSymbols == null) { | 101 if (_constSymbols == null) { |
116 _constSymbols = new Setlet<String>(); | 102 _constSymbols = new Setlet<String>(); |
117 } | 103 } |
118 _constSymbols.add(name); | 104 _constSymbols.add(name); |
119 } | 105 } |
120 | 106 |
121 Iterable<String> get constSymbols { | 107 Iterable<String> get constSymbols { |
122 return _constSymbols != null | 108 return _constSymbols != null ? _constSymbols : const <String>[]; |
123 ? _constSymbols : const <String>[]; | |
124 } | 109 } |
125 | 110 |
126 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { | 111 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { |
127 if (_specializedGetInterceptors == null) { | 112 if (_specializedGetInterceptors == null) { |
128 _specializedGetInterceptors = <Set<ClassElement>>[]; | 113 _specializedGetInterceptors = <Set<ClassElement>>[]; |
129 } | 114 } |
130 _specializedGetInterceptors.add(classes); | 115 _specializedGetInterceptors.add(classes); |
131 } | 116 } |
132 | 117 |
133 Iterable<Set<ClassElement>> get specializedGetInterceptors { | 118 Iterable<Set<ClassElement>> get specializedGetInterceptors { |
134 return _specializedGetInterceptors != null | 119 return _specializedGetInterceptors != null |
135 ? _specializedGetInterceptors : const <Set<ClassElement>>[]; | 120 ? _specializedGetInterceptors |
| 121 : const <Set<ClassElement>>[]; |
136 } | 122 } |
137 | 123 |
138 void registerUseInterceptor() { | 124 void registerUseInterceptor() { |
139 _usesInterceptor = true; | 125 _usesInterceptor = true; |
140 } | 126 } |
141 | 127 |
142 bool get usesInterceptor => _usesInterceptor; | 128 bool get usesInterceptor => _usesInterceptor; |
143 | 129 |
144 void registerTypeConstant(ClassElement element) { | 130 void registerTypeConstant(ClassElement element) { |
145 if (_typeConstants == null) { | 131 if (_typeConstants == null) { |
146 _typeConstants = new Setlet<ClassElement>(); | 132 _typeConstants = new Setlet<ClassElement>(); |
147 } | 133 } |
148 _typeConstants.add(element); | 134 _typeConstants.add(element); |
149 } | 135 } |
150 | 136 |
151 Iterable<ClassElement> get typeConstants { | 137 Iterable<ClassElement> get typeConstants { |
152 return _typeConstants != null | 138 return _typeConstants != null ? _typeConstants : const <ClassElement>[]; |
153 ? _typeConstants : const <ClassElement>[]; | |
154 } | 139 } |
155 | 140 |
156 void registerAsyncMarker(FunctionElement element) { | 141 void registerAsyncMarker(FunctionElement element) { |
157 if (_asyncMarkers == null) { | 142 if (_asyncMarkers == null) { |
158 _asyncMarkers = new Setlet<FunctionElement>(); | 143 _asyncMarkers = new Setlet<FunctionElement>(); |
159 } | 144 } |
160 _asyncMarkers.add(element); | 145 _asyncMarkers.add(element); |
161 } | 146 } |
162 | 147 |
163 Iterable<Element> get asyncMarkers { | 148 Iterable<Element> get asyncMarkers { |
164 return _asyncMarkers != null | 149 return _asyncMarkers != null ? _asyncMarkers : const <FunctionElement>[]; |
165 ? _asyncMarkers : const <FunctionElement>[]; | |
166 } | 150 } |
167 } | 151 } |
168 | 152 |
169 // TODO(johnniwinther): Split this class into interface and implementation. | 153 // TODO(johnniwinther): Split this class into interface and implementation. |
170 // TODO(johnniwinther): Move this implementation to the JS backend. | 154 // TODO(johnniwinther): Move this implementation to the JS backend. |
171 class CodegenRegistry extends Registry { | 155 class CodegenRegistry extends Registry { |
172 final Compiler compiler; | 156 final Compiler compiler; |
173 final Element currentElement; | 157 final Element currentElement; |
174 final _CodegenImpact worldImpact; | 158 final _CodegenImpact worldImpact; |
175 | 159 |
176 CodegenRegistry(Compiler compiler, AstElement currentElement) | 160 CodegenRegistry(Compiler compiler, AstElement currentElement) |
177 : this.compiler = compiler, | 161 : this.compiler = compiler, |
178 this.currentElement = currentElement, | 162 this.currentElement = currentElement, |
179 this.worldImpact = new _CodegenImpact(new EagerRegistry( | 163 this.worldImpact = new _CodegenImpact(new EagerRegistry( |
180 'EagerRegistry for $currentElement', compiler.enqueuer.codegen)); | 164 'EagerRegistry for $currentElement', compiler.enqueuer.codegen)); |
181 | 165 |
182 bool get isForResolution => false; | 166 bool get isForResolution => false; |
183 | 167 |
184 String toString() => 'CodegenRegistry for $currentElement'; | 168 String toString() => 'CodegenRegistry for $currentElement'; |
185 | 169 |
186 @deprecated | 170 @deprecated |
187 void registerInstantiatedClass(ClassElement element) { | 171 void registerInstantiatedClass(ClassElement element) { |
188 registerInstantiation(element.rawType); | 172 registerInstantiation(element.rawType); |
189 } | 173 } |
190 | 174 |
191 void registerStaticUse(StaticUse staticUse) { | 175 void registerStaticUse(StaticUse staticUse) { |
192 worldImpact.registerStaticUse(staticUse); | 176 worldImpact.registerStaticUse(staticUse); |
193 } | 177 } |
194 | 178 |
195 void registerDynamicUse(DynamicUse dynamicUse) { | 179 void registerDynamicUse(DynamicUse dynamicUse) { |
196 worldImpact.registerDynamicUse(dynamicUse); | 180 worldImpact.registerDynamicUse(dynamicUse); |
197 } | 181 } |
198 | 182 |
199 void registerTypeUse(TypeUse typeUse) { | 183 void registerTypeUse(TypeUse typeUse) { |
200 worldImpact.registerTypeUse(typeUse); | 184 worldImpact.registerTypeUse(typeUse); |
201 } | 185 } |
202 | 186 |
203 void registerCompileTimeConstant(ConstantValue constant) { | 187 void registerCompileTimeConstant(ConstantValue constant) { |
204 worldImpact.registerCompileTimeConstant(constant); | 188 worldImpact.registerCompileTimeConstant(constant); |
205 } | 189 } |
206 | 190 |
207 void registerTypeVariableBoundsSubtypeCheck(DartType subtype, | 191 void registerTypeVariableBoundsSubtypeCheck( |
208 DartType supertype) { | 192 DartType subtype, DartType supertype) { |
209 worldImpact.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); | 193 worldImpact.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); |
210 } | 194 } |
211 | 195 |
212 void registerInstantiatedClosure(LocalFunctionElement element) { | 196 void registerInstantiatedClosure(LocalFunctionElement element) { |
213 worldImpact.registerStaticUse(new StaticUse.closure(element)); | 197 worldImpact.registerStaticUse(new StaticUse.closure(element)); |
214 } | 198 } |
215 | 199 |
216 void registerConstSymbol(String name) { | 200 void registerConstSymbol(String name) { |
217 worldImpact.registerConstSymbol(name); | 201 worldImpact.registerConstSymbol(name); |
218 } | 202 } |
(...skipping 16 matching lines...) Expand all Loading... |
235 | 219 |
236 void registerAsyncMarker(FunctionElement element) { | 220 void registerAsyncMarker(FunctionElement element) { |
237 worldImpact.registerAsyncMarker(element); | 221 worldImpact.registerAsyncMarker(element); |
238 } | 222 } |
239 } | 223 } |
240 | 224 |
241 /// [WorkItem] used exclusively by the [CodegenEnqueuer]. | 225 /// [WorkItem] used exclusively by the [CodegenEnqueuer]. |
242 class CodegenWorkItem extends WorkItem { | 226 class CodegenWorkItem extends WorkItem { |
243 CodegenRegistry registry; | 227 CodegenRegistry registry; |
244 | 228 |
245 factory CodegenWorkItem( | 229 factory CodegenWorkItem(Compiler compiler, AstElement element, |
246 Compiler compiler, | |
247 AstElement element, | |
248 ItemCompilationContext compilationContext) { | 230 ItemCompilationContext compilationContext) { |
249 // If this assertion fails, the resolution callbacks of the backend may be | 231 // If this assertion fails, the resolution callbacks of the backend may be |
250 // missing call of form registry.registerXXX. Alternatively, the code | 232 // missing call of form registry.registerXXX. Alternatively, the code |
251 // generation could spuriously be adding dependencies on things we know we | 233 // generation could spuriously be adding dependencies on things we know we |
252 // don't need. | 234 // don't need. |
253 assert(invariant(element, | 235 assert(invariant( |
254 compiler.enqueuer.resolution.hasBeenProcessed(element), | 236 element, compiler.enqueuer.resolution.hasBeenProcessed(element), |
255 message: "$element has not been resolved.")); | 237 message: "$element has not been resolved.")); |
256 assert(invariant(element, element.resolvedAst.elements != null, | 238 assert(invariant(element, element.resolvedAst.elements != null, |
257 message: 'Resolution tree is null for $element in codegen work item')); | 239 message: 'Resolution tree is null for $element in codegen work item')); |
258 return new CodegenWorkItem.internal(element, compilationContext); | 240 return new CodegenWorkItem.internal(element, compilationContext); |
259 } | 241 } |
260 | 242 |
261 CodegenWorkItem.internal( | 243 CodegenWorkItem.internal( |
262 AstElement element, | 244 AstElement element, ItemCompilationContext compilationContext) |
263 ItemCompilationContext compilationContext) | |
264 : super(element, compilationContext); | 245 : super(element, compilationContext); |
265 | 246 |
266 TreeElements get resolutionTree => element.resolvedAst.elements; | 247 TreeElements get resolutionTree => element.resolvedAst.elements; |
267 | 248 |
268 WorldImpact run(Compiler compiler, CodegenEnqueuer world) { | 249 WorldImpact run(Compiler compiler, CodegenEnqueuer world) { |
269 if (world.isProcessed(element)) return const WorldImpact(); | 250 if (world.isProcessed(element)) return const WorldImpact(); |
270 | 251 |
271 registry = new CodegenRegistry(compiler, element); | 252 registry = new CodegenRegistry(compiler, element); |
272 return compiler.codegen(this, world); | 253 return compiler.codegen(this, world); |
273 } | 254 } |
274 } | 255 } |
OLD | NEW |