| 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 /** | 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 2793 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2804 // Keep track of the JavaScript names we've already added so we | 2804 // Keep track of the JavaScript names we've already added so we |
| 2805 // do not introduce duplicates (bad for code size). | 2805 // do not introduce duplicates (bad for code size). |
| 2806 Map<String, Selector> addedJsNames = new Map<String, Selector>(); | 2806 Map<String, Selector> addedJsNames = new Map<String, Selector>(); |
| 2807 | 2807 |
| 2808 void addNoSuchMethodHandlers(SourceString ignore, Set<Selector> selectors) { | 2808 void addNoSuchMethodHandlers(SourceString ignore, Set<Selector> selectors) { |
| 2809 // Cache the object class and type. | 2809 // Cache the object class and type. |
| 2810 ClassElement objectClass = compiler.objectClass; | 2810 ClassElement objectClass = compiler.objectClass; |
| 2811 DartType objectType = objectClass.computeType(compiler); | 2811 DartType objectType = objectClass.computeType(compiler); |
| 2812 | 2812 |
| 2813 for (Selector selector in selectors) { | 2813 for (Selector selector in selectors) { |
| 2814 // If the selector is typed, we check to see if that type may | |
| 2815 // have a user-defined noSuchMethod implementation. If not, we | |
| 2816 // skip the selector altogether. | |
| 2817 | |
| 2818 TypeMask mask = selector.mask; | 2814 TypeMask mask = selector.mask; |
| 2819 if (mask == null) { | 2815 if (mask == null) { |
| 2820 mask = new TypeMask.subclass(compiler.objectClass.rawType); | 2816 mask = new TypeMask.subclass(compiler.objectClass.rawType); |
| 2821 } | 2817 } |
| 2822 | 2818 |
| 2823 // If the receiver is guaranteed to have a member that | 2819 if (!mask.needsNoSuchMethodHandling(selector, compiler)) continue; |
| 2824 // matches what we're looking for, there's no need to | |
| 2825 // introduce a noSuchMethod handler. It will never be called. | |
| 2826 // | |
| 2827 // As an example, consider this class hierarchy: | |
| 2828 // | |
| 2829 // A <-- noSuchMethod | |
| 2830 // / \ | |
| 2831 // C B <-- foo | |
| 2832 // | |
| 2833 // If we know we're calling foo on an object of type B we | |
| 2834 // don't have to worry about the noSuchMethod method in A | |
| 2835 // because objects of type B implement foo. On the other hand, | |
| 2836 // if we end up calling foo on something of type C we have to | |
| 2837 // add a handler for it. | |
| 2838 | |
| 2839 // If the holders of all user-defined noSuchMethod | |
| 2840 // implementations that might be applicable to the receiver | |
| 2841 // type have a matching member for the current name and | |
| 2842 // selector, we avoid introducing a noSuchMethod handler. | |
| 2843 // | |
| 2844 // As an example, consider this class hierarchy: | |
| 2845 // | |
| 2846 // A <-- foo | |
| 2847 // / \ | |
| 2848 // noSuchMethod --> B C <-- bar | |
| 2849 // | | | |
| 2850 // C D <-- noSuchMethod | |
| 2851 // | |
| 2852 // When calling foo on an object of type A, we know that the | |
| 2853 // implementations of noSuchMethod are in the classes B and D | |
| 2854 // that also (indirectly) implement foo, so we do not need a | |
| 2855 // handler for it. | |
| 2856 // | |
| 2857 // If we're calling bar on an object of type D, we don't need | |
| 2858 // the handler either because all objects of type D implement | |
| 2859 // bar through inheritance. | |
| 2860 // | |
| 2861 // If we're calling bar on an object of type A we do need the | |
| 2862 // handler because we may have to call B.noSuchMethod since B | |
| 2863 // does not implement bar. | |
| 2864 if (mask.willHit(selector, compiler)) continue; | |
| 2865 String jsName = namer.invocationMirrorInternalName(selector); | 2820 String jsName = namer.invocationMirrorInternalName(selector); |
| 2866 addedJsNames[jsName] = selector; | 2821 addedJsNames[jsName] = selector; |
| 2867 String reflectionName = getReflectionName(selector, jsName); | 2822 String reflectionName = getReflectionName(selector, jsName); |
| 2868 if (reflectionName != null) { | 2823 if (reflectionName != null) { |
| 2869 mangledFieldNames[jsName] = reflectionName; | 2824 mangledFieldNames[jsName] = reflectionName; |
| 2870 } | 2825 } |
| 2871 } | 2826 } |
| 2872 } | 2827 } |
| 2873 | 2828 |
| 2874 compiler.codegenWorld.invokedNames.forEach(addNoSuchMethodHandlers); | 2829 compiler.codegenWorld.invokedNames.forEach(addNoSuchMethodHandlers); |
| (...skipping 1277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4152 | 4107 |
| 4153 const String HOOKS_API_USAGE = """ | 4108 const String HOOKS_API_USAGE = """ |
| 4154 // The code supports the following hooks: | 4109 // The code supports the following hooks: |
| 4155 // dartPrint(message) - if this function is defined it is called | 4110 // dartPrint(message) - if this function is defined it is called |
| 4156 // instead of the Dart [print] method. | 4111 // instead of the Dart [print] method. |
| 4157 // dartMainRunner(main) - if this function is defined, the Dart [main] | 4112 // dartMainRunner(main) - if this function is defined, the Dart [main] |
| 4158 // method will not be invoked directly. | 4113 // method will not be invoked directly. |
| 4159 // Instead, a closure that will invoke [main] is | 4114 // Instead, a closure that will invoke [main] is |
| 4160 // passed to [dartMainRunner]. | 4115 // passed to [dartMainRunner]. |
| 4161 """; | 4116 """; |
| OLD | NEW |