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 |
9 Compiler; | 9 Compiler; |
10 import '../constants/values.dart' show | 10 import '../constants/values.dart' show |
(...skipping 11 matching lines...) Expand all Loading... |
22 CodegenEnqueuer; | 22 CodegenEnqueuer; |
23 import '../js_backend/js_backend.dart' show | 23 import '../js_backend/js_backend.dart' show |
24 JavaScriptBackend; | 24 JavaScriptBackend; |
25 import '../resolution/tree_elements.dart' show | 25 import '../resolution/tree_elements.dart' show |
26 TreeElements; | 26 TreeElements; |
27 import '../universe/selector.dart' show | 27 import '../universe/selector.dart' show |
28 Selector; | 28 Selector; |
29 import '../universe/universe.dart' show | 29 import '../universe/universe.dart' show |
30 UniverseSelector; | 30 UniverseSelector; |
31 import '../universe/world_impact.dart' show | 31 import '../universe/world_impact.dart' show |
32 WorldImpact; | 32 WorldImpact, |
| 33 WorldImpactBuilder; |
33 import '../util/util.dart' show | 34 import '../util/util.dart' show |
| 35 Pair, |
34 Setlet; | 36 Setlet; |
35 import 'registry.dart' show | 37 import 'registry.dart' show |
36 Registry; | 38 Registry, |
| 39 EagerRegistry; |
37 import 'work.dart' show | 40 import 'work.dart' show |
38 ItemCompilationContext, | 41 ItemCompilationContext, |
39 WorkItem; | 42 WorkItem; |
40 | 43 |
| 44 class CodegenImpact extends WorldImpact { |
| 45 const CodegenImpact(); |
| 46 |
| 47 // TODO(johnniwinther): Remove this. |
| 48 Registry get registry => null; |
| 49 |
| 50 Iterable<Element> get getterForSuperElements => const <Element>[]; |
| 51 |
| 52 Iterable<Element> get fieldGetters => const <Element>[]; |
| 53 |
| 54 Iterable<Element> get fieldSetters => const <Element>[]; |
| 55 |
| 56 Iterable<ConstantValue> get compileTimeConstants => const <ConstantValue>[]; |
| 57 |
| 58 Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks { |
| 59 return const <Pair<DartType, DartType>>[]; |
| 60 } |
| 61 |
| 62 Iterable<String> get constSymbols => const <String>[]; |
| 63 |
| 64 Iterable<Set<ClassElement>> get specializedGetInterceptors { |
| 65 return const <Set<ClassElement>>[]; |
| 66 } |
| 67 |
| 68 bool get usesInterceptor => false; |
| 69 |
| 70 Iterable<ClassElement> get typeConstants => const <ClassElement>[]; |
| 71 |
| 72 Iterable<Element> get asyncMarkers => const <FunctionElement>[]; |
| 73 } |
| 74 |
| 75 class _CodegenImpact extends WorldImpactBuilder implements CodegenImpact { |
| 76 // TODO(johnniwinther): Remove this. |
| 77 final Registry registry; |
| 78 |
| 79 |
| 80 Setlet<Element> _getterForSuperElements; |
| 81 Setlet<Element> _fieldGetters; |
| 82 Setlet<Element> _fieldSetters; |
| 83 Setlet<ConstantValue> _compileTimeConstants; |
| 84 Setlet<Pair<DartType, DartType>> _typeVariableBoundsSubtypeChecks; |
| 85 Setlet<String> _constSymbols; |
| 86 List<Set<ClassElement>> _specializedGetInterceptors; |
| 87 bool _usesInterceptor = false; |
| 88 Setlet<ClassElement> _typeConstants; |
| 89 Setlet<FunctionElement> _asyncMarkers; |
| 90 |
| 91 _CodegenImpact(this.registry); |
| 92 |
| 93 void registerGetterForSuperMethod(Element element) { |
| 94 if (_getterForSuperElements == null) { |
| 95 _getterForSuperElements = new Setlet<Element>(); |
| 96 } |
| 97 _getterForSuperElements.add(element); |
| 98 } |
| 99 |
| 100 Iterable<Element> get getterForSuperElements { |
| 101 return _getterForSuperElements != null |
| 102 ? _getterForSuperElements : const <Element>[]; |
| 103 } |
| 104 |
| 105 void registerFieldGetter(Element element) { |
| 106 if (_fieldGetters == null) { |
| 107 _fieldGetters = new Setlet<Element>(); |
| 108 } |
| 109 _fieldGetters.add(element); |
| 110 } |
| 111 |
| 112 Iterable<Element> get fieldGetters { |
| 113 return _fieldGetters != null |
| 114 ? _fieldGetters : const <Element>[]; |
| 115 } |
| 116 |
| 117 void registerFieldSetter(Element element) { |
| 118 if (_fieldSetters == null) { |
| 119 _fieldSetters = new Setlet<Element>(); |
| 120 } |
| 121 _fieldSetters.add(element); |
| 122 } |
| 123 |
| 124 Iterable<Element> get fieldSetters { |
| 125 return _fieldSetters != null |
| 126 ? _fieldSetters : const <Element>[]; |
| 127 } |
| 128 |
| 129 void registerCompileTimeConstant(ConstantValue constant) { |
| 130 if (_compileTimeConstants == null) { |
| 131 _compileTimeConstants = new Setlet<ConstantValue>(); |
| 132 } |
| 133 _compileTimeConstants.add(constant); |
| 134 } |
| 135 |
| 136 Iterable<ConstantValue> get compileTimeConstants { |
| 137 return _compileTimeConstants != null |
| 138 ? _compileTimeConstants : const <ConstantValue>[]; |
| 139 } |
| 140 |
| 141 void registerTypeVariableBoundsSubtypeCheck(DartType subtype, |
| 142 DartType supertype) { |
| 143 if (_typeVariableBoundsSubtypeChecks == null) { |
| 144 _typeVariableBoundsSubtypeChecks = new Setlet<Pair<DartType, DartType>>(); |
| 145 } |
| 146 _typeVariableBoundsSubtypeChecks.add( |
| 147 new Pair<DartType, DartType>(subtype, supertype)); |
| 148 } |
| 149 |
| 150 Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks { |
| 151 return _typeVariableBoundsSubtypeChecks != null |
| 152 ? _typeVariableBoundsSubtypeChecks : const <Pair<DartType, DartType>>[]; |
| 153 } |
| 154 |
| 155 void registerConstSymbol(String name) { |
| 156 if (_constSymbols == null) { |
| 157 _constSymbols = new Setlet<String>(); |
| 158 } |
| 159 _constSymbols.add(name); |
| 160 } |
| 161 |
| 162 Iterable<String> get constSymbols { |
| 163 return _constSymbols != null |
| 164 ? _constSymbols : const <String>[]; |
| 165 } |
| 166 |
| 167 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { |
| 168 if (_specializedGetInterceptors == null) { |
| 169 _specializedGetInterceptors = <Set<ClassElement>>[]; |
| 170 } |
| 171 _specializedGetInterceptors.add(classes); |
| 172 } |
| 173 |
| 174 Iterable<Set<ClassElement>> get specializedGetInterceptors { |
| 175 return _specializedGetInterceptors != null |
| 176 ? _specializedGetInterceptors : const <Set<ClassElement>>[]; |
| 177 } |
| 178 |
| 179 void registerUseInterceptor() { |
| 180 _usesInterceptor = true; |
| 181 } |
| 182 |
| 183 bool get usesInterceptor => _usesInterceptor; |
| 184 |
| 185 void registerTypeConstant(ClassElement element) { |
| 186 if (_typeConstants == null) { |
| 187 _typeConstants = new Setlet<ClassElement>(); |
| 188 } |
| 189 _typeConstants.add(element); |
| 190 } |
| 191 |
| 192 Iterable<ClassElement> get typeConstants { |
| 193 return _typeConstants != null |
| 194 ? _typeConstants : const <ClassElement>[]; |
| 195 } |
| 196 |
| 197 void registerAsyncMarker(FunctionElement element) { |
| 198 if (_asyncMarkers == null) { |
| 199 _asyncMarkers = new Setlet<FunctionElement>(); |
| 200 } |
| 201 _asyncMarkers.add(element); |
| 202 } |
| 203 |
| 204 Iterable<Element> get asyncMarkers { |
| 205 return _asyncMarkers != null |
| 206 ? _asyncMarkers : const <FunctionElement>[]; |
| 207 } |
| 208 } |
| 209 |
41 // TODO(johnniwinther): Split this class into interface and implementation. | 210 // TODO(johnniwinther): Split this class into interface and implementation. |
42 // TODO(johnniwinther): Move this implementation to the JS backend. | 211 // TODO(johnniwinther): Move this implementation to the JS backend. |
43 class CodegenRegistry extends Registry { | 212 class CodegenRegistry extends Registry { |
44 final Compiler compiler; | 213 final Compiler compiler; |
45 final TreeElements treeElements; | 214 final Element currentElement; |
46 | 215 final _CodegenImpact worldImpact; |
47 CodegenRegistry(this.compiler, this.treeElements); | 216 |
| 217 CodegenRegistry(Compiler compiler, AstElement currentElement) |
| 218 : this.compiler = compiler, |
| 219 this.currentElement = currentElement, |
| 220 this.worldImpact = new _CodegenImpact(new EagerRegistry( |
| 221 'EagerRegistry for $currentElement', compiler.enqueuer.codegen)); |
48 | 222 |
49 bool get isForResolution => false; | 223 bool get isForResolution => false; |
50 | 224 |
51 Element get currentElement => treeElements.analyzedElement; | |
52 | |
53 String toString() => 'CodegenRegistry for $currentElement'; | 225 String toString() => 'CodegenRegistry for $currentElement'; |
54 | 226 |
55 CodegenEnqueuer get world => compiler.enqueuer.codegen; | |
56 JavaScriptBackend get backend => compiler.backend; | |
57 | |
58 void registerAssert(bool hasMessage) { | |
59 // Codegen does not register asserts. They have been lowered to calls. | |
60 assert(false); | |
61 } | |
62 | |
63 void registerInstantiatedClass(ClassElement element) { | 227 void registerInstantiatedClass(ClassElement element) { |
64 backend.registerInstantiatedType(element.rawType, world, this); | 228 registerInstantiatedType(element.rawType); |
65 } | 229 } |
66 | 230 |
67 void registerInstantiatedType(InterfaceType type) { | 231 void registerInstantiatedType(InterfaceType type) { |
68 backend.registerInstantiatedType(type, world, this); | 232 worldImpact.registerInstantiatedType(type); |
69 } | 233 } |
70 | 234 |
71 void registerStaticUse(Element element) { | 235 void registerStaticUse(Element element) { |
72 world.registerStaticUse(element); | 236 worldImpact.registerStaticUse(element); |
73 } | 237 } |
74 | 238 |
75 void registerDynamicInvocation(UniverseSelector selector) { | 239 void registerDynamicInvocation(UniverseSelector selector) { |
76 world.registerDynamicInvocation(selector); | 240 worldImpact.registerDynamicInvocation(selector); |
77 compiler.dumpInfoTask.elementUsesSelector(currentElement, selector); | 241 compiler.dumpInfoTask.elementUsesSelector(currentElement, selector); |
78 } | 242 } |
79 | 243 |
80 void registerDynamicSetter(UniverseSelector selector) { | 244 void registerDynamicSetter(UniverseSelector selector) { |
81 world.registerDynamicSetter(selector); | 245 worldImpact.registerDynamicSetter(selector); |
82 compiler.dumpInfoTask.elementUsesSelector(currentElement, selector); | 246 compiler.dumpInfoTask.elementUsesSelector(currentElement, selector); |
83 } | 247 } |
84 | 248 |
85 void registerDynamicGetter(UniverseSelector selector) { | 249 void registerDynamicGetter(UniverseSelector selector) { |
86 world.registerDynamicGetter(selector); | 250 worldImpact.registerDynamicGetter(selector); |
87 compiler.dumpInfoTask.elementUsesSelector(currentElement, selector); | 251 compiler.dumpInfoTask.elementUsesSelector(currentElement, selector); |
88 } | 252 } |
89 | 253 |
90 void registerGetterForSuperMethod(Element element) { | 254 void registerGetterForSuperMethod(Element element) { |
91 world.registerGetterForSuperMethod(element); | 255 worldImpact.registerGetterForSuperMethod(element); |
92 } | 256 } |
93 | 257 |
94 void registerFieldGetter(Element element) { | 258 void registerFieldGetter(Element element) { |
95 world.registerFieldGetter(element); | 259 worldImpact.registerFieldGetter(element); |
96 } | 260 } |
97 | 261 |
98 void registerFieldSetter(Element element) { | 262 void registerFieldSetter(Element element) { |
99 world.registerFieldSetter(element); | 263 worldImpact.registerFieldSetter(element); |
100 } | 264 } |
101 | 265 |
102 void registerIsCheck(DartType type) { | 266 void registerIsCheck(DartType type) { |
103 world.registerIsCheck(type); | 267 worldImpact.registerIsCheck(type); |
104 backend.registerIsCheckForCodegen(type, world, this); | |
105 } | 268 } |
106 | 269 |
107 void registerCompileTimeConstant(ConstantValue constant) { | 270 void registerCompileTimeConstant(ConstantValue constant) { |
108 backend.registerCompileTimeConstant(constant, this); | 271 worldImpact.registerCompileTimeConstant(constant); |
109 backend.addCompileTimeConstantForEmission(constant); | |
110 } | 272 } |
111 | 273 |
112 void registerTypeVariableBoundsSubtypeCheck(DartType subtype, | 274 void registerTypeVariableBoundsSubtypeCheck(DartType subtype, |
113 DartType supertype) { | 275 DartType supertype) { |
114 backend.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); | 276 worldImpact.registerTypeVariableBoundsSubtypeCheck(subtype, supertype); |
115 } | 277 } |
116 | 278 |
117 void registerInstantiatedClosure(LocalFunctionElement element) { | 279 void registerInstantiatedClosure(LocalFunctionElement element) { |
118 backend.registerInstantiatedClosure(element, this); | 280 worldImpact.registerClosure(element); |
119 } | 281 } |
120 | 282 |
121 void registerGetOfStaticFunction(FunctionElement element) { | 283 void registerGetOfStaticFunction(FunctionElement element) { |
122 world.registerGetOfStaticFunction(element); | 284 worldImpact.registerClosurizedFunction(element); |
123 } | 285 } |
124 | 286 |
125 void registerSelectorUse(Selector selector) { | 287 void registerSelectorUse(Selector selector) { |
126 world.registerSelectorUse(new UniverseSelector(selector, null)); | 288 if (selector.isGetter) { |
| 289 registerDynamicGetter(new UniverseSelector(selector, null)); |
| 290 } else if (selector.isSetter) { |
| 291 registerDynamicSetter(new UniverseSelector(selector, null)); |
| 292 } else { |
| 293 registerDynamicInvocation(new UniverseSelector(selector, null)); |
| 294 } |
127 } | 295 } |
128 | 296 |
129 void registerConstSymbol(String name) { | 297 void registerConstSymbol(String name) { |
130 backend.registerConstSymbol(name); | 298 worldImpact.registerConstSymbol(name); |
131 } | 299 } |
132 | 300 |
133 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { | 301 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { |
134 backend.registerSpecializedGetInterceptor(classes); | 302 worldImpact.registerSpecializedGetInterceptor(classes); |
135 } | 303 } |
136 | 304 |
137 void registerUseInterceptor() { | 305 void registerUseInterceptor() { |
138 backend.registerUseInterceptor(world); | 306 worldImpact.registerUseInterceptor(); |
139 } | 307 } |
140 | 308 |
141 void registerTypeConstant(ClassElement element) { | 309 void registerTypeConstant(ClassElement element) { |
142 backend.customElementsAnalysis.registerTypeConstant(element, world); | 310 worldImpact.registerTypeConstant(element); |
143 backend.lookupMapAnalysis.registerTypeConstant(element); | |
144 } | 311 } |
145 | 312 |
146 void registerStaticInvocation(Element element) { | 313 void registerStaticInvocation(Element element) { |
147 world.registerStaticUse(element); | 314 registerStaticUse(element); |
148 } | 315 } |
149 | 316 |
150 void registerSuperInvocation(Element element) { | 317 void registerSuperInvocation(Element element) { |
151 world.registerStaticUse(element); | 318 registerStaticUse(element); |
152 } | 319 } |
153 | 320 |
154 void registerDirectInvocation(Element element) { | 321 void registerDirectInvocation(Element element) { |
155 world.registerStaticUse(element); | 322 registerStaticUse(element); |
156 } | 323 } |
157 | 324 |
158 void registerInstantiation(InterfaceType type) { | 325 void registerInstantiation(InterfaceType type) { |
159 backend.registerInstantiatedType(type, world, this); | 326 registerInstantiatedType(type); |
160 } | 327 } |
161 | 328 |
162 void registerAsyncMarker(FunctionElement element) { | 329 void registerAsyncMarker(FunctionElement element) { |
163 backend.registerAsyncMarker(element, world, this); | 330 worldImpact.registerAsyncMarker(element); |
164 } | 331 } |
165 | |
166 } | 332 } |
167 | 333 |
168 /// [WorkItem] used exclusively by the [CodegenEnqueuer]. | 334 /// [WorkItem] used exclusively by the [CodegenEnqueuer]. |
169 class CodegenWorkItem extends WorkItem { | 335 class CodegenWorkItem extends WorkItem { |
170 CodegenRegistry registry; | 336 CodegenRegistry registry; |
171 | 337 |
172 factory CodegenWorkItem( | 338 factory CodegenWorkItem( |
173 Compiler compiler, | 339 Compiler compiler, |
174 AstElement element, | 340 AstElement element, |
175 ItemCompilationContext compilationContext) { | 341 ItemCompilationContext compilationContext) { |
(...skipping 12 matching lines...) Expand all Loading... |
188 CodegenWorkItem.internal( | 354 CodegenWorkItem.internal( |
189 AstElement element, | 355 AstElement element, |
190 ItemCompilationContext compilationContext) | 356 ItemCompilationContext compilationContext) |
191 : super(element, compilationContext); | 357 : super(element, compilationContext); |
192 | 358 |
193 TreeElements get resolutionTree => element.resolvedAst.elements; | 359 TreeElements get resolutionTree => element.resolvedAst.elements; |
194 | 360 |
195 WorldImpact run(Compiler compiler, CodegenEnqueuer world) { | 361 WorldImpact run(Compiler compiler, CodegenEnqueuer world) { |
196 if (world.isProcessed(element)) return const WorldImpact(); | 362 if (world.isProcessed(element)) return const WorldImpact(); |
197 | 363 |
198 registry = new CodegenRegistry(compiler, resolutionTree); | 364 registry = new CodegenRegistry(compiler, element); |
199 return compiler.codegen(this, world); | 365 return compiler.codegen(this, world); |
200 } | 366 } |
201 } | 367 } |
OLD | NEW |