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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart

Issue 11453032: Reapply class/method/field minification (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Changes to bring patch up to date and fix bugs Created 8 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 js_backend; 5 part of js_backend;
6 6
7 /** 7 /**
8 * A function element that represents a closure call. The signature is copied 8 * A function element that represents a closure call. The signature is copied
9 * from the given element. 9 * from the given element.
10 */ 10 */
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 => '${namer.ISOLATE}.\$finishIsolateConstructor'; 103 => '${namer.ISOLATE}.\$finishIsolateConstructor';
104 String get pendingClassesName 104 String get pendingClassesName
105 => '${namer.ISOLATE}.\$pendingClasses'; 105 => '${namer.ISOLATE}.\$pendingClasses';
106 String get isolatePropertiesName 106 String get isolatePropertiesName
107 => '${namer.ISOLATE}.${namer.ISOLATE_PROPERTIES}'; 107 => '${namer.ISOLATE}.${namer.ISOLATE_PROPERTIES}';
108 String get supportsProtoName 108 String get supportsProtoName
109 => 'supportsProto'; 109 => 'supportsProto';
110 String get lazyInitializerName 110 String get lazyInitializerName
111 => '${namer.ISOLATE}.\$lazy'; 111 => '${namer.ISOLATE}.\$lazy';
112 112
113 final String GETTER_SUFFIX = "?"; 113 // Property name suffixes. If the accessors are renaming then the format
114 final String SETTER_SUFFIX = "!"; 114 // is <accessorName>:<fieldName><suffix>. We use the suffix to know whether
115 final String GETTER_SETTER_SUFFIX = "="; 115 // to look for the ':' separator in order to avoid doing the indexOf operation
116 // on every single property (they are quite rare). None of these characters
117 // are legal in an identifier and they are related by bit patterns.
118 // setter < 0x3c
119 // both = 0x3d
120 // getter > 0x3e
121 // renaming setter | 0x7c
122 // renaming both } 0x7d
123 // renaming getter ~ 0x7e
124 const SUFFIX_MASK = 0x3f;
125 const FIRST_SUFFIX_CODE = 0x3c;
126 const SETTER_CODE = 0x3c;
127 const GETTER_SETTER_CODE = 0x3d;
128 const GETTER_CODE = 0x3e;
129 const RENAMING_FLAG = 0x40;
130 String needsGetterCode(String variable) => '($variable & 3) > 0';
131 String needsSetterCode(String variable) => '($variable & 2) == 0';
132 String isRenaming(String variable) => '($variable & $RENAMING_FLAG) != 0';
116 133
117 String get generateAccessorFunction { 134 String get generateAccessorFunction {
118 return """ 135 return """
119 function generateAccessor(field, prototype) { 136 function generateAccessor(field, prototype) {
120 var len = field.length; 137 var len = field.length;
121 var lastChar = field[len - 1]; 138 var lastCharCode = field.charCodeAt(len - 1);
122 var needsGetter = lastChar == '$GETTER_SUFFIX' || lastChar == '$GETTER_SETTER_ SUFFIX'; 139 var needsAccessor = (lastCharCode & $SUFFIX_MASK) >= $FIRST_SUFFIX_CODE;
123 var needsSetter = lastChar == '$SETTER_SUFFIX' || lastChar == '$GETTER_SETTER_ SUFFIX'; 140 if (needsAccessor) {
124 if (needsGetter || needsSetter) field = field.substring(0, len - 1); 141 var needsGetter = ${needsGetterCode('lastCharCode')};
125 if (needsGetter) { 142 var needsSetter = ${needsSetterCode('lastCharCode')};
126 var getterString = "return this." + field + ";"; 143 var renaming = ${isRenaming('lastCharCode')};
127 """ 144 var accessorName = field = field.substring(0, len - 1);
128 /* The supportsProtoCheck below depends on the getter/setter convention. 145 if (renaming) {
129 When changing here, update the protoCheck too. */ 146 var divider = field.indexOf(":");
130 """ 147 accessorName = field.substring(0, divider);
131 prototype["get\$" + field] = new Function(getterString); 148 field = field.substring(divider + 1);
149 }
150 if (needsGetter) {
151 var getterString = "return this." + field + ";";
152 prototype["get\$" + accessorName] = new Function(getterString);
132 } 153 }
133 if (needsSetter) { 154 if (needsSetter) {
134 var setterString = "this." + field + " = v;"; 155 var setterString = "this." + field + " = v;";
135 prototype["set\$" + field] = new Function("v", setterString); 156 prototype["set\$" + accessorName] = new Function("v", setterString);
136 } 157 }
137 return field; 158 }
138 }"""; 159 return field;
160 }""";
139 } 161 }
140 162
141 String get defineClassFunction { 163 String get defineClassFunction {
142 // First the class name, then the field names in an array and the members 164 // First the class name, then the field names in an array and the members
143 // (inside an Object literal). 165 // (inside an Object literal).
144 // The caller can also pass in the constructor as a function if needed. 166 // The caller can also pass in the constructor as a function if needed.
145 // 167 //
146 // Example: 168 // Example:
147 // defineClass("A", ["x", "y"], { 169 // defineClass("A", ["x", "y"], {
148 // foo$1: function(y) { 170 // foo$1: function(y) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 // (http://my.opera.com/desktopteam/blog/2012/07/20/more-12-01-fixes). 208 // (http://my.opera.com/desktopteam/blog/2012/07/20/more-12-01-fixes).
187 // If the browser does not support __proto__ we need to instantiate an 209 // If the browser does not support __proto__ we need to instantiate an
188 // object with the correct (internal) prototype set up correctly, and then 210 // object with the correct (internal) prototype set up correctly, and then
189 // copy the members. 211 // copy the members.
190 212
191 return ''' 213 return '''
192 var $supportsProtoName = false; 214 var $supportsProtoName = false;
193 var tmp = $defineClassName('c', ['f?'], {}).prototype; 215 var tmp = $defineClassName('c', ['f?'], {}).prototype;
194 if (tmp.__proto__) { 216 if (tmp.__proto__) {
195 tmp.__proto__ = {}; 217 tmp.__proto__ = {};
196 if (typeof tmp.get\$f !== "undefined") $supportsProtoName = true; 218 if (typeof tmp.get\$f !== 'undefined') $supportsProtoName = true;
197 } 219 }
198 '''; 220 ''';
199 } 221 }
200 222
201 String get finishClassesFunction { 223 String get finishClassesFunction {
202 // 'defineClass' does not require the classes to be constructed in order. 224 // 'defineClass' does not require the classes to be constructed in order.
203 // Classes are initially just stored in the 'pendingClasses' field. 225 // Classes are initially just stored in the 'pendingClasses' field.
204 // 'finishClasses' takes all pending classes and sets up the prototype. 226 // 'finishClasses' takes all pending classes and sets up the prototype.
205 // Once set up, the constructors prototype field satisfy: 227 // Once set up, the constructors prototype field satisfy:
206 // - it contains all (local) members. 228 // - it contains all (local) members.
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
520 // (3) foo$3$d(a, b, d) => foo$4$c$d(a, b, null, d); 542 // (3) foo$3$d(a, b, d) => foo$4$c$d(a, b, null, d);
521 // (4) No stub generated, call is direct. 543 // (4) No stub generated, call is direct.
522 // (5) No stub generated, call is direct. 544 // (5) No stub generated, call is direct.
523 545
524 // Keep a cache of which stubs have already been generated, to 546 // Keep a cache of which stubs have already been generated, to
525 // avoid duplicates. Note that even if selectors are 547 // avoid duplicates. Note that even if selectors are
526 // canonicalized, we would still need this cache: a typed selector 548 // canonicalized, we would still need this cache: a typed selector
527 // on A and a typed selector on B could yield the same stub. 549 // on A and a typed selector on B could yield the same stub.
528 Set<String> generatedStubNames = new Set<String>(); 550 Set<String> generatedStubNames = new Set<String>();
529 if (compiler.enabledFunctionApply 551 if (compiler.enabledFunctionApply
530 && member.name == Namer.CLOSURE_INVOCATION_NAME) { 552 && member.name == namer.CLOSURE_INVOCATION_NAME) {
531 // If [Function.apply] is called, we pessimistically compile all 553 // If [Function.apply] is called, we pessimistically compile all
532 // possible stubs for this closure. 554 // possible stubs for this closure.
533 FunctionSignature signature = member.computeSignature(compiler); 555 FunctionSignature signature = member.computeSignature(compiler);
534 Set<Selector> selectors = signature.optionalParametersAreNamed 556 Set<Selector> selectors = signature.optionalParametersAreNamed
535 ? computeNamedSelectors(signature, member) 557 ? computeNamedSelectors(signature, member)
536 : computeOptionalSelectors(signature, member); 558 : computeOptionalSelectors(signature, member);
537 for (Selector selector in selectors) { 559 for (Selector selector in selectors) {
538 addParameterStub( 560 addParameterStub(
539 member, selector, defineInstanceMember, generatedStubNames); 561 member, selector, defineInstanceMember, generatedStubNames);
540 } 562 }
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
615 637
616 bool instanceFieldNeedsSetter(Element member) { 638 bool instanceFieldNeedsSetter(Element member) {
617 assert(member.isField()); 639 assert(member.isField());
618 return (!member.modifiers.isFinalOrConst()) 640 return (!member.modifiers.isFinalOrConst())
619 && compiler.codegenWorld.hasInvokedSetter(member, compiler); 641 && compiler.codegenWorld.hasInvokedSetter(member, compiler);
620 } 642 }
621 643
622 String compiledFieldName(Element member) { 644 String compiledFieldName(Element member) {
623 assert(member.isField()); 645 assert(member.isField());
624 return member.isNative() 646 return member.isNative()
625 ? member.name.slowToString() 647 ? member.nativeName()
626 : namer.getName(member); 648 : namer.getName(member);
627 } 649 }
628 650
629 /** 651 /**
630 * Documentation wanted -- johnniwinther 652 * Documentation wanted -- johnniwinther
631 * 653 *
632 * Invariant: [member] must be a declaration element. 654 * Invariant: [member] must be a declaration element.
633 */ 655 */
634 void addInstanceMember(Element member, 656 void addInstanceMember(Element member,
635 DefineMemberFunction defineInstanceMember) { 657 DefineMemberFunction defineInstanceMember) {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 } 741 }
720 742
721 /** 743 /**
722 * Documentation wanted -- johnniwinther 744 * Documentation wanted -- johnniwinther
723 * 745 *
724 * Invariant: [classElement] must be a declaration element. 746 * Invariant: [classElement] must be a declaration element.
725 */ 747 */
726 void visitClassFields(ClassElement classElement, 748 void visitClassFields(ClassElement classElement,
727 void addField(Element member, 749 void addField(Element member,
728 String name, 750 String name,
751 String accessorName,
729 bool needsGetter, 752 bool needsGetter,
730 bool needsSetter, 753 bool needsSetter,
731 bool needsCheckedSetter)) { 754 bool needsCheckedSetter)) {
732 assert(invariant(classElement, classElement.isDeclaration)); 755 assert(invariant(classElement, classElement.isDeclaration));
733 // If the class is never instantiated we still need to set it up for 756 // If the class is never instantiated we still need to set it up for
734 // inheritance purposes, but we can simplify its JavaScript constructor. 757 // inheritance purposes, but we can simplify its JavaScript constructor.
735 bool isInstantiated = 758 bool isInstantiated =
736 compiler.codegenWorld.instantiatedClasses.contains(classElement); 759 compiler.codegenWorld.instantiatedClasses.contains(classElement);
737 760
738 void visitField(ClassElement enclosingClass, Element member) { 761 void visitField(ClassElement enclosingClass, Element member) {
(...skipping 18 matching lines...) Expand all
757 isShadowed = classElement.isShadowedByField(member); 780 isShadowed = classElement.isShadowedByField(member);
758 } 781 }
759 782
760 if ((isInstantiated && !enclosingClass.isNative()) 783 if ((isInstantiated && !enclosingClass.isNative())
761 || needsGetter 784 || needsGetter
762 || needsSetter) { 785 || needsSetter) {
763 String accessorName = isShadowed 786 String accessorName = isShadowed
764 ? namer.shadowedFieldName(member) 787 ? namer.shadowedFieldName(member)
765 : namer.getName(member); 788 : namer.getName(member);
766 String fieldName = member.isNative() 789 String fieldName = member.isNative()
767 ? member.nativeName() 790 ? member.nativeName()
floitsch 2012/12/07 12:01:01 accidental space?
erikcorry 2012/12/10 08:36:01 Done.
768 : accessorName; 791 : accessorName;
769 bool needsCheckedSetter = false; 792 bool needsCheckedSetter = false;
770 if (needsSetter && compiler.enableTypeAssertions 793 if (needsSetter && compiler.enableTypeAssertions
771 && canGenerateCheckedSetter(member)) { 794 && canGenerateCheckedSetter(member)) {
772 needsCheckedSetter = true; 795 needsCheckedSetter = true;
773 needsSetter = false; 796 needsSetter = false;
774 } 797 }
775 // Getters and setters with suffixes will be generated dynamically. 798 // Getters and setters with suffixes will be generated dynamically.
776 addField(member, 799 addField(member,
777 fieldName, 800 fieldName,
801 accessorName,
778 needsGetter, 802 needsGetter,
779 needsSetter, 803 needsSetter,
780 needsCheckedSetter); 804 needsCheckedSetter);
781 } 805 }
782 } 806 }
783 807
784 // If a class is not instantiated then we add the field just so we can 808 // If a class is not instantiated then we add the field just so we can
785 // generate the field getter/setter dynamically. Since this is only 809 // generate the field getter/setter dynamically. Since this is only
786 // allowed on fields that are in [classElement] we don't need to visit 810 // allowed on fields that are in [classElement] we don't need to visit
787 // superclasses for non-instantiated classes. 811 // superclasses for non-instantiated classes.
788 classElement.implementation.forEachInstanceField( 812 classElement.implementation.forEachInstanceField(
789 visitField, 813 visitField,
790 includeBackendMembers: true, 814 includeBackendMembers: true,
791 includeSuperMembers: isInstantiated && !classElement.isNative()); 815 includeSuperMembers: isInstantiated && !classElement.isNative());
792 } 816 }
793 817
794 void generateGetter(Element member, String fieldName, CodeBuffer buffer) {
795 String getterName = namer.getterName(member.getLibrary(), member.name);
796 buffer.add("$getterName: function() { return this.$fieldName; }");
797 }
798
799 void generateSetter(Element member, String fieldName, CodeBuffer buffer) {
800 String setterName = namer.setterName(member.getLibrary(), member.name);
801 buffer.add("$setterName: function(v) { this.$fieldName = v; }");
802 }
803
804 bool canGenerateCheckedSetter(Element member) { 818 bool canGenerateCheckedSetter(Element member) {
805 DartType type = member.computeType(compiler); 819 DartType type = member.computeType(compiler);
806 if (type.element.isTypeVariable() 820 if (type.element.isTypeVariable()
807 || type.element == compiler.dynamicClass 821 || type.element == compiler.dynamicClass
808 || type.element == compiler.objectClass) { 822 || type.element == compiler.objectClass) {
809 // TODO(ngeoffray): Support type checks on type parameters. 823 // TODO(ngeoffray): Support type checks on type parameters.
810 return false; 824 return false;
811 } 825 }
812 return true; 826 return true;
813 } 827 }
814 828
815 void generateCheckedSetter(Element member, 829 void generateCheckedSetter(Element member,
816 String fieldName, 830 String fieldName,
831 String accessorName,
817 CodeBuffer buffer) { 832 CodeBuffer buffer) {
818 assert(canGenerateCheckedSetter(member)); 833 assert(canGenerateCheckedSetter(member));
819 DartType type = member.computeType(compiler); 834 DartType type = member.computeType(compiler);
820 SourceString helper = compiler.backend.getCheckedModeHelper(type); 835 SourceString helper = compiler.backend.getCheckedModeHelper(type);
821 FunctionElement helperElement = compiler.findHelper(helper); 836 FunctionElement helperElement = compiler.findHelper(helper);
822 String helperName = namer.isolateAccess(helperElement); 837 String helperName = namer.isolateAccess(helperElement);
823 String additionalArgument = ''; 838 String additionalArgument = '';
824 if (helperElement.computeSignature(compiler).parameterCount != 1) { 839 if (helperElement.computeSignature(compiler).parameterCount != 1) {
825 additionalArgument = ", '${namer.operatorIs(type.element)}'"; 840 additionalArgument = ", '${namer.operatorIs(type.element)}'";
826 } 841 }
827 String setterName = namer.setterName(member.getLibrary(), member.name); 842 String setterName =
843 namer.setterNameFromAccessorName(accessorName);
sra1 2012/12/07 06:03:18 Single line?
erikcorry 2012/12/10 08:36:01 Done.
828 buffer.add("$setterName: function(v) { " 844 buffer.add("$setterName: function(v) { "
829 "this.$fieldName = $helperName(v$additionalArgument); }"); 845 "this.$fieldName = $helperName(v$additionalArgument); }");
830 } 846 }
831 847
832 void emitClassConstructor(ClassElement classElement, CodeBuffer buffer) { 848 void emitClassConstructor(ClassElement classElement, CodeBuffer buffer) {
833 /* Do nothing. */ 849 /* Do nothing. */
834 } 850 }
835 851
836 void emitClassFields(ClassElement classElement, 852 void emitClassFields(ClassElement classElement,
837 CodeBuffer buffer, 853 CodeBuffer buffer,
838 bool emitEndingComma, 854 bool emitEndingComma,
839 { String superClass: "", 855 { String superClass: "",
840 bool isNative: false}) { 856 bool isNative: false}) {
841 bool isFirstField = true; 857 bool isFirstField = true;
842 bool isAnythingOutput = false; 858 bool isAnythingOutput = false;
843 if (!isNative) { 859 if (!isNative) {
844 buffer.add('"":"$superClass;'); 860 buffer.add('"":"$superClass;');
845 isAnythingOutput = true; 861 isAnythingOutput = true;
846 } 862 }
847 visitClassFields(classElement, (Element member, 863 visitClassFields(classElement, (Element member,
848 String name, 864 String name,
865 String accessorName,
849 bool needsGetter, 866 bool needsGetter,
850 bool needsSetter, 867 bool needsSetter,
851 bool needsCheckedSetter) { 868 bool needsCheckedSetter) {
852 if (!getterAndSetterCanBeImplementedByFieldSpec(
853 member, name, needsGetter, needsSetter)) {
854 return;
855 }
856 if (!isNative || needsCheckedSetter || needsGetter || needsSetter) { 869 if (!isNative || needsCheckedSetter || needsGetter || needsSetter) {
857 if (isFirstField) { 870 if (isFirstField) {
858 isFirstField = false; 871 isFirstField = false;
859 if (!isAnythingOutput) { 872 if (!isAnythingOutput) {
860 buffer.add('"":"'); 873 buffer.add('"":"');
861 isAnythingOutput = true; 874 isAnythingOutput = true;
862 } 875 }
863 } else { 876 } else {
864 buffer.add(","); 877 buffer.add(",");
865 } 878 }
866 buffer.add('$name'); 879 buffer.add('$accessorName');
880 int flag = 0;
881 if (name != accessorName) {
882 buffer.add(':$name');
883 assert(needsGetter || needsSetter);
884 flag = RENAMING_FLAG;
885 }
867 if (needsGetter && needsSetter) { 886 if (needsGetter && needsSetter) {
868 buffer.add(GETTER_SETTER_SUFFIX); 887 buffer.addCharCode(GETTER_SETTER_CODE + flag);
869 } else if (needsGetter) { 888 } else if (needsGetter) {
870 buffer.add(GETTER_SUFFIX); 889 buffer.addCharCode(GETTER_CODE + flag);
871 } else if (needsSetter) { 890 } else if (needsSetter) {
872 buffer.add(SETTER_SUFFIX); 891 buffer.addCharCode(SETTER_CODE + flag);
873 } 892 }
874 } 893 }
875 }); 894 });
876 if (isAnythingOutput) { 895 if (isAnythingOutput) {
877 buffer.add('"'); 896 buffer.add('"');
878 if (emitEndingComma) { 897 if (emitEndingComma) {
879 buffer.add(','); 898 buffer.add(',');
880 } 899 }
881 } 900 }
882 } 901 }
883 902
884 /** Each getter/setter must be prefixed with a ",\n ". */ 903 /** Each getter/setter must be prefixed with a ",\n ". */
885 void emitClassGettersSetters(ClassElement classElement, 904 void emitClassGettersSetters(ClassElement classElement,
886 CodeBuffer buffer, 905 CodeBuffer buffer,
887 bool emitLeadingComma) { 906 bool emitLeadingComma) {
888 emitComma() { 907 emitComma() {
889 if (emitLeadingComma) { 908 if (emitLeadingComma) {
890 buffer.add(",\n "); 909 buffer.add(",\n ");
891 } else { 910 } else {
892 emitLeadingComma = true; 911 emitLeadingComma = true;
893 } 912 }
894 } 913 }
895 914
896 visitClassFields(classElement, (Element member, 915 visitClassFields(classElement, (Element member,
897 String name, 916 String name,
917 String accessorName,
898 bool needsGetter, 918 bool needsGetter,
899 bool needsSetter, 919 bool needsSetter,
900 bool needsCheckedSetter) { 920 bool needsCheckedSetter) {
901 if (name == null) throw 123;
902 if (getterAndSetterCanBeImplementedByFieldSpec(
903 member, name, needsGetter, needsSetter)) {
904 needsGetter = false;
905 needsSetter = false;
906 }
907 if (needsGetter) {
908 emitComma();
909 generateGetter(member, name, buffer);
910 }
911 if (needsSetter) {
912 emitComma();
913 generateSetter(member, name, buffer);
914 }
915 if (needsCheckedSetter) { 921 if (needsCheckedSetter) {
916 assert(!needsSetter); 922 assert(!needsSetter);
917 emitComma(); 923 emitComma();
918 generateCheckedSetter(member, name, buffer); 924 generateCheckedSetter(member, name, accessorName, buffer);
919 } 925 }
920 }); 926 });
921 } 927 }
922 928
923 bool getterAndSetterCanBeImplementedByFieldSpec(Element member,
924 String name,
925 bool needsGetter,
926 bool needsSetter) {
927 if (needsGetter) {
928 if (namer.getterName(member.getLibrary(), member.name) != 'get\$$name') {
929 return false;
930 }
931 }
932 if (needsSetter) {
933 if (namer.setterName(member.getLibrary(), member.name) != 'set\$$name') {
934 return false;
935 }
936 }
937 return true;
938 }
939
940 /** 929 /**
941 * Documentation wanted -- johnniwinther 930 * Documentation wanted -- johnniwinther
942 * 931 *
943 * Invariant: [classElement] must be a declaration element. 932 * Invariant: [classElement] must be a declaration element.
944 */ 933 */
945 void generateClass(ClassElement classElement, CodeBuffer buffer) { 934 void generateClass(ClassElement classElement, CodeBuffer buffer) {
946 assert(invariant(classElement, classElement.isDeclaration)); 935 assert(invariant(classElement, classElement.isDeclaration));
947 if (classElement.isNative()) { 936 if (classElement.isNative()) {
948 nativeEmitter.generateNativeClass(classElement); 937 nativeEmitter.generateNativeClass(classElement);
949 return; 938 return;
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1151 1140
1152 void emitStaticFunctionGetters(CodeBuffer buffer) { 1141 void emitStaticFunctionGetters(CodeBuffer buffer) {
1153 Set<FunctionElement> functionsNeedingGetter = 1142 Set<FunctionElement> functionsNeedingGetter =
1154 compiler.codegenWorld.staticFunctionsNeedingGetter; 1143 compiler.codegenWorld.staticFunctionsNeedingGetter;
1155 for (FunctionElement element in functionsNeedingGetter) { 1144 for (FunctionElement element in functionsNeedingGetter) {
1156 // The static function does not have the correct name. Since 1145 // The static function does not have the correct name. Since
1157 // [addParameterStubs] use the name to create its stubs we simply 1146 // [addParameterStubs] use the name to create its stubs we simply
1158 // create a fake element with the correct name. 1147 // create a fake element with the correct name.
1159 // Note: the callElement will not have any enclosingElement. 1148 // Note: the callElement will not have any enclosingElement.
1160 FunctionElement callElement = 1149 FunctionElement callElement =
1161 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, element); 1150 new ClosureInvocationElement(namer.CLOSURE_INVOCATION_NAME, element);
kasperl 2012/12/07 10:37:45 It looks a bit fishy to try to grab a constant (we
erikcorry 2012/12/10 08:36:01 Done and changed: ISOLATE -> isolateName ISOLATE_
1162 String staticName = namer.getName(element); 1151 String staticName = namer.getName(element);
1163 String invocationName = namer.instanceMethodName(callElement); 1152 String invocationName = namer.instanceMethodName(callElement);
1164 String fieldAccess = '$isolateProperties.$staticName'; 1153 String fieldAccess = '$isolateProperties.$staticName';
1165 buffer.add("$fieldAccess.$invocationName = $fieldAccess;\n"); 1154 buffer.add("$fieldAccess.$invocationName = $fieldAccess;\n");
1166 addParameterStubs(callElement, (String name, CodeBuffer value) { 1155 addParameterStubs(callElement, (String name, CodeBuffer value) {
1167 buffer.add('$fieldAccess.$name = $value;\n'); 1156 buffer.add('$fieldAccess.$name = $value;\n');
1168 }); 1157 });
1169 // If a static function is used as a closure we need to add its name 1158 // If a static function is used as a closure we need to add its name
1170 // in case it is used in spawnFunction. 1159 // in case it is used in spawnFunction.
1171 String fieldName = namer.STATIC_CLOSURE_NAME_NAME; 1160 String fieldName = namer.STATIC_CLOSURE_NAME_NAME;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
1248 1237
1249 // Define the constructor with a name so that Object.toString can 1238 // Define the constructor with a name so that Object.toString can
1250 // find the class name of the closure class. 1239 // find the class name of the closure class.
1251 emitBoundClosureClassHeader( 1240 emitBoundClosureClassHeader(
1252 mangledName, superName, extraArgWithoutComma, boundClosureBuffer); 1241 mangledName, superName, extraArgWithoutComma, boundClosureBuffer);
1253 // Now add the methods on the closure class. The instance method does not 1242 // Now add the methods on the closure class. The instance method does not
1254 // have the correct name. Since [addParameterStubs] use the name to create 1243 // have the correct name. Since [addParameterStubs] use the name to create
1255 // its stubs we simply create a fake element with the correct name. 1244 // its stubs we simply create a fake element with the correct name.
1256 // Note: the callElement will not have any enclosingElement. 1245 // Note: the callElement will not have any enclosingElement.
1257 FunctionElement callElement = 1246 FunctionElement callElement =
1258 new ClosureInvocationElement(Namer.CLOSURE_INVOCATION_NAME, member); 1247 new ClosureInvocationElement(namer.CLOSURE_INVOCATION_NAME, member);
1259 1248
1260 String invocationName = namer.instanceMethodName(callElement); 1249 String invocationName = namer.instanceMethodName(callElement);
1261 List<String> arguments = new List<String>(parameterCount); 1250 List<String> arguments = new List<String>(parameterCount);
1262 for (int i = 0; i < parameterCount; i++) { 1251 for (int i = 0; i < parameterCount; i++) {
1263 arguments[i] = "p$i"; 1252 arguments[i] = "p$i";
1264 } 1253 }
1265 String joinedArgs = Strings.join(arguments, ", "); 1254 String joinedArgs = Strings.join(arguments, ", ");
1266 boundClosureBuffer.add( 1255 boundClosureBuffer.add(
1267 "$invocationName: function($joinedArgs) {"); 1256 "$invocationName: function($joinedArgs) {");
1268 String callArgs = hasExtraArgument 1257 String callArgs = hasExtraArgument
1269 ? joinedArgs.isEmpty 1258 ? joinedArgs.isEmpty
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1319 ? member.nativeName() 1308 ? member.nativeName()
1320 : namer.instanceFieldName(memberLibrary, member.name); 1309 : namer.instanceFieldName(memberLibrary, member.name);
1321 getter = "this.$name"; 1310 getter = "this.$name";
1322 } 1311 }
1323 1312
1324 for (Selector selector in selectors) { 1313 for (Selector selector in selectors) {
1325 if (selector.applies(member, compiler)) { 1314 if (selector.applies(member, compiler)) {
1326 String invocationName = 1315 String invocationName =
1327 namer.instanceMethodInvocationName(memberLibrary, member.name, 1316 namer.instanceMethodInvocationName(memberLibrary, member.name,
1328 selector); 1317 selector);
1329 SourceString callName = Namer.CLOSURE_INVOCATION_NAME; 1318 SourceString callName = namer.CLOSURE_INVOCATION_NAME;
1330 String closureCallName = 1319 String closureCallName =
1331 namer.instanceMethodInvocationName(memberLibrary, callName, 1320 namer.instanceMethodInvocationName(memberLibrary, callName,
1332 selector); 1321 selector);
1333 List<String> arguments = <String>[]; 1322 List<String> arguments = <String>[];
1334 for (int i = 0; i < selector.argumentCount; i++) { 1323 for (int i = 0; i < selector.argumentCount; i++) {
1335 arguments.add("arg$i"); 1324 arguments.add("arg$i");
1336 } 1325 }
1337 String joined = Strings.join(arguments, ", "); 1326 String joined = Strings.join(arguments, ", ");
1338 CodeBuffer getterBuffer = new CodeBuffer(); 1327 CodeBuffer getterBuffer = new CodeBuffer();
1339 getterBuffer.add("function("); 1328 getterBuffer.add("function(");
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1516 CodeBuffer argNames = new CodeBuffer(); 1505 CodeBuffer argNames = new CodeBuffer();
1517 List<SourceString> names = selector.getOrderedNamedArguments(); 1506 List<SourceString> names = selector.getOrderedNamedArguments();
1518 for (int i = 0; i < names.length; i++) { 1507 for (int i = 0; i < names.length; i++) {
1519 if (i != 0) argNames.add(', '); 1508 if (i != 0) argNames.add(', ');
1520 argNames.add('"'); 1509 argNames.add('"');
1521 argNames.add(names[i].slowToString()); 1510 argNames.add(names[i].slowToString());
1522 argNames.add('"'); 1511 argNames.add('"');
1523 } 1512 }
1524 String internalName = namer.instanceMethodInvocationName( 1513 String internalName = namer.instanceMethodInvocationName(
1525 selector.library, new SourceString(methodName), selector); 1514 selector.library, new SourceString(methodName), selector);
1515 Element createInvocationMirror =
1516 compiler.findHelper(const SourceString('createInvocationMirror'));
1526 CodeBuffer buffer = new CodeBuffer(); 1517 CodeBuffer buffer = new CodeBuffer();
1527 buffer.add('function($args) {\n'); 1518 buffer.add('function($args) {\n');
1528 buffer.add(' return this.$noSuchMethodName(' 1519 buffer.add(' return this.$noSuchMethodName('
1529 '\$.createInvocationMirror("$methodName", "$internalName",' 1520 '${namer.isolateAccess(createInvocationMirror)}('
1530 ' $type, [$args], [$argNames]));\n'); 1521 '"$methodName", "$internalName",'
1522 '$type, [$args], [$argNames]));\n');
1531 buffer.add(' }'); 1523 buffer.add(' }');
1532 return buffer; 1524 return buffer;
1533 } 1525 }
1534 1526
1535 void addNoSuchMethodHandlers(SourceString ignore, Set<Selector> selectors) { 1527 void addNoSuchMethodHandlers(SourceString ignore, Set<Selector> selectors) {
1536 // Cache the object class and type. 1528 // Cache the object class and type.
1537 ClassElement objectClass = compiler.objectClass; 1529 ClassElement objectClass = compiler.objectClass;
1538 DartType objectType = objectClass.computeType(compiler); 1530 DartType objectType = objectClass.computeType(compiler);
1539 1531
1540 for (Selector selector in selectors) { 1532 for (Selector selector in selectors) {
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
1693 compiler.isolateLibrary.find(Compiler.START_ROOT_ISOLATE); 1685 compiler.isolateLibrary.find(Compiler.START_ROOT_ISOLATE);
1694 mainCall = buildIsolateSetup(buffer, main, isolateMain); 1686 mainCall = buildIsolateSetup(buffer, main, isolateMain);
1695 } else { 1687 } else {
1696 mainCall = '${namer.isolateAccess(main)}()'; 1688 mainCall = '${namer.isolateAccess(main)}()';
1697 } 1689 }
1698 buffer.add(""" 1690 buffer.add("""
1699 1691
1700 // 1692 //
1701 // BEGIN invoke [main]. 1693 // BEGIN invoke [main].
1702 // 1694 //
1703 if (typeof document != 'undefined' && document.readyState != 'complete') { 1695 if (typeof document !== 'undefined' && document.readyState != 'complete') {
floitsch 2012/12/07 12:01:01 not sure that's needed. In theory it should be cle
erikcorry 2012/12/10 08:36:01 Done.
1704 document.addEventListener('readystatechange', function () { 1696 document.addEventListener('readystatechange', function () {
1705 if (document.readyState == 'complete') { 1697 if (document.readyState == 'complete') {
1706 if (typeof dartMainRunner == 'function') { 1698 if (typeof dartMainRunner === 'function') {
1707 dartMainRunner(function() { ${mainCall}; }); 1699 dartMainRunner(function() { ${mainCall}; });
1708 } else { 1700 } else {
1709 ${mainCall}; 1701 ${mainCall};
1710 } 1702 }
1711 } 1703 }
1712 }, false); 1704 }, false);
1713 } else { 1705 } else {
1714 if (typeof dartMainRunner == 'function') { 1706 if (typeof dartMainRunner === 'function') {
1715 dartMainRunner(function() { ${mainCall}; }); 1707 dartMainRunner(function() { ${mainCall}; });
1716 } else { 1708 } else {
1717 ${mainCall}; 1709 ${mainCall};
1718 } 1710 }
1719 } 1711 }
1720 // 1712 //
1721 // END invoke [main]. 1713 // END invoke [main].
1722 // 1714 //
1723 1715
1724 """); 1716 """);
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1847 const String HOOKS_API_USAGE = """ 1839 const String HOOKS_API_USAGE = """
1848 // Generated by dart2js, the Dart to JavaScript compiler. 1840 // Generated by dart2js, the Dart to JavaScript compiler.
1849 // The code supports the following hooks: 1841 // The code supports the following hooks:
1850 // dartPrint(message) - if this function is defined it is called 1842 // dartPrint(message) - if this function is defined it is called
1851 // instead of the Dart [print] method. 1843 // instead of the Dart [print] method.
1852 // dartMainRunner(main) - if this function is defined, the Dart [main] 1844 // dartMainRunner(main) - if this function is defined, the Dart [main]
1853 // method will not be invoked directly. 1845 // method will not be invoked directly.
1854 // Instead, a closure that will invoke [main] is 1846 // Instead, a closure that will invoke [main] is
1855 // passed to [dartMainRunner]. 1847 // passed to [dartMainRunner].
1856 """; 1848 """;
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698