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

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

Issue 819993003: dart2js OldEmitter: inline FinishClasses. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years 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 part of dart2js.js_emitter; 5 part of dart2js.js_emitter;
6 6
7 7
8 class OldEmitter implements Emitter { 8 class OldEmitter implements Emitter {
9 final Compiler compiler; 9 final Compiler compiler;
10 final CodeEmitterTask task; 10 final CodeEmitterTask task;
11 11
12 final ContainerBuilder containerBuilder = new ContainerBuilder(); 12 final ContainerBuilder containerBuilder = new ContainerBuilder();
13 final ClassEmitter classEmitter = new ClassEmitter(); 13 final ClassEmitter classEmitter = new ClassEmitter();
14 final NsmEmitter nsmEmitter = new NsmEmitter(); 14 final NsmEmitter nsmEmitter = new NsmEmitter();
15 final TypeTestEmitter typeTestEmitter = new TypeTestEmitter(); 15 final TypeTestEmitter typeTestEmitter = new TypeTestEmitter();
16 final InterceptorEmitter interceptorEmitter = new InterceptorEmitter(); 16 final InterceptorEmitter interceptorEmitter = new InterceptorEmitter();
17 final MetadataEmitter metadataEmitter = new MetadataEmitter(); 17 final MetadataEmitter metadataEmitter = new MetadataEmitter();
18 18
19 final Set<ConstantValue> cachedEmittedConstants; 19 final Set<ConstantValue> cachedEmittedConstants;
20 final CodeBuffer cachedEmittedConstantsBuffer = new CodeBuffer(); 20 final CodeBuffer cachedEmittedConstantsBuffer = new CodeBuffer();
21 final Map<Element, ClassBuilder> cachedClassBuilders; 21 final Map<Element, ClassBuilder> cachedClassBuilders;
22 final Set<Element> cachedElements; 22 final Set<Element> cachedElements;
23 23
24 bool needsDefineClass = false; 24 bool hasClasses = false;
floitsch 2014/12/29 18:00:22 I prefer to stay consistent: needsClassSupport ?
zarah 2014/12/30 14:02:43 Done.
25 bool needsMixinSupport = false; 25 bool needsMixinSupport = false;
26 bool needsLazyInitializer = false; 26 bool needsLazyInitializer = false;
27 final Namer namer; 27 final Namer namer;
28 ConstantEmitter constantEmitter; 28 ConstantEmitter constantEmitter;
29 NativeEmitter get nativeEmitter => task.nativeEmitter; 29 NativeEmitter get nativeEmitter => task.nativeEmitter;
30 TypeTestRegistry get typeTestRegistry => task.typeTestRegistry; 30 TypeTestRegistry get typeTestRegistry => task.typeTestRegistry;
31 31
32 // The full code that is written to each hunk part-file. 32 // The full code that is written to each hunk part-file.
33 Map<OutputUnit, CodeBuffer> outputBuffers = new Map<OutputUnit, CodeBuffer>(); 33 Map<OutputUnit, CodeBuffer> outputBuffers = new Map<OutputUnit, CodeBuffer>();
34 final CodeBuffer deferredConstants = new CodeBuffer(); 34 final CodeBuffer deferredConstants = new CodeBuffer();
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 jsAst.Expression constantReference(ConstantValue value) { 140 jsAst.Expression constantReference(ConstantValue value) {
141 return constantEmitter.reference(value); 141 return constantEmitter.reference(value);
142 } 142 }
143 143
144 jsAst.Expression constantInitializerExpression(ConstantValue value) { 144 jsAst.Expression constantInitializerExpression(ConstantValue value) {
145 return constantEmitter.initializationExpression(value); 145 return constantEmitter.initializationExpression(value);
146 } 146 }
147 147
148 String get name => 'CodeEmitter'; 148 String get name => 'CodeEmitter';
149 149
150 String get currentGenerateAccessorName
151 => '${namer.currentIsolate}.\$generateAccessor';
152 String get generateAccessorHolder
153 => '$isolatePropertiesName.\$generateAccessor';
154 String get finishClassesProperty
155 => r'$finishClasses';
156 String get finishClassesName
157 => '${namer.isolateName}.$finishClassesProperty';
158 String get finishIsolateConstructorName 150 String get finishIsolateConstructorName
159 => '${namer.isolateName}.\$finishIsolateConstructor'; 151 => '${namer.isolateName}.\$finishIsolateConstructor';
160 String get isolatePropertiesName 152 String get isolatePropertiesName
161 => '${namer.isolateName}.${namer.isolatePropertiesName}'; 153 => '${namer.isolateName}.${namer.isolatePropertiesName}';
162 String get lazyInitializerProperty 154 String get lazyInitializerProperty
163 => r'$lazy'; 155 => r'$lazy';
164 String get lazyInitializerName 156 String get lazyInitializerName
165 => '${namer.isolateName}.${lazyInitializerProperty}'; 157 => '${namer.isolateName}.${lazyInitializerProperty}';
166 String get initName => 'init'; 158 String get initName => 'init';
167 String get makeConstListProperty 159 String get makeConstListProperty
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 } 206 }
215 207
216 jsAst.PropertyAccess classAccess(Element element) { 208 jsAst.PropertyAccess classAccess(Element element) {
217 return globalPropertyAccess(element); 209 return globalPropertyAccess(element);
218 } 210 }
219 211
220 jsAst.PropertyAccess typedefAccess(Element element) { 212 jsAst.PropertyAccess typedefAccess(Element element) {
221 return globalPropertyAccess(element); 213 return globalPropertyAccess(element);
222 } 214 }
223 215
216 List<jsAst.Statement> buildTrivialNsmHandlers(){
217 return nsmEmitter.buildTrivialNsmHandlers();
218 }
219
224 jsAst.FunctionDeclaration get generateAccessorFunction { 220 jsAst.FunctionDeclaration get generateAccessorFunction {
225 const RANGE1_SIZE = RANGE1_LAST - RANGE1_FIRST + 1; 221 const RANGE1_SIZE = RANGE1_LAST - RANGE1_FIRST + 1;
226 const RANGE2_SIZE = RANGE2_LAST - RANGE2_FIRST + 1; 222 const RANGE2_SIZE = RANGE2_LAST - RANGE2_FIRST + 1;
227 const RANGE1_ADJUST = - (FIRST_FIELD_CODE - RANGE1_FIRST); 223 const RANGE1_ADJUST = - (FIRST_FIELD_CODE - RANGE1_FIRST);
228 const RANGE2_ADJUST = - (FIRST_FIELD_CODE + RANGE1_SIZE - RANGE2_FIRST); 224 const RANGE2_ADJUST = - (FIRST_FIELD_CODE + RANGE1_SIZE - RANGE2_FIRST);
229 const RANGE3_ADJUST = 225 const RANGE3_ADJUST =
230 - (FIRST_FIELD_CODE + RANGE1_SIZE + RANGE2_SIZE - RANGE3_FIRST); 226 - (FIRST_FIELD_CODE + RANGE1_SIZE + RANGE2_SIZE - RANGE3_FIRST);
231 227
232 String receiverParamName = compiler.enableMinification ? "r" : "receiver"; 228 String receiverParamName = compiler.enableMinification ? "r" : "receiver";
233 String valueParamName = compiler.enableMinification ? "v" : "value"; 229 String valueParamName = compiler.enableMinification ? "v" : "value";
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 if (typeof defineClass.name != "string") { 333 if (typeof defineClass.name != "string") {
338 str += name + ".name=\\"" + name + "\\";\\n"; 334 str += name + ".name=\\"" + name + "\\";\\n";
339 } 335 }
340 if (#hasIsolateSupport) { 336 if (#hasIsolateSupport) {
341 str += name + ".$fieldNamesProperty=[" + fieldNames + "];\\n"; 337 str += name + ".$fieldNamesProperty=[" + fieldNames + "];\\n";
342 } 338 }
343 str += accessors.join(""); 339 str += accessors.join("");
344 340
345 return str; 341 return str;
346 }''', { 'hasIsolateSupport': hasIsolateSupport }); 342 }''', { 'hasIsolateSupport': hasIsolateSupport });
347
floitsch 2014/12/29 18:00:21 nit. I would keep this new line.
zarah 2014/12/30 14:02:43 Done.
348 // Declare a function called "generateAccessor". This is used in 343 // Declare a function called "generateAccessor". This is used in
349 // defineClassFunction (it's a local declaration in init()). 344 // defineClassFunction.
350 List result = <jsAst.Node>[ 345 List result = <jsAst.Node>[
351 generateAccessorFunction, 346 generateAccessorFunction,
352 js('$generateAccessorHolder = generateAccessor'),
353 new jsAst.FunctionDeclaration( 347 new jsAst.FunctionDeclaration(
354 new jsAst.VariableDeclaration('defineClass'), defineClass) ]; 348 new jsAst.VariableDeclaration('defineClass'), defineClass) ];
355 349
356 if (compiler.hasIncrementalSupport) { 350 if (compiler.hasIncrementalSupport) {
357 result.add( 351 result.add(
358 js(r'#.defineClass = defineClass', [namer.accessIncrementalHelper])); 352 js(r'#.defineClass = defineClass', [namer.accessIncrementalHelper]));
359 } 353 }
360 354
361 if (hasIsolateSupport) { 355 if (hasIsolateSupport) {
362 jsAst.Expression classIdExtractorAccess = 356 jsAst.Expression classIdExtractorAccess =
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 }; 430 };
437 }() 431 }()
438 '''); 432 ''');
439 if (compiler.hasIncrementalSupport) { 433 if (compiler.hasIncrementalSupport) {
440 result = js( 434 result = js(
441 r'#.inheritFrom = #', [namer.accessIncrementalHelper, result]); 435 r'#.inheritFrom = #', [namer.accessIncrementalHelper, result]);
442 } 436 }
443 return js(r'var inheritFrom = #', [result]); 437 return js(r'var inheritFrom = #', [result]);
444 } 438 }
445 439
446 /// Code that needs to be run before first invocation of 440 /// Code that needs to be run before processing reflection data,
447 /// [finishClassesFunction], but should only be run once. 441 /// but should only be run once.
floitsch 2014/12/29 18:00:21 specify that the "once" refers to deferred librari
zarah 2014/12/30 14:02:43 Done.
448 jsAst.Expression get initFinishClasses { 442 jsAst.Expression get initProcessStatics {
floitsch 2014/12/29 18:00:21 was already a bad name: "initX" looks/sounds like
zarah 2014/12/30 14:02:43 Done.
449 jsAst.Expression allClassesAccess = 443 jsAst.Expression allClassesAccess =
450 generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES); 444 generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES);
451 jsAst.Expression interceptorsByTagAccess = 445 jsAst.Expression interceptorsByTagAccess =
452 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG); 446 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG);
453 jsAst.Expression leafTagsAccess = 447 jsAst.Expression leafTagsAccess =
454 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS); 448 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS);
455 jsAst.Expression finishedClassesAccess = 449 jsAst.Expression finishedClassesAccess =
456 generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES); 450 generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES);
457 451
458 return js(''' 452 return js('''
459 (function(){ 453 (function(){
floitsch 2014/12/29 18:00:22 I don't see any reason why there should be the ano
zarah 2014/12/30 14:02:43 Acknowledged.
460 # = Object.create(null); // embedded allClasses. 454 # = Object.create(null); // embedded allClasses.
461 # = Object.create(null); // embedded interceptorsByTag. 455 # = Object.create(null); // embedded interceptorsByTag.
462 # = Object.create(null); // embedded leafTags. 456 # = Object.create(null); // embedded leafTags.
463 # = Object.create(null); // embedded finishedClasses 457 # = Object.create(null); // embedded finishedClasses
464 })() 458 })()
465 ''', [allClassesAccess, 459 ''', [allClassesAccess,
466 interceptorsByTagAccess, 460 interceptorsByTagAccess,
467 leafTagsAccess, 461 leafTagsAccess,
468 finishedClassesAccess]); 462 finishedClassesAccess]);
469 } 463 }
470 464
471 jsAst.Fun get finishClassesFunction {
472 // Class descriptions are collected in a JS object.
473 // 'finishClasses' takes all collected descriptions and sets up
474 // the prototype.
475 // Once set up, the constructors prototype field satisfy:
476 // - it contains all (local) members.
477 // - its internal prototype (__proto__) points to the superclass'
478 // prototype field.
479 // - the prototype's constructor field points to the JavaScript
480 // constructor.
481 // For engines where we have access to the '__proto__' we can manipulate
482 // the object literal directly. For other engines we have to create a new
483 // object and copy over the members.
484
485 String reflectableField = namer.reflectableField;
486 jsAst.Expression allClassesAccess =
487 generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES);
488 jsAst.Expression metadataAccess =
489 generateEmbeddedGlobalAccess(embeddedNames.METADATA);
490 String signaturePropertyName = namer.operatorSignature;
491
492 return js('''
493 function(collectedClasses, isolateProperties, existingIsolateProperties) {
494 var pendingClasses = Object.create(null);
495 var allClasses = #allClasses;
496 var constructors;
497
498 if (#debugFastObjects)
499 print("Number of classes: " +
500 Object.getOwnPropertyNames(\$\$).length);
501
502 var hasOwnProperty = Object.prototype.hasOwnProperty;
503
504 if (#inCspMode) {
505 constructors = dart_precompiled(collectedClasses);
506 }
507
508 if (#notInCspMode) {
509 var combinedConstructorFunction =
510 "function \$reflectable(fn){fn.$reflectableField=1;return fn};\\n"+
511 "var \$desc;\\n";
512 var constructorsList = [];
513 }
514
515 for (var cls in collectedClasses) {
516 var desc = collectedClasses[cls];
517 if (desc instanceof Array) desc = desc[1];
518
519 /* The 'fields' are either a constructor function or a
520 * string encoding fields, constructor and superclass. Gets the
521 * superclass and fields in the format
522 * 'Super;field1,field2'
523 * from the CLASS_DESCRIPTOR_PROPERTY property on the descriptor.
524 */
525 var classData = desc["${namer.classDescriptorProperty}"],
526 supr, fields = classData;
527 if (#hasRetainedMetadata)
528 if (typeof classData == "object" &&
529 classData instanceof Array) {
530 classData = fields = classData[0];
531 }
532 // ${ClassBuilder.fieldEncodingDescription}.
533 var s = fields.split(";");
534 fields = s[1] == "" ? [] : s[1].split(",");
535 supr = s[0];
536 // ${ClassBuilder.functionTypeEncodingDescription}.
537 split = supr.split(":");
538 if (split.length == 2) {
539 supr = split[0];
540 var functionSignature = split[1];
541 if (functionSignature)
542 desc.$signaturePropertyName = (function(s) {
543 return function(){ return #metadata[s]; };
544 })(functionSignature);
545 }
546
547 if (#notInCspMode) {
548 combinedConstructorFunction += defineClass(cls, fields);
549 constructorsList.push(cls);
550 }
551 if (supr) pendingClasses[cls] = supr;
552 }
553
554 if (#notInCspMode) {
555 combinedConstructorFunction +=
556 "return [\\n " + constructorsList.join(",\\n ") + "\\n]";
557 var constructors =
558 new Function("\$collectedClasses", combinedConstructorFunction)
559 (collectedClasses);
560 combinedConstructorFunction = null;
561 }
562
563 for (var i = 0; i < constructors.length; i++) {
564 var constructor = constructors[i];
565 var cls = constructor.name;
566 var desc = collectedClasses[cls];
567 var globalObject = isolateProperties;
568 if (desc instanceof Array) {
569 globalObject = desc[0] || isolateProperties;
570 desc = desc[1];
571 }
572 if (#isTreeShakingDisabled)
573 constructor["${namer.metadataField}"] = desc;
574 allClasses[cls] = constructor;
575 globalObject[cls] = constructor;
576 }
577
578 constructors = null;
579
580 #finishClassFunction;
581
582 #trivialNsmHandlers;
583
584 for (var cls in pendingClasses) finishClass(cls);
585 }''', { 'allClasses': allClassesAccess,
586 'debugFastObjects': DEBUG_FAST_OBJECTS,
587 'hasRetainedMetadata': backend.hasRetainedMetadata,
588 'metadata': metadataAccess,
589 'isTreeShakingDisabled': backend.isTreeShakingDisabled,
590 'finishClassFunction': buildFinishClass(),
591 'trivialNsmHandlers': nsmEmitter.buildTrivialNsmHandlers(),
592 'inCspMode': compiler.useContentSecurityPolicy,
593 'notInCspMode': !compiler.useContentSecurityPolicy});
594 }
595
596 jsAst.Node optional(bool condition, jsAst.Node node) { 465 jsAst.Node optional(bool condition, jsAst.Node node) {
597 return condition ? node : new jsAst.EmptyStatement(); 466 return condition ? node : new jsAst.EmptyStatement();
598 } 467 }
599 468
600 jsAst.Statement buildFinishClass() { 469 jsAst.Statement buildFinishClass() {
601 String specProperty = '"${namer.nativeSpecProperty}"'; // "%" 470 String specProperty = '"${namer.nativeSpecProperty}"'; // "%"
602 471
603 jsAst.Expression finishedClassesAccess = 472 jsAst.Expression finishedClassesAccess =
604 generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES); 473 generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES);
605 jsAst.Expression interceptorsByTagAccess = 474 jsAst.Expression interceptorsByTagAccess =
606 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG); 475 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG);
607 jsAst.Expression leafTagsAccess = 476 jsAst.Expression leafTagsAccess =
608 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS); 477 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS);
609 478
610 return js.statement(''' 479 return js.statement('''
611 { 480 {
612 var finishedClasses = #finishedClassesAccess; 481 var finishedClasses = #finishedClassesAccess;
613 482
614 function finishClass(cls) { 483 function finishClass(cls) {
615 484
616 if (finishedClasses[cls]) return; 485 if (finishedClasses[cls]) return;
617 finishedClasses[cls] = true; 486 finishedClasses[cls] = true;
618 487
619 var superclass = pendingClasses[cls]; 488 var superclass = processedClasses.pending[cls];
620 489
621 if (#needsMixinSupport) { 490 if (#needsMixinSupport) {
622 if (superclass && superclass.indexOf("+") > 0) { 491 if (superclass && superclass.indexOf("+") > 0) {
623 var s = superclass.split("+"); 492 var s = superclass.split("+");
624 superclass = s[0]; 493 superclass = s[0];
625 var mixinClass = s[1]; 494 var mixinClass = s[1];
626 finishClass(mixinClass); 495 finishClass(mixinClass);
627 var mixin = allClasses[mixinClass]; 496 var mixin = allClasses[mixinClass];
628 // TODO(21896): this test shouldn't be necessary. Without it 497 // TODO(21896): this test shouldn't be necessary. Without it
629 // we have a crash in language/mixin_only_for_rti and 498 // we have a crash in language/mixin_only_for_rti and
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 619
751 // Now, after being a fast map we can set the lazies again. 620 // Now, after being a fast map we can set the lazies again.
752 for (var lazyInit in lazies) { 621 for (var lazyInit in lazies) {
753 var lazyInitName = lazies[lazyInit]; 622 var lazyInitName = lazies[lazyInit];
754 this[lazyInitName] = isolateProperties[lazyInitName]; 623 this[lazyInitName] = isolateProperties[lazyInitName];
755 } 624 }
756 } 625 }
757 Isolate.prototype = oldIsolate.prototype; 626 Isolate.prototype = oldIsolate.prototype;
758 Isolate.prototype.constructor = Isolate; 627 Isolate.prototype.constructor = Isolate;
759 Isolate.#isolatePropertiesName = isolateProperties; 628 Isolate.#isolatePropertiesName = isolateProperties;
760 if (#needsDefineClass)
761 Isolate.#finishClassesProperty = oldIsolate.#finishClassesProperty;
762 if (#outputContainsConstantList) 629 if (#outputContainsConstantList)
763 Isolate.#makeConstListProperty = oldIsolate.#makeConstListProperty; 630 Isolate.#makeConstListProperty = oldIsolate.#makeConstListProperty;
764 if (#hasIncrementalSupport) 631 if (#hasIncrementalSupport)
765 Isolate.#lazyInitializerProperty = 632 Isolate.#lazyInitializerProperty =
766 oldIsolate.#lazyInitializerProperty; 633 oldIsolate.#lazyInitializerProperty;
767 return Isolate; 634 return Isolate;
768 } 635 }
769 """, 636 """,
770 { 'isolatePropertiesName': namer.isolatePropertiesName, 637 { 'isolatePropertiesName': namer.isolatePropertiesName,
771 'needsDefineClass': needsDefineClass,
772 'finishClassesProperty': finishClassesProperty,
773 'outputContainsConstantList': task.outputContainsConstantList, 638 'outputContainsConstantList': task.outputContainsConstantList,
774 'makeConstListProperty': makeConstListProperty, 639 'makeConstListProperty': makeConstListProperty,
775 'hasIncrementalSupport': compiler.hasIncrementalSupport, 640 'hasIncrementalSupport': compiler.hasIncrementalSupport,
776 'lazyInitializerProperty': lazyInitializerProperty, 641 'lazyInitializerProperty': lazyInitializerProperty,
777 }); 642 });
778 } 643 }
779 644
780 jsAst.Fun get lazyInitializerFunction { 645 jsAst.Fun get lazyInitializerFunction {
781 String isolate = namer.currentIsolate; 646 String isolate = namer.currentIsolate;
782 jsAst.Expression cyclicThrow = 647 jsAst.Expression cyclicThrow =
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 } finally { 681 } finally {
817 $isolate[getterName] = function() { return this[fieldName]; }; 682 $isolate[getterName] = function() { return this[fieldName]; };
818 } 683 }
819 } 684 }
820 } 685 }
821 ''', [laziesAccess, laziesAccess, 686 ''', [laziesAccess, laziesAccess,
822 laziesAccess, 687 laziesAccess,
823 cyclicThrow]); 688 cyclicThrow]);
824 } 689 }
825 690
826 List buildDefineClassAndFinishClassFunctionsIfNecessary() {
827 if (!needsDefineClass) return [];
828 return defineClassFunction
829 ..add(buildInheritFrom())
830 ..add(js('$finishClassesName = #', finishClassesFunction))
831 ..add(initFinishClasses);
832 }
833
834 List buildLazyInitializerFunctionIfNecessary() { 691 List buildLazyInitializerFunctionIfNecessary() {
835 if (!needsLazyInitializer) return []; 692 if (!needsLazyInitializer) return [];
836 693
837 return [js('# = #', [js(lazyInitializerName), lazyInitializerFunction])]; 694 return [js('# = #', [js(lazyInitializerName), lazyInitializerFunction])];
838 } 695 }
839 696
840 List buildFinishIsolateConstructor() { 697 List buildFinishIsolateConstructor() {
841 return [ 698 return [
842 js('$finishIsolateConstructorName = #', finishIsolateConstructorFunction) 699 js('$finishIsolateConstructorName = #', finishIsolateConstructorFunction)
843 ]; 700 ];
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
1010 invariant(classElement, builder.functionType == null); 867 invariant(classElement, builder.functionType == null);
1011 invariant(classElement, builder.fieldMetadata == null); 868 invariant(classElement, builder.fieldMetadata == null);
1012 properties.properties.addAll(builder.properties); 869 properties.properties.addAll(builder.properties);
1013 } else { 870 } else {
1014 classEmitter.generateClass( 871 classEmitter.generateClass(
1015 classElement, properties, additionalProperties[classElement]); 872 classElement, properties, additionalProperties[classElement]);
1016 } 873 }
1017 }); 874 });
1018 } 875 }
1019 876
1020 void emitFinishClassesInvocationIfNecessary(CodeBuffer buffer) {
1021 if (needsDefineClass) {
1022 buffer.write('$finishClassesName($classesCollector,'
1023 '$_$isolateProperties,'
1024 '${_}null)$N');
1025
1026 // Reset the map.
1027 buffer.write("$classesCollector$_=${_}null$N$n");
1028 }
1029 }
1030
1031 void emitStaticFunctions(List<Element> staticFunctions) { 877 void emitStaticFunctions(List<Element> staticFunctions) {
1032 for (Element element in staticFunctions) { 878 for (Element element in staticFunctions) {
1033 ClassBuilder builder = new ClassBuilder(element, namer); 879 ClassBuilder builder = new ClassBuilder(element, namer);
1034 containerBuilder.addMember(element, builder); 880 containerBuilder.addMember(element, builder);
1035 getElementDescriptor(element).properties.addAll(builder.properties); 881 getElementDescriptor(element).properties.addAll(builder.properties);
1036 } 882 }
1037 } 883 }
1038 884
1039 void emitStaticNonFinalFieldInitializations(CodeBuffer buffer, 885 void emitStaticNonFinalFieldInitializations(CodeBuffer buffer,
1040 OutputUnit outputUnit) { 886 OutputUnit outputUnit) {
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
1343 buffer.write(N); 1189 buffer.write(N);
1344 addComment('END invoke [main].', buffer); 1190 addComment('END invoke [main].', buffer);
1345 } 1191 }
1346 1192
1347 void emitInitFunction(CodeBuffer buffer) { 1193 void emitInitFunction(CodeBuffer buffer) {
1348 jsAst.FunctionDeclaration decl = js.statement(''' 1194 jsAst.FunctionDeclaration decl = js.statement('''
1349 function init() { 1195 function init() {
1350 $isolateProperties = Object.create(null); 1196 $isolateProperties = Object.create(null);
1351 #; #; #; 1197 #; #; #;
1352 }''', [ 1198 }''', [
1353 buildDefineClassAndFinishClassFunctionsIfNecessary(), 1199 initProcessStatics,
1354 buildLazyInitializerFunctionIfNecessary(), 1200 buildLazyInitializerFunctionIfNecessary(),
floitsch 2014/12/29 18:00:21 just inline all three functions. Use "if (#) ..."
zarah 2014/12/30 14:02:43 Done.
1355 buildFinishIsolateConstructor()]); 1201 buildFinishIsolateConstructor()]);
1356 1202
1357 buffer.write(jsAst.prettyPrint(decl, 1203 buffer.write(jsAst.prettyPrint(decl,
1358 compiler, monitor: compiler.dumpInfoTask).getText()); 1204 compiler, monitor: compiler.dumpInfoTask).getText());
1359 if (compiler.enableMinification) buffer.write('\n'); 1205 if (compiler.enableMinification) buffer.write('\n');
1360 } 1206 }
1361 1207
1362 void emitConvertToFastObjectFunction() { 1208 void emitConvertToFastObjectFunction() {
1363 List<jsAst.Statement> debugCode = <jsAst.Statement>[]; 1209 List<jsAst.Statement> debugCode = <jsAst.Statement>[];
1364 if (DEBUG_FAST_OBJECTS) { 1210 if (DEBUG_FAST_OBJECTS) {
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
1667 mainBuffer 1513 mainBuffer
1668 .write('${globalsHolder}.${namer.isolateName}$_=$_' 1514 .write('${globalsHolder}.${namer.isolateName}$_=$_'
1669 '${namer.isolateName}$N' 1515 '${namer.isolateName}$N'
1670 '${globalsHolder}.$initName$_=${_}$initName$N'); 1516 '${globalsHolder}.$initName$_=${_}$initName$N');
1671 } 1517 }
1672 mainBuffer.add('init()$N$n'); 1518 mainBuffer.add('init()$N$n');
1673 mainBuffer.add('$isolateProperties$_=$_$isolatePropertiesName$N'); 1519 mainBuffer.add('$isolateProperties$_=$_$isolatePropertiesName$N');
1674 1520
1675 emitStaticFunctions(task.outputStaticLists[mainOutputUnit]); 1521 emitStaticFunctions(task.outputStaticLists[mainOutputUnit]);
1676 1522
1677 // Only output the classesCollector if we actually have any classes.
1678 if (needsDefineClass ||
1679 !(nativeClasses.isEmpty &&
1680 compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty &&
1681 outputClassLists.values.every((classList) => classList.isEmpty) &&
1682 typedefsNeededForReflection.isEmpty)) {
1683 // Shorten the code by using "$$" as temporary.
1684 classesCollector = r"$$";
1685 mainBuffer.add('var $classesCollector$_=${_}Object.create(null)$N$n');
1686 }
1687
1688 if (!nativeClasses.isEmpty) { 1523 if (!nativeClasses.isEmpty) {
1689 addComment('Native classes', mainBuffer); 1524 addComment('Native classes', mainBuffer);
1690 } 1525 }
1691 1526
1692 List<ClassElement> classes = task.outputClassLists[mainOutputUnit]; 1527 List<ClassElement> classes = task.outputClassLists[mainOutputUnit];
1693 if (classes != null) { 1528 if (classes != null) {
1694 for (ClassElement element in classes) { 1529 for (ClassElement element in classes) {
1695 generateClass(element, getElementDescriptor(element)); 1530 generateClass(element, getElementDescriptor(element));
1696 } 1531 }
1697 } 1532 }
(...skipping 15 matching lines...) Expand all
1713 CodeBuffer libraryBuffer = new CodeBuffer(); 1548 CodeBuffer libraryBuffer = new CodeBuffer();
1714 for (LibraryElement library in Elements.sortedByPosition(libraries)) { 1549 for (LibraryElement library in Elements.sortedByPosition(libraries)) {
1715 writeLibraryDescriptors(libraryBuffer, library); 1550 writeLibraryDescriptors(libraryBuffer, library);
1716 elementDescriptors.remove(library); 1551 elementDescriptors.remove(library);
1717 } 1552 }
1718 1553
1719 mainBuffer 1554 mainBuffer
1720 ..write('(') 1555 ..write('(')
1721 ..write( 1556 ..write(
1722 jsAst.prettyPrint( 1557 jsAst.prettyPrint(
1723 getReflectionDataParser(classesCollector, backend), 1558 getReflectionDataParser(this, backend),
1724 compiler)) 1559 compiler))
1725 ..write(')') 1560 ..write(')')
1726 ..write('([$n') 1561 ..write('([$n')
1727 ..add(libraryBuffer) 1562 ..add(libraryBuffer)
1728 ..write('])$N'); 1563 ..write('])$N');
1729
1730 emitFinishClassesInvocationIfNecessary(mainBuffer);
1731 } 1564 }
1732 1565
1733 interceptorEmitter.emitGetInterceptorMethods(mainBuffer); 1566 interceptorEmitter.emitGetInterceptorMethods(mainBuffer);
1734 interceptorEmitter.emitOneShotInterceptors(mainBuffer); 1567 interceptorEmitter.emitOneShotInterceptors(mainBuffer);
1735 1568
1736 if (task.outputContainsConstantList) { 1569 if (task.outputContainsConstantList) {
1737 emitMakeConstantList(mainBuffer); 1570 emitMakeConstantList(mainBuffer);
1738 } 1571 }
1739 1572
1740 // Constants in checked mode call into RTI code to set type information 1573 // Constants in checked mode call into RTI code to set type information
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
2013 nativeEmitter.finishGenerateNativeClasses(); 1846 nativeEmitter.finishGenerateNativeClasses();
2014 nativeEmitter.assembleCode(nativeBuffer); 1847 nativeEmitter.assembleCode(nativeBuffer);
2015 1848
2016 return nativeBuffer; 1849 return nativeBuffer;
2017 } 1850 }
2018 1851
2019 void emitProgram(Program program) { 1852 void emitProgram(Program program) {
2020 // Shorten the code by using [namer.currentIsolate] as temporary. 1853 // Shorten the code by using [namer.currentIsolate] as temporary.
2021 isolateProperties = namer.currentIsolate; 1854 isolateProperties = namer.currentIsolate;
2022 1855
2023 classesCollector = r"$$";
2024
2025 // Emit deferred units first, so we have their hashes. 1856 // Emit deferred units first, so we have their hashes.
2026 // Map from OutputUnit to a hash of its content. The hash uniquely 1857 // Map from OutputUnit to a hash of its content. The hash uniquely
2027 // identifies the code of the output-unit. It does not include 1858 // identifies the code of the output-unit. It does not include
2028 // boilerplate JS code, like the sourcemap directives or the hash 1859 // boilerplate JS code, like the sourcemap directives or the hash
2029 // itself. 1860 // itself.
2030 Map<OutputUnit, String> deferredLoadHashes = emitDeferredOutputUnits(); 1861 Map<OutputUnit, String> deferredLoadHashes = emitDeferredOutputUnits();
2031 CodeBuffer nativeBuffer = buildNativesBuffer(); 1862 CodeBuffer nativeBuffer = buildNativesBuffer();
2032 emitMainOutputUnit(deferredLoadHashes, nativeBuffer); 1863 emitMainOutputUnit(deferredLoadHashes, nativeBuffer);
2033 1864
2034 if (backend.requiresPreamble && 1865 if (backend.requiresPreamble &&
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
2163 ..write('var init$_=$_${globalsHolder}.init$N') 1994 ..write('var init$_=$_${globalsHolder}.init$N')
2164 ..write('var ${namer.isolateName}$_=$_' 1995 ..write('var ${namer.isolateName}$_=$_'
2165 '${globalsHolder}.${namer.isolateName}$N'); 1996 '${globalsHolder}.${namer.isolateName}$N');
2166 if (libraryDescriptorBuffer != null) { 1997 if (libraryDescriptorBuffer != null) {
2167 // TODO(ahe): This defines a lot of properties on the 1998 // TODO(ahe): This defines a lot of properties on the
2168 // Isolate.prototype object. We know this will turn it into a 1999 // Isolate.prototype object. We know this will turn it into a
2169 // slow object in V8, so instead we should do something similar 2000 // slow object in V8, so instead we should do something similar
2170 // to Isolate.$finishIsolateConstructor. 2001 // to Isolate.$finishIsolateConstructor.
2171 outputBuffer 2002 outputBuffer
2172 ..write('var ${namer.currentIsolate}$_=$_$isolatePropertiesName$N') 2003 ..write('var ${namer.currentIsolate}$_=$_$isolatePropertiesName$N')
2173 // The classesCollector object ($$).
2174 ..write('$classesCollector$_=${_}Object.create(null);$n')
2175 ..write('(') 2004 ..write('(')
2176 ..write( 2005 ..write(
2177 jsAst.prettyPrint( 2006 jsAst.prettyPrint(
2178 getReflectionDataParser(classesCollector, backend), 2007 getReflectionDataParser(this, backend),
2179 compiler, monitor: compiler.dumpInfoTask)) 2008 compiler, monitor: compiler.dumpInfoTask))
2180 ..write(')') 2009 ..write(')')
2181 ..write('([$n') 2010 ..write('([$n')
2182 ..addBuffer(libraryDescriptorBuffer) 2011 ..addBuffer(libraryDescriptorBuffer)
2183 ..write('])$N'); 2012 ..write('])$N');
2184 2013
2185 if (outputClassLists.containsKey(outputUnit)) {
2186 outputBuffer.write(
2187 '$finishClassesName($classesCollector,$_${namer.currentIsolate},'
2188 '$_$isolatePropertiesName)$N');
2189 }
2190
2191 } 2014 }
2192 2015
2193 // Set the currentIsolate variable to the current isolate (which is 2016 // Set the currentIsolate variable to the current isolate (which is
2194 // provided as second argument). 2017 // provided as second argument).
2195 // We need to do this, because we use the same variable for setting up 2018 // We need to do this, because we use the same variable for setting up
2196 // the isolate-properties and for storing the current isolate. During 2019 // the isolate-properties and for storing the current isolate. During
2197 // the setup (the code above this lines) we must set the variable to 2020 // the setup (the code above this lines) we must set the variable to
2198 // the isolate-properties. 2021 // the isolate-properties.
2199 // After we have done the setup (finishing with `finishClasses`) it must 2022 // After we have done the setup it must point to the current Isolate.
2200 // point to the current Isolate. Otherwise all methods/functions 2023 // Otherwise all methods/functions accessing isolate variables will
2201 // accessing isolate variables will access the wrong object. 2024 // access the wrong object.
2202 outputBuffer.write("${namer.currentIsolate}$_=${_}arguments[1]$N"); 2025 outputBuffer.write("${namer.currentIsolate}$_=${_}arguments[1]$N");
2203 2026
2204 emitCompileTimeConstants(outputBuffer, outputUnit); 2027 emitCompileTimeConstants(outputBuffer, outputUnit);
2205 emitStaticNonFinalFieldInitializations(outputBuffer, outputUnit); 2028 emitStaticNonFinalFieldInitializations(outputBuffer, outputUnit);
2206 outputBuffer.write('}$N'); 2029 outputBuffer.write('}$N');
2207 2030
2208 if (compiler.useContentSecurityPolicy) { 2031 if (compiler.useContentSecurityPolicy) {
2209 jsAst.FunctionDeclaration precompiledFunctionAst = 2032 jsAst.FunctionDeclaration precompiledFunctionAst =
2210 buildCspPrecompiledFunctionFor(outputUnit); 2033 buildCspPrecompiledFunctionFor(outputUnit);
2211 2034
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
2288 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { 2111 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) {
2289 if (element.isInstanceMember) { 2112 if (element.isInstanceMember) {
2290 cachedClassBuilders.remove(element.enclosingClass); 2113 cachedClassBuilders.remove(element.enclosingClass);
2291 2114
2292 nativeEmitter.cachedBuilders.remove(element.enclosingClass); 2115 nativeEmitter.cachedBuilders.remove(element.enclosingClass);
2293 2116
2294 } 2117 }
2295 } 2118 }
2296 } 2119 }
2297 } 2120 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698