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 |