| 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 |