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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_emitter/program_builder.dart

Issue 661783002: dart2js: Add support for static fields to new emitter. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 6 years, 2 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 'model.dart'; 7 import 'model.dart';
8 import '../common.dart'; 8 import '../common.dart';
9 import '../js/js.dart' as js; 9 import '../js/js.dart' as js;
10 10
11 import '../js_backend/js_backend.dart' show Namer, JavaScriptBackend; 11 import '../js_backend/js_backend.dart' show
12 Namer,
13 JavaScriptBackend,
14 JavaScriptConstantCompiler;
15
12 import '../js_emitter/js_emitter.dart' as emitterTask show 16 import '../js_emitter/js_emitter.dart' as emitterTask show
13 CodeEmitterTask, 17 CodeEmitterTask,
14 Emitter; 18 Emitter;
15 19
16 import '../universe/universe.dart' show Universe; 20 import '../universe/universe.dart' show Universe;
17 import '../deferred_load.dart' show DeferredLoadTask, OutputUnit; 21 import '../deferred_load.dart' show DeferredLoadTask, OutputUnit;
18 22
19 part 'registry.dart'; 23 part 'registry.dart';
20 24
21 class ProgramBuilder { 25 class ProgramBuilder {
(...skipping 20 matching lines...) Expand all
42 /// generate the deferredLoadingMap (to know which hunks to load). 46 /// generate the deferredLoadingMap (to know which hunks to load).
43 final Map<OutputUnit, Output> _outputs = <OutputUnit, Output>{}; 47 final Map<OutputUnit, Output> _outputs = <OutputUnit, Output>{};
44 48
45 /// Mapping from [ConstantValue] to constructed [Constant]. We need this to 49 /// Mapping from [ConstantValue] to constructed [Constant]. We need this to
46 /// update field-initializers to point to the ConstantModel. 50 /// update field-initializers to point to the ConstantModel.
47 final Map<ConstantValue, Constant> _constants = <ConstantValue, Constant>{}; 51 final Map<ConstantValue, Constant> _constants = <ConstantValue, Constant>{};
48 52
49 Program buildProgram() { 53 Program buildProgram() {
50 _task.outputClassLists.forEach(_registry.registerElements); 54 _task.outputClassLists.forEach(_registry.registerElements);
51 _task.outputStaticLists.forEach(_registry.registerElements); 55 _task.outputStaticLists.forEach(_registry.registerElements);
56 _task.outputConstantLists.forEach(_registerConstants);
52 57
53 // TODO(kasperl): There's code that implicitly needs access to the special 58 // TODO(kasperl): There's code that implicitly needs access to the special
54 // $ holder so we have to register that. Can we track if we have to? 59 // $ holder so we have to register that. Can we track if we have to?
55 _registry.registerHolder(r'$'); 60 _registry.registerHolder(r'$');
56 61
57 MainOutput mainOutput = _buildMainOutput(_registry.mainFragment); 62 MainOutput mainOutput = _buildMainOutput(_registry.mainFragment);
58 Iterable<Output> deferredOutputs = _registry.deferredFragments 63 Iterable<Output> deferredOutputs = _registry.deferredFragments
59 .map((fragment) => _buildDeferredOutput(mainOutput, fragment)); 64 .map((fragment) => _buildDeferredOutput(mainOutput, fragment));
60 65
61 List<Output> outputs = new List<Output>(_registry.fragmentCount); 66 List<Output> outputs = new List<Output>(_registry.fragmentCount);
(...skipping 27 matching lines...) Expand all
89 }); 94 });
90 return loadMap; 95 return loadMap;
91 } 96 }
92 97
93 MainOutput _buildMainOutput(Fragment fragment) { 98 MainOutput _buildMainOutput(Fragment fragment) {
94 // Construct the main output from the libraries and the registered holders. 99 // Construct the main output from the libraries and the registered holders.
95 MainOutput result = new MainOutput( 100 MainOutput result = new MainOutput(
96 "", // The empty string is the name for the main output file. 101 "", // The empty string is the name for the main output file.
97 namer.elementAccess(_compiler.mainFunction), 102 namer.elementAccess(_compiler.mainFunction),
98 _buildLibraries(fragment), 103 _buildLibraries(fragment),
104 _buildStaticNonFinalFields(fragment),
99 _buildConstants(fragment), 105 _buildConstants(fragment),
100 _registry.holders.toList(growable: false)); 106 _registry.holders.toList(growable: false));
101 _outputs[fragment.outputUnit] = result; 107 _outputs[fragment.outputUnit] = result;
102 return result; 108 return result;
103 } 109 }
104 110
105 /// Returns a name composed of the main output file name and [name]. 111 /// Returns a name composed of the main output file name and [name].
106 String _outputFileName(String name) { 112 String _outputFileName(String name) {
107 assert(name != ""); 113 assert(name != "");
108 String outPath = _compiler.outputUri != null 114 String outPath = _compiler.outputUri != null
109 ? _compiler.outputUri.path 115 ? _compiler.outputUri.path
110 : "out"; 116 : "out";
111 String outName = outPath.substring(outPath.lastIndexOf('/') + 1); 117 String outName = outPath.substring(outPath.lastIndexOf('/') + 1);
112 return "${outName}_$name"; 118 return "${outName}_$name";
113 } 119 }
114 120
115 DeferredOutput _buildDeferredOutput(MainOutput mainOutput, 121 DeferredOutput _buildDeferredOutput(MainOutput mainOutput,
116 Fragment fragment) { 122 Fragment fragment) {
117 DeferredOutput result = new DeferredOutput( 123 DeferredOutput result = new DeferredOutput(
118 _outputFileName(fragment.name), fragment.name, 124 _outputFileName(fragment.name), fragment.name,
119 mainOutput, 125 mainOutput,
120 _buildLibraries(fragment), 126 _buildLibraries(fragment),
127 _buildStaticNonFinalFields(fragment),
121 _buildConstants(fragment)); 128 _buildConstants(fragment));
122 _outputs[fragment.outputUnit] = result; 129 _outputs[fragment.outputUnit] = result;
123 return result; 130 return result;
124 } 131 }
125 132
126 List<Constant> _buildConstants(Fragment fragment) { 133 List<Constant> _buildConstants(Fragment fragment) {
127 List<ConstantValue> constantValues = 134 List<ConstantValue> constantValues =
128 _task.outputConstantLists[fragment.outputUnit]; 135 _task.outputConstantLists[fragment.outputUnit];
129 if (constantValues == null) return const <Constant>[]; 136 if (constantValues == null) return const <Constant>[];
130 return constantValues.map((ConstantValue constantValue) { 137 return constantValues.map((ConstantValue value) => _constants[value])
131 assert(!_constants.containsKey(constantValue)); 138 .toList(growable: false);
132 String name = namer.constantName(constantValue); 139 }
133 String constantObject = namer.globalObjectForConstant(constantValue); 140
134 Holder holder = _registry.registerHolder(constantObject); 141 List<StaticField> _buildStaticNonFinalFields(Fragment fragment) {
135 Constant constant = new Constant(name, holder, constantValue); 142 // TODO(floitsch): handle static non-final fields correctly with deferred
136 _constants[constantValue] = constant; 143 // libraries.
137 return constant; 144 if (fragment != _registry.mainFragment) return const <StaticField>[];
138 }).toList(); 145 Iterable<VariableElement> staticNonFinalFields =
146 backend.constants.getStaticNonFinalFieldsForEmission();
147 return Elements.sortedByPosition(staticNonFinalFields)
148 .map(_buildStaticField)
149 .toList(growable: false);
150 }
151
152 StaticField _buildStaticField(Element element) {
153 JavaScriptConstantCompiler handler = backend.constants;
154 ConstantValue initialValue = handler.getInitialValueFor(element).value;
155 js.Expression code = _task.emitter.constantReference(initialValue);
156 String name = namer.getNameOfGlobalField(element);
157 bool isFinal = false;
158 bool isLazy = false;
159 return new StaticField(name, _registry.registerHolder(r'$'), code,
160 isFinal, isLazy);
161 }
162
163 List<StaticField> _buildStaticLazilyInitializedFields(Fragment fragment) {
164 JavaScriptConstantCompiler handler = backend.constants;
165 List<VariableElement> lazyFields =
166 handler.getLazilyInitializedFieldsForEmission();
167 // TODO(floitsch): handle static lazy finals correctly with deferred
168 // libraries.
169 if (fragment != _registry.mainFragment) return const <StaticField>[];
170 throw new UnimplementedError("lazy statics");
139 } 171 }
140 172
141 List<Library> _buildLibraries(Fragment fragment) { 173 List<Library> _buildLibraries(Fragment fragment) {
142 List<Library> libraries = new List<Library>(fragment.length); 174 List<Library> libraries = new List<Library>(fragment.length);
143 int count = 0; 175 int count = 0;
144 fragment.forEach((LibraryElement library, List<Element> elements) { 176 fragment.forEach((LibraryElement library, List<Element> elements) {
145 libraries[count++] = _buildLibrary(library, elements); 177 libraries[count++] = _buildLibrary(library, elements);
146 }); 178 });
147 return libraries; 179 return libraries;
148 } 180 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 return new StaticMethod(name, _registry.registerHolder(holder), code); 231 return new StaticMethod(name, _registry.registerHolder(holder), code);
200 } 232 }
201 233
202 StaticMethod _buildStaticMethodTearOff(FunctionElement element) { 234 StaticMethod _buildStaticMethodTearOff(FunctionElement element) {
203 String name = namer.getStaticClosureName(element); 235 String name = namer.getStaticClosureName(element);
204 String holder = namer.globalObjectFor(element); 236 String holder = namer.globalObjectFor(element);
205 // TODO(kasperl): This clearly doesn't work yet. 237 // TODO(kasperl): This clearly doesn't work yet.
206 js.Expression code = js.string("<<unimplemented>>"); 238 js.Expression code = js.string("<<unimplemented>>");
207 return new StaticMethod(name, _registry.registerHolder(holder), code); 239 return new StaticMethod(name, _registry.registerHolder(holder), code);
208 } 240 }
241
242 void _registerConstants(OutputUnit outputUnit,
243 List<ConstantValue> constantValues) {
244 if (constantValues == null) return;
245 for (ConstantValue constantValue in constantValues) {
246 assert(!_constants.containsKey(constantValue));
247 String name = namer.constantName(constantValue);
248 String constantObject = namer.globalObjectForConstant(constantValue);
249 Holder holder = _registry.registerHolder(constantObject);
250 Constant constant = new Constant(name, holder, constantValue);
251 _constants[constantValue] = constant;
252 };
253 }
209 } 254 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698