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.program_builder; | 5 library dart2js.js_emitter.program_builder; |
6 | 6 |
7 import '../../closure.dart' show ClosureTask, ClosureFieldElement; | 7 import '../../closure.dart' show ClosureTask, ClosureFieldElement; |
8 import '../../common.dart'; | 8 import '../../common.dart'; |
9 import '../../common/names.dart' show Names, Selectors; | 9 import '../../common/names.dart' show Names, Selectors; |
10 import '../../compiler.dart' show Compiler; | |
11 import '../../constants/values.dart' | 10 import '../../constants/values.dart' |
12 show ConstantValue, InterceptorConstantValue; | 11 show ConstantValue, InterceptorConstantValue; |
13 import '../../common_elements.dart' show CommonElements; | 12 import '../../common_elements.dart' show CommonElements; |
14 import '../../elements/resolution_types.dart' | 13 import '../../elements/resolution_types.dart' |
15 show ResolutionDartType, ResolutionFunctionType, ResolutionTypedefType; | 14 show ResolutionDartType, ResolutionFunctionType, ResolutionTypedefType; |
16 import '../../deferred_load.dart' show DeferredLoadTask, OutputUnit; | 15 import '../../deferred_load.dart' show DeferredLoadTask, OutputUnit; |
17 import '../../elements/elements.dart' | 16 import '../../elements/elements.dart' |
18 show | 17 show |
19 ClassElement, | 18 ClassElement, |
20 Element, | 19 Element, |
21 Elements, | 20 Elements, |
22 FieldElement, | 21 FieldElement, |
23 FunctionElement, | 22 FunctionElement, |
24 FunctionSignature, | 23 FunctionSignature, |
25 GetterElement, | 24 GetterElement, |
26 LibraryElement, | 25 LibraryElement, |
27 MemberElement, | 26 MemberElement, |
28 MethodElement, | 27 MethodElement, |
29 ParameterElement, | 28 ParameterElement, |
30 TypedefElement, | 29 TypedefElement, |
31 VariableElement; | 30 VariableElement; |
32 import '../../elements/entities.dart'; | 31 import '../../elements/entities.dart'; |
33 import '../../elements/resolution_types.dart' show Types; | 32 import '../../elements/resolution_types.dart' show Types; |
34 import '../../elements/types.dart' show DartType; | 33 import '../../elements/types.dart' show DartType; |
35 import '../../js/js.dart' as js; | 34 import '../../js/js.dart' as js; |
36 import '../../js_backend/backend.dart' | 35 import '../../js_backend/backend.dart' |
37 show | 36 show |
38 JavaScriptBackend, | |
39 RuntimeTypesChecks, | 37 RuntimeTypesChecks, |
40 RuntimeTypesNeed, | 38 RuntimeTypesNeed, |
41 RuntimeTypesEncoder, | 39 RuntimeTypesEncoder, |
42 RuntimeTypesSubstitutions, | 40 RuntimeTypesSubstitutions, |
43 SuperMemberData; | 41 SuperMemberData; |
44 import '../../js_backend/backend_usage.dart'; | 42 import '../../js_backend/backend_usage.dart'; |
45 import '../../js_backend/constant_handler_javascript.dart' | 43 import '../../js_backend/constant_handler_javascript.dart' |
46 show JavaScriptConstantCompiler; | 44 show JavaScriptConstantCompiler; |
47 import '../../js_backend/custom_elements_analysis.dart'; | 45 import '../../js_backend/custom_elements_analysis.dart'; |
48 import '../../js_backend/namer.dart' show Namer, StringBackedName; | 46 import '../../js_backend/namer.dart' show Namer, StringBackedName; |
(...skipping 20 matching lines...) Expand all Loading... |
69 TypeTestProperties; | 67 TypeTestProperties; |
70 import '../model.dart'; | 68 import '../model.dart'; |
71 | 69 |
72 part 'collector.dart'; | 70 part 'collector.dart'; |
73 part 'field_visitor.dart'; | 71 part 'field_visitor.dart'; |
74 part 'registry.dart'; | 72 part 'registry.dart'; |
75 | 73 |
76 /// Builds a self-contained representation of the program that can then be | 74 /// Builds a self-contained representation of the program that can then be |
77 /// emitted more easily by the individual emitters. | 75 /// emitted more easily by the individual emitters. |
78 class ProgramBuilder { | 76 class ProgramBuilder { |
79 final Compiler _compiler; | 77 final CompilerOptions _options; |
| 78 final CommonElements _commonElements; |
| 79 final Types _types; |
| 80 final DeferredLoadTask _deferredLoadTask; |
| 81 final ClosureTask _closureToClassMapper; |
| 82 final CodegenWorldBuilder _worldBuilder; |
| 83 final NativeCodegenEnqueuer _nativeCodegenEnqueuer; |
| 84 final BackendUsage _backendUsage; |
| 85 final JavaScriptConstantCompiler _constantHandler; |
| 86 final NativeData _nativeData; |
| 87 final RuntimeTypesNeed _rtiNeed; |
| 88 final MirrorsData _mirrorsData; |
| 89 final InterceptorData _interceptorData; |
| 90 final SuperMemberData _superMemberData; |
| 91 final RuntimeTypesChecks _rtiChecks; |
| 92 final RuntimeTypesEncoder _rtiEncoder; |
| 93 final RuntimeTypesSubstitutions _rtiSubstitutions; |
| 94 final JsInteropAnalysis _jsInteropAnalysis; |
| 95 final OneShotInterceptorData _oneShotInterceptorData; |
| 96 final CustomElementsCodegenAnalysis _customElementsCodegenAnalysis; |
| 97 final Map<MemberElement, js.Expression> _generatedCode; |
80 final Namer _namer; | 98 final Namer _namer; |
81 final CodeEmitterTask _task; | 99 final CodeEmitterTask _task; |
82 final ClosedWorld _closedWorld; | 100 final ClosedWorld _closedWorld; |
83 | 101 |
84 /// Contains the collected information the program builder used to build | 102 /// Contains the collected information the program builder used to build |
85 /// the model. | 103 /// the model. |
86 // The collector will be filled on the first call to `buildProgram`. | 104 // The collector will be filled on the first call to `buildProgram`. |
87 // It is stored and publicly exposed for backwards compatibility. New code | 105 // It is stored and publicly exposed for backwards compatibility. New code |
88 // (and in particular new emitters) should not use it. | 106 // (and in particular new emitters) should not use it. |
89 final Collector collector; | 107 final Collector collector; |
90 | 108 |
91 final Registry _registry; | 109 final Registry _registry; |
92 | 110 |
| 111 final FunctionEntity _mainFunction; |
| 112 final bool _isMockCompilation; |
| 113 |
93 /// True if the program should store function types in the metadata. | 114 /// True if the program should store function types in the metadata. |
94 bool _storeFunctionTypesInMetadata = false; | 115 bool _storeFunctionTypesInMetadata = false; |
95 | 116 |
96 ProgramBuilder(Compiler compiler, Namer _namer, this._task, Emitter emitter, | 117 ProgramBuilder( |
97 ClosedWorld closedWorld, Set<ClassElement> rtiNeededClasses) | 118 this._options, |
98 : this._compiler = compiler, | 119 this._commonElements, |
99 this._namer = _namer, | 120 this._types, |
100 this._closedWorld = closedWorld, | 121 this._deferredLoadTask, |
| 122 this._closureToClassMapper, |
| 123 this._worldBuilder, |
| 124 this._nativeCodegenEnqueuer, |
| 125 this._backendUsage, |
| 126 this._constantHandler, |
| 127 this._nativeData, |
| 128 this._rtiNeed, |
| 129 this._mirrorsData, |
| 130 this._interceptorData, |
| 131 this._superMemberData, |
| 132 this._rtiChecks, |
| 133 this._rtiEncoder, |
| 134 this._rtiSubstitutions, |
| 135 this._jsInteropAnalysis, |
| 136 this._oneShotInterceptorData, |
| 137 this._customElementsCodegenAnalysis, |
| 138 this._generatedCode, |
| 139 this._namer, |
| 140 this._task, |
| 141 this._closedWorld, |
| 142 Set<ClassElement> rtiNeededClasses, |
| 143 this._mainFunction, |
| 144 {bool isMockCompilation}) |
| 145 : this._isMockCompilation = isMockCompilation, |
101 this.collector = new Collector( | 146 this.collector = new Collector( |
102 compiler, _namer, closedWorld, rtiNeededClasses, emitter), | 147 _options, |
103 this._registry = new Registry(compiler); | 148 _commonElements, |
104 | 149 _deferredLoadTask, |
105 JavaScriptBackend get _backend => _compiler.backend; | 150 _worldBuilder, |
106 CodegenWorldBuilder get _worldBuilder => _compiler.codegenWorldBuilder; | 151 _namer, |
107 DeferredLoadTask get _deferredLoadTask => _compiler.deferredLoadTask; | 152 _task.emitter, |
108 Types get _types => _compiler.types; | 153 _constantHandler, |
109 CommonElements get _commonElements => _compiler.commonElements; | 154 _nativeData, |
110 CompilerOptions get _options => _compiler.options; | 155 _interceptorData, |
111 ClosureTask get _closureToClassMapper => _compiler.closureToClassMapper; | 156 _oneShotInterceptorData, |
112 NativeCodegenEnqueuer get _nativeCodegenEnqueuer => | 157 _mirrorsData, |
113 _backend.nativeCodegenEnqueuer; | 158 _closedWorld, |
114 BackendUsage get _backendUsage => _backend.backendUsage; | 159 rtiNeededClasses, |
115 JavaScriptConstantCompiler get _constantHandler => _backend.constants; | 160 _generatedCode), |
116 NativeData get _nativeData => _backend.nativeData; | 161 this._registry = new Registry(_deferredLoadTask); |
117 RuntimeTypesNeed get _rtiNeed => _backend.rtiNeed; | |
118 MirrorsData get _mirrorsData => _backend.mirrorsData; | |
119 InterceptorData get _interceptorData => _backend.interceptorData; | |
120 SuperMemberData get _superMemberData => _backend.superMemberData; | |
121 RuntimeTypesChecks get _rtiChecks => _backend.rtiChecks; | |
122 RuntimeTypesEncoder get _rtiEncoder => _backend.rtiEncoder; | |
123 RuntimeTypesSubstitutions get _rtiSubstitutions => _backend.rtiSubstitutions; | |
124 JsInteropAnalysis get _jsInteropAnalysis => _backend.jsInteropAnalysis; | |
125 OneShotInterceptorData get _oneShotInterceptorData => | |
126 _backend.oneShotInterceptorData; | |
127 CustomElementsCodegenAnalysis get _customElementsCodegenAnalysis => | |
128 _backend.customElementsCodegenAnalysis; | |
129 | 162 |
130 /// Mapping from [ClassElement] to constructed [Class]. We need this to | 163 /// Mapping from [ClassElement] to constructed [Class]. We need this to |
131 /// update the superclass in the [Class]. | 164 /// update the superclass in the [Class]. |
132 final Map<ClassElement, Class> _classes = <ClassElement, Class>{}; | 165 final Map<ClassElement, Class> _classes = <ClassElement, Class>{}; |
133 | 166 |
134 /// Mapping from [OutputUnit] to constructed [Fragment]. We need this to | 167 /// Mapping from [OutputUnit] to constructed [Fragment]. We need this to |
135 /// generate the deferredLoadingMap (to know which hunks to load). | 168 /// generate the deferredLoadingMap (to know which hunks to load). |
136 final Map<OutputUnit, Fragment> _outputs = <OutputUnit, Fragment>{}; | 169 final Map<OutputUnit, Fragment> _outputs = <OutputUnit, Fragment>{}; |
137 | 170 |
138 /// Mapping from [ConstantValue] to constructed [Constant]. We need this to | 171 /// Mapping from [ConstantValue] to constructed [Constant]. We need this to |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
272 _buildInvokeMain(), | 305 _buildInvokeMain(), |
273 _buildLibraries(librariesMap), | 306 _buildLibraries(librariesMap), |
274 _buildStaticNonFinalFields(librariesMap), | 307 _buildStaticNonFinalFields(librariesMap), |
275 _buildStaticLazilyInitializedFields(librariesMap), | 308 _buildStaticLazilyInitializedFields(librariesMap), |
276 _buildConstants(librariesMap)); | 309 _buildConstants(librariesMap)); |
277 _outputs[librariesMap.outputUnit] = result; | 310 _outputs[librariesMap.outputUnit] = result; |
278 return result; | 311 return result; |
279 } | 312 } |
280 | 313 |
281 js.Statement _buildInvokeMain() { | 314 js.Statement _buildInvokeMain() { |
282 if (_compiler.isMockCompilation) return js.js.comment("Mock compilation"); | 315 if (_isMockCompilation) return js.js.comment("Mock compilation"); |
283 | 316 |
284 MainCallStubGenerator generator = new MainCallStubGenerator( | 317 MainCallStubGenerator generator = new MainCallStubGenerator( |
285 _commonElements, _task.emitter, _backendUsage); | 318 _commonElements, _task.emitter, _backendUsage); |
286 return generator.generateInvokeMain(_compiler.mainFunction); | 319 return generator.generateInvokeMain(_mainFunction); |
287 } | 320 } |
288 | 321 |
289 DeferredFragment _buildDeferredFragment(LibrariesMap librariesMap) { | 322 DeferredFragment _buildDeferredFragment(LibrariesMap librariesMap) { |
290 DeferredFragment result = new DeferredFragment( | 323 DeferredFragment result = new DeferredFragment( |
291 librariesMap.outputUnit, | 324 librariesMap.outputUnit, |
292 _backend.deferredPartFileName(librariesMap.name, addExtension: false), | 325 _deferredLoadTask.deferredPartFileName(librariesMap.name, |
| 326 addExtension: false), |
293 librariesMap.name, | 327 librariesMap.name, |
294 _buildLibraries(librariesMap), | 328 _buildLibraries(librariesMap), |
295 _buildStaticNonFinalFields(librariesMap), | 329 _buildStaticNonFinalFields(librariesMap), |
296 _buildStaticLazilyInitializedFields(librariesMap), | 330 _buildStaticLazilyInitializedFields(librariesMap), |
297 _buildConstants(librariesMap)); | 331 _buildConstants(librariesMap)); |
298 _outputs[librariesMap.outputUnit] = result; | 332 _outputs[librariesMap.outputUnit] = result; |
299 return result; | 333 return result; |
300 } | 334 } |
301 | 335 |
302 List<Constant> _buildConstants(LibrariesMap librariesMap) { | 336 List<Constant> _buildConstants(LibrariesMap librariesMap) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 _deferredLoadTask.outputUnitForElement(element) == | 378 _deferredLoadTask.outputUnitForElement(element) == |
345 librariesMap.outputUnit); | 379 librariesMap.outputUnit); |
346 return Elements | 380 return Elements |
347 .sortedByPosition(lazyFields) | 381 .sortedByPosition(lazyFields) |
348 .map(_buildLazyField) | 382 .map(_buildLazyField) |
349 .where((field) => field != null) // Happens when the field was unused. | 383 .where((field) => field != null) // Happens when the field was unused. |
350 .toList(growable: false); | 384 .toList(growable: false); |
351 } | 385 } |
352 | 386 |
353 StaticField _buildLazyField(FieldElement element) { | 387 StaticField _buildLazyField(FieldElement element) { |
354 js.Expression code = _backend.generatedCode[element]; | 388 js.Expression code = _generatedCode[element]; |
355 // The code is null if we ended up not needing the lazily | 389 // The code is null if we ended up not needing the lazily |
356 // initialized field after all because of constant folding | 390 // initialized field after all because of constant folding |
357 // before code generation. | 391 // before code generation. |
358 if (code == null) return null; | 392 if (code == null) return null; |
359 | 393 |
360 js.Name name = _namer.globalPropertyName(element); | 394 js.Name name = _namer.globalPropertyName(element); |
361 bool isFinal = element.isFinal; | 395 bool isFinal = element.isFinal; |
362 bool isLazy = true; | 396 bool isLazy = true; |
363 // TODO(floitsch): we shouldn't update the registry in the middle of | 397 // TODO(floitsch): we shouldn't update the registry in the middle of |
364 // building a static field. (Note that the static-state holder was | 398 // building a static field. (Note that the static-state holder was |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 typeTests.properties.forEach((js.Name name, js.Node code) { | 682 typeTests.properties.forEach((js.Name name, js.Node code) { |
649 _classes[_commonElements.jsInterceptorClass] | 683 _classes[_commonElements.jsInterceptorClass] |
650 .isChecks | 684 .isChecks |
651 .add(_buildStubMethod(name, code)); | 685 .add(_buildStubMethod(name, code)); |
652 }); | 686 }); |
653 } else { | 687 } else { |
654 for (Field field in instanceFields) { | 688 for (Field field in instanceFields) { |
655 if (field.needsCheckedSetter) { | 689 if (field.needsCheckedSetter) { |
656 assert(!field.needsUncheckedSetter); | 690 assert(!field.needsUncheckedSetter); |
657 FieldElement element = field.element; | 691 FieldElement element = field.element; |
658 js.Expression code = _backend.generatedCode[element]; | 692 js.Expression code = _generatedCode[element]; |
659 assert(code != null); | 693 assert(code != null); |
660 js.Name name = _namer.deriveSetterName(field.accessorName); | 694 js.Name name = _namer.deriveSetterName(field.accessorName); |
661 checkedSetters.add(_buildStubMethod(name, code, element: element)); | 695 checkedSetters.add(_buildStubMethod(name, code, element: element)); |
662 } | 696 } |
663 } | 697 } |
664 | 698 |
665 typeTests.properties.forEach((js.Name name, js.Node code) { | 699 typeTests.properties.forEach((js.Name name, js.Node code) { |
666 isChecks.add(_buildStubMethod(name, code)); | 700 isChecks.add(_buildStubMethod(name, code)); |
667 }); | 701 }); |
668 } | 702 } |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 _constantHandler.getConstantValue(parameter.constant); | 780 _constantHandler.getConstantValue(parameter.constant); |
747 optionalParameterDefaultValues.add(def); | 781 optionalParameterDefaultValues.add(def); |
748 }); | 782 }); |
749 } | 783 } |
750 return optionalParameterDefaultValues; | 784 return optionalParameterDefaultValues; |
751 } | 785 } |
752 | 786 |
753 DartMethod _buildMethod(MethodElement element) { | 787 DartMethod _buildMethod(MethodElement element) { |
754 assert(element.isDeclaration); | 788 assert(element.isDeclaration); |
755 js.Name name = _namer.methodPropertyName(element); | 789 js.Name name = _namer.methodPropertyName(element); |
756 js.Expression code = _backend.generatedCode[element]; | 790 js.Expression code = _generatedCode[element]; |
757 | 791 |
758 // TODO(kasperl): Figure out under which conditions code is null. | 792 // TODO(kasperl): Figure out under which conditions code is null. |
759 if (code == null) return null; | 793 if (code == null) return null; |
760 | 794 |
761 bool canTearOff = false; | 795 bool canTearOff = false; |
762 js.Name tearOffName; | 796 js.Name tearOffName; |
763 bool isClosureCallMethod = false; | 797 bool isClosureCallMethod = false; |
764 bool isNotApplyTarget = !element.isFunction || element.isAccessor; | 798 bool isNotApplyTarget = !element.isFunction || element.isAccessor; |
765 | 799 |
766 bool canBeReflected = _methodCanBeReflected(element); | 800 bool canBeReflected = _methodCanBeReflected(element); |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
992 List<js.Name> names = _oneShotInterceptorData.oneShotInterceptorNames; | 1026 List<js.Name> names = _oneShotInterceptorData.oneShotInterceptorNames; |
993 return names.map((js.Name name) { | 1027 return names.map((js.Name name) { |
994 js.Expression code = stubGenerator.generateOneShotInterceptor(name); | 1028 js.Expression code = stubGenerator.generateOneShotInterceptor(name); |
995 return new StaticStubMethod(name, holder, code); | 1029 return new StaticStubMethod(name, holder, code); |
996 }); | 1030 }); |
997 } | 1031 } |
998 | 1032 |
999 StaticDartMethod _buildStaticMethod(MethodElement element) { | 1033 StaticDartMethod _buildStaticMethod(MethodElement element) { |
1000 js.Name name = _namer.methodPropertyName(element); | 1034 js.Name name = _namer.methodPropertyName(element); |
1001 String holder = _namer.globalObjectFor(element); | 1035 String holder = _namer.globalObjectFor(element); |
1002 js.Expression code = _backend.generatedCode[element]; | 1036 js.Expression code = _generatedCode[element]; |
1003 | 1037 |
1004 bool isApplyTarget = !element.isConstructor && !element.isAccessor; | 1038 bool isApplyTarget = !element.isConstructor && !element.isAccessor; |
1005 bool canBeApplied = _methodCanBeApplied(element); | 1039 bool canBeApplied = _methodCanBeApplied(element); |
1006 bool canBeReflected = _methodCanBeReflected(element); | 1040 bool canBeReflected = _methodCanBeReflected(element); |
1007 | 1041 |
1008 bool needsTearOff = isApplyTarget && | 1042 bool needsTearOff = isApplyTarget && |
1009 (canBeReflected || | 1043 (canBeReflected || |
1010 _worldBuilder.staticFunctionsNeedingGetter.contains(element)); | 1044 _worldBuilder.staticFunctionsNeedingGetter.contains(element)); |
1011 | 1045 |
1012 js.Name tearOffName = | 1046 js.Name tearOffName = |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1061 Constant constant = new Constant(name, holder, constantValue); | 1095 Constant constant = new Constant(name, holder, constantValue); |
1062 _constants[constantValue] = constant; | 1096 _constants[constantValue] = constant; |
1063 } | 1097 } |
1064 } | 1098 } |
1065 | 1099 |
1066 Holder _registerStaticStateHolder() { | 1100 Holder _registerStaticStateHolder() { |
1067 return _registry.registerHolder(_namer.staticStateHolder, | 1101 return _registry.registerHolder(_namer.staticStateHolder, |
1068 isStaticStateHolder: true); | 1102 isStaticStateHolder: true); |
1069 } | 1103 } |
1070 } | 1104 } |
OLD | NEW |