Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: pkg/compiler/lib/src/js_emitter/program_builder.dart

Issue 878553002: dart2js: native classes go through the normal code path. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebase Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 'js_emitter.dart' show computeMixinClass; 7 import 'js_emitter.dart' show computeMixinClass;
8 import 'model.dart'; 8 import 'model.dart';
9 9
10 import '../common.dart'; 10 import '../common.dart';
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 final Map<ClassElement, Class> _classes = <ClassElement, Class>{}; 51 final Map<ClassElement, Class> _classes = <ClassElement, Class>{};
52 52
53 /// Mapping from [OutputUnit] to constructed [Fragment]. We need this to 53 /// Mapping from [OutputUnit] to constructed [Fragment]. We need this to
54 /// generate the deferredLoadingMap (to know which hunks to load). 54 /// generate the deferredLoadingMap (to know which hunks to load).
55 final Map<OutputUnit, Fragment> _outputs = <OutputUnit, Fragment>{}; 55 final Map<OutputUnit, Fragment> _outputs = <OutputUnit, Fragment>{};
56 56
57 /// Mapping from [ConstantValue] to constructed [Constant]. We need this to 57 /// Mapping from [ConstantValue] to constructed [Constant]. We need this to
58 /// update field-initializers to point to the ConstantModel. 58 /// update field-initializers to point to the ConstantModel.
59 final Map<ConstantValue, Constant> _constants = <ConstantValue, Constant>{}; 59 final Map<ConstantValue, Constant> _constants = <ConstantValue, Constant>{};
60 60
61 Set<Class> _unneededNativeClasses;
62
61 Program buildProgram({bool storeFunctionTypesInMetadata: false}) { 63 Program buildProgram({bool storeFunctionTypesInMetadata: false}) {
62 this._storeFunctionTypesInMetadata = storeFunctionTypesInMetadata; 64 this._storeFunctionTypesInMetadata = storeFunctionTypesInMetadata;
63 // Note: In rare cases (mostly tests) output units can be empty. This 65 // Note: In rare cases (mostly tests) output units can be empty. This
64 // happens when the deferred code is dead-code eliminated but we still need 66 // happens when the deferred code is dead-code eliminated but we still need
65 // to check that the library has been loaded. 67 // to check that the library has been loaded.
66 _compiler.deferredLoadTask.allOutputUnits.forEach( 68 _compiler.deferredLoadTask.allOutputUnits.forEach(
67 _registry.registerOutputUnit); 69 _registry.registerOutputUnit);
68 _task.outputClassLists.forEach(_registry.registerElements); 70 _task.outputClassLists.forEach(_registry.registerElements);
69 _task.outputStaticLists.forEach(_registry.registerElements); 71 _task.outputStaticLists.forEach(_registry.registerElements);
70 _task.outputConstantLists.forEach(_registerConstants); 72 _task.outputConstantLists.forEach(_registerConstants);
71 _task.outputStaticNonFinalFieldLists.forEach(_registry.registerElements); 73 _task.outputStaticNonFinalFieldLists.forEach(_registry.registerElements);
72 74
73 // TODO(kasperl): There's code that implicitly needs access to the special 75 // TODO(kasperl): There's code that implicitly needs access to the special
74 // $ holder so we have to register that. Can we track if we have to? 76 // $ holder so we have to register that. Can we track if we have to?
75 _registry.registerHolder(r'$'); 77 _registry.registerHolder(r'$');
76 78
77 MainFragment mainOutput = _buildMainOutput(_registry.mainLibrariesMap); 79 // We need to run the native-preparation before we build the output. The
78 Iterable<Fragment> deferredOutputs = _registry.deferredLibrariesMap 80 // preparation code, in turn needs the classes to be set up.
79 .map((librariesMap) => _buildDeferredOutput(mainOutput, librariesMap)); 81 // We thus build the classes before building their containers.
80 82 _task.outputClassLists.forEach((OutputUnit _, List<ClassElement> classes) {
81 List<Fragment> outputs = new List<Fragment>(_registry.librariesMapCount); 83 classes.forEach(_buildClass);
82 outputs[0] = mainOutput; 84 });
83 outputs.setAll(1, deferredOutputs);
84
85 List<Class> nativeClasses = _task.nativeClasses
86 .map((ClassElement classElement) {
87 Class result = _classes[classElement];
88 return (result == null) ? _buildClass(classElement) : result;
89 })
90 .toList();
91 85
92 // Resolve the superclass references after we've processed all the classes. 86 // Resolve the superclass references after we've processed all the classes.
93 _classes.forEach((ClassElement element, Class c) { 87 _classes.forEach((ClassElement element, Class c) {
94 if (element.superclass != null) { 88 if (element.superclass != null) {
95 c.setSuperclass(_classes[element.superclass]); 89 c.setSuperclass(_classes[element.superclass]);
96 assert(c.superclass != null); 90 assert(c.superclass != null);
97 } 91 }
98 if (c is MixinApplication) { 92 if (c is MixinApplication) {
99 c.setMixinClass(_classes[computeMixinClass(element)]); 93 c.setMixinClass(_classes[computeMixinClass(element)]);
100 assert(c.mixinClass != null); 94 assert(c.mixinClass != null);
101 } 95 }
102 }); 96 });
103 97
98 List<Class> nativeClasses = _task.nativeClassesAndSubclasses
99 .map((ClassElement classElement) => _classes[classElement])
100 .toList();
101
104 Map<Class, Map<String, js.Expression>> additionalProperties = 102 Map<Class, Map<String, js.Expression>> additionalProperties =
105 new Map<Class, Map<String, js.Expression>>(); 103 new Map<Class, Map<String, js.Expression>>();
106 104
107 List<Class> neededNativeClasses = 105 _unneededNativeClasses =
108 _task.nativeEmitter.prepareNativeClasses( 106 _task.nativeEmitter.prepareNativeClasses(
109 nativeClasses, 107 nativeClasses,
110 additionalProperties); 108 additionalProperties);
111 109
110 MainFragment mainOutput = _buildMainOutput(_registry.mainLibrariesMap);
111 Iterable<Fragment> deferredOutputs = _registry.deferredLibrariesMap
112 .map((librariesMap) => _buildDeferredOutput(mainOutput, librariesMap));
113
114 List<Fragment> outputs = new List<Fragment>(_registry.librariesMapCount);
115 outputs[0] = mainOutput;
116 outputs.setAll(1, deferredOutputs);
117
112 _markEagerClasses(); 118 _markEagerClasses();
113 119
120 bool containsNativeClasses =
121 nativeClasses.length != _unneededNativeClasses.length;
122
114 return new Program( 123 return new Program(
115 outputs, 124 outputs,
116 neededNativeClasses,
117 additionalProperties, 125 additionalProperties,
118 _buildLoadMap(), 126 _buildLoadMap(),
119 outputContainsNativeClasses: neededNativeClasses.isNotEmpty, 127 outputContainsNativeClasses: containsNativeClasses,
120 outputContainsConstantList: _task.outputContainsConstantList); 128 outputContainsConstantList: _task.outputContainsConstantList);
121 } 129 }
122 130
123 void _markEagerClasses() { 131 void _markEagerClasses() {
124 _markEagerInterceptorClasses(); 132 _markEagerInterceptorClasses();
125 } 133 }
126 134
127 /// Builds a map from loadId to outputs-to-load. 135 /// Builds a map from loadId to outputs-to-load.
128 Map<String, List<Fragment>> _buildLoadMap() { 136 Map<String, List<Fragment>> _buildLoadMap() {
129 List<OutputUnit> convertHunks(List<OutputUnit> hunks) {
130 return hunks.map((OutputUnit unit) => _outputs[unit])
131 .toList(growable: false);
132 }
133
134 Map<String, List<Fragment>> loadMap = <String, List<Fragment>>{}; 137 Map<String, List<Fragment>> loadMap = <String, List<Fragment>>{};
135 _compiler.deferredLoadTask.hunksToLoad 138 _compiler.deferredLoadTask.hunksToLoad
136 .forEach((String loadId, List<OutputUnit> outputUnits) { 139 .forEach((String loadId, List<OutputUnit> outputUnits) {
137 loadMap[loadId] = outputUnits 140 loadMap[loadId] = outputUnits
138 .map((OutputUnit unit) => _outputs[unit]) 141 .map((OutputUnit unit) => _outputs[unit])
139 .toList(growable: false); 142 .toList(growable: false);
140 }); 143 });
141 return loadMap; 144 return loadMap;
142 } 145 }
143 146
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 JavaScriptConstantCompiler handler = backend.constants; 218 JavaScriptConstantCompiler handler = backend.constants;
216 List<VariableElement> lazyFields = 219 List<VariableElement> lazyFields =
217 handler.getLazilyInitializedFieldsForEmission(); 220 handler.getLazilyInitializedFieldsForEmission();
218 return Elements.sortedByPosition(lazyFields) 221 return Elements.sortedByPosition(lazyFields)
219 .map(_buildLazyField) 222 .map(_buildLazyField)
220 .where((field) => field != null) // Happens when the field was unused. 223 .where((field) => field != null) // Happens when the field was unused.
221 .toList(growable: false); 224 .toList(growable: false);
222 } 225 }
223 226
224 StaticField _buildLazyField(Element element) { 227 StaticField _buildLazyField(Element element) {
225 JavaScriptConstantCompiler handler = backend.constants;
226 js.Expression code = backend.generatedCode[element]; 228 js.Expression code = backend.generatedCode[element];
227 // The code is null if we ended up not needing the lazily 229 // The code is null if we ended up not needing the lazily
228 // initialized field after all because of constant folding 230 // initialized field after all because of constant folding
229 // before code generation. 231 // before code generation.
230 if (code == null) return null; 232 if (code == null) return null;
231 233
232 String name = namer.getNameOfGlobalField(element); 234 String name = namer.getNameOfGlobalField(element);
233 bool isFinal = element.isFinal; 235 bool isFinal = element.isFinal;
234 bool isLazy = true; 236 bool isLazy = true;
235 return new StaticField(element, 237 return new StaticField(element,
(...skipping 20 matching lines...) Expand all
256 .map(_buildStaticMethod) 258 .map(_buildStaticMethod)
257 .toList(); 259 .toList();
258 260
259 if (library == backend.interceptorsLibrary) { 261 if (library == backend.interceptorsLibrary) {
260 statics.addAll(_generateGetInterceptorMethods()); 262 statics.addAll(_generateGetInterceptorMethods());
261 statics.addAll(_generateOneShotInterceptors()); 263 statics.addAll(_generateOneShotInterceptors());
262 } 264 }
263 265
264 List<Class> classes = elements 266 List<Class> classes = elements
265 .where((e) => e is ClassElement) 267 .where((e) => e is ClassElement)
266 .map(_buildClass) 268 .map((ClassElement classElement) => _classes[classElement])
269 .where((Class cls) =>
270 !cls.isNative || !_unneededNativeClasses.contains(cls))
267 .toList(growable: false); 271 .toList(growable: false);
268 272
269 bool visitStatics = true; 273 bool visitStatics = true;
270 List<Field> staticFieldsForReflection = _buildFields(library, visitStatics); 274 List<Field> staticFieldsForReflection = _buildFields(library, visitStatics);
271 275
272 return new Library(library, uri, statics, classes, 276 return new Library(library, uri, statics, classes,
273 staticFieldsForReflection); 277 staticFieldsForReflection);
274 } 278 }
275 279
276 /// HACK for Try. 280 /// HACK for Try.
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 _registry.registerConstant(outputUnit, constantValue); 517 _registry.registerConstant(outputUnit, constantValue);
514 assert(!_constants.containsKey(constantValue)); 518 assert(!_constants.containsKey(constantValue));
515 String name = namer.constantName(constantValue); 519 String name = namer.constantName(constantValue);
516 String constantObject = namer.globalObjectForConstant(constantValue); 520 String constantObject = namer.globalObjectForConstant(constantValue);
517 Holder holder = _registry.registerHolder(constantObject); 521 Holder holder = _registry.registerHolder(constantObject);
518 Constant constant = new Constant(name, holder, constantValue); 522 Constant constant = new Constant(name, holder, constantValue);
519 _constants[constantValue] = constant; 523 _constants[constantValue] = constant;
520 } 524 }
521 } 525 }
522 } 526 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698