| OLD | NEW |
| 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 typedef void Recompile(Element element); | 7 typedef void Recompile(Element element); |
| 8 | 8 |
| 9 class ReturnInfo { | 9 class ReturnInfo { |
| 10 HType returnType; | 10 HType returnType; |
| (...skipping 747 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 758 } | 758 } |
| 759 | 759 |
| 760 void initializeInterceptorElements() { | 760 void initializeInterceptorElements() { |
| 761 objectInterceptorClass = | 761 objectInterceptorClass = |
| 762 compiler.findInterceptor(const SourceString('ObjectInterceptor')); | 762 compiler.findInterceptor(const SourceString('ObjectInterceptor')); |
| 763 getInterceptorMethod = | 763 getInterceptorMethod = |
| 764 compiler.findInterceptor(const SourceString('getInterceptor')); | 764 compiler.findInterceptor(const SourceString('getInterceptor')); |
| 765 List<ClassElement> classes = [ | 765 List<ClassElement> classes = [ |
| 766 jsStringClass = compiler.findInterceptor(const SourceString('JSString')), | 766 jsStringClass = compiler.findInterceptor(const SourceString('JSString')), |
| 767 jsArrayClass = compiler.findInterceptor(const SourceString('JSArray')), | 767 jsArrayClass = compiler.findInterceptor(const SourceString('JSArray')), |
| 768 jsNumberClass = compiler.findInterceptor(const SourceString('JSNumber')), | 768 // The int class must be before the double class, because the |
| 769 // emitter relies on this list for the order of type checks. |
| 769 jsIntClass = compiler.findInterceptor(const SourceString('JSInt')), | 770 jsIntClass = compiler.findInterceptor(const SourceString('JSInt')), |
| 770 jsDoubleClass = compiler.findInterceptor(const SourceString('JSDouble')), | 771 jsDoubleClass = compiler.findInterceptor(const SourceString('JSDouble')), |
| 772 jsNumberClass = compiler.findInterceptor(const SourceString('JSNumber')), |
| 771 jsNullClass = compiler.findInterceptor(const SourceString('JSNull')), | 773 jsNullClass = compiler.findInterceptor(const SourceString('JSNull')), |
| 772 jsFunctionClass = | 774 jsFunctionClass = |
| 773 compiler.findInterceptor(const SourceString('JSFunction')), | 775 compiler.findInterceptor(const SourceString('JSFunction')), |
| 774 jsBoolClass = compiler.findInterceptor(const SourceString('JSBool'))]; | 776 jsBoolClass = compiler.findInterceptor(const SourceString('JSBool'))]; |
| 775 | 777 |
| 776 jsArrayClass.ensureResolved(compiler); | 778 jsArrayClass.ensureResolved(compiler); |
| 777 jsArrayLength = | 779 jsArrayLength = |
| 778 jsArrayClass.lookupLocalMember(const SourceString('length')); | 780 jsArrayClass.lookupLocalMember(const SourceString('length')); |
| 779 jsArrayRemoveLast = | 781 jsArrayRemoveLast = |
| 780 jsArrayClass.lookupLocalMember(const SourceString('removeLast')); | 782 jsArrayClass.lookupLocalMember(const SourceString('removeLast')); |
| 781 jsArrayAdd = | 783 jsArrayAdd = |
| 782 jsArrayClass.lookupLocalMember(const SourceString('add')); | 784 jsArrayClass.lookupLocalMember(const SourceString('add')); |
| 783 | 785 |
| 784 jsStringClass.ensureResolved(compiler); | 786 jsStringClass.ensureResolved(compiler); |
| 785 jsStringLength = | 787 jsStringLength = |
| 786 jsStringClass.lookupLocalMember(const SourceString('length')); | 788 jsStringClass.lookupLocalMember(const SourceString('length')); |
| 787 jsStringSplit = | 789 jsStringSplit = |
| 788 jsStringClass.lookupLocalMember(const SourceString('split')); | 790 jsStringClass.lookupLocalMember(const SourceString('split')); |
| 789 jsStringConcat = | 791 jsStringConcat = |
| 790 jsStringClass.lookupLocalMember(const SourceString('concat')); | 792 jsStringClass.lookupLocalMember(const SourceString('concat')); |
| 791 | 793 |
| 792 for (ClassElement cls in classes) { | 794 for (ClassElement cls in classes) { |
| 793 if (cls != null) interceptedClasses[cls] = null; | 795 if (cls != null) interceptedClasses[cls] = null; |
| 794 } | 796 } |
| 795 } | 797 } |
| 796 | 798 |
| 797 void addInterceptors(ClassElement cls) { | 799 void addInterceptors(ClassElement cls, Enqueuer enqueuer) { |
| 798 cls.ensureResolved(compiler); | 800 if (enqueuer.isResolutionQueue) { |
| 799 cls.forEachMember((ClassElement classElement, Element member) { | 801 cls.ensureResolved(compiler); |
| 800 Set<Element> set = interceptedElements.putIfAbsent( | 802 cls.forEachMember((ClassElement classElement, Element member) { |
| 801 member.name, () => new Set<Element>()); | 803 Set<Element> set = interceptedElements.putIfAbsent( |
| 802 set.add(member); | 804 member.name, () => new Set<Element>()); |
| 803 }, | 805 set.add(member); |
| 804 includeSuperMembers: true); | 806 }, |
| 807 includeSuperMembers: true); |
| 808 } |
| 809 enqueuer.registerInstantiatedClass(cls); |
| 805 } | 810 } |
| 806 | 811 |
| 807 String registerSpecializedGetInterceptor(Set<ClassElement> classes) { | 812 String registerSpecializedGetInterceptor(Set<ClassElement> classes) { |
| 808 compiler.enqueuer.codegen.registerInstantiatedClass(objectInterceptorClass); | 813 compiler.enqueuer.codegen.registerInstantiatedClass(objectInterceptorClass); |
| 809 if (classes.contains(compiler.objectClass)) { | 814 if (classes.contains(compiler.objectClass)) { |
| 810 // We can't use a specialized [getInterceptorMethod], so we make | 815 // We can't use a specialized [getInterceptorMethod], so we make |
| 811 // sure we emit the one with all checks. | 816 // sure we emit the one with all checks. |
| 812 String name = namer.getName(getInterceptorMethod); | 817 String name = namer.getName(getInterceptorMethod); |
| 813 specializedGetInterceptors.putIfAbsent(name, () { | 818 specializedGetInterceptors.putIfAbsent(name, () { |
| 814 // It is important to take the order provided by this list, | 819 // It is important to take the order provided by the map, |
| 815 // because we want the int type check to happen before the | 820 // because we want the int type check to happen before the |
| 816 // double type check: the double type check covers the int | 821 // double type check: the double type check covers the int |
| 817 // type check. | 822 // type check. Also we don't need to do a number type check |
| 818 return interceptedClasses.keys; | 823 // because that is covered by the double type check. |
| 824 List<ClassElement> keys = <ClassElement>[]; |
| 825 interceptedClasses.forEach((ClassElement cls, _) { |
| 826 if (cls != jsNumberClass) keys.add(cls); |
| 827 }); |
| 828 return keys; |
| 819 }); | 829 }); |
| 820 return namer.isolateAccess(getInterceptorMethod); | 830 return namer.isolateAccess(getInterceptorMethod); |
| 821 } else { | 831 } else { |
| 822 String name = namer.getSpecializedName(getInterceptorMethod, classes); | 832 String name = namer.getSpecializedName(getInterceptorMethod, classes); |
| 823 specializedGetInterceptors[name] = classes; | 833 specializedGetInterceptors[name] = classes; |
| 824 return '${namer.CURRENT_ISOLATE}.$name'; | 834 return '${namer.CURRENT_ISOLATE}.$name'; |
| 825 } | 835 } |
| 826 } | 836 } |
| 827 | 837 |
| 828 void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) { | 838 void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) { |
| 829 ClassElement result = null; | 839 ClassElement result = null; |
| 830 if (!_interceptorsAreInitialized) { | 840 if (!_interceptorsAreInitialized) { |
| 831 initializeInterceptorElements(); | 841 initializeInterceptorElements(); |
| 832 _interceptorsAreInitialized = true; | 842 _interceptorsAreInitialized = true; |
| 833 } | 843 } |
| 834 if (cls == compiler.stringClass) { | 844 if (cls == compiler.stringClass) { |
| 835 result = jsStringClass; | 845 addInterceptors(jsStringClass, enqueuer); |
| 836 } else if (cls == compiler.listClass) { | 846 } else if (cls == compiler.listClass) { |
| 837 result = jsArrayClass; | 847 addInterceptors(jsArrayClass, enqueuer); |
| 838 } else if (cls == compiler.intClass) { | 848 } else if (cls == compiler.intClass) { |
| 839 result = jsIntClass; | 849 addInterceptors(jsIntClass, enqueuer); |
| 840 enqueuer.registerInstantiatedClass(jsNumberClass); | 850 addInterceptors(jsNumberClass, enqueuer); |
| 841 } else if (cls == compiler.doubleClass) { | 851 } else if (cls == compiler.doubleClass) { |
| 842 result = jsDoubleClass; | 852 addInterceptors(jsDoubleClass, enqueuer); |
| 843 enqueuer.registerInstantiatedClass(jsNumberClass); | 853 addInterceptors(jsNumberClass, enqueuer); |
| 844 } else if (cls == compiler.functionClass) { | 854 } else if (cls == compiler.functionClass) { |
| 845 result = jsFunctionClass; | 855 addInterceptors(jsFunctionClass, enqueuer); |
| 846 } else if (cls == compiler.boolClass) { | 856 } else if (cls == compiler.boolClass) { |
| 847 result = jsBoolClass; | 857 addInterceptors(jsBoolClass, enqueuer); |
| 848 } else if (cls == compiler.nullClass) { | 858 } else if (cls == compiler.nullClass) { |
| 849 result = jsNullClass; | 859 addInterceptors(jsNullClass, enqueuer); |
| 860 } else if (cls == compiler.numClass) { |
| 861 addInterceptors(jsIntClass, enqueuer); |
| 862 addInterceptors(jsDoubleClass, enqueuer); |
| 863 addInterceptors(jsNumberClass, enqueuer); |
| 850 } | 864 } |
| 851 | |
| 852 if (result == null) return; | |
| 853 if (enqueuer.isResolutionQueue) addInterceptors(result); | |
| 854 enqueuer.registerInstantiatedClass(result); | |
| 855 } | 865 } |
| 856 | 866 |
| 857 Element get cyclicThrowHelper { | 867 Element get cyclicThrowHelper { |
| 858 return compiler.findHelper(const SourceString("throwCyclicInit")); | 868 return compiler.findHelper(const SourceString("throwCyclicInit")); |
| 859 } | 869 } |
| 860 | 870 |
| 861 JavaScriptItemCompilationContext createItemCompilationContext() { | 871 JavaScriptItemCompilationContext createItemCompilationContext() { |
| 862 return new JavaScriptItemCompilationContext(); | 872 return new JavaScriptItemCompilationContext(); |
| 863 } | 873 } |
| 864 | 874 |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1116 print("Inferred return types:"); | 1126 print("Inferred return types:"); |
| 1117 print("----------------------"); | 1127 print("----------------------"); |
| 1118 dumpReturnTypes(); | 1128 dumpReturnTypes(); |
| 1119 print(""); | 1129 print(""); |
| 1120 print("Inferred field types:"); | 1130 print("Inferred field types:"); |
| 1121 print("------------------------"); | 1131 print("------------------------"); |
| 1122 fieldTypes.dump(); | 1132 fieldTypes.dump(); |
| 1123 print(""); | 1133 print(""); |
| 1124 } | 1134 } |
| 1125 } | 1135 } |
| OLD | NEW |