| 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 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 } | 641 } |
| 642 | 642 |
| 643 class JavaScriptBackend extends Backend { | 643 class JavaScriptBackend extends Backend { |
| 644 SsaBuilderTask builder; | 644 SsaBuilderTask builder; |
| 645 SsaOptimizerTask optimizer; | 645 SsaOptimizerTask optimizer; |
| 646 SsaCodeGeneratorTask generator; | 646 SsaCodeGeneratorTask generator; |
| 647 CodeEmitterTask emitter; | 647 CodeEmitterTask emitter; |
| 648 | 648 |
| 649 ClassElement jsStringClass; | 649 ClassElement jsStringClass; |
| 650 ClassElement jsArrayClass; | 650 ClassElement jsArrayClass; |
| 651 ClassElement jsNumberClass; |
| 652 ClassElement jsIntClass; |
| 653 ClassElement jsDoubleClass; |
| 651 ClassElement objectInterceptorClass; | 654 ClassElement objectInterceptorClass; |
| 652 Element getInterceptorMethod; | 655 Element getInterceptorMethod; |
| 656 bool _interceptorsAreInitialized = false; |
| 653 | 657 |
| 654 final Namer namer; | 658 final Namer namer; |
| 655 | 659 |
| 656 /** | 660 /** |
| 657 * Interface used to determine if an object has the JavaScript | 661 * Interface used to determine if an object has the JavaScript |
| 658 * indexing behavior. The interface is only visible to specific | 662 * indexing behavior. The interface is only visible to specific |
| 659 * libraries. | 663 * libraries. |
| 660 */ | 664 */ |
| 661 ClassElement jsIndexingBehaviorInterface; | 665 ClassElement jsIndexingBehaviorInterface; |
| 662 | 666 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 } | 714 } |
| 711 | 715 |
| 712 static Namer determineNamer(Compiler compiler) { | 716 static Namer determineNamer(Compiler compiler) { |
| 713 return compiler.enableMinification ? | 717 return compiler.enableMinification ? |
| 714 new MinifyNamer(compiler) : | 718 new MinifyNamer(compiler) : |
| 715 new Namer(compiler); | 719 new Namer(compiler); |
| 716 } | 720 } |
| 717 | 721 |
| 718 bool isInterceptorClass(Element element) { | 722 bool isInterceptorClass(Element element) { |
| 719 if (element == null) return false; | 723 if (element == null) return false; |
| 720 return element == jsStringClass || element == jsArrayClass; | 724 return element == jsStringClass |
| 725 || element == jsArrayClass |
| 726 || element == jsIntClass |
| 727 || element == jsDoubleClass |
| 728 || element == jsNumberClass; |
| 721 } | 729 } |
| 722 | 730 |
| 723 void addInterceptedSelector(Selector selector) { | 731 void addInterceptedSelector(Selector selector) { |
| 724 usedInterceptors.add(selector); | 732 usedInterceptors.add(selector); |
| 725 } | 733 } |
| 726 | 734 |
| 727 bool shouldInterceptSelector(Selector selector) { | 735 bool shouldInterceptSelector(Selector selector) { |
| 728 List<Element> intercepted = interceptedElements[selector.name]; | 736 List<Element> intercepted = interceptedElements[selector.name]; |
| 729 if (intercepted == null) return false; | 737 if (intercepted == null) return false; |
| 730 for (Element element in intercepted) { | 738 for (Element element in intercepted) { |
| 731 if (selector.applies(element, compiler)) return true; | 739 if (selector.applies(element, compiler)) return true; |
| 732 } | 740 } |
| 733 return false; | 741 return false; |
| 734 } | 742 } |
| 735 | 743 |
| 736 void initializeInterceptorElements() { | 744 void initializeInterceptorElements() { |
| 737 objectInterceptorClass = | 745 objectInterceptorClass = |
| 738 compiler.findInterceptor(const SourceString('ObjectInterceptor')); | 746 compiler.findInterceptor(const SourceString('ObjectInterceptor')); |
| 739 getInterceptorMethod = | 747 getInterceptorMethod = |
| 740 compiler.findInterceptor(const SourceString('getInterceptor')); | 748 compiler.findInterceptor(const SourceString('getInterceptor')); |
| 749 jsStringClass = |
| 750 compiler.findInterceptor(const SourceString('JSString')); |
| 751 jsArrayClass = |
| 752 compiler.findInterceptor(const SourceString('JSArray')); |
| 753 jsNumberClass = |
| 754 compiler.findInterceptor(const SourceString('JSNumber')); |
| 755 jsIntClass = |
| 756 compiler.findInterceptor(const SourceString('JSInt')); |
| 757 jsDoubleClass = |
| 758 compiler.findInterceptor(const SourceString('JSDouble')); |
| 741 } | 759 } |
| 742 | 760 |
| 761 void addInterceptors(ClassElement cls) { |
| 762 cls.ensureResolved(compiler); |
| 763 cls.forEachMember((ClassElement classElement, Element member) { |
| 764 // TODO(ngeoffray): Support interceptors on Object methods. |
| 765 if (classElement == compiler.objectClass) return; |
| 766 List<Element> list = interceptedElements.putIfAbsent( |
| 767 member.name, () => new List<Element>()); |
| 768 list.add(member); |
| 769 }, includeSuperMembers: true); |
| 770 } |
| 743 | 771 |
| 744 void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) { | 772 void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) { |
| 745 ClassElement result = null; | 773 ClassElement result = null; |
| 774 if (!_interceptorsAreInitialized) { |
| 775 initializeInterceptorElements(); |
| 776 _interceptorsAreInitialized = true; |
| 777 } |
| 746 if (cls == compiler.stringClass) { | 778 if (cls == compiler.stringClass) { |
| 747 if (jsStringClass == null) { | |
| 748 jsStringClass = | |
| 749 compiler.findInterceptor(const SourceString('JSString')); | |
| 750 initializeInterceptorElements(); | |
| 751 } | |
| 752 result = jsStringClass; | 779 result = jsStringClass; |
| 753 } else if (cls == compiler.listClass) { | 780 } else if (cls == compiler.listClass) { |
| 754 if (jsArrayClass == null) { | |
| 755 jsArrayClass = | |
| 756 compiler.findInterceptor(const SourceString('JSArray')); | |
| 757 initializeInterceptorElements(); | |
| 758 } | |
| 759 result = jsArrayClass; | 781 result = jsArrayClass; |
| 782 } else if (cls == compiler.intClass) { |
| 783 result = jsIntClass; |
| 784 } else if (cls == compiler.doubleClass) { |
| 785 result = jsDoubleClass; |
| 760 } | 786 } |
| 761 | 787 |
| 762 if (result == null) return; | 788 if (result == null) return; |
| 763 | 789 if (enqueuer.isResolutionQueue) addInterceptors(result); |
| 764 result.forEachMember((_, Element member) { | |
| 765 List<Element> list = interceptedElements.putIfAbsent( | |
| 766 member.name, () => new List<Element>()); | |
| 767 list.add(member); | |
| 768 }); | |
| 769 | |
| 770 enqueuer.registerInstantiatedClass(result); | 790 enqueuer.registerInstantiatedClass(result); |
| 771 } | 791 } |
| 772 | 792 |
| 773 Element get cyclicThrowHelper { | 793 Element get cyclicThrowHelper { |
| 774 return compiler.findHelper(const SourceString("throwCyclicInit")); | 794 return compiler.findHelper(const SourceString("throwCyclicInit")); |
| 775 } | 795 } |
| 776 | 796 |
| 777 JavaScriptItemCompilationContext createItemCompilationContext() { | 797 JavaScriptItemCompilationContext createItemCompilationContext() { |
| 778 return new JavaScriptItemCompilationContext(); | 798 return new JavaScriptItemCompilationContext(); |
| 779 } | 799 } |
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1036 print("Inferred return types:"); | 1056 print("Inferred return types:"); |
| 1037 print("----------------------"); | 1057 print("----------------------"); |
| 1038 dumpReturnTypes(); | 1058 dumpReturnTypes(); |
| 1039 print(""); | 1059 print(""); |
| 1040 print("Inferred field types:"); | 1060 print("Inferred field types:"); |
| 1041 print("------------------------"); | 1061 print("------------------------"); |
| 1042 fieldTypes.dump(); | 1062 fieldTypes.dump(); |
| 1043 print(""); | 1063 print(""); |
| 1044 } | 1064 } |
| 1045 } | 1065 } |
| OLD | NEW |