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

Side by Side Diff: dart/pkg/dart2js_incremental/lib/library_updater.dart

Issue 764353002: Follow up to CL 764533002. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Merged with r42279 and CL 760383003. 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
« no previous file with comments | « dart/pkg/compiler/lib/src/js_emitter/old_emitter/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_incremental.library_updater; 5 library dart2js_incremental.library_updater;
6 6
7 import 'dart:async' show 7 import 'dart:async' show
8 Future; 8 Future;
9 9
10 import 'dart:convert' show 10 import 'dart:convert' show
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 611
612 List<jsAst.Statement> updates = <jsAst.Statement>[]; 612 List<jsAst.Statement> updates = <jsAst.Statement>[];
613 613
614 Set<ClassElementX> newClasses = new Set.from( 614 Set<ClassElementX> newClasses = new Set.from(
615 compiler.codegenWorld.directlyInstantiatedClasses); 615 compiler.codegenWorld.directlyInstantiatedClasses);
616 newClasses.removeAll(_directlyInstantiatedClasses); 616 newClasses.removeAll(_directlyInstantiatedClasses);
617 617
618 if (!newClasses.isEmpty) { 618 if (!newClasses.isEmpty) {
619 // Ask the emitter to compute "needs" (only) if new classes were 619 // Ask the emitter to compute "needs" (only) if new classes were
620 // instantiated. 620 // instantiated.
621 _ensureNeedsComputed(); 621 _ensureAllNeededEntitiesComputed();
622 newClasses = new Set.from(emitter.neededClasses); 622 newClasses = new Set.from(emitter.neededClasses);
623 newClasses.removeAll(_emittedClasses); 623 newClasses.removeAll(_emittedClasses);
624 } else { 624 } else {
625 // Make sure that the set of emitted classes is preserved for subsequent 625 // Make sure that the set of emitted classes is preserved for subsequent
626 // updates. 626 // updates.
627 // TODO(ahe): This is a bit convoluted, find a better approach. 627 // TODO(ahe): This is a bit convoluted, find a better approach.
628 emitter.neededClasses 628 emitter.neededClasses
629 ..clear() 629 ..clear()
630 ..addAll(_emittedClasses); 630 ..addAll(_emittedClasses);
631 } 631 }
632 632
633 List<jsAst.Statement> inherits = <jsAst.Statement>[]; 633 List<jsAst.Statement> inherits = <jsAst.Statement>[];
634 634
635 for (ClassElementX cls in newClasses) { 635 for (ClassElementX cls in newClasses) {
636 jsAst.Node classAccess = emitter.classAccess(cls); 636 jsAst.Node classAccess = emitter.classAccess(cls);
637 String name = namer.getNameOfClass(cls); 637 String name = namer.getNameOfClass(cls);
638 638
639 updates.add( 639 updates.add(
640 js.statement( 640 js.statement(
641 r'# = #', [classAccess, invokeDefineClass(cls)])); 641 r'# = #', [classAccess, invokeDefineClass(cls)]));
642 642
643 ClassElement superclass = cls.superclass; 643 ClassElement superclass = cls.superclass;
644 if (superclass != null) { 644 if (superclass != null) {
645 jsAst.Node superAccess = emitter.classAccess(superclass); 645 jsAst.Node superAccess = emitter.classAccess(superclass);
646 inherits.add( 646 inherits.add(
647 js.statement( 647 js.statement(
648 r'self.$dart_unsafe_eval.inheritFrom(#, #)', 648 r'#.inheritFrom(#, #)', [helper, classAccess, superAccess]));
649 [classAccess, superAccess]));
650 } 649 }
651 } 650 }
652 651
653 // Call inheritFrom after all classes have been created. This way we don't 652 // Call inheritFrom after all classes have been created. This way we don't
654 // need to sort the classes by having superclasses defined before their 653 // need to sort the classes by having superclasses defined before their
655 // subclasses. 654 // subclasses.
656 updates.addAll(inherits); 655 updates.addAll(inherits);
657 656
658 for (ClassElementX cls in changedClasses) { 657 for (ClassElementX cls in changedClasses) {
659 ClassElement superclass = cls.superclass; 658 ClassElement superclass = cls.superclass;
660 jsAst.Node superAccess = 659 jsAst.Node superAccess =
661 superclass == null ? js('null') 660 superclass == null ? js('null')
662 : emitter.classAccess(superclass); 661 : emitter.classAccess(superclass);
663 jsAst.Node classAccess = emitter.classAccess(cls); 662 jsAst.Node classAccess = emitter.classAccess(cls);
664 updates.add( 663 updates.add(
665 js.statement( 664 js.statement(
666 r'# = self.$dart_unsafe_eval.schemaChange(#, #, #)', 665 r'# = #.schemaChange(#, #, #)',
667 [classAccess, invokeDefineClass(cls), classAccess, superAccess])); 666 [classAccess, helper,
667 invokeDefineClass(cls), classAccess, superAccess]));
668 } 668 }
669 669
670 for (RemovalUpdate update in removals) { 670 for (RemovalUpdate update in removals) {
671 update.writeUpdateJsOn(updates); 671 update.writeUpdateJsOn(updates);
672 } 672 }
673 for (Element element in enqueuer.codegen.newlyEnqueuedElements) { 673 for (Element element in enqueuer.codegen.newlyEnqueuedElements) {
674 if (element.isField) { 674 if (element.isField) {
675 updates.addAll(computeFieldUpdateJs(element)); 675 updates.addAll(computeFieldUpdateJs(element));
676 } else { 676 } else {
677 updates.add(computeMethodUpdateJs(element)); 677 updates.add(computeMethodUpdateJs(element));
678 } 678 }
679 } 679 }
680 680
681 Set<ConstantValue> newConstants = new Set<ConstantValue>.identity()..addAll( 681 Set<ConstantValue> newConstants = new Set<ConstantValue>.identity()..addAll(
682 compiler.backend.constants.compiledConstants); 682 compiler.backend.constants.compiledConstants);
683 newConstants.removeAll(_compiledConstants); 683 newConstants.removeAll(_compiledConstants);
684 684
685 if (!newConstants.isEmpty) { 685 if (!newConstants.isEmpty) {
686 _ensureNeedsComputed(); 686 _ensureAllNeededEntitiesComputed();
687 List<ConstantValue> constants = 687 List<ConstantValue> constants =
688 emitter.outputConstantLists[compiler.deferredLoadTask.mainOutputUnit]; 688 emitter.outputConstantLists[compiler.deferredLoadTask.mainOutputUnit];
689 if (constants != null) { 689 if (constants != null) {
690 for (ConstantValue constant in constants) { 690 for (ConstantValue constant in constants) {
691 if (newConstants.contains(constant)) { 691 if (newConstants.contains(constant)) {
692 jsAst.Statement constantInitializer = emitter.oldEmitter 692 jsAst.Statement constantInitializer = emitter.oldEmitter
693 .buildConstantInitializer(constant).toStatement(); 693 .buildConstantInitializer(constant).toStatement();
694 updates.add(constantInitializer); 694 updates.add(constantInitializer);
695 } 695 }
696 } 696 }
697 } 697 }
698 } 698 }
699 699
700 updates.add(js.statement(r''' 700 updates.add(js.statement(r'''
701 if (self.$dart_unsafe_eval.pendingStubs) { 701 if (#helper.pendingStubs) {
702 self.$dart_unsafe_eval.pendingStubs.map(function(e) { return e(); }); 702 #helper.pendingStubs.map(function(e) { return e(); });
703 self.$dart_unsafe_eval.pendingStubs = void 0; 703 #helper.pendingStubs = void 0;
704 } 704 }
705 ''')); 705 ''', {'helper': helper}));
706 706
707 if (updates.length == 1) { 707 if (updates.length == 1) {
708 return prettyPrintJs(updates.single); 708 return prettyPrintJs(updates.single);
709 } else { 709 } else {
710 return prettyPrintJs(js.statement('{#}', [updates])); 710 return prettyPrintJs(js.statement('{#}', [updates]));
711 } 711 }
712 } 712 }
713 713
714 jsAst.Expression invokeDefineClass(ClassElementX cls) { 714 jsAst.Expression invokeDefineClass(ClassElementX cls) {
715 String name = namer.getNameOfClass(cls); 715 String name = namer.getNameOfClass(cls);
716 var descriptor = js('Object.create(null)'); 716 var descriptor = js('Object.create(null)');
717 return js( 717 return js(
718 r''' 718 r'''
719 (new Function( 719 (new Function(
720 "$collectedClasses", "$desc", 720 "$collectedClasses", "$desc",
721 self.$dart_unsafe_eval.defineClass(#, #) +"\n;return " + #))({#: #})''', 721 #helper.defineClass(#name, #computeFields) +"\n;return " + #name))(
722 [js.string(name), js.stringArray(computeFields(cls)), 722 {#name: #descriptor})''',
723 js.string(name), 723 {'helper': helper,
724 js.string(name), descriptor]); 724 'name': js.string(name),
725 'computeFields': js.stringArray(computeFields(cls)),
726 'descriptor': descriptor});
725 } 727 }
726 728
727 jsAst.Node computeMethodUpdateJs(Element element) { 729 jsAst.Node computeMethodUpdateJs(Element element) {
728 MemberInfo info = containerBuilder.analyzeMemberMethod(element); 730 MemberInfo info = containerBuilder.analyzeMemberMethod(element);
729 if (info == null) { 731 if (info == null) {
730 compiler.internalError(element, '${element.runtimeType}'); 732 compiler.internalError(element, '${element.runtimeType}');
731 } 733 }
732 ClassBuilder builder = new ClassBuilder(element, namer); 734 ClassBuilder builder = new ClassBuilder(element, namer);
733 containerBuilder.addMemberMethodFromInfo(info, builder); 735 containerBuilder.addMemberMethodFromInfo(info, builder);
734 jsAst.Node partialDescriptor = 736 jsAst.Node partialDescriptor =
735 builder.toObjectInitializer(omitClassDescriptor: true); 737 builder.toObjectInitializer(emitClassDescriptor: false);
736 738
737 String name = info.name; 739 String name = info.name;
738 jsAst.Node function = info.code; 740 jsAst.Node function = info.code;
739 bool isStatic = !element.isInstanceMember; 741 bool isStatic = !element.isInstanceMember;
740 742
741 /// Either a global object (non-instance members) or a prototype (instance 743 /// Either a global object (non-instance members) or a prototype (instance
742 /// members). 744 /// members).
743 jsAst.Node holder; 745 jsAst.Node holder;
744 746
745 if (element.isInstanceMember) { 747 if (element.isInstanceMember) {
746 holder = js('#.prototype', emitter.classAccess(element.enclosingClass)); 748 holder = js('#.prototype', emitter.classAccess(element.enclosingClass));
747 } else { 749 } else {
748 holder = js('#', namer.globalObjectFor(element)); 750 holder = js('#', namer.globalObjectFor(element));
749 } 751 }
750 752
751 jsAst.Expression globalFunctionsAccess = 753 jsAst.Expression globalFunctionsAccess =
752 emitter.generateEmbeddedGlobalAccess(embeddedNames.GLOBAL_FUNCTIONS); 754 emitter.generateEmbeddedGlobalAccess(embeddedNames.GLOBAL_FUNCTIONS);
753 755
754 return js.statement( 756 return js.statement(
755 r'self.$dart_unsafe_eval.addMethod(#, #, #, #, #)', 757 r'#.addMethod(#, #, #, #, #)',
756 [partialDescriptor, js.string(name), holder, 758 [helper, partialDescriptor, js.string(name), holder,
757 new jsAst.LiteralBool(isStatic), globalFunctionsAccess]); 759 new jsAst.LiteralBool(isStatic), globalFunctionsAccess]);
758 } 760 }
759 761
760 List<jsAst.Statement> computeFieldUpdateJs(FieldElementX element) { 762 List<jsAst.Statement> computeFieldUpdateJs(FieldElementX element) {
761 if (element.isInstanceMember) { 763 if (element.isInstanceMember) {
762 // Any initializers are inlined in factory methods, and the field is 764 // Any initializers are inlined in factory methods, and the field is
763 // declared by adding its class to [_classesWithSchemaChanges]. 765 // declared by adding its class to [_classesWithSchemaChanges].
764 return const <jsAst.Statement>[]; 766 return const <jsAst.Statement>[];
765 } 767 }
766 // A static (or top-level) field. 768 // A static (or top-level) field.
(...skipping 27 matching lines...) Expand all
794 // TODO(ahe): Call a method in the compiler to obtain this name. 796 // TODO(ahe): Call a method in the compiler to obtain this name.
795 String callPrefix = namer.callPrefix; 797 String callPrefix = namer.callPrefix;
796 int parameterCount = element.functionSignature.parameterCount; 798 int parameterCount = element.functionSignature.parameterCount;
797 return '$callPrefix\$$parameterCount'; 799 return '$callPrefix\$$parameterCount';
798 } 800 }
799 801
800 List<String> computeFields(ClassElement cls) { 802 List<String> computeFields(ClassElement cls) {
801 return new EmitterHelper(compiler).computeFields(cls); 803 return new EmitterHelper(compiler).computeFields(cls);
802 } 804 }
803 805
804 void _ensureNeedsComputed() { 806 void _ensureAllNeededEntitiesComputed() {
805 if (_hasComputedNeeds) return; 807 if (_hasComputedNeeds) return;
806 emitter.computeAllNeededEntities(); 808 emitter.computeAllNeededEntities();
807 _hasComputedNeeds = true; 809 _hasComputedNeeds = true;
808 } 810 }
809 } 811 }
810 812
811 /// Represents an update (aka patch) of [before] to [after]. We use the word 813 /// Represents an update (aka patch) of [before] to [after]. We use the word
812 /// "update" to avoid confusion with the compiler feature of "patch" methods. 814 /// "update" to avoid confusion with the compiler feature of "patch" methods.
813 abstract class Update { 815 abstract class Update {
814 final Compiler compiler; 816 final Compiler compiler;
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
1251 1253
1252 JavaScriptBackend get backend => compiler.backend; 1254 JavaScriptBackend get backend => compiler.backend;
1253 1255
1254 Namer get namer => backend.namer; 1256 Namer get namer => backend.namer;
1255 1257
1256 CodeEmitterTask get emitter => backend.emitter; 1258 CodeEmitterTask get emitter => backend.emitter;
1257 1259
1258 ContainerBuilder get containerBuilder => emitter.oldEmitter.containerBuilder; 1260 ContainerBuilder get containerBuilder => emitter.oldEmitter.containerBuilder;
1259 1261
1260 EnqueueTask get enqueuer => compiler.enqueuer; 1262 EnqueueTask get enqueuer => compiler.enqueuer;
1263
1264 jsAst.Expression get helper => namer.accessIncrementalHelper;
1261 } 1265 }
1262 1266
1263 class EmitterHelper extends JsFeatures { 1267 class EmitterHelper extends JsFeatures {
1264 final Compiler compiler; 1268 final Compiler compiler;
1265 1269
1266 EmitterHelper(this.compiler); 1270 EmitterHelper(this.compiler);
1267 1271
1268 ClassEmitter get classEmitter => backend.emitter.oldEmitter.classEmitter; 1272 ClassEmitter get classEmitter => backend.emitter.oldEmitter.classEmitter;
1269 1273
1270 List<String> computeFields(ClassElement cls) { 1274 List<String> computeFields(ClassElement cls) {
1271 // TODO(ahe): Rewrite for new emitter. 1275 // TODO(ahe): Rewrite for new emitter.
1272 ClassBuilder builder = new ClassBuilder(cls, namer); 1276 ClassBuilder builder = new ClassBuilder(cls, namer);
1273 classEmitter.emitFields(cls, builder); 1277 classEmitter.emitFields(cls, builder);
1274 return builder.fields; 1278 return builder.fields;
1275 } 1279 }
1276 } 1280 }
1277 1281
1278 // TODO(ahe): Remove this method. 1282 // TODO(ahe): Remove this method.
1279 NO_WARN(x) => x; 1283 NO_WARN(x) => x;
OLDNEW
« no previous file with comments | « dart/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698