| 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 library js_backend.backend; | 5 library js_backend.backend; |
| 6 | 6 |
| 7 import 'dart:async' show Future; | 7 import 'dart:async' show Future; |
| 8 | 8 |
| 9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; | 9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; |
| 10 | 10 |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 454 JavaScriptBackendSerialization serialization; | 454 JavaScriptBackendSerialization serialization; |
| 455 | 455 |
| 456 StagedWorldImpactBuilder constantImpactsForResolution = | 456 StagedWorldImpactBuilder constantImpactsForResolution = |
| 457 new StagedWorldImpactBuilder(); | 457 new StagedWorldImpactBuilder(); |
| 458 | 458 |
| 459 StagedWorldImpactBuilder constantImpactsForCodegen = | 459 StagedWorldImpactBuilder constantImpactsForCodegen = |
| 460 new StagedWorldImpactBuilder(); | 460 new StagedWorldImpactBuilder(); |
| 461 | 461 |
| 462 final NativeData nativeData = new NativeData(); | 462 final NativeData nativeData = new NativeData(); |
| 463 InterceptorData _interceptorData; | 463 InterceptorData _interceptorData; |
| 464 BackendUsage _backendUsage; | 464 BackendUsageImpl _backendUsage; |
| 465 final MirrorsData mirrorsData; | 465 final MirrorsData mirrorsData; |
| 466 CheckedModeHelpers _checkedModeHelpers; | 466 CheckedModeHelpers _checkedModeHelpers; |
| 467 | 467 |
| 468 BackendHelpers helpers; | 468 BackendHelpers helpers; |
| 469 final BackendImpacts impacts; | 469 final BackendImpacts impacts; |
| 470 | 470 |
| 471 /// Common classes used by the backend. | 471 /// Common classes used by the backend. |
| 472 BackendClasses backendClasses; | 472 BackendClasses backendClasses; |
| 473 | 473 |
| 474 /// Backend access to the front-end. | 474 /// Backend access to the front-end. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 487 this.sourceInformationStrategy = generateSourceMap | 487 this.sourceInformationStrategy = generateSourceMap |
| 488 ? (useNewSourceInfo | 488 ? (useNewSourceInfo |
| 489 ? new PositionSourceInformationStrategy() | 489 ? new PositionSourceInformationStrategy() |
| 490 : const StartEndSourceInformationStrategy()) | 490 : const StartEndSourceInformationStrategy()) |
| 491 : const JavaScriptSourceInformationStrategy(), | 491 : const JavaScriptSourceInformationStrategy(), |
| 492 impacts = new BackendImpacts(compiler), | 492 impacts = new BackendImpacts(compiler), |
| 493 frontend = new JSFrontendAccess(compiler), | 493 frontend = new JSFrontendAccess(compiler), |
| 494 mirrorsData = new MirrorsData(compiler), | 494 mirrorsData = new MirrorsData(compiler), |
| 495 this.compiler = compiler { | 495 this.compiler = compiler { |
| 496 helpers = new BackendHelpers(compiler.elementEnvironment, commonElements); | 496 helpers = new BackendHelpers(compiler.elementEnvironment, commonElements); |
| 497 _backendUsage = new BackendUsage(commonElements, helpers, resolution); | 497 _backendUsage = new BackendUsageImpl(commonElements, helpers, resolution); |
| 498 _checkedModeHelpers = new CheckedModeHelpers(commonElements, helpers); | 498 _checkedModeHelpers = new CheckedModeHelpers(commonElements, helpers); |
| 499 emitter = | 499 emitter = |
| 500 new CodeEmitterTask(compiler, generateSourceMap, useStartupEmitter); | 500 new CodeEmitterTask(compiler, generateSourceMap, useStartupEmitter); |
| 501 typeVariableHandler = new TypeVariableHandler(compiler); | 501 typeVariableHandler = new TypeVariableHandler(compiler); |
| 502 customElementsAnalysis = new CustomElementsAnalysis(this); | 502 customElementsAnalysis = new CustomElementsAnalysis(this); |
| 503 lookupMapAnalysis = new LookupMapAnalysis(this, reporter); | 503 lookupMapAnalysis = new LookupMapAnalysis(this, reporter); |
| 504 jsInteropAnalysis = new JsInteropAnalysis(this); | 504 jsInteropAnalysis = new JsInteropAnalysis(this); |
| 505 mirrorsAnalysis = new MirrorsAnalysis(this, compiler.resolution); | 505 mirrorsAnalysis = new MirrorsAnalysis(this, compiler.resolution); |
| 506 | 506 |
| 507 noSuchMethodRegistry = new NoSuchMethodRegistry(this); | 507 noSuchMethodRegistry = new NoSuchMethodRegistry(this); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 524 DiagnosticReporter get reporter => compiler.reporter; | 524 DiagnosticReporter get reporter => compiler.reporter; |
| 525 | 525 |
| 526 CommonElements get commonElements => compiler.commonElements; | 526 CommonElements get commonElements => compiler.commonElements; |
| 527 | 527 |
| 528 Resolution get resolution => compiler.resolution; | 528 Resolution get resolution => compiler.resolution; |
| 529 | 529 |
| 530 InterceptorData get interceptorData => _interceptorData; | 530 InterceptorData get interceptorData => _interceptorData; |
| 531 | 531 |
| 532 BackendUsage get backendUsage => _backendUsage; | 532 BackendUsage get backendUsage => _backendUsage; |
| 533 | 533 |
| 534 BackendUsageBuilder get backendUsageBuilder => _backendUsage; |
| 535 |
| 534 CheckedModeHelpers get checkedModeHelpers => _checkedModeHelpers; | 536 CheckedModeHelpers get checkedModeHelpers => _checkedModeHelpers; |
| 535 | 537 |
| 536 /// Returns constant environment for the JavaScript interpretation of the | 538 /// Returns constant environment for the JavaScript interpretation of the |
| 537 /// constants. | 539 /// constants. |
| 538 JavaScriptConstantCompiler get constants { | 540 JavaScriptConstantCompiler get constants { |
| 539 return constantCompilerTask.jsConstantCompiler; | 541 return constantCompilerTask.jsConstantCompiler; |
| 540 } | 542 } |
| 541 | 543 |
| 542 @override | 544 @override |
| 543 bool isDefaultNoSuchMethod(MethodElement element) { | 545 bool isDefaultNoSuchMethod(MethodElement element) { |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 716 interceptorData.addInterceptorsForNativeClassMembers(cls); | 718 interceptorData.addInterceptorsForNativeClassMembers(cls); |
| 717 } | 719 } |
| 718 } | 720 } |
| 719 | 721 |
| 720 void addInterceptors(ClassElement cls, WorldImpactBuilder impactBuilder, | 722 void addInterceptors(ClassElement cls, WorldImpactBuilder impactBuilder, |
| 721 {bool forResolution}) { | 723 {bool forResolution}) { |
| 722 if (forResolution) { | 724 if (forResolution) { |
| 723 cls.ensureResolved(resolution); | 725 cls.ensureResolved(resolution); |
| 724 interceptorData.addInterceptors(cls); | 726 interceptorData.addInterceptors(cls); |
| 725 } | 727 } |
| 726 backendUsage.registerBackendInstantiation(impactBuilder, cls); | 728 backendUsageBuilder.registerBackendInstantiation(impactBuilder, cls); |
| 727 } | 729 } |
| 728 | 730 |
| 729 /// Called during codegen when [constant] has been used. | 731 /// Called during codegen when [constant] has been used. |
| 730 void computeImpactForCompileTimeConstant(ConstantValue constant, | 732 void computeImpactForCompileTimeConstant(ConstantValue constant, |
| 731 WorldImpactBuilder impactBuilder, bool isForResolution) { | 733 WorldImpactBuilder impactBuilder, bool isForResolution) { |
| 732 computeImpactForCompileTimeConstantInternal( | 734 computeImpactForCompileTimeConstantInternal( |
| 733 constant, impactBuilder, isForResolution); | 735 constant, impactBuilder, isForResolution); |
| 734 | 736 |
| 735 if (!isForResolution && lookupMapAnalysis.isLookupMap(constant)) { | 737 if (!isForResolution && lookupMapAnalysis.isLookupMap(constant)) { |
| 736 // Note: internally, this registration will temporarily remove the | 738 // Note: internally, this registration will temporarily remove the |
| (...skipping 25 matching lines...) Expand all Loading... |
| 762 InterceptorConstantValue interceptor = constant; | 764 InterceptorConstantValue interceptor = constant; |
| 763 ClassElement cls = interceptor.cls; | 765 ClassElement cls = interceptor.cls; |
| 764 computeImpactForInstantiatedConstantType(cls.thisType, impactBuilder); | 766 computeImpactForInstantiatedConstantType(cls.thisType, impactBuilder); |
| 765 } else if (constant.isType) { | 767 } else if (constant.isType) { |
| 766 if (isForResolution) { | 768 if (isForResolution) { |
| 767 MethodElement helper = helpers.createRuntimeType; | 769 MethodElement helper = helpers.createRuntimeType; |
| 768 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( | 770 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
| 769 // TODO(johnniwinther): Find the right [CallStructure]. | 771 // TODO(johnniwinther): Find the right [CallStructure]. |
| 770 helper, | 772 helper, |
| 771 null)); | 773 null)); |
| 772 backendUsage.registerBackendUse(helper); | 774 backendUsageBuilder.registerBackendUse(helper); |
| 773 } | 775 } |
| 774 impactBuilder | 776 impactBuilder |
| 775 .registerTypeUse(new TypeUse.instantiation(backendClasses.typeType)); | 777 .registerTypeUse(new TypeUse.instantiation(backendClasses.typeType)); |
| 776 } | 778 } |
| 777 lookupMapAnalysis.registerConstantKey(constant); | 779 lookupMapAnalysis.registerConstantKey(constant); |
| 778 } | 780 } |
| 779 | 781 |
| 780 void computeImpactForInstantiatedConstantType( | 782 void computeImpactForInstantiatedConstantType( |
| 781 DartType type, WorldImpactBuilder impactBuilder) { | 783 DartType type, WorldImpactBuilder impactBuilder) { |
| 782 if (type is ResolutionInterfaceType) { | 784 if (type is ResolutionInterfaceType) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 813 if (!cls.typeVariables.isEmpty) { | 815 if (!cls.typeVariables.isEmpty) { |
| 814 typeVariableHandler.registerClassWithTypeVariables(cls, | 816 typeVariableHandler.registerClassWithTypeVariables(cls, |
| 815 forResolution: forResolution); | 817 forResolution: forResolution); |
| 816 } | 818 } |
| 817 | 819 |
| 818 // Register any helper that will be needed by the backend. | 820 // Register any helper that will be needed by the backend. |
| 819 if (forResolution) { | 821 if (forResolution) { |
| 820 if (cls == commonElements.intClass || | 822 if (cls == commonElements.intClass || |
| 821 cls == commonElements.doubleClass || | 823 cls == commonElements.doubleClass || |
| 822 cls == commonElements.numClass) { | 824 cls == commonElements.numClass) { |
| 823 backendUsage.registerBackendImpact(impactBuilder, impacts.numClasses); | 825 backendUsageBuilder.registerBackendImpact( |
| 826 impactBuilder, impacts.numClasses); |
| 824 } else if (cls == commonElements.listClass || | 827 } else if (cls == commonElements.listClass || |
| 825 cls == commonElements.stringClass) { | 828 cls == commonElements.stringClass) { |
| 826 backendUsage.registerBackendImpact( | 829 backendUsageBuilder.registerBackendImpact( |
| 827 impactBuilder, impacts.listOrStringClasses); | 830 impactBuilder, impacts.listOrStringClasses); |
| 828 } else if (cls == commonElements.functionClass) { | 831 } else if (cls == commonElements.functionClass) { |
| 829 backendUsage.registerBackendImpact( | 832 backendUsageBuilder.registerBackendImpact( |
| 830 impactBuilder, impacts.functionClass); | 833 impactBuilder, impacts.functionClass); |
| 831 } else if (cls == commonElements.mapClass) { | 834 } else if (cls == commonElements.mapClass) { |
| 832 backendUsage.registerBackendImpact(impactBuilder, impacts.mapClass); | 835 backendUsageBuilder.registerBackendImpact( |
| 836 impactBuilder, impacts.mapClass); |
| 833 // For map literals, the dependency between the implementation class | 837 // For map literals, the dependency between the implementation class |
| 834 // and [Map] is not visible, so we have to add it manually. | 838 // and [Map] is not visible, so we have to add it manually. |
| 835 rti.registerRtiDependency(helpers.mapLiteralClass, cls); | 839 rti.registerRtiDependency(helpers.mapLiteralClass, cls); |
| 836 } else if (cls == helpers.boundClosureClass) { | 840 } else if (cls == helpers.boundClosureClass) { |
| 837 backendUsage.registerBackendImpact( | 841 backendUsageBuilder.registerBackendImpact( |
| 838 impactBuilder, impacts.boundClosureClass); | 842 impactBuilder, impacts.boundClosureClass); |
| 839 } else if (nativeData.isNativeOrExtendsNative(cls)) { | 843 } else if (nativeData.isNativeOrExtendsNative(cls)) { |
| 840 backendUsage.registerBackendImpact( | 844 backendUsageBuilder.registerBackendImpact( |
| 841 impactBuilder, impacts.nativeOrExtendsClass); | 845 impactBuilder, impacts.nativeOrExtendsClass); |
| 842 } else if (cls == helpers.mapLiteralClass) { | 846 } else if (cls == helpers.mapLiteralClass) { |
| 843 backendUsage.registerBackendImpact( | 847 backendUsageBuilder.registerBackendImpact( |
| 844 impactBuilder, impacts.mapLiteralClass); | 848 impactBuilder, impacts.mapLiteralClass); |
| 845 } | 849 } |
| 846 } | 850 } |
| 847 if (cls == helpers.closureClass) { | 851 if (cls == helpers.closureClass) { |
| 848 backendUsage.registerBackendImpact(impactBuilder, impacts.closureClass); | 852 backendUsageBuilder.registerBackendImpact( |
| 853 impactBuilder, impacts.closureClass); |
| 849 } | 854 } |
| 850 if (cls == commonElements.stringClass || cls == helpers.jsStringClass) { | 855 if (cls == commonElements.stringClass || cls == helpers.jsStringClass) { |
| 851 addInterceptors(helpers.jsStringClass, impactBuilder, | 856 addInterceptors(helpers.jsStringClass, impactBuilder, |
| 852 forResolution: forResolution); | 857 forResolution: forResolution); |
| 853 } else if (cls == commonElements.listClass || | 858 } else if (cls == commonElements.listClass || |
| 854 cls == helpers.jsArrayClass || | 859 cls == helpers.jsArrayClass || |
| 855 cls == helpers.jsFixedArrayClass || | 860 cls == helpers.jsFixedArrayClass || |
| 856 cls == helpers.jsExtendableArrayClass || | 861 cls == helpers.jsExtendableArrayClass || |
| 857 cls == helpers.jsUnmodifiableArrayClass) { | 862 cls == helpers.jsUnmodifiableArrayClass) { |
| 858 addInterceptors(helpers.jsArrayClass, impactBuilder, | 863 addInterceptors(helpers.jsArrayClass, impactBuilder, |
| 859 forResolution: forResolution); | 864 forResolution: forResolution); |
| 860 addInterceptors(helpers.jsMutableArrayClass, impactBuilder, | 865 addInterceptors(helpers.jsMutableArrayClass, impactBuilder, |
| 861 forResolution: forResolution); | 866 forResolution: forResolution); |
| 862 addInterceptors(helpers.jsFixedArrayClass, impactBuilder, | 867 addInterceptors(helpers.jsFixedArrayClass, impactBuilder, |
| 863 forResolution: forResolution); | 868 forResolution: forResolution); |
| 864 addInterceptors(helpers.jsExtendableArrayClass, impactBuilder, | 869 addInterceptors(helpers.jsExtendableArrayClass, impactBuilder, |
| 865 forResolution: forResolution); | 870 forResolution: forResolution); |
| 866 addInterceptors(helpers.jsUnmodifiableArrayClass, impactBuilder, | 871 addInterceptors(helpers.jsUnmodifiableArrayClass, impactBuilder, |
| 867 forResolution: forResolution); | 872 forResolution: forResolution); |
| 868 if (forResolution) { | 873 if (forResolution) { |
| 869 backendUsage.registerBackendImpact(impactBuilder, impacts.listClasses); | 874 backendUsageBuilder.registerBackendImpact( |
| 875 impactBuilder, impacts.listClasses); |
| 870 } | 876 } |
| 871 } else if (cls == commonElements.intClass || cls == helpers.jsIntClass) { | 877 } else if (cls == commonElements.intClass || cls == helpers.jsIntClass) { |
| 872 addInterceptors(helpers.jsIntClass, impactBuilder, | 878 addInterceptors(helpers.jsIntClass, impactBuilder, |
| 873 forResolution: forResolution); | 879 forResolution: forResolution); |
| 874 addInterceptors(helpers.jsPositiveIntClass, impactBuilder, | 880 addInterceptors(helpers.jsPositiveIntClass, impactBuilder, |
| 875 forResolution: forResolution); | 881 forResolution: forResolution); |
| 876 addInterceptors(helpers.jsUInt32Class, impactBuilder, | 882 addInterceptors(helpers.jsUInt32Class, impactBuilder, |
| 877 forResolution: forResolution); | 883 forResolution: forResolution); |
| 878 addInterceptors(helpers.jsUInt31Class, impactBuilder, | 884 addInterceptors(helpers.jsUInt31Class, impactBuilder, |
| 879 forResolution: forResolution); | 885 forResolution: forResolution); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 912 forResolution: forResolution); | 918 forResolution: forResolution); |
| 913 } else if (cls == helpers.jsUnknownJavaScriptObjectClass) { | 919 } else if (cls == helpers.jsUnknownJavaScriptObjectClass) { |
| 914 addInterceptors(helpers.jsUnknownJavaScriptObjectClass, impactBuilder, | 920 addInterceptors(helpers.jsUnknownJavaScriptObjectClass, impactBuilder, |
| 915 forResolution: forResolution); | 921 forResolution: forResolution); |
| 916 } else if (cls == helpers.jsJavaScriptFunctionClass) { | 922 } else if (cls == helpers.jsJavaScriptFunctionClass) { |
| 917 addInterceptors(helpers.jsJavaScriptFunctionClass, impactBuilder, | 923 addInterceptors(helpers.jsJavaScriptFunctionClass, impactBuilder, |
| 918 forResolution: forResolution); | 924 forResolution: forResolution); |
| 919 } else if (nativeData.isNativeOrExtendsNative(cls)) { | 925 } else if (nativeData.isNativeOrExtendsNative(cls)) { |
| 920 addInterceptorsForNativeClassMembers(cls, forResolution: forResolution); | 926 addInterceptorsForNativeClassMembers(cls, forResolution: forResolution); |
| 921 } else if (cls == helpers.jsIndexingBehaviorInterface) { | 927 } else if (cls == helpers.jsIndexingBehaviorInterface) { |
| 922 backendUsage.registerBackendImpact( | 928 backendUsageBuilder.registerBackendImpact( |
| 923 impactBuilder, impacts.jsIndexingBehavior); | 929 impactBuilder, impacts.jsIndexingBehavior); |
| 924 } | 930 } |
| 925 | 931 |
| 926 customElementsAnalysis.registerInstantiatedClass(cls, | 932 customElementsAnalysis.registerInstantiatedClass(cls, |
| 927 forResolution: forResolution); | 933 forResolution: forResolution); |
| 928 if (!forResolution) { | 934 if (!forResolution) { |
| 929 lookupMapAnalysis.registerInstantiatedClass(cls); | 935 lookupMapAnalysis.registerInstantiatedClass(cls); |
| 930 } | 936 } |
| 931 | 937 |
| 932 return impactBuilder; | 938 return impactBuilder; |
| 933 } | 939 } |
| 934 | 940 |
| 935 void registerInstantiatedType(ResolutionInterfaceType type, | 941 void registerInstantiatedType(ResolutionInterfaceType type, |
| 936 {bool isGlobal: false}) { | 942 {bool isGlobal: false}) { |
| 937 if (isGlobal) { | 943 if (isGlobal) { |
| 938 backendUsage.registerGlobalDependency(type.element); | 944 backendUsageBuilder.registerGlobalDependency(type.element); |
| 939 } | 945 } |
| 940 lookupMapAnalysis.registerInstantiatedType(type); | 946 lookupMapAnalysis.registerInstantiatedType(type); |
| 941 } | 947 } |
| 942 | 948 |
| 943 /// Compute the [WorldImpact] for backend helper methods. | 949 /// Compute the [WorldImpact] for backend helper methods. |
| 944 WorldImpact computeHelpersImpact() { | 950 WorldImpact computeHelpersImpact() { |
| 945 assert(helpers.interceptorsLibrary != null); | 951 assert(helpers.interceptorsLibrary != null); |
| 946 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); | 952 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); |
| 947 // TODO(ngeoffray): Not enqueuing those two classes currently make | 953 // TODO(ngeoffray): Not enqueuing those two classes currently make |
| 948 // the compiler potentially crash. However, any reasonable program | 954 // the compiler potentially crash. However, any reasonable program |
| 949 // will instantiate those two classes. | 955 // will instantiate those two classes. |
| 950 addInterceptors(helpers.jsBoolClass, impactBuilder, forResolution: true); | 956 addInterceptors(helpers.jsBoolClass, impactBuilder, forResolution: true); |
| 951 addInterceptors(helpers.jsNullClass, impactBuilder, forResolution: true); | 957 addInterceptors(helpers.jsNullClass, impactBuilder, forResolution: true); |
| 952 if (compiler.options.enableTypeAssertions) { | 958 if (compiler.options.enableTypeAssertions) { |
| 953 backendUsage.registerBackendImpact( | 959 backendUsageBuilder.registerBackendImpact( |
| 954 impactBuilder, impacts.enableTypeAssertions); | 960 impactBuilder, impacts.enableTypeAssertions); |
| 955 } | 961 } |
| 956 | 962 |
| 957 if (TRACE_CALLS) { | 963 if (TRACE_CALLS) { |
| 958 backendUsage.registerBackendImpact(impactBuilder, impacts.traceHelper); | 964 backendUsageBuilder.registerBackendImpact( |
| 965 impactBuilder, impacts.traceHelper); |
| 959 } | 966 } |
| 960 backendUsage.registerBackendImpact( | 967 backendUsageBuilder.registerBackendImpact( |
| 961 impactBuilder, impacts.assertUnreachable); | 968 impactBuilder, impacts.assertUnreachable); |
| 962 _registerCheckedModeHelpers(impactBuilder); | 969 _registerCheckedModeHelpers(impactBuilder); |
| 963 return impactBuilder; | 970 return impactBuilder; |
| 964 } | 971 } |
| 965 | 972 |
| 966 void onResolutionComplete( | 973 void onResolutionComplete( |
| 967 ClosedWorld closedWorld, ClosedWorldRefiner closedWorldRefiner) { | 974 ClosedWorld closedWorld, ClosedWorldRefiner closedWorldRefiner) { |
| 968 for (Entity entity in compiler.enqueuer.resolution.processedEntities) { | 975 for (Entity entity in compiler.enqueuer.resolution.processedEntities) { |
| 969 processAnnotations(entity, closedWorldRefiner); | 976 processAnnotations(entity, closedWorldRefiner); |
| 970 } | 977 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 994 | 1001 |
| 995 WorldImpact registerClosureWithFreeTypeVariables(MethodElement closure, | 1002 WorldImpact registerClosureWithFreeTypeVariables(MethodElement closure, |
| 996 {bool forResolution}) { | 1003 {bool forResolution}) { |
| 997 if (forResolution || methodNeedsRti(closure)) { | 1004 if (forResolution || methodNeedsRti(closure)) { |
| 998 return _registerComputeSignature(); | 1005 return _registerComputeSignature(); |
| 999 } | 1006 } |
| 1000 return const WorldImpact(); | 1007 return const WorldImpact(); |
| 1001 } | 1008 } |
| 1002 | 1009 |
| 1003 WorldImpact registerBoundClosure() { | 1010 WorldImpact registerBoundClosure() { |
| 1004 return backendUsage.createImpactFor(impacts.memberClosure); | 1011 return backendUsageBuilder.createImpactFor(impacts.memberClosure); |
| 1005 } | 1012 } |
| 1006 | 1013 |
| 1007 WorldImpact registerGetOfStaticFunction() { | 1014 WorldImpact registerGetOfStaticFunction() { |
| 1008 return backendUsage.createImpactFor(impacts.staticClosure); | 1015 return backendUsageBuilder.createImpactFor(impacts.staticClosure); |
| 1009 } | 1016 } |
| 1010 | 1017 |
| 1011 WorldImpact _registerComputeSignature() { | 1018 WorldImpact _registerComputeSignature() { |
| 1012 return backendUsage.createImpactFor(impacts.computeSignature); | 1019 return backendUsageBuilder.createImpactFor(impacts.computeSignature); |
| 1013 } | 1020 } |
| 1014 | 1021 |
| 1015 /// Called to register that the `runtimeType` property has been accessed. Any | 1022 /// Called to register that the `runtimeType` property has been accessed. Any |
| 1016 /// backend specific [WorldImpact] of this is returned. | 1023 /// backend specific [WorldImpact] of this is returned. |
| 1017 WorldImpact registerRuntimeType() { | 1024 WorldImpact registerRuntimeType() { |
| 1018 return backendUsage.createImpactFor(impacts.runtimeTypeSupport); | 1025 return backendUsageBuilder.createImpactFor(impacts.runtimeTypeSupport); |
| 1019 } | 1026 } |
| 1020 | 1027 |
| 1021 /// Register a runtime type variable bound tests between [typeArgument] and | 1028 /// Register a runtime type variable bound tests between [typeArgument] and |
| 1022 /// [bound]. | 1029 /// [bound]. |
| 1023 void registerTypeVariableBoundsSubtypeCheck( | 1030 void registerTypeVariableBoundsSubtypeCheck( |
| 1024 ResolutionDartType typeArgument, ResolutionDartType bound) { | 1031 ResolutionDartType typeArgument, ResolutionDartType bound) { |
| 1025 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound); | 1032 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound); |
| 1026 } | 1033 } |
| 1027 | 1034 |
| 1028 /// Returns the [WorldImpact] of enabling deferred loading. | 1035 /// Returns the [WorldImpact] of enabling deferred loading. |
| 1029 WorldImpact computeDeferredLoadingImpact() { | 1036 WorldImpact computeDeferredLoadingImpact() { |
| 1030 return backendUsage.createImpactFor(impacts.deferredLoading); | 1037 return backendUsageBuilder.createImpactFor(impacts.deferredLoading); |
| 1031 } | 1038 } |
| 1032 | 1039 |
| 1033 /// Called to register a `noSuchMethod` implementation. | 1040 /// Called to register a `noSuchMethod` implementation. |
| 1034 void registerNoSuchMethod(MethodElement noSuchMethod) { | 1041 void registerNoSuchMethod(MethodElement noSuchMethod) { |
| 1035 noSuchMethodRegistry.registerNoSuchMethod(noSuchMethod); | 1042 noSuchMethodRegistry.registerNoSuchMethod(noSuchMethod); |
| 1036 } | 1043 } |
| 1037 | 1044 |
| 1038 /// Called when resolving a call to a foreign function. | 1045 /// Called when resolving a call to a foreign function. |
| 1039 native.NativeBehavior resolveForeignCall(Send node, Element element, | 1046 native.NativeBehavior resolveForeignCall(Send node, Element element, |
| 1040 CallStructure callStructure, ForeignResolver resolver) { | 1047 CallStructure callStructure, ForeignResolver resolver) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1063 } | 1070 } |
| 1064 } | 1071 } |
| 1065 reporter.reportErrorMessage( | 1072 reporter.reportErrorMessage( |
| 1066 node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); | 1073 node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); |
| 1067 } | 1074 } |
| 1068 // No native behavior for this call. | 1075 // No native behavior for this call. |
| 1069 return null; | 1076 return null; |
| 1070 } | 1077 } |
| 1071 | 1078 |
| 1072 WorldImpact computeNoSuchMethodImpact() { | 1079 WorldImpact computeNoSuchMethodImpact() { |
| 1073 return backendUsage.createImpactFor(impacts.noSuchMethodSupport); | 1080 return backendUsageBuilder.createImpactFor(impacts.noSuchMethodSupport); |
| 1074 } | 1081 } |
| 1075 | 1082 |
| 1076 /// Called to enable support for isolates. Any backend specific [WorldImpact] | 1083 /// Called to enable support for isolates. Any backend specific [WorldImpact] |
| 1077 /// of this is returned. | 1084 /// of this is returned. |
| 1078 WorldImpact enableIsolateSupport({bool forResolution}) { | 1085 WorldImpact enableIsolateSupport({bool forResolution}) { |
| 1079 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); | 1086 WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl(); |
| 1080 // TODO(floitsch): We should also ensure that the class IsolateMessage is | 1087 // TODO(floitsch): We should also ensure that the class IsolateMessage is |
| 1081 // instantiated. Currently, just enabling isolate support works. | 1088 // instantiated. Currently, just enabling isolate support works. |
| 1082 if (compiler.mainFunction != null) { | 1089 if (compiler.mainFunction != null) { |
| 1083 // The JavaScript backend implements [Isolate.spawn] by looking up | 1090 // The JavaScript backend implements [Isolate.spawn] by looking up |
| 1084 // top-level functions by name. So all top-level function tear-off | 1091 // top-level functions by name. So all top-level function tear-off |
| 1085 // closures have a private name field. | 1092 // closures have a private name field. |
| 1086 // | 1093 // |
| 1087 // The JavaScript backend of [Isolate.spawnUri] uses the same internal | 1094 // The JavaScript backend of [Isolate.spawnUri] uses the same internal |
| 1088 // implementation as [Isolate.spawn], and fails if it cannot look main up | 1095 // implementation as [Isolate.spawn], and fails if it cannot look main up |
| 1089 // by name. | 1096 // by name. |
| 1090 impactBuilder.registerStaticUse( | 1097 impactBuilder.registerStaticUse( |
| 1091 new StaticUse.staticTearOff(compiler.mainFunction)); | 1098 new StaticUse.staticTearOff(compiler.mainFunction)); |
| 1092 } | 1099 } |
| 1093 backendUsage.registerBackendImpact(impactBuilder, impacts.isolateSupport); | 1100 backendUsageBuilder.registerBackendImpact( |
| 1101 impactBuilder, impacts.isolateSupport); |
| 1094 if (forResolution) { | 1102 if (forResolution) { |
| 1095 backendUsage.registerBackendImpact( | 1103 backendUsageBuilder.registerBackendImpact( |
| 1096 impactBuilder, impacts.isolateSupportForResolution); | 1104 impactBuilder, impacts.isolateSupportForResolution); |
| 1097 } | 1105 } |
| 1098 return impactBuilder; | 1106 return impactBuilder; |
| 1099 } | 1107 } |
| 1100 | 1108 |
| 1101 bool classNeedsRti(ClassElement cls) { | 1109 bool classNeedsRti(ClassElement cls) { |
| 1102 if (hasRuntimeTypeSupport) return true; | 1110 if (hasRuntimeTypeSupport) return true; |
| 1103 return rti.classesNeedingRti.contains(cls.declaration); | 1111 return rti.classesNeedingRti.contains(cls.declaration); |
| 1104 } | 1112 } |
| 1105 | 1113 |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1268 return element; | 1276 return element; |
| 1269 } | 1277 } |
| 1270 | 1278 |
| 1271 void _registerCheckedModeHelpers(WorldImpactBuilder impactBuilder) { | 1279 void _registerCheckedModeHelpers(WorldImpactBuilder impactBuilder) { |
| 1272 // We register all the helpers in the resolution queue. | 1280 // We register all the helpers in the resolution queue. |
| 1273 // TODO(13155): Find a way to register fewer helpers. | 1281 // TODO(13155): Find a way to register fewer helpers. |
| 1274 List<Element> staticUses = <Element>[]; | 1282 List<Element> staticUses = <Element>[]; |
| 1275 for (CheckedModeHelper helper in CheckedModeHelpers.helpers) { | 1283 for (CheckedModeHelper helper in CheckedModeHelpers.helpers) { |
| 1276 staticUses.add(helper.getStaticUse(helpers).element); | 1284 staticUses.add(helper.getStaticUse(helpers).element); |
| 1277 } | 1285 } |
| 1278 backendUsage.registerBackendImpact( | 1286 backendUsageBuilder.registerBackendImpact( |
| 1279 impactBuilder, new BackendImpact(globalUses: staticUses)); | 1287 impactBuilder, new BackendImpact(globalUses: staticUses)); |
| 1280 } | 1288 } |
| 1281 | 1289 |
| 1282 /** | 1290 /** |
| 1283 * Returns [:true:] if the checking of [type] is performed directly on the | 1291 * Returns [:true:] if the checking of [type] is performed directly on the |
| 1284 * object and not on an interceptor. | 1292 * object and not on an interceptor. |
| 1285 */ | 1293 */ |
| 1286 bool hasDirectCheckFor(ResolutionDartType type) { | 1294 bool hasDirectCheckFor(ResolutionDartType type) { |
| 1287 Element element = type.element; | 1295 Element element = type.element; |
| 1288 return element == commonElements.stringClass || | 1296 return element == commonElements.stringClass || |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1302 // is mixed-in or in an implements clause. | 1310 // is mixed-in or in an implements clause. |
| 1303 | 1311 |
| 1304 if (!type.isRaw) return false; | 1312 if (!type.isRaw) return false; |
| 1305 ClassElement classElement = type.element; | 1313 ClassElement classElement = type.element; |
| 1306 if (interceptorData.isInterceptorClass(classElement)) return false; | 1314 if (interceptorData.isInterceptorClass(classElement)) return false; |
| 1307 return _closedWorld.hasOnlySubclasses(classElement); | 1315 return _closedWorld.hasOnlySubclasses(classElement); |
| 1308 } | 1316 } |
| 1309 | 1317 |
| 1310 WorldImpact registerUsedElement(MemberElement element, {bool forResolution}) { | 1318 WorldImpact registerUsedElement(MemberElement element, {bool forResolution}) { |
| 1311 WorldImpactBuilderImpl worldImpact = new WorldImpactBuilderImpl(); | 1319 WorldImpactBuilderImpl worldImpact = new WorldImpactBuilderImpl(); |
| 1320 backendUsageBuilder.registerUsedMember(element); |
| 1312 if (element == helpers.disableTreeShakingMarker) { | 1321 if (element == helpers.disableTreeShakingMarker) { |
| 1313 mirrorsData.isTreeShakingDisabled = true; | 1322 mirrorsData.isTreeShakingDisabled = true; |
| 1314 } else if (element == helpers.preserveNamesMarker) { | 1323 } else if (element == helpers.preserveNamesMarker) { |
| 1315 mirrorsData.mustPreserveNames = true; | 1324 mirrorsData.mustPreserveNames = true; |
| 1316 } else if (element == helpers.preserveMetadataMarker) { | 1325 } else if (element == helpers.preserveMetadataMarker) { |
| 1317 mirrorsData.mustRetainMetadata = true; | 1326 mirrorsData.mustRetainMetadata = true; |
| 1318 } else if (element == helpers.preserveUrisMarker) { | 1327 } else if (element == helpers.preserveUrisMarker) { |
| 1319 if (compiler.options.preserveUris) mustPreserveUris = true; | 1328 if (compiler.options.preserveUris) mustPreserveUris = true; |
| 1320 } else if (element == helpers.preserveLibraryNamesMarker) { | 1329 } else if (element == helpers.preserveLibraryNamesMarker) { |
| 1321 mirrorsData.mustRetainLibraryNames = true; | 1330 mirrorsData.mustRetainLibraryNames = true; |
| 1322 } else if (element == helpers.getIsolateAffinityTagMarker) { | |
| 1323 backendUsage.needToInitializeIsolateAffinityTag = true; | |
| 1324 } else if (element.isDeferredLoaderGetter) { | 1331 } else if (element.isDeferredLoaderGetter) { |
| 1325 // TODO(sigurdm): Create a function registerLoadLibraryAccess. | 1332 // TODO(sigurdm): Create a function registerLoadLibraryAccess. |
| 1326 if (!isLoadLibraryFunctionResolved) { | 1333 if (!isLoadLibraryFunctionResolved) { |
| 1327 isLoadLibraryFunctionResolved = true; | 1334 isLoadLibraryFunctionResolved = true; |
| 1328 if (forResolution) { | 1335 if (forResolution) { |
| 1329 backendUsage.registerBackendImpact(worldImpact, impacts.loadLibrary); | 1336 backendUsageBuilder.registerBackendImpact( |
| 1337 worldImpact, impacts.loadLibrary); |
| 1330 } | 1338 } |
| 1331 } | 1339 } |
| 1332 } else if (element == helpers.requiresPreambleMarker) { | 1340 } else if (element == helpers.requiresPreambleMarker) { |
| 1333 requiresPreamble = true; | 1341 requiresPreamble = true; |
| 1334 } else if (element == helpers.invokeOnMethod && forResolution) { | 1342 } else if (element == helpers.invokeOnMethod && forResolution) { |
| 1335 hasInvokeOnSupport = true; | 1343 hasInvokeOnSupport = true; |
| 1336 } | 1344 } |
| 1337 customElementsAnalysis.registerStaticUse(element, | 1345 customElementsAnalysis.registerStaticUse(element, |
| 1338 forResolution: forResolution); | 1346 forResolution: forResolution); |
| 1339 | 1347 |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1794 | 1802 |
| 1795 MethodElement helperForMissingMain() => helpers.missingMain; | 1803 MethodElement helperForMissingMain() => helpers.missingMain; |
| 1796 | 1804 |
| 1797 MethodElement helperForMainArity() => helpers.mainHasTooManyParameters; | 1805 MethodElement helperForMainArity() => helpers.mainHasTooManyParameters; |
| 1798 | 1806 |
| 1799 /// Computes the [WorldImpact] of calling [mainMethod] as the entry point. | 1807 /// Computes the [WorldImpact] of calling [mainMethod] as the entry point. |
| 1800 WorldImpact computeMainImpact(MethodElement mainMethod, | 1808 WorldImpact computeMainImpact(MethodElement mainMethod, |
| 1801 {bool forResolution}) { | 1809 {bool forResolution}) { |
| 1802 WorldImpactBuilderImpl mainImpact = new WorldImpactBuilderImpl(); | 1810 WorldImpactBuilderImpl mainImpact = new WorldImpactBuilderImpl(); |
| 1803 if (mainMethod.parameters.isNotEmpty) { | 1811 if (mainMethod.parameters.isNotEmpty) { |
| 1804 backendUsage.registerBackendImpact(mainImpact, impacts.mainWithArguments); | 1812 backendUsageBuilder.registerBackendImpact( |
| 1813 mainImpact, impacts.mainWithArguments); |
| 1805 mainImpact.registerStaticUse( | 1814 mainImpact.registerStaticUse( |
| 1806 new StaticUse.staticInvoke(mainMethod, CallStructure.TWO_ARGS)); | 1815 new StaticUse.staticInvoke(mainMethod, CallStructure.TWO_ARGS)); |
| 1807 // If the main method takes arguments, this compilation could be the | 1816 // If the main method takes arguments, this compilation could be the |
| 1808 // target of Isolate.spawnUri. Strictly speaking, that can happen also if | 1817 // target of Isolate.spawnUri. Strictly speaking, that can happen also if |
| 1809 // main takes no arguments, but in this case the spawned isolate can't | 1818 // main takes no arguments, but in this case the spawned isolate can't |
| 1810 // communicate with the spawning isolate. | 1819 // communicate with the spawning isolate. |
| 1811 mainImpact.addImpact(enableIsolateSupport(forResolution: forResolution)); | 1820 mainImpact.addImpact(enableIsolateSupport(forResolution: forResolution)); |
| 1812 } | 1821 } |
| 1813 mainImpact.registerStaticUse( | 1822 mainImpact.registerStaticUse( |
| 1814 new StaticUse.staticInvoke(mainMethod, CallStructure.NO_ARGS)); | 1823 new StaticUse.staticInvoke(mainMethod, CallStructure.NO_ARGS)); |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2012 } | 2021 } |
| 2013 } | 2022 } |
| 2014 | 2023 |
| 2015 class JavaScriptImpactTransformer extends ImpactTransformer { | 2024 class JavaScriptImpactTransformer extends ImpactTransformer { |
| 2016 final JavaScriptBackend backend; | 2025 final JavaScriptBackend backend; |
| 2017 | 2026 |
| 2018 JavaScriptImpactTransformer(this.backend); | 2027 JavaScriptImpactTransformer(this.backend); |
| 2019 | 2028 |
| 2020 BackendImpacts get impacts => backend.impacts; | 2029 BackendImpacts get impacts => backend.impacts; |
| 2021 | 2030 |
| 2022 BackendUsage get backendUsage => backend.backendUsage; | 2031 BackendUsageBuilder get backendUsage => backend.backendUsageBuilder; |
| 2023 | 2032 |
| 2024 @override | 2033 @override |
| 2025 WorldImpact transformResolutionImpact( | 2034 WorldImpact transformResolutionImpact( |
| 2026 ResolutionEnqueuer enqueuer, ResolutionImpact worldImpact) { | 2035 ResolutionEnqueuer enqueuer, ResolutionImpact worldImpact) { |
| 2027 TransformedWorldImpact transformed = | 2036 TransformedWorldImpact transformed = |
| 2028 new TransformedWorldImpact(worldImpact); | 2037 new TransformedWorldImpact(worldImpact); |
| 2029 for (Feature feature in worldImpact.features) { | 2038 for (Feature feature in worldImpact.features) { |
| 2030 switch (feature) { | 2039 switch (feature) { |
| 2031 case Feature.ABSTRACT_CLASS_INSTANTIATION: | 2040 case Feature.ABSTRACT_CLASS_INSTANTIATION: |
| 2032 backendUsage.registerBackendImpact( | 2041 backendUsage.registerBackendImpact( |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2319 if (inCheckedMode) { | 2328 if (inCheckedMode) { |
| 2320 // All helpers are added to resolution queue in enqueueHelpers. These | 2329 // All helpers are added to resolution queue in enqueueHelpers. These |
| 2321 // calls to [enqueue] with the resolution enqueuer serve as assertions | 2330 // calls to [enqueue] with the resolution enqueuer serve as assertions |
| 2322 // that the helper was in fact added. | 2331 // that the helper was in fact added. |
| 2323 // TODO(13155): Find a way to enqueue helpers lazily. | 2332 // TODO(13155): Find a way to enqueue helpers lazily. |
| 2324 CheckedModeHelper helper = backend.checkedModeHelpers | 2333 CheckedModeHelper helper = backend.checkedModeHelpers |
| 2325 .getCheckedModeHelper(type, typeCast: false); | 2334 .getCheckedModeHelper(type, typeCast: false); |
| 2326 if (helper != null) { | 2335 if (helper != null) { |
| 2327 StaticUse staticUse = helper.getStaticUse(backend.helpers); | 2336 StaticUse staticUse = helper.getStaticUse(backend.helpers); |
| 2328 transformed.registerStaticUse(staticUse); | 2337 transformed.registerStaticUse(staticUse); |
| 2329 backend.backendUsage.registerBackendUse(staticUse.element); | 2338 backendUsage.registerBackendUse(staticUse.element); |
| 2330 } | 2339 } |
| 2331 // We also need the native variant of the check (for DOM types). | 2340 // We also need the native variant of the check (for DOM types). |
| 2332 helper = backend.checkedModeHelpers | 2341 helper = backend.checkedModeHelpers |
| 2333 .getNativeCheckedModeHelper(type, typeCast: false); | 2342 .getNativeCheckedModeHelper(type, typeCast: false); |
| 2334 if (helper != null) { | 2343 if (helper != null) { |
| 2335 StaticUse staticUse = helper.getStaticUse(backend.helpers); | 2344 StaticUse staticUse = helper.getStaticUse(backend.helpers); |
| 2336 transformed.registerStaticUse(staticUse); | 2345 transformed.registerStaticUse(staticUse); |
| 2337 backend.backendUsage.registerBackendUse(staticUse.element); | 2346 backendUsage.registerBackendUse(staticUse.element); |
| 2338 } | 2347 } |
| 2339 } | 2348 } |
| 2340 if (!type.treatAsRaw || type.containsTypeVariables) { | 2349 if (!type.treatAsRaw || type.containsTypeVariables) { |
| 2341 backendUsage.registerBackendImpact(transformed, impacts.genericIsCheck); | 2350 backendUsage.registerBackendImpact(transformed, impacts.genericIsCheck); |
| 2342 } | 2351 } |
| 2343 if (type.element != null && backend.isNative(type.element)) { | 2352 if (type.element != null && backend.isNative(type.element)) { |
| 2344 // We will neeed to add the "$is" and "$as" properties on the | 2353 // We will neeed to add the "$is" and "$as" properties on the |
| 2345 // JavaScript object prototype, so we make sure | 2354 // JavaScript object prototype, so we make sure |
| 2346 // [:defineProperty:] is compiled. | 2355 // [:defineProperty:] is compiled. |
| 2347 backendUsage.registerBackendImpact(transformed, impacts.nativeTypeCheck); | 2356 backendUsage.registerBackendImpact(transformed, impacts.nativeTypeCheck); |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2564 } | 2573 } |
| 2565 | 2574 |
| 2566 @override | 2575 @override |
| 2567 FieldEntity get symbolField => helpers.symbolImplementationField; | 2576 FieldEntity get symbolField => helpers.symbolImplementationField; |
| 2568 | 2577 |
| 2569 @override | 2578 @override |
| 2570 InterfaceType get symbolType { | 2579 InterfaceType get symbolType { |
| 2571 return _env.getRawType(helpers.symbolImplementationClass); | 2580 return _env.getRawType(helpers.symbolImplementationClass); |
| 2572 } | 2581 } |
| 2573 } | 2582 } |
| OLD | NEW |