| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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.js_emitter.full_emitter; | 5 library dart2js.js_emitter.full_emitter; |
| 6 | 6 |
| 7 import 'dart:collection' show HashMap; | 7 import 'dart:collection' show HashMap; |
| 8 import 'dart:convert'; | 8 import 'dart:convert'; |
| 9 | 9 |
| 10 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; | 10 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 45 CompoundName, | 45 CompoundName, |
| 46 ConstantEmitter, | 46 ConstantEmitter, |
| 47 GetterName, | 47 GetterName, |
| 48 JavaScriptBackend, | 48 JavaScriptBackend, |
| 49 JavaScriptConstantCompiler, | 49 JavaScriptConstantCompiler, |
| 50 Namer, | 50 Namer, |
| 51 SetterName, | 51 SetterName, |
| 52 TypeVariableHandler; | 52 TypeVariableHandler; |
| 53 import '../../universe/call_structure.dart' show CallStructure; | 53 import '../../universe/call_structure.dart' show CallStructure; |
| 54 import '../../universe/selector.dart' show Selector; | 54 import '../../universe/selector.dart' show Selector; |
| 55 import '../../universe/world_builder.dart' show CodegenWorldBuilder; |
| 55 import '../../util/characters.dart' show $$, $A, $HASH, $Z, $a, $z; | 56 import '../../util/characters.dart' show $$, $A, $HASH, $Z, $a, $z; |
| 56 import '../../util/uri_extras.dart' show relativize; | 57 import '../../util/uri_extras.dart' show relativize; |
| 57 import '../../util/util.dart' show equalElements; | 58 import '../../util/util.dart' show equalElements; |
| 59 import '../../world.dart' show ClosedWorld; |
| 58 import '../constant_ordering.dart' show deepCompareConstants; | 60 import '../constant_ordering.dart' show deepCompareConstants; |
| 59 import '../headers.dart'; | 61 import '../headers.dart'; |
| 60 import '../js_emitter.dart' hide Emitter; | 62 import '../js_emitter.dart' hide Emitter, EmitterFactory; |
| 61 import '../js_emitter.dart' as js_emitter show Emitter; | 63 import '../js_emitter.dart' as js_emitter show Emitter, EmitterFactory; |
| 62 import '../model.dart'; | 64 import '../model.dart'; |
| 63 import '../program_builder/program_builder.dart'; | 65 import '../program_builder/program_builder.dart'; |
| 64 | 66 |
| 65 part 'class_builder.dart'; | 67 part 'class_builder.dart'; |
| 66 part 'class_emitter.dart'; | 68 part 'class_emitter.dart'; |
| 67 part 'code_emitter_helper.dart'; | 69 part 'code_emitter_helper.dart'; |
| 68 part 'container_builder.dart'; | 70 part 'container_builder.dart'; |
| 69 part 'declarations.dart'; | 71 part 'declarations.dart'; |
| 70 part 'deferred_output_unit_hash.dart'; | 72 part 'deferred_output_unit_hash.dart'; |
| 71 part 'interceptor_emitter.dart'; | 73 part 'interceptor_emitter.dart'; |
| 72 part 'nsm_emitter.dart'; | 74 part 'nsm_emitter.dart'; |
| 73 part 'setup_program_builder.dart'; | 75 part 'setup_program_builder.dart'; |
| 74 | 76 |
| 77 class EmitterFactory implements js_emitter.EmitterFactory { |
| 78 final bool generateSourceMap; |
| 79 |
| 80 EmitterFactory({this.generateSourceMap}); |
| 81 |
| 82 @override |
| 83 String get patchVersion => "full"; |
| 84 |
| 85 @override |
| 86 bool get supportsReflection => true; |
| 87 |
| 88 @override |
| 89 Emitter createEmitter( |
| 90 CodeEmitterTask task, Namer namer, ClosedWorld closedWorld) { |
| 91 return new Emitter( |
| 92 task.compiler, namer, closedWorld, generateSourceMap, task); |
| 93 } |
| 94 } |
| 95 |
| 75 class Emitter implements js_emitter.Emitter { | 96 class Emitter implements js_emitter.Emitter { |
| 76 final Compiler compiler; | 97 final Compiler compiler; |
| 77 final CodeEmitterTask task; | 98 final CodeEmitterTask task; |
| 78 | 99 |
| 79 // The following fields will be set to copies of the program-builder's | 100 // The following fields will be set to copies of the program-builder's |
| 80 // collector. | 101 // collector. |
| 81 Map<OutputUnit, List<VariableElement>> outputStaticNonFinalFieldLists; | 102 Map<OutputUnit, List<VariableElement>> outputStaticNonFinalFieldLists; |
| 82 Map<OutputUnit, Set<LibraryElement>> outputLibraryLists; | 103 Map<OutputUnit, Set<LibraryElement>> outputLibraryLists; |
| 83 List<TypedefElement> typedefsNeededForReflection; | 104 List<TypedefElement> typedefsNeededForReflection; |
| 84 | 105 |
| 85 final ContainerBuilder containerBuilder = new ContainerBuilder(); | 106 final ContainerBuilder containerBuilder = new ContainerBuilder(); |
| 86 final ClassEmitter classEmitter = new ClassEmitter(); | 107 final ClassEmitter classEmitter; |
| 87 final NsmEmitter nsmEmitter = new NsmEmitter(); | 108 final NsmEmitter nsmEmitter; |
| 88 final InterceptorEmitter interceptorEmitter = new InterceptorEmitter(); | 109 final InterceptorEmitter interceptorEmitter; |
| 89 | 110 |
| 90 // TODO(johnniwinther): Wrap these fields in a caching strategy. | 111 // TODO(johnniwinther): Wrap these fields in a caching strategy. |
| 91 final Set<ConstantValue> cachedEmittedConstants; | 112 final Set<ConstantValue> cachedEmittedConstants; |
| 92 final List<jsAst.Statement> cachedEmittedConstantsAst = <jsAst.Statement>[]; | 113 final List<jsAst.Statement> cachedEmittedConstantsAst = <jsAst.Statement>[]; |
| 93 final Map<Element, ClassBuilder> cachedClassBuilders; | 114 final Map<Element, ClassBuilder> cachedClassBuilders; |
| 94 final Set<Element> cachedElements; | 115 final Set<Element> cachedElements; |
| 95 | 116 |
| 96 bool needsClassSupport = false; | 117 bool needsClassSupport = false; |
| 97 bool needsMixinSupport = false; | 118 bool needsMixinSupport = false; |
| 98 bool needsLazyInitializer = false; | 119 bool needsLazyInitializer = false; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 * | 168 * |
| 148 * See [getElementDescriptor]. | 169 * See [getElementDescriptor]. |
| 149 */ | 170 */ |
| 150 // TODO(ahe): Generate statics with their class, and store only libraries in | 171 // TODO(ahe): Generate statics with their class, and store only libraries in |
| 151 // this map. | 172 // this map. |
| 152 final Map<Fragment, Map<Element, ClassBuilder>> elementDescriptors = | 173 final Map<Fragment, Map<Element, ClassBuilder>> elementDescriptors = |
| 153 new Map<Fragment, Map<Element, ClassBuilder>>(); | 174 new Map<Fragment, Map<Element, ClassBuilder>>(); |
| 154 | 175 |
| 155 final bool generateSourceMap; | 176 final bool generateSourceMap; |
| 156 | 177 |
| 157 Emitter(Compiler compiler, Namer namer, this.generateSourceMap, this.task) | 178 Emitter(Compiler compiler, Namer namer, ClosedWorld closedWorld, |
| 179 this.generateSourceMap, this.task) |
| 158 : this.compiler = compiler, | 180 : this.compiler = compiler, |
| 159 this.namer = namer, | 181 this.namer = namer, |
| 160 cachedEmittedConstants = compiler.cacheStrategy.newSet(), | 182 cachedEmittedConstants = compiler.cacheStrategy.newSet(), |
| 161 cachedClassBuilders = compiler.cacheStrategy.newMap(), | 183 cachedClassBuilders = compiler.cacheStrategy.newMap(), |
| 162 cachedElements = compiler.cacheStrategy.newSet() { | 184 cachedElements = compiler.cacheStrategy.newSet(), |
| 185 classEmitter = new ClassEmitter(closedWorld), |
| 186 interceptorEmitter = new InterceptorEmitter(closedWorld), |
| 187 nsmEmitter = new NsmEmitter(closedWorld) { |
| 163 constantEmitter = new ConstantEmitter( | 188 constantEmitter = new ConstantEmitter( |
| 164 compiler, namer, this.constantReference, constantListGenerator); | 189 compiler, namer, this.constantReference, constantListGenerator); |
| 165 containerBuilder.emitter = this; | 190 containerBuilder.emitter = this; |
| 166 classEmitter.emitter = this; | 191 classEmitter.emitter = this; |
| 167 nsmEmitter.emitter = this; | 192 nsmEmitter.emitter = this; |
| 168 interceptorEmitter.emitter = this; | 193 interceptorEmitter.emitter = this; |
| 194 if (compiler.options.hasIncrementalSupport) { |
| 195 // Much like a scout, an incremental compiler is always prepared. For |
| 196 // mixins, classes, and lazy statics, at least. |
| 197 needsClassSupport = true; |
| 198 needsMixinSupport = true; |
| 199 needsLazyInitializer = true; |
| 200 needsStructuredMemberInfo = true; |
| 201 } |
| 169 } | 202 } |
| 170 | 203 |
| 171 DiagnosticReporter get reporter => compiler.reporter; | 204 DiagnosticReporter get reporter => compiler.reporter; |
| 172 | 205 |
| 173 List<jsAst.Node> cspPrecompiledFunctionFor(OutputUnit outputUnit) { | 206 List<jsAst.Node> cspPrecompiledFunctionFor(OutputUnit outputUnit) { |
| 174 return _cspPrecompiledFunctions.putIfAbsent( | 207 return _cspPrecompiledFunctions.putIfAbsent( |
| 175 outputUnit, () => new List<jsAst.Node>()); | 208 outputUnit, () => new List<jsAst.Node>()); |
| 176 } | 209 } |
| 177 | 210 |
| 178 List<jsAst.Expression> cspPrecompiledConstructorNamesFor( | 211 List<jsAst.Expression> cspPrecompiledConstructorNamesFor( |
| 179 OutputUnit outputUnit) { | 212 OutputUnit outputUnit) { |
| 180 return _cspPrecompiledConstructorNames.putIfAbsent( | 213 return _cspPrecompiledConstructorNames.putIfAbsent( |
| 181 outputUnit, () => new List<jsAst.Expression>()); | 214 outputUnit, () => new List<jsAst.Expression>()); |
| 182 } | 215 } |
| 183 | 216 |
| 184 /// Erases the precompiled information for csp mode for all output units. | 217 /// Erases the precompiled information for csp mode for all output units. |
| 185 /// Used by the incremental compiler. | 218 /// Used by the incremental compiler. |
| 186 void clearCspPrecompiledNodes() { | 219 void clearCspPrecompiledNodes() { |
| 187 _cspPrecompiledFunctions.clear(); | 220 _cspPrecompiledFunctions.clear(); |
| 188 _cspPrecompiledConstructorNames.clear(); | 221 _cspPrecompiledConstructorNames.clear(); |
| 189 } | 222 } |
| 190 | 223 |
| 191 @override | 224 @override |
| 192 String get patchVersion => "full"; | |
| 193 | |
| 194 @override | |
| 195 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) { | 225 bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) { |
| 196 if (constant.isFunction) return true; // Already emitted. | 226 if (constant.isFunction) return true; // Already emitted. |
| 197 if (constant.isPrimitive) return true; // Inlined. | 227 if (constant.isPrimitive) return true; // Inlined. |
| 198 if (constant.isDummy) return true; // Inlined. | 228 if (constant.isDummy) return true; // Inlined. |
| 199 // The name is null when the constant is already a JS constant. | 229 // The name is null when the constant is already a JS constant. |
| 200 // TODO(floitsch): every constant should be registered, so that we can | 230 // TODO(floitsch): every constant should be registered, so that we can |
| 201 // share the ones that take up too much space (like some strings). | 231 // share the ones that take up too much space (like some strings). |
| 202 if (namer.constantName(constant) == null) return true; | 232 if (namer.constantName(constant) == null) return true; |
| 203 return false; | 233 return false; |
| 204 } | 234 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 static const String FIELD_NAMES_PROPERTY_NAME = r"$__fields__"; | 296 static const String FIELD_NAMES_PROPERTY_NAME = r"$__fields__"; |
| 267 | 297 |
| 268 /// For deferred loading we communicate the initializers via this global var. | 298 /// For deferred loading we communicate the initializers via this global var. |
| 269 final String deferredInitializers = r"$dart_deferred_initializers$"; | 299 final String deferredInitializers = r"$dart_deferred_initializers$"; |
| 270 | 300 |
| 271 /// Contains the global state that is needed to initialize and load a | 301 /// Contains the global state that is needed to initialize and load a |
| 272 /// deferred library. | 302 /// deferred library. |
| 273 String get globalsHolder => r"$globals$"; | 303 String get globalsHolder => r"$globals$"; |
| 274 | 304 |
| 275 @override | 305 @override |
| 276 bool get supportsReflection => true; | |
| 277 | |
| 278 @override | |
| 279 jsAst.Expression generateEmbeddedGlobalAccess(String global) { | 306 jsAst.Expression generateEmbeddedGlobalAccess(String global) { |
| 280 return js(generateEmbeddedGlobalAccessString(global)); | 307 return js(generateEmbeddedGlobalAccessString(global)); |
| 281 } | 308 } |
| 282 | 309 |
| 283 String generateEmbeddedGlobalAccessString(String global) { | 310 String generateEmbeddedGlobalAccessString(String global) { |
| 284 // TODO(floitsch): don't use 'init' as global embedder storage. | 311 // TODO(floitsch): don't use 'init' as global embedder storage. |
| 285 return '$initName.$global'; | 312 return '$initName.$global'; |
| 286 } | 313 } |
| 287 | 314 |
| 288 jsAst.PropertyAccess globalPropertyAccess(Element element) { | 315 jsAst.PropertyAccess globalPropertyAccess(Element element) { |
| (...skipping 1863 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2152 if (cachedElements.isEmpty) return; | 2179 if (cachedElements.isEmpty) return; |
| 2153 for (Element element in backend.codegenEnqueuer.newlyEnqueuedElements) { | 2180 for (Element element in backend.codegenEnqueuer.newlyEnqueuedElements) { |
| 2154 if (element.isInstanceMember) { | 2181 if (element.isInstanceMember) { |
| 2155 cachedClassBuilders.remove(element.enclosingClass); | 2182 cachedClassBuilders.remove(element.enclosingClass); |
| 2156 | 2183 |
| 2157 nativeEmitter.cachedBuilders.remove(element.enclosingClass); | 2184 nativeEmitter.cachedBuilders.remove(element.enclosingClass); |
| 2158 } | 2185 } |
| 2159 } | 2186 } |
| 2160 } | 2187 } |
| 2161 } | 2188 } |
| OLD | NEW |