| 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 '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../common/backend_api.dart' | 8 import '../common/backend_api.dart' |
| 9 show ForeignResolver, NativeRegistry, ImpactTransformer; | 9 show ForeignResolver, NativeRegistry, ImpactTransformer; |
| 10 import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem; | 10 import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem; |
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 | 434 |
| 435 /// Interface for serialization of backend specific data. | 435 /// Interface for serialization of backend specific data. |
| 436 JavaScriptBackendSerialization serialization; | 436 JavaScriptBackendSerialization serialization; |
| 437 | 437 |
| 438 NativeDataBuilderImpl _nativeDataBuilder; | 438 NativeDataBuilderImpl _nativeDataBuilder; |
| 439 final NativeBasicDataBuilderImpl _nativeBasicDataBuilder = | 439 final NativeBasicDataBuilderImpl _nativeBasicDataBuilder = |
| 440 new NativeBasicDataBuilderImpl(); | 440 new NativeBasicDataBuilderImpl(); |
| 441 NativeBasicDataImpl _nativeBasicData; | 441 NativeBasicDataImpl _nativeBasicData; |
| 442 NativeDataBuilder get nativeDataBuilder => _nativeDataBuilder; | 442 NativeDataBuilder get nativeDataBuilder => _nativeDataBuilder; |
| 443 final NativeDataResolver _nativeDataResolver; | 443 final NativeDataResolver _nativeDataResolver; |
| 444 InterceptorDataBuilder _interceptorDataBuilder; | |
| 445 InterceptorData _interceptorData; | |
| 446 OneShotInterceptorData _oneShotInterceptorData; | 444 OneShotInterceptorData _oneShotInterceptorData; |
| 447 BackendUsage _backendUsage; | 445 BackendUsage _backendUsage; |
| 448 BackendUsageBuilder _backendUsageBuilder; | 446 BackendUsageBuilder _backendUsageBuilder; |
| 449 MirrorsDataImpl _mirrorsData; | 447 MirrorsDataImpl _mirrorsData; |
| 450 CheckedModeHelpers _checkedModeHelpers; | 448 CheckedModeHelpers _checkedModeHelpers; |
| 451 | 449 |
| 452 final SuperMemberData superMemberData = new SuperMemberData(); | 450 final SuperMemberData superMemberData = new SuperMemberData(); |
| 453 | 451 |
| 454 native.NativeResolutionEnqueuer _nativeResolutionEnqueuer; | 452 native.NativeResolutionEnqueuer _nativeResolutionEnqueuer; |
| 455 native.NativeCodegenEnqueuer _nativeCodegenEnqueuer; | 453 native.NativeCodegenEnqueuer _nativeCodegenEnqueuer; |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 return _mirrorsCodegenAnalysis; | 593 return _mirrorsCodegenAnalysis; |
| 596 } | 594 } |
| 597 | 595 |
| 598 /// Codegen support for tree-shaking entries of `LookupMap`. | 596 /// Codegen support for tree-shaking entries of `LookupMap`. |
| 599 LookupMapAnalysis get lookupMapAnalysis { | 597 LookupMapAnalysis get lookupMapAnalysis { |
| 600 assert(invariant(NO_LOCATION_SPANNABLE, _lookupMapAnalysis != null, | 598 assert(invariant(NO_LOCATION_SPANNABLE, _lookupMapAnalysis != null, |
| 601 message: "LookupMapAnalysis has not been created yet.")); | 599 message: "LookupMapAnalysis has not been created yet.")); |
| 602 return _lookupMapAnalysis; | 600 return _lookupMapAnalysis; |
| 603 } | 601 } |
| 604 | 602 |
| 605 InterceptorData get interceptorData { | |
| 606 assert(invariant(NO_LOCATION_SPANNABLE, _interceptorData != null, | |
| 607 message: "InterceptorData has not been computed yet.")); | |
| 608 return _interceptorData; | |
| 609 } | |
| 610 | |
| 611 InterceptorDataBuilder get interceptorDataBuilder { | |
| 612 assert(invariant(NO_LOCATION_SPANNABLE, _interceptorData == null, | |
| 613 message: "InterceptorData has already been computed.")); | |
| 614 return _interceptorDataBuilder; | |
| 615 } | |
| 616 | |
| 617 OneShotInterceptorData get oneShotInterceptorData { | 603 OneShotInterceptorData get oneShotInterceptorData { |
| 618 assert(invariant(NO_LOCATION_SPANNABLE, _oneShotInterceptorData != null, | 604 assert(invariant(NO_LOCATION_SPANNABLE, _oneShotInterceptorData != null, |
| 619 message: "OneShotInterceptorData has not been prepared yet.")); | 605 message: "OneShotInterceptorData has not been prepared yet.")); |
| 620 return _oneShotInterceptorData; | 606 return _oneShotInterceptorData; |
| 621 } | 607 } |
| 622 | 608 |
| 623 BackendUsage get backendUsage { | 609 BackendUsage get backendUsage { |
| 624 assert(invariant(NO_LOCATION_SPANNABLE, _backendUsage != null, | 610 assert(invariant(NO_LOCATION_SPANNABLE, _backendUsage != null, |
| 625 message: "BackendUsage has not been computed yet.")); | 611 message: "BackendUsage has not been computed yet.")); |
| 626 return _backendUsage; | 612 return _backendUsage; |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 770 commonElements.jsInterceptorClass); | 756 commonElements.jsInterceptorClass); |
| 771 // The null-interceptor must also implement *all* methods. | 757 // The null-interceptor must also implement *all* methods. |
| 772 validateInterceptorImplementsAllObjectMethods(commonElements.jsNullClass); | 758 validateInterceptorImplementsAllObjectMethods(commonElements.jsNullClass); |
| 773 } | 759 } |
| 774 | 760 |
| 775 /// Called when the resolution queue has been closed. | 761 /// Called when the resolution queue has been closed. |
| 776 void onResolutionEnd() { | 762 void onResolutionEnd() { |
| 777 compiler.frontEndStrategy.annotationProcesser | 763 compiler.frontEndStrategy.annotationProcesser |
| 778 .processJsInteropAnnotations(nativeBasicData, nativeDataBuilder); | 764 .processJsInteropAnnotations(nativeBasicData, nativeDataBuilder); |
| 779 _backendUsage = backendUsageBuilder.close(); | 765 _backendUsage = backendUsageBuilder.close(); |
| 780 _interceptorData = interceptorDataBuilder.onResolutionComplete(); | |
| 781 } | 766 } |
| 782 | 767 |
| 783 /// Called when the closed world from resolution has been computed. | 768 /// Called when the closed world from resolution has been computed. |
| 784 void onResolutionClosedWorld( | 769 void onResolutionClosedWorld( |
| 785 ClosedWorld closedWorld, ClosedWorldRefiner closedWorldRefiner) { | 770 ClosedWorld closedWorld, ClosedWorldRefiner closedWorldRefiner) { |
| 786 for (MemberEntity entity | 771 for (MemberEntity entity |
| 787 in compiler.enqueuer.resolution.processedEntities) { | 772 in compiler.enqueuer.resolution.processedEntities) { |
| 788 processAnnotations(entity, closedWorldRefiner); | 773 processAnnotations(entity, closedWorldRefiner); |
| 789 } | 774 } |
| 790 mirrorsDataBuilder.computeMembersNeededForReflection( | 775 mirrorsDataBuilder.computeMembersNeededForReflection( |
| 791 compiler.enqueuer.resolution.worldBuilder, closedWorld); | 776 compiler.enqueuer.resolution.worldBuilder, closedWorld); |
| 792 _rtiNeed = rtiNeedBuilder.computeRuntimeTypesNeed( | 777 _rtiNeed = rtiNeedBuilder.computeRuntimeTypesNeed( |
| 793 compiler.enqueuer.resolution.worldBuilder, | 778 compiler.enqueuer.resolution.worldBuilder, |
| 794 closedWorld, | 779 closedWorld, |
| 795 compiler.types, | 780 compiler.types, |
| 796 commonElements, | 781 commonElements, |
| 797 _backendUsage, | 782 _backendUsage, |
| 798 enableTypeAssertions: compiler.options.enableTypeAssertions); | 783 enableTypeAssertions: compiler.options.enableTypeAssertions); |
| 799 _oneShotInterceptorData = | |
| 800 new OneShotInterceptorData(interceptorData, commonElements); | |
| 801 mirrorsResolutionAnalysis.onResolutionComplete(); | 784 mirrorsResolutionAnalysis.onResolutionComplete(); |
| 802 } | 785 } |
| 803 | 786 |
| 804 void onTypeInferenceComplete(GlobalTypeInferenceResults results) { | 787 void onTypeInferenceComplete(GlobalTypeInferenceResults results) { |
| 805 noSuchMethodRegistry.onTypeInferenceComplete(results); | 788 noSuchMethodRegistry.onTypeInferenceComplete(results); |
| 806 } | 789 } |
| 807 | 790 |
| 808 /// Called when resolving a call to a foreign function. | 791 /// Called when resolving a call to a foreign function. |
| 809 native.NativeBehavior resolveForeignCall(Send node, Element element, | 792 native.NativeBehavior resolveForeignCall(Send node, Element element, |
| 810 CallStructure callStructure, ForeignResolver resolver) { | 793 CallStructure callStructure, ForeignResolver resolver) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 855 compiler.options, | 838 compiler.options, |
| 856 compiler.elementEnvironment, | 839 compiler.elementEnvironment, |
| 857 commonElements, | 840 commonElements, |
| 858 impacts, | 841 impacts, |
| 859 nativeBasicData, | 842 nativeBasicData, |
| 860 _nativeResolutionEnqueuer, | 843 _nativeResolutionEnqueuer, |
| 861 backendUsageBuilder, | 844 backendUsageBuilder, |
| 862 mirrorsDataBuilder, | 845 mirrorsDataBuilder, |
| 863 customElementsResolutionAnalysis, | 846 customElementsResolutionAnalysis, |
| 864 rtiNeedBuilder); | 847 rtiNeedBuilder); |
| 865 _interceptorDataBuilder = new InterceptorDataBuilderImpl( | 848 InterceptorDataBuilder interceptorDataBuilder = |
| 866 nativeBasicData, compiler.elementEnvironment, commonElements); | 849 new InterceptorDataBuilderImpl( |
| 850 nativeBasicData, compiler.elementEnvironment, commonElements); |
| 867 return new ResolutionEnqueuer( | 851 return new ResolutionEnqueuer( |
| 868 task, | 852 task, |
| 869 compiler.options, | 853 compiler.options, |
| 870 compiler.reporter, | 854 compiler.reporter, |
| 871 compiler.options.analyzeOnly && compiler.options.analyzeMain | 855 compiler.options.analyzeOnly && compiler.options.analyzeMain |
| 872 ? const DirectEnqueuerStrategy() | 856 ? const DirectEnqueuerStrategy() |
| 873 : const TreeShakingEnqueuerStrategy(), | 857 : const TreeShakingEnqueuerStrategy(), |
| 874 new ResolutionEnqueuerListener( | 858 new ResolutionEnqueuerListener( |
| 875 compiler.options, | 859 compiler.options, |
| 876 compiler.elementEnvironment, | 860 compiler.elementEnvironment, |
| 877 commonElements, | 861 commonElements, |
| 878 impacts, | 862 impacts, |
| 879 nativeBasicData, | 863 nativeBasicData, |
| 880 interceptorDataBuilder, | 864 interceptorDataBuilder, |
| 881 backendUsageBuilder, | 865 backendUsageBuilder, |
| 882 rtiNeedBuilder, | 866 rtiNeedBuilder, |
| 883 mirrorsDataBuilder, | 867 mirrorsDataBuilder, |
| 884 noSuchMethodRegistry, | 868 noSuchMethodRegistry, |
| 885 customElementsResolutionAnalysis, | 869 customElementsResolutionAnalysis, |
| 886 lookupMapResolutionAnalysis, | 870 lookupMapResolutionAnalysis, |
| 887 mirrorsResolutionAnalysis, | 871 mirrorsResolutionAnalysis, |
| 888 typeVariableResolutionAnalysis, | 872 typeVariableResolutionAnalysis, |
| 889 _nativeResolutionEnqueuer, | 873 _nativeResolutionEnqueuer, |
| 890 compiler.deferredLoadTask, | 874 compiler.deferredLoadTask, |
| 891 kernelTask), | 875 kernelTask), |
| 892 compiler.frontEndStrategy.createResolutionWorldBuilder( | 876 compiler.frontEndStrategy.createResolutionWorldBuilder( |
| 893 nativeBasicData, _nativeDataBuilder, const OpenWorldStrategy()), | 877 nativeBasicData, |
| 878 _nativeDataBuilder, |
| 879 interceptorDataBuilder, |
| 880 const OpenWorldStrategy()), |
| 894 compiler.frontEndStrategy | 881 compiler.frontEndStrategy |
| 895 .createResolutionWorkItemBuilder(impactTransformer)); | 882 .createResolutionWorkItemBuilder(impactTransformer)); |
| 896 } | 883 } |
| 897 | 884 |
| 898 /// Creates an [Enqueuer] for code generation specific to this backend. | 885 /// Creates an [Enqueuer] for code generation specific to this backend. |
| 899 CodegenEnqueuer createCodegenEnqueuer( | 886 CodegenEnqueuer createCodegenEnqueuer( |
| 900 CompilerTask task, Compiler compiler, ClosedWorld closedWorld) { | 887 CompilerTask task, Compiler compiler, ClosedWorld closedWorld) { |
| 901 _typeVariableCodegenAnalysis = new TypeVariableCodegenAnalysis( | 888 _typeVariableCodegenAnalysis = new TypeVariableCodegenAnalysis( |
| 902 compiler.elementEnvironment, this, commonElements, mirrorsData); | 889 compiler.elementEnvironment, this, commonElements, mirrorsData); |
| 903 _lookupMapAnalysis = new LookupMapAnalysis( | 890 _lookupMapAnalysis = new LookupMapAnalysis( |
| (...skipping 12 matching lines...) Expand all Loading... |
| 916 commonElements, | 903 commonElements, |
| 917 emitter, | 904 emitter, |
| 918 _nativeResolutionEnqueuer, | 905 _nativeResolutionEnqueuer, |
| 919 closedWorld.nativeData); | 906 closedWorld.nativeData); |
| 920 return new CodegenEnqueuer( | 907 return new CodegenEnqueuer( |
| 921 task, | 908 task, |
| 922 compiler.options, | 909 compiler.options, |
| 923 const TreeShakingEnqueuerStrategy(), | 910 const TreeShakingEnqueuerStrategy(), |
| 924 new CodegenWorldBuilderImpl( | 911 new CodegenWorldBuilderImpl( |
| 925 nativeBasicData, closedWorld, constants, const TypeMaskStrategy()), | 912 nativeBasicData, closedWorld, constants, const TypeMaskStrategy()), |
| 926 new CodegenWorkItemBuilder(this, compiler.options), | 913 new CodegenWorkItemBuilder(this, closedWorld, compiler.options), |
| 927 new CodegenEnqueuerListener( | 914 new CodegenEnqueuerListener( |
| 928 compiler.elementEnvironment, | 915 compiler.elementEnvironment, |
| 929 commonElements, | 916 commonElements, |
| 930 impacts, | 917 impacts, |
| 931 backendUsage, | 918 backendUsage, |
| 932 rtiNeed, | 919 rtiNeed, |
| 933 customElementsCodegenAnalysis, | 920 customElementsCodegenAnalysis, |
| 934 typeVariableCodegenAnalysis, | 921 typeVariableCodegenAnalysis, |
| 935 lookupMapAnalysis, | 922 lookupMapAnalysis, |
| 936 mirrorsCodegenAnalysis, | 923 mirrorsCodegenAnalysis, |
| 937 nativeCodegenEnqueuer)); | 924 nativeCodegenEnqueuer)); |
| 938 } | 925 } |
| 939 | 926 |
| 940 WorldImpact codegen(CodegenWorkItem work) { | 927 WorldImpact codegen(CodegenWorkItem work, ClosedWorld closedWorld) { |
| 941 MemberElement element = work.element; | 928 MemberElement element = work.element; |
| 942 if (compiler.elementHasCompileTimeError(element)) { | 929 if (compiler.elementHasCompileTimeError(element)) { |
| 943 DiagnosticMessage message = | 930 DiagnosticMessage message = |
| 944 // If there's more than one error, the first is probably most | 931 // If there's more than one error, the first is probably most |
| 945 // informative, as the following errors may be side-effects of the | 932 // informative, as the following errors may be side-effects of the |
| 946 // first error. | 933 // first error. |
| 947 compiler.elementsWithCompileTimeErrors[element].first; | 934 compiler.elementsWithCompileTimeErrors[element].first; |
| 948 String messageText = message.message.computeMessage(); | 935 String messageText = message.message.computeMessage(); |
| 949 jsAst.LiteralString messageLiteral = | 936 jsAst.LiteralString messageLiteral = |
| 950 js.escapedString("Compile time error in $element: $messageText"); | 937 js.escapedString("Compile time error in $element: $messageText"); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 988 } else { | 975 } else { |
| 989 // If the constant-handler was not able to produce a result we have to | 976 // If the constant-handler was not able to produce a result we have to |
| 990 // go through the builder (below) to generate the lazy initializer for | 977 // go through the builder (below) to generate the lazy initializer for |
| 991 // the static variable. | 978 // the static variable. |
| 992 // We also need to register the use of the cyclic-error helper. | 979 // We also need to register the use of the cyclic-error helper. |
| 993 work.registry.worldImpact.registerStaticUse(new StaticUse.staticInvoke( | 980 work.registry.worldImpact.registerStaticUse(new StaticUse.staticInvoke( |
| 994 commonElements.cyclicThrowHelper, CallStructure.ONE_ARG)); | 981 commonElements.cyclicThrowHelper, CallStructure.ONE_ARG)); |
| 995 } | 982 } |
| 996 } | 983 } |
| 997 | 984 |
| 998 jsAst.Fun function = functionCompiler.compile(work, _closedWorld); | 985 jsAst.Fun function = functionCompiler.compile(work, closedWorld); |
| 999 if (function.sourceInformation == null) { | 986 if (function.sourceInformation == null) { |
| 1000 function = function.withSourceInformation( | 987 function = function.withSourceInformation( |
| 1001 sourceInformationStrategy.buildSourceMappedMarker()); | 988 sourceInformationStrategy.buildSourceMappedMarker()); |
| 1002 } | 989 } |
| 1003 generatedCode[element] = function; | 990 generatedCode[element] = function; |
| 1004 WorldImpact worldImpact = _codegenImpactTransformer | 991 WorldImpact worldImpact = _codegenImpactTransformer |
| 1005 .transformCodegenImpact(work.registry.worldImpact); | 992 .transformCodegenImpact(work.registry.worldImpact); |
| 1006 compiler.dumpInfoTask.registerImpact(element, worldImpact); | 993 compiler.dumpInfoTask.registerImpact(element, worldImpact); |
| 1007 return worldImpact; | 994 return worldImpact; |
| 1008 } | 995 } |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1119 inlineCache.markAsNonInlinable(commonElements.getInterceptorMethod, | 1106 inlineCache.markAsNonInlinable(commonElements.getInterceptorMethod, |
| 1120 insideLoop: true); | 1107 insideLoop: true); |
| 1121 | 1108 |
| 1122 specialOperatorEqClasses | 1109 specialOperatorEqClasses |
| 1123 ..add(commonElements.objectClass) | 1110 ..add(commonElements.objectClass) |
| 1124 ..add(commonElements.jsInterceptorClass) | 1111 ..add(commonElements.jsInterceptorClass) |
| 1125 ..add(commonElements.jsNullClass); | 1112 ..add(commonElements.jsNullClass); |
| 1126 } | 1113 } |
| 1127 } | 1114 } |
| 1128 | 1115 |
| 1129 // TODO(johnniwinther): Create a CodegenPhase object for the backend to hold | |
| 1130 // data only available during code generation. | |
| 1131 ClosedWorld _closedWorldCache; | |
| 1132 ClosedWorld get _closedWorld { | |
| 1133 assert(invariant(NO_LOCATION_SPANNABLE, _closedWorldCache != null, | |
| 1134 message: "ClosedWorld has not be set yet.")); | |
| 1135 return _closedWorldCache; | |
| 1136 } | |
| 1137 | |
| 1138 void set _closedWorld(ClosedWorld value) { | |
| 1139 _closedWorldCache = value; | |
| 1140 } | |
| 1141 | |
| 1142 /// Called when the compiler starts running the codegen enqueuer. The | 1116 /// Called when the compiler starts running the codegen enqueuer. The |
| 1143 /// [WorldImpact] of enabled backend features is returned. | 1117 /// [WorldImpact] of enabled backend features is returned. |
| 1144 WorldImpact onCodegenStart( | 1118 WorldImpact onCodegenStart( |
| 1145 ClosedWorld closedWorld, CodegenWorldBuilder codegenWorldBuilder) { | 1119 ClosedWorld closedWorld, CodegenWorldBuilder codegenWorldBuilder) { |
| 1146 _closedWorld = closedWorld; | 1120 _oneShotInterceptorData = |
| 1121 new OneShotInterceptorData(closedWorld.interceptorData, commonElements); |
| 1147 _namer = determineNamer(closedWorld, codegenWorldBuilder); | 1122 _namer = determineNamer(closedWorld, codegenWorldBuilder); |
| 1148 tracer = new Tracer(closedWorld, namer, compiler); | 1123 tracer = new Tracer(closedWorld, namer, compiler); |
| 1149 _rtiEncoder = | 1124 _rtiEncoder = |
| 1150 _namer.rtiEncoder = new _RuntimeTypesEncoder(namer, commonElements); | 1125 _namer.rtiEncoder = new _RuntimeTypesEncoder(namer, commonElements); |
| 1151 emitter.createEmitter(namer, closedWorld, codegenWorldBuilder); | 1126 emitter.createEmitter(namer, closedWorld, codegenWorldBuilder); |
| 1152 _codegenImpactTransformer = new CodegenImpactTransformer( | 1127 _codegenImpactTransformer = new CodegenImpactTransformer( |
| 1153 compiler.options, | 1128 compiler.options, |
| 1154 compiler.elementEnvironment, | 1129 compiler.elementEnvironment, |
| 1155 commonElements, | 1130 commonElements, |
| 1156 impacts, | 1131 impacts, |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1472 | 1447 |
| 1473 bool canUseAliasedSuperMember(MemberEntity member, Selector selector) { | 1448 bool canUseAliasedSuperMember(MemberEntity member, Selector selector) { |
| 1474 return !selector.isGetter; | 1449 return !selector.isGetter; |
| 1475 } | 1450 } |
| 1476 | 1451 |
| 1477 /// Returns `true` if [member] is called from a subclass via `super`. | 1452 /// Returns `true` if [member] is called from a subclass via `super`. |
| 1478 bool isAliasedSuperMember(MemberEntity member) { | 1453 bool isAliasedSuperMember(MemberEntity member) { |
| 1479 return _aliasedSuperMembers.contains(member); | 1454 return _aliasedSuperMembers.contains(member); |
| 1480 } | 1455 } |
| 1481 } | 1456 } |
| OLD | NEW |