| 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 const VERBOSE_OPTIMIZER_HINTS = false; | 7 const VERBOSE_OPTIMIZER_HINTS = false; |
| 8 | 8 |
| 9 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 9 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
| 10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); | 10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 | 209 |
| 210 void markAsMustInline(FunctionElement element) { | 210 void markAsMustInline(FunctionElement element) { |
| 211 _cachedDecisions[element] = _mustInline; | 211 _cachedDecisions[element] = _mustInline; |
| 212 } | 212 } |
| 213 } | 213 } |
| 214 | 214 |
| 215 enum SyntheticConstantKind { | 215 enum SyntheticConstantKind { |
| 216 DUMMY_INTERCEPTOR, | 216 DUMMY_INTERCEPTOR, |
| 217 EMPTY_VALUE, | 217 EMPTY_VALUE, |
| 218 TYPEVARIABLE_REFERENCE, | 218 TYPEVARIABLE_REFERENCE, |
| 219 NAME |
| 219 } | 220 } |
| 220 | 221 |
| 221 class JavaScriptBackend extends Backend { | 222 class JavaScriptBackend extends Backend { |
| 222 static final Uri DART_JS_HELPER = new Uri(scheme: 'dart', path: '_js_helper'); | 223 static final Uri DART_JS_HELPER = new Uri(scheme: 'dart', path: '_js_helper'); |
| 223 static final Uri DART_INTERCEPTORS = | 224 static final Uri DART_INTERCEPTORS = |
| 224 new Uri(scheme: 'dart', path: '_interceptors'); | 225 new Uri(scheme: 'dart', path: '_interceptors'); |
| 225 static final Uri DART_INTERNAL = | 226 static final Uri DART_INTERNAL = |
| 226 new Uri(scheme: 'dart', path: '_internal'); | 227 new Uri(scheme: 'dart', path: '_internal'); |
| 227 static final Uri DART_FOREIGN_HELPER = | 228 static final Uri DART_FOREIGN_HELPER = |
| 228 new Uri(scheme: 'dart', path: '_foreign_helper'); | 229 new Uri(scheme: 'dart', path: '_foreign_helper'); |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 * Interface used to determine if an object has the JavaScript | 429 * Interface used to determine if an object has the JavaScript |
| 429 * indexing behavior. The interface is only visible to specific | 430 * indexing behavior. The interface is only visible to specific |
| 430 * libraries. | 431 * libraries. |
| 431 */ | 432 */ |
| 432 ClassElement jsIndexingBehaviorInterface; | 433 ClassElement jsIndexingBehaviorInterface; |
| 433 | 434 |
| 434 /** | 435 /** |
| 435 * A collection of selectors that must have a one shot interceptor | 436 * A collection of selectors that must have a one shot interceptor |
| 436 * generated. | 437 * generated. |
| 437 */ | 438 */ |
| 438 final Map<String, Selector> oneShotInterceptors; | 439 final Map<jsAst.Name, Selector> oneShotInterceptors; |
| 439 | 440 |
| 440 /** | 441 /** |
| 441 * The members of instantiated interceptor classes: maps a member name to the | 442 * The members of instantiated interceptor classes: maps a member name to the |
| 442 * list of members that have that name. This map is used by the codegen to | 443 * list of members that have that name. This map is used by the codegen to |
| 443 * know whether a send must be intercepted or not. | 444 * know whether a send must be intercepted or not. |
| 444 */ | 445 */ |
| 445 final Map<String, Set<Element>> interceptedElements; | 446 final Map<String, Set<Element>> interceptedElements; |
| 446 | 447 |
| 447 /** | 448 /** |
| 448 * The members of mixin classes that are mixed into an instantiated | 449 * The members of mixin classes that are mixed into an instantiated |
| (...skipping 10 matching lines...) Expand all Loading... |
| 459 new Map<String, Set<Element>>(); | 460 new Map<String, Set<Element>>(); |
| 460 | 461 |
| 461 /** | 462 /** |
| 462 * A map of specialized versions of the [getInterceptorMethod]. | 463 * A map of specialized versions of the [getInterceptorMethod]. |
| 463 * Since [getInterceptorMethod] is a hot method at runtime, we're | 464 * Since [getInterceptorMethod] is a hot method at runtime, we're |
| 464 * always specializing it based on the incoming type. The keys in | 465 * always specializing it based on the incoming type. The keys in |
| 465 * the map are the names of these specialized versions. Note that | 466 * the map are the names of these specialized versions. Note that |
| 466 * the generic version that contains all possible type checks is | 467 * the generic version that contains all possible type checks is |
| 467 * also stored in this map. | 468 * also stored in this map. |
| 468 */ | 469 */ |
| 469 final Map<String, Set<ClassElement>> specializedGetInterceptors; | 470 final Map<jsAst.Name, Set<ClassElement>> specializedGetInterceptors; |
| 470 | 471 |
| 471 /** | 472 /** |
| 472 * Set of classes whose methods are intercepted. | 473 * Set of classes whose methods are intercepted. |
| 473 */ | 474 */ |
| 474 final Set<ClassElement> _interceptedClasses = new Set<ClassElement>(); | 475 final Set<ClassElement> _interceptedClasses = new Set<ClassElement>(); |
| 475 | 476 |
| 476 /** | 477 /** |
| 477 * Set of classes used as mixins on intercepted (native and primitive) | 478 * Set of classes used as mixins on intercepted (native and primitive) |
| 478 * classes. Methods on these classes might also be mixed in to regular Dart | 479 * classes. Methods on these classes might also be mixed in to regular Dart |
| 479 * (unintercepted) classes. | 480 * (unintercepted) classes. |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 JavaScriptResolutionCallbacks resolutionCallbacks; | 614 JavaScriptResolutionCallbacks resolutionCallbacks; |
| 614 | 615 |
| 615 PatchResolverTask patchResolverTask; | 616 PatchResolverTask patchResolverTask; |
| 616 | 617 |
| 617 bool enabledNoSuchMethod = false; | 618 bool enabledNoSuchMethod = false; |
| 618 | 619 |
| 619 JavaScriptBackend(Compiler compiler, | 620 JavaScriptBackend(Compiler compiler, |
| 620 SourceInformationFactory sourceInformationFactory, | 621 SourceInformationFactory sourceInformationFactory, |
| 621 {bool generateSourceMap: true}) | 622 {bool generateSourceMap: true}) |
| 622 : namer = determineNamer(compiler), | 623 : namer = determineNamer(compiler), |
| 623 oneShotInterceptors = new Map<String, Selector>(), | 624 oneShotInterceptors = new Map<jsAst.Name, Selector>(), |
| 624 interceptedElements = new Map<String, Set<Element>>(), | 625 interceptedElements = new Map<String, Set<Element>>(), |
| 625 rti = new RuntimeTypes(compiler), | 626 rti = new RuntimeTypes(compiler), |
| 626 specializedGetInterceptors = new Map<String, Set<ClassElement>>(), | 627 specializedGetInterceptors = new Map<jsAst.Name, Set<ClassElement>>(), |
| 627 annotations = new Annotations(compiler), | 628 annotations = new Annotations(compiler), |
| 628 super(compiler) { | 629 super(compiler) { |
| 629 emitter = new CodeEmitterTask(compiler, namer, generateSourceMap); | 630 emitter = new CodeEmitterTask(compiler, namer, generateSourceMap); |
| 630 typeVariableHandler = new TypeVariableHandler(compiler); | 631 typeVariableHandler = new TypeVariableHandler(compiler); |
| 631 customElementsAnalysis = new CustomElementsAnalysis(this); | 632 customElementsAnalysis = new CustomElementsAnalysis(this); |
| 632 noSuchMethodRegistry = new NoSuchMethodRegistry(this); | 633 noSuchMethodRegistry = new NoSuchMethodRegistry(this); |
| 633 constantCompilerTask = new JavaScriptConstantTask(compiler); | 634 constantCompilerTask = new JavaScriptConstantTask(compiler); |
| 634 resolutionCallbacks = new JavaScriptResolutionCallbacks(this); | 635 resolutionCallbacks = new JavaScriptResolutionCallbacks(this); |
| 635 patchResolverTask = new PatchResolverTask(compiler); | 636 patchResolverTask = new PatchResolverTask(compiler); |
| 636 functionCompiler = compiler.useCpsIr | 637 functionCompiler = compiler.useCpsIr |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 709 } | 710 } |
| 710 | 711 |
| 711 bool isInterceptorClass(ClassElement element) { | 712 bool isInterceptorClass(ClassElement element) { |
| 712 if (element == null) return false; | 713 if (element == null) return false; |
| 713 if (Elements.isNativeOrExtendsNative(element)) return true; | 714 if (Elements.isNativeOrExtendsNative(element)) return true; |
| 714 if (interceptedClasses.contains(element)) return true; | 715 if (interceptedClasses.contains(element)) return true; |
| 715 if (classesMixedIntoInterceptedClasses.contains(element)) return true; | 716 if (classesMixedIntoInterceptedClasses.contains(element)) return true; |
| 716 return false; | 717 return false; |
| 717 } | 718 } |
| 718 | 719 |
| 719 String registerOneShotInterceptor(Selector selector) { | 720 jsAst.Name registerOneShotInterceptor(Selector selector) { |
| 720 Set<ClassElement> classes = getInterceptedClassesOn(selector.name); | 721 Set<ClassElement> classes = getInterceptedClassesOn(selector.name); |
| 721 String name = namer.nameForGetOneShotInterceptor(selector, classes); | 722 jsAst.Name name = namer.nameForGetOneShotInterceptor(selector, classes); |
| 722 if (!oneShotInterceptors.containsKey(name)) { | 723 if (!oneShotInterceptors.containsKey(name)) { |
| 723 registerSpecializedGetInterceptor(classes); | 724 registerSpecializedGetInterceptor(classes); |
| 724 oneShotInterceptors[name] = selector; | 725 oneShotInterceptors[name] = selector; |
| 725 } | 726 } |
| 726 return name; | 727 return name; |
| 727 } | 728 } |
| 728 | 729 |
| 729 /** | 730 /** |
| 730 * Record that [method] is called from a subclass via `super`. | 731 * Record that [method] is called from a subclass via `super`. |
| 731 */ | 732 */ |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 917 } | 918 } |
| 918 enqueueClass(enqueuer, cls, registry); | 919 enqueueClass(enqueuer, cls, registry); |
| 919 } | 920 } |
| 920 | 921 |
| 921 Set<ClassElement> get interceptedClasses { | 922 Set<ClassElement> get interceptedClasses { |
| 922 assert(compiler.enqueuer.resolution.queueIsClosed); | 923 assert(compiler.enqueuer.resolution.queueIsClosed); |
| 923 return _interceptedClasses; | 924 return _interceptedClasses; |
| 924 } | 925 } |
| 925 | 926 |
| 926 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { | 927 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { |
| 927 String name = namer.nameForGetInterceptor(classes); | 928 jsAst.Name name = namer.nameForGetInterceptor(classes); |
| 928 if (classes.contains(jsInterceptorClass)) { | 929 if (classes.contains(jsInterceptorClass)) { |
| 929 // We can't use a specialized [getInterceptorMethod], so we make | 930 // We can't use a specialized [getInterceptorMethod], so we make |
| 930 // sure we emit the one with all checks. | 931 // sure we emit the one with all checks. |
| 931 specializedGetInterceptors[name] = interceptedClasses; | 932 specializedGetInterceptors[name] = interceptedClasses; |
| 932 } else { | 933 } else { |
| 933 specializedGetInterceptors[name] = classes; | 934 specializedGetInterceptors[name] = classes; |
| 934 } | 935 } |
| 935 } | 936 } |
| 936 | 937 |
| 937 void registerCompileTimeConstant(ConstantValue constant, Registry registry) { | 938 void registerCompileTimeConstant(ConstantValue constant, Registry registry) { |
| (...skipping 2049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2987 } | 2988 } |
| 2988 } | 2989 } |
| 2989 | 2990 |
| 2990 /// Records that [constant] is used by the element behind [registry]. | 2991 /// Records that [constant] is used by the element behind [registry]. |
| 2991 class Dependency { | 2992 class Dependency { |
| 2992 final ConstantValue constant; | 2993 final ConstantValue constant; |
| 2993 final Element annotatedElement; | 2994 final Element annotatedElement; |
| 2994 | 2995 |
| 2995 const Dependency(this.constant, this.annotatedElement); | 2996 const Dependency(this.constant, this.annotatedElement); |
| 2996 } | 2997 } |
| OLD | NEW |