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

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

Issue 840553002: dart2js: Add elements to the emitter's model. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 11 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
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 .toList(growable: false); 170 .toList(growable: false);
171 } 171 }
172 172
173 StaticField _buildStaticField(Element element) { 173 StaticField _buildStaticField(Element element) {
174 JavaScriptConstantCompiler handler = backend.constants; 174 JavaScriptConstantCompiler handler = backend.constants;
175 ConstantValue initialValue = handler.getInitialValueFor(element).value; 175 ConstantValue initialValue = handler.getInitialValueFor(element).value;
176 js.Expression code = _task.emitter.constantReference(initialValue); 176 js.Expression code = _task.emitter.constantReference(initialValue);
177 String name = namer.getNameOfGlobalField(element); 177 String name = namer.getNameOfGlobalField(element);
178 bool isFinal = false; 178 bool isFinal = false;
179 bool isLazy = false; 179 bool isLazy = false;
180 return new StaticField(name, _registry.registerHolder(r'$'), code, 180 return new StaticField(element,
181 name, _registry.registerHolder(r'$'), code,
181 isFinal, isLazy); 182 isFinal, isLazy);
182 } 183 }
183 184
184 List<StaticField> _buildStaticLazilyInitializedFields(Fragment fragment) { 185 List<StaticField> _buildStaticLazilyInitializedFields(Fragment fragment) {
185 // TODO(floitsch): lazy fields should just be in their respective 186 // TODO(floitsch): lazy fields should just be in their respective
186 // libraries. 187 // libraries.
187 if (fragment != _registry.mainFragment) return const <StaticField>[]; 188 if (fragment != _registry.mainFragment) return const <StaticField>[];
188 189
189 JavaScriptConstantCompiler handler = backend.constants; 190 JavaScriptConstantCompiler handler = backend.constants;
190 List<VariableElement> lazyFields = 191 List<VariableElement> lazyFields =
191 handler.getLazilyInitializedFieldsForEmission(); 192 handler.getLazilyInitializedFieldsForEmission();
192 return Elements.sortedByPosition(lazyFields) 193 return Elements.sortedByPosition(lazyFields)
193 .map(_buildLazyField) 194 .map(_buildLazyField)
194 .where((field) => field != null) // Happens when the field was unused. 195 .where((field) => field != null) // Happens when the field was unused.
195 .toList(growable: false); 196 .toList(growable: false);
196 } 197 }
197 198
198 StaticField _buildLazyField(Element element) { 199 StaticField _buildLazyField(Element element) {
199 JavaScriptConstantCompiler handler = backend.constants; 200 JavaScriptConstantCompiler handler = backend.constants;
200 js.Expression code = backend.generatedCode[element]; 201 js.Expression code = backend.generatedCode[element];
201 // The code is null if we ended up not needing the lazily 202 // The code is null if we ended up not needing the lazily
202 // initialized field after all because of constant folding 203 // initialized field after all because of constant folding
203 // before code generation. 204 // before code generation.
204 if (code == null) return null; 205 if (code == null) return null;
205 206
206 String name = namer.getNameOfGlobalField(element); 207 String name = namer.getNameOfGlobalField(element);
207 bool isFinal = element.isFinal; 208 bool isFinal = element.isFinal;
208 bool isLazy = true; 209 bool isLazy = true;
209 return new StaticField(name, _registry.registerHolder(r'$'), code, 210 return new StaticField(element,
211 name, _registry.registerHolder(r'$'), code,
210 isFinal, isLazy); 212 isFinal, isLazy);
211 } 213 }
212 214
213 List<Library> _buildLibraries(Fragment fragment) { 215 List<Library> _buildLibraries(Fragment fragment) {
214 List<Library> libraries = new List<Library>(fragment.length); 216 List<Library> libraries = new List<Library>(fragment.length);
215 int count = 0; 217 int count = 0;
216 fragment.forEach((LibraryElement library, List<Element> elements) { 218 fragment.forEach((LibraryElement library, List<Element> elements) {
217 libraries[count++] = _buildLibrary(library, elements); 219 libraries[count++] = _buildLibrary(library, elements);
218 }); 220 });
219 return libraries; 221 return libraries;
(...skipping 15 matching lines...) Expand all
235 if (library == backend.interceptorsLibrary) { 237 if (library == backend.interceptorsLibrary) {
236 statics.addAll(_generateGetInterceptorMethods()); 238 statics.addAll(_generateGetInterceptorMethods());
237 statics.addAll(_generateOneShotInterceptors()); 239 statics.addAll(_generateOneShotInterceptors());
238 } 240 }
239 241
240 List<Class> classes = elements 242 List<Class> classes = elements
241 .where((e) => e is ClassElement) 243 .where((e) => e is ClassElement)
242 .map(_buildClass) 244 .map(_buildClass)
243 .toList(growable: false); 245 .toList(growable: false);
244 246
245 return new Library(uri, statics, classes); 247 return new Library(library, uri, statics, classes);
246 } 248 }
247 249
248 Class _buildClass(ClassElement element) { 250 Class _buildClass(ClassElement element) {
249 List<Method> methods = []; 251 List<Method> methods = [];
250 List<InstanceField> fields = []; 252 List<InstanceField> fields = [];
251 253
252 void visitMember(ClassElement enclosing, Element member) { 254 void visitMember(ClassElement enclosing, Element member) {
253 assert(invariant(element, member.isDeclaration)); 255 assert(invariant(element, member.isDeclaration));
254 assert(invariant(element, element == enclosing)); 256 assert(invariant(element, element == enclosing));
255 257
(...skipping 22 matching lines...) Expand all
278 // At this point a mixin application must not have any methods or fields. 280 // At this point a mixin application must not have any methods or fields.
279 // Type-tests might be added to mixin applications, too. 281 // Type-tests might be added to mixin applications, too.
280 assert(!element.isMixinApplication || methods.isEmpty); 282 assert(!element.isMixinApplication || methods.isEmpty);
281 assert(!element.isMixinApplication || fields.isEmpty); 283 assert(!element.isMixinApplication || fields.isEmpty);
282 284
283 // TODO(floitsch): we should not add the code here, but have a list of 285 // TODO(floitsch): we should not add the code here, but have a list of
284 // is/as classes in the Class object. 286 // is/as classes in the Class object.
285 // The individual emitters should then call the type test generator to 287 // The individual emitters should then call the type test generator to
286 // generate the code. 288 // generate the code.
287 typeTests.properties.forEach((String name, js.Node code) { 289 typeTests.properties.forEach((String name, js.Node code) {
288 methods.add(_buildMethodWithName(name, code)); 290 methods.add(_buildStubMethod(name, code));
289 }); 291 });
290 292
291 String name = namer.getNameOfClass(element); 293 String name = namer.getNameOfClass(element);
292 String holderName = namer.globalObjectFor(element); 294 String holderName = namer.globalObjectFor(element);
293 Holder holder = _registry.registerHolder(holderName); 295 Holder holder = _registry.registerHolder(holderName);
294 bool onlyForRti = _task.typeTestRegistry.rtiNeededClasses.contains(element); 296 bool onlyForRti = _task.typeTestRegistry.rtiNeededClasses.contains(element);
295 bool isInstantiated = 297 bool isInstantiated =
296 _compiler.codegenWorld.directlyInstantiatedClasses.contains(element); 298 _compiler.codegenWorld.directlyInstantiatedClasses.contains(element);
297 299
298 Class result; 300 Class result;
299 if (element.isMixinApplication) { 301 if (element.isMixinApplication) {
300 result = new MixinApplication(name, holder, methods, fields, 302 result = new MixinApplication(element,
303 name, holder, methods, fields,
301 isDirectlyInstantiated: isInstantiated, 304 isDirectlyInstantiated: isInstantiated,
302 onlyForRti: onlyForRti); 305 onlyForRti: onlyForRti);
303 } else { 306 } else {
304 result = new Class(name, holder, methods, fields, 307 result = new Class(element,
308 name, holder, methods, fields,
305 isDirectlyInstantiated: isInstantiated, 309 isDirectlyInstantiated: isInstantiated,
306 onlyForRti: onlyForRti); 310 onlyForRti: onlyForRti);
307 } 311 }
308 _classes[element] = result; 312 _classes[element] = result;
309 return result; 313 return result;
310 } 314 }
311 315
312 Method _buildMethod(FunctionElement element, js.Expression code) { 316 Method _buildMethod(FunctionElement element, js.Expression code) {
313 String name = namer.getNameOfInstanceMember(element); 317 String name = namer.getNameOfInstanceMember(element);
314 return new Method(name, code); 318 return new Method(element, name, code);
315 } 319 }
316 320
317 Method _buildMethodWithName(String name, js.Expression code) { 321 Method _buildStubMethod(String name, js.Expression code) {
318 return new Method(name, code); 322 return new StubMethod(name, code);
319 } 323 }
320 324
321 // The getInterceptor methods directly access the prototype of classes. 325 // The getInterceptor methods directly access the prototype of classes.
322 // We must evaluate these classes eagerly so that the prototype is 326 // We must evaluate these classes eagerly so that the prototype is
323 // accessible. 327 // accessible.
324 void _markEagerInterceptorClasses() { 328 void _markEagerInterceptorClasses() {
325 Map<String, Set<ClassElement>> specializedGetInterceptors = 329 Map<String, Set<ClassElement>> specializedGetInterceptors =
326 backend.specializedGetInterceptors; 330 backend.specializedGetInterceptors;
327 for (Set<ClassElement> classes in specializedGetInterceptors.values) { 331 for (Set<ClassElement> classes in specializedGetInterceptors.values) {
328 for (ClassElement element in classes) { 332 for (ClassElement element in classes) {
329 Class cls = _classes[element]; 333 Class cls = _classes[element];
330 if (cls != null) cls.isEager = true; 334 if (cls != null) cls.isEager = true;
331 } 335 }
332 } 336 }
333 } 337 }
334 338
335 Iterable<StaticMethod> _generateGetInterceptorMethods() { 339 Iterable<StaticMethod> _generateGetInterceptorMethods() {
336 emitterTask.InterceptorStubGenerator stubGenerator = 340 emitterTask.InterceptorStubGenerator stubGenerator =
337 new emitterTask.InterceptorStubGenerator(_compiler, namer, backend); 341 new emitterTask.InterceptorStubGenerator(_compiler, namer, backend);
338 342
339 String holderName = namer.globalObjectFor(backend.interceptorsLibrary); 343 String holderName = namer.globalObjectFor(backend.interceptorsLibrary);
340 Holder holder = _registry.registerHolder(holderName); 344 Holder holder = _registry.registerHolder(holderName);
341 345
342 Map<String, Set<ClassElement>> specializedGetInterceptors = 346 Map<String, Set<ClassElement>> specializedGetInterceptors =
343 backend.specializedGetInterceptors; 347 backend.specializedGetInterceptors;
344 List<String> names = specializedGetInterceptors.keys.toList()..sort(); 348 List<String> names = specializedGetInterceptors.keys.toList()..sort();
345 return names.map((String name) { 349 return names.map((String name) {
346 Set<ClassElement> classes = specializedGetInterceptors[name]; 350 Set<ClassElement> classes = specializedGetInterceptors[name];
347 js.Expression code = stubGenerator.generateGetInterceptorMethod(classes); 351 js.Expression code = stubGenerator.generateGetInterceptorMethod(classes);
348 return new StaticMethod(name, holder, code); 352 return new StaticStubMethod(name, holder, code);
349 }); 353 });
350 } 354 }
351 355
352 bool _fieldNeedsGetter(VariableElement field) { 356 bool _fieldNeedsGetter(VariableElement field) {
353 assert(field.isField); 357 assert(field.isField);
354 if (_fieldAccessNeverThrows(field)) return false; 358 if (_fieldAccessNeverThrows(field)) return false;
355 return backend.shouldRetainGetter(field) 359 return backend.shouldRetainGetter(field)
356 || _compiler.codegenWorld.hasInvokedGetter(field, _compiler.world); 360 || _compiler.codegenWorld.hasInvokedGetter(field, _compiler.world);
357 } 361 }
358 362
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 if (isIntercepted) { 399 if (isIntercepted) {
396 setterFlags += 2; 400 setterFlags += 2;
397 if (backend.isInterceptorClass(holder)) { 401 if (backend.isInterceptorClass(holder)) {
398 setterFlags += 1; 402 setterFlags += 1;
399 } 403 }
400 } else { 404 } else {
401 setterFlags = 1; 405 setterFlags = 1;
402 } 406 }
403 } 407 }
404 408
405 return new InstanceField(name, getterFlags, setterFlags); 409 return new InstanceField(field, name, getterFlags, setterFlags);
406 } 410 }
407 411
408 Iterable<StaticMethod> _generateOneShotInterceptors() { 412 Iterable<StaticMethod> _generateOneShotInterceptors() {
409 emitterTask.InterceptorStubGenerator stubGenerator = 413 emitterTask.InterceptorStubGenerator stubGenerator =
410 new emitterTask.InterceptorStubGenerator(_compiler, namer, backend); 414 new emitterTask.InterceptorStubGenerator(_compiler, namer, backend);
411 415
412 String holderName = namer.globalObjectFor(backend.interceptorsLibrary); 416 String holderName = namer.globalObjectFor(backend.interceptorsLibrary);
413 Holder holder = _registry.registerHolder(holderName); 417 Holder holder = _registry.registerHolder(holderName);
414 418
415 List<String> names = backend.oneShotInterceptors.keys.toList()..sort(); 419 List<String> names = backend.oneShotInterceptors.keys.toList()..sort();
416 return names.map((String name) { 420 return names.map((String name) {
417 js.Expression code = stubGenerator.generateOneShotInterceptor(name); 421 js.Expression code = stubGenerator.generateOneShotInterceptor(name);
418 return new StaticMethod(name, holder, code); 422 return new StaticStubMethod(name, holder, code);
419 }); 423 });
420 } 424 }
421 425
422 StaticMethod _buildStaticMethod(FunctionElement element) { 426 StaticMethod _buildStaticMethod(FunctionElement element) {
423 String name = namer.getNameOfMember(element); 427 String name = namer.getNameOfMember(element);
424 String holder = namer.globalObjectFor(element); 428 String holder = namer.globalObjectFor(element);
425 js.Expression code = backend.generatedCode[element]; 429 js.Expression code = backend.generatedCode[element];
426 return new StaticMethod(name, _registry.registerHolder(holder), code); 430 return new StaticMethod(element,
431 name, _registry.registerHolder(holder), code);
427 } 432 }
428 433
429 StaticMethod _buildStaticMethodTearOff(FunctionElement element) { 434 StaticMethod _buildStaticMethodTearOff(FunctionElement element) {
430 String name = namer.getStaticClosureName(element); 435 String name = namer.getStaticClosureName(element);
431 String holder = namer.globalObjectFor(element); 436 String holder = namer.globalObjectFor(element);
432 // TODO(kasperl): This clearly doesn't work yet. 437 // TODO(kasperl): This clearly doesn't work yet.
433 js.Expression code = js.string("<<unimplemented>>"); 438 js.Expression code = js.string("<<unimplemented>>");
434 return new StaticMethod(name, _registry.registerHolder(holder), code); 439 return new StaticMethod(element,
440 name, _registry.registerHolder(holder), code);
435 } 441 }
436 442
437 void _registerConstants(OutputUnit outputUnit, 443 void _registerConstants(OutputUnit outputUnit,
438 List<ConstantValue> constantValues) { 444 List<ConstantValue> constantValues) {
439 if (constantValues == null) return; 445 if (constantValues == null) return;
440 for (ConstantValue constantValue in constantValues) { 446 for (ConstantValue constantValue in constantValues) {
441 assert(!_constants.containsKey(constantValue)); 447 assert(!_constants.containsKey(constantValue));
442 String name = namer.constantName(constantValue); 448 String name = namer.constantName(constantValue);
443 String constantObject = namer.globalObjectForConstant(constantValue); 449 String constantObject = namer.globalObjectForConstant(constantValue);
444 Holder holder = _registry.registerHolder(constantObject); 450 Holder holder = _registry.registerHolder(constantObject);
445 Constant constant = new Constant(name, holder, constantValue); 451 Constant constant = new Constant(name, holder, constantValue);
446 _constants[constantValue] = constant; 452 _constants[constantValue] = constant;
447 }; 453 };
448 } 454 }
449 } 455 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698