Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(153)

Side by Side Diff: pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart

Issue 2908153003: It's alive! (Closed)
Patch Set: Updated cf. comments Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 dart2js.js_emitter.program_builder; 5 library dart2js.js_emitter.program_builder;
6 6
7 import 'dart:io'; 7 import 'dart:io';
8 import 'dart:convert' show JSON; 8 import 'dart:convert' show JSON;
9 9
10 import '../../closure.dart' show ClosureTask, ClosureFieldElement; 10 import '../../closure.dart' show ClosureTask, ClosureFieldElement;
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 this._namer, 146 this._namer,
147 this._task, 147 this._task,
148 this._closedWorld, 148 this._closedWorld,
149 Set<ClassEntity> rtiNeededClasses, 149 Set<ClassEntity> rtiNeededClasses,
150 this._mainFunction, 150 this._mainFunction,
151 {bool isMockCompilation}) 151 {bool isMockCompilation})
152 : this._isMockCompilation = isMockCompilation, 152 : this._isMockCompilation = isMockCompilation,
153 this.collector = new Collector( 153 this.collector = new Collector(
154 _options, 154 _options,
155 _commonElements, 155 _commonElements,
156 _elementEnvironment,
156 _deferredLoadTask, 157 _deferredLoadTask,
157 _worldBuilder, 158 _worldBuilder,
158 _namer, 159 _namer,
159 _task.emitter, 160 _task.emitter,
160 _constantHandler, 161 _constantHandler,
161 _nativeData, 162 _nativeData,
162 _interceptorData, 163 _interceptorData,
163 _oneShotInterceptorData, 164 _oneShotInterceptorData,
164 _mirrorsData, 165 _mirrorsData,
165 _closedWorld, 166 _closedWorld,
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 } 629 }
629 } 630 }
630 }); 631 });
631 } 632 }
632 } 633 }
633 }); 634 });
634 } 635 }
635 636
636 // Note that a library-element may have multiple [Library]s, if it is split 637 // Note that a library-element may have multiple [Library]s, if it is split
637 // into multiple output units. 638 // into multiple output units.
638 Library _buildLibrary(LibraryElement library, List<ClassEntity> classElements, 639 Library _buildLibrary(LibraryEntity library, List<ClassEntity> classElements,
639 List<MemberEntity> memberElements) { 640 List<MemberEntity> memberElements) {
640 String uri = library.canonicalUri.toString(); 641 String uri = library.canonicalUri.toString();
641 642
642 List<StaticMethod> statics = memberElements 643 List<StaticMethod> statics = memberElements
643 .where((e) => e is MethodElement) 644 .where((e) => !e.isField)
644 .map(_buildStaticMethod) 645 .map(_buildStaticMethod)
645 .toList(); 646 .toList();
646 647
647 if (library == _commonElements.interceptorsLibrary) { 648 if (library == _commonElements.interceptorsLibrary) {
648 statics.addAll(_generateGetInterceptorMethods()); 649 statics.addAll(_generateGetInterceptorMethods());
649 statics.addAll(_generateOneShotInterceptors()); 650 statics.addAll(_generateOneShotInterceptors());
650 } 651 }
651 652
652 List<Class> classes = classElements 653 List<Class> classes = classElements
653 .map((ClassElement classElement) => _classes[classElement]) 654 .map((ClassEntity classElement) => _classes[classElement])
654 .where((Class cls) => 655 .where((Class cls) =>
655 !cls.isNative || !_unneededNativeClasses.contains(cls)) 656 !cls.isNative || !_unneededNativeClasses.contains(cls))
656 .toList(growable: false); 657 .toList(growable: false);
657 658
658 bool visitStatics = true; 659 bool visitStatics = true;
659 List<Field> staticFieldsForReflection = 660 List<Field> staticFieldsForReflection =
660 _buildFields(library, visitStatics: visitStatics); 661 _buildFields(library: library, visitStatics: visitStatics);
661 662
662 return new Library( 663 return new Library(
663 library, uri, statics, classes, staticFieldsForReflection); 664 library, uri, statics, classes, staticFieldsForReflection);
664 } 665 }
665 666
666 bool _isSoftDeferred(ClassElement element) { 667 bool _isSoftDeferred(ClassElement element) {
667 return _notSoftDeferred != null && !_notSoftDeferred.contains(element); 668 return _notSoftDeferred != null && !_notSoftDeferred.contains(element);
668 } 669 }
669 670
670 Class _buildClass(ClassElement element) { 671 Class _buildClass(ClassElement element) {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 ClassElement implementation = element.implementation; 745 ClassElement implementation = element.implementation;
745 746
746 // MixinApplications run through the members of their mixin. Here, we are 747 // MixinApplications run through the members of their mixin. Here, we are
747 // only interested in direct members. 748 // only interested in direct members.
748 if (!onlyForRti && !element.isMixinApplication) { 749 if (!onlyForRti && !element.isMixinApplication) {
749 implementation.forEachMember(visitMember, includeBackendMembers: true); 750 implementation.forEachMember(visitMember, includeBackendMembers: true);
750 } 751 }
751 bool isInterceptedClass = _interceptorData.isInterceptedClass(element); 752 bool isInterceptedClass = _interceptorData.isInterceptedClass(element);
752 List<Field> instanceFields = onlyForRti 753 List<Field> instanceFields = onlyForRti
753 ? const <Field>[] 754 ? const <Field>[]
754 : _buildFields(element, 755 : _buildFields(
755 visitStatics: false, isHolderInterceptedClass: isInterceptedClass); 756 cls: element,
757 visitStatics: false,
758 isHolderInterceptedClass: isInterceptedClass);
756 List<Field> staticFieldsForReflection = onlyForRti 759 List<Field> staticFieldsForReflection = onlyForRti
757 ? const <Field>[] 760 ? const <Field>[]
758 : _buildFields(element, 761 : _buildFields(
759 visitStatics: true, isHolderInterceptedClass: isInterceptedClass); 762 cls: element,
763 visitStatics: true,
764 isHolderInterceptedClass: isInterceptedClass);
760 765
761 TypeTestProperties typeTests = runtimeTypeGenerator.generateIsTests(element, 766 TypeTestProperties typeTests = runtimeTypeGenerator.generateIsTests(element,
762 storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata); 767 storeFunctionTypeInMetadata: _storeFunctionTypesInMetadata);
763 768
764 List<StubMethod> checkedSetters = <StubMethod>[]; 769 List<StubMethod> checkedSetters = <StubMethod>[];
765 List<StubMethod> isChecks = <StubMethod>[]; 770 List<StubMethod> isChecks = <StubMethod>[];
766 if (_nativeData.isJsInteropClass(element)) { 771 if (_nativeData.isJsInteropClass(element)) {
767 typeTests.properties.forEach((js.Name name, js.Node code) { 772 typeTests.properties.forEach((js.Name name, js.Node code) {
768 _classes[_commonElements.jsInterceptorClass] 773 _classes[_commonElements.jsInterceptorClass]
769 .isChecks 774 .isChecks
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
830 hasRtiField: hasRtiField, 835 hasRtiField: hasRtiField,
831 onlyForRti: onlyForRti, 836 onlyForRti: onlyForRti,
832 isNative: _nativeData.isNativeClass(element), 837 isNative: _nativeData.isNativeClass(element),
833 isClosureBaseClass: isClosureBaseClass, 838 isClosureBaseClass: isClosureBaseClass,
834 isSoftDeferred: _isSoftDeferred(element)); 839 isSoftDeferred: _isSoftDeferred(element));
835 } 840 }
836 _classes[element] = result; 841 _classes[element] = result;
837 return result; 842 return result;
838 } 843 }
839 844
840 bool _methodNeedsStubs(FunctionElement method) { 845 bool _methodNeedsStubs(FunctionEntity method) {
841 return !method.functionSignature.optionalParameters.isEmpty; 846 return method.parameterStructure.optionalParameters != 0;
842 } 847 }
843 848
844 bool _methodCanBeReflected(MethodElement method) { 849 bool _methodCanBeReflected(FunctionEntity method) {
845 return _mirrorsData.isMemberAccessibleByReflection(method); 850 return _mirrorsData.isMemberAccessibleByReflection(method);
846 } 851 }
847 852
848 bool _methodCanBeApplied(FunctionElement method) { 853 bool _methodCanBeApplied(FunctionEntity method) {
849 return _backendUsage.isFunctionApplyUsed && 854 return _backendUsage.isFunctionApplyUsed &&
850 _closedWorld.getMightBePassedToApply(method); 855 _closedWorld.getMightBePassedToApply(method);
851 } 856 }
852 857
853 /* Map | List */ _computeParameterDefaultValues(FunctionSignature signature) { 858 /* Map | List */ _computeParameterDefaultValues(FunctionSignature signature) {
854 var /* Map | List */ optionalParameterDefaultValues; 859 var /* Map | List */ optionalParameterDefaultValues;
855 if (signature.optionalParametersAreNamed) { 860 if (signature.optionalParametersAreNamed) {
856 optionalParameterDefaultValues = new Map<String, ConstantValue>(); 861 optionalParameterDefaultValues = new Map<String, ConstantValue>();
857 signature.forEachOptionalParameter((ParameterElement parameter) { 862 signature.forEachOptionalParameter((ParameterElement parameter) {
858 ConstantValue def = 863 ConstantValue def =
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 isClosureCallMethod: isClosureCallMethod, 957 isClosureCallMethod: isClosureCallMethod,
953 aliasName: aliasName, 958 aliasName: aliasName,
954 canBeApplied: canBeApplied, 959 canBeApplied: canBeApplied,
955 canBeReflected: canBeReflected, 960 canBeReflected: canBeReflected,
956 requiredParameterCount: requiredParameterCount, 961 requiredParameterCount: requiredParameterCount,
957 optionalParameterDefaultValues: optionalParameterDefaultValues, 962 optionalParameterDefaultValues: optionalParameterDefaultValues,
958 functionType: functionType); 963 functionType: functionType);
959 } 964 }
960 965
961 js.Expression _generateFunctionType( 966 js.Expression _generateFunctionType(
962 ResolutionDartType type, OutputUnit outputUnit) { 967 ResolutionFunctionType type, OutputUnit outputUnit) {
963 if (type.containsTypeVariables) { 968 if (type.containsTypeVariables) {
964 js.Expression thisAccess = js.js(r'this.$receiver'); 969 js.Expression thisAccess = js.js(r'this.$receiver');
965 return _rtiEncoder.getSignatureEncoding(_task.emitter, type, thisAccess); 970 return _rtiEncoder.getSignatureEncoding(_task.emitter, type, thisAccess);
966 } else { 971 } else {
967 return _task.metadataCollector.reifyTypeForOutputUnit(type, outputUnit); 972 return _task.metadataCollector.reifyTypeForOutputUnit(type, outputUnit);
968 } 973 }
969 } 974 }
970 975
971 List<ParameterStubMethod> _generateParameterStubs( 976 List<ParameterStubMethod> _generateParameterStubs(
972 MethodElement element, bool canTearOff) { 977 FunctionEntity element, bool canTearOff) {
973 if (!_methodNeedsStubs(element)) return const <ParameterStubMethod>[]; 978 if (!_methodNeedsStubs(element)) return const <ParameterStubMethod>[];
974 979
975 ParameterStubGenerator generator = new ParameterStubGenerator( 980 ParameterStubGenerator generator = new ParameterStubGenerator(
976 _commonElements, 981 _commonElements,
977 _task, 982 _task,
978 _constantHandler, 983 _constantHandler,
979 _namer, 984 _namer,
980 _nativeData, 985 _nativeData,
981 _interceptorData, 986 _interceptorData,
982 _worldBuilder, 987 _worldBuilder,
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 Iterable<js.Name> names = 1035 Iterable<js.Name> names =
1031 _oneShotInterceptorData.specializedGetInterceptorNames; 1036 _oneShotInterceptorData.specializedGetInterceptorNames;
1032 return names.map((js.Name name) { 1037 return names.map((js.Name name) {
1033 Set<ClassEntity> classes = 1038 Set<ClassEntity> classes =
1034 _oneShotInterceptorData.getSpecializedGetInterceptorsFor(name); 1039 _oneShotInterceptorData.getSpecializedGetInterceptorsFor(name);
1035 js.Expression code = stubGenerator.generateGetInterceptorMethod(classes); 1040 js.Expression code = stubGenerator.generateGetInterceptorMethod(classes);
1036 return new StaticStubMethod(name, holder, code); 1041 return new StaticStubMethod(name, holder, code);
1037 }); 1042 });
1038 } 1043 }
1039 1044
1040 List<Field> _buildFields(Element holder, 1045 List<Field> _buildFields(
1041 {bool visitStatics, bool isHolderInterceptedClass: false}) { 1046 {bool visitStatics: false,
1047 bool isHolderInterceptedClass: false,
1048 LibraryEntity library,
1049 ClassEntity cls}) {
1042 List<Field> fields = <Field>[]; 1050 List<Field> fields = <Field>[];
1043 new FieldVisitor(_options, _worldBuilder, _nativeData, _mirrorsData, _namer, 1051
1044 _closedWorld) 1052 void visitField(FieldElement field, js.Name name, js.Name accessorName,
1045 .visitFields(holder, visitStatics, (FieldElement field, 1053 bool needsGetter, bool needsSetter, bool needsCheckedSetter) {
1046 js.Name name,
1047 js.Name accessorName,
1048 bool needsGetter,
1049 bool needsSetter,
1050 bool needsCheckedSetter) {
1051 assert(field.isDeclaration, failedAt(field)); 1054 assert(field.isDeclaration, failedAt(field));
1052 1055
1053 int getterFlags = 0; 1056 int getterFlags = 0;
1054 if (needsGetter) { 1057 if (needsGetter) {
1055 if (visitStatics || 1058 if (visitStatics ||
1056 !_interceptorData.fieldHasInterceptedGetter(field)) { 1059 !_interceptorData.fieldHasInterceptedGetter(field)) {
1057 getterFlags = 1; 1060 getterFlags = 1;
1058 } else { 1061 } else {
1059 getterFlags += 2; 1062 getterFlags += 2;
1060 // TODO(sra): 'isInterceptedClass' might not be the correct test 1063 // TODO(sra): 'isInterceptedClass' might not be the correct test
(...skipping 13 matching lines...) Expand all
1074 } else { 1077 } else {
1075 setterFlags += 2; 1078 setterFlags += 2;
1076 if (!isHolderInterceptedClass) { 1079 if (!isHolderInterceptedClass) {
1077 setterFlags += 1; 1080 setterFlags += 1;
1078 } 1081 }
1079 } 1082 }
1080 } 1083 }
1081 1084
1082 fields.add(new Field(field, name, accessorName, getterFlags, setterFlags, 1085 fields.add(new Field(field, name, accessorName, getterFlags, setterFlags,
1083 needsCheckedSetter)); 1086 needsCheckedSetter));
1084 }); 1087 }
1088
1089 FieldVisitor visitor = new FieldVisitor(_options, _elementEnvironment,
1090 _worldBuilder, _nativeData, _mirrorsData, _namer, _closedWorld);
1091 visitor.visitFields(visitField,
1092 visitStatics: visitStatics, library: library, cls: cls);
1085 1093
1086 return fields; 1094 return fields;
1087 } 1095 }
1088 1096
1089 Iterable<StaticStubMethod> _generateOneShotInterceptors() { 1097 Iterable<StaticStubMethod> _generateOneShotInterceptors() {
1090 InterceptorStubGenerator stubGenerator = new InterceptorStubGenerator( 1098 InterceptorStubGenerator stubGenerator = new InterceptorStubGenerator(
1091 _options, 1099 _options,
1092 _commonElements, 1100 _commonElements,
1093 _task, 1101 _task,
1094 _nativeCodegenEnqueuer, 1102 _nativeCodegenEnqueuer,
(...skipping 10 matching lines...) Expand all
1105 // generating the interceptor methods. 1113 // generating the interceptor methods.
1106 Holder holder = _registry.registerHolder(holderName); 1114 Holder holder = _registry.registerHolder(holderName);
1107 1115
1108 List<js.Name> names = _oneShotInterceptorData.oneShotInterceptorNames; 1116 List<js.Name> names = _oneShotInterceptorData.oneShotInterceptorNames;
1109 return names.map((js.Name name) { 1117 return names.map((js.Name name) {
1110 js.Expression code = stubGenerator.generateOneShotInterceptor(name); 1118 js.Expression code = stubGenerator.generateOneShotInterceptor(name);
1111 return new StaticStubMethod(name, holder, code); 1119 return new StaticStubMethod(name, holder, code);
1112 }); 1120 });
1113 } 1121 }
1114 1122
1115 StaticDartMethod _buildStaticMethod(MethodElement element) { 1123 StaticDartMethod _buildStaticMethod(FunctionEntity element) {
1116 js.Name name = _namer.methodPropertyName(element); 1124 js.Name name = _namer.methodPropertyName(element);
1117 String holder = _namer.globalObjectForMember(element); 1125 String holder = _namer.globalObjectForMember(element);
1118 js.Expression code = _generatedCode[element]; 1126 js.Expression code = _generatedCode[element];
1119 1127
1120 bool isApplyTarget = !element.isConstructor && !element.isAccessor; 1128 bool isApplyTarget =
1129 !element.isConstructor && !element.isGetter && !element.isSetter;
1121 bool canBeApplied = _methodCanBeApplied(element); 1130 bool canBeApplied = _methodCanBeApplied(element);
1122 bool canBeReflected = _methodCanBeReflected(element); 1131 bool canBeReflected = _methodCanBeReflected(element);
1123 1132
1124 bool needsTearOff = isApplyTarget && 1133 bool needsTearOff = isApplyTarget &&
1125 (canBeReflected || 1134 (canBeReflected ||
1126 _worldBuilder.staticFunctionsNeedingGetter.contains(element)); 1135 _worldBuilder.staticFunctionsNeedingGetter.contains(element));
1127 1136
1128 js.Name tearOffName = 1137 js.Name tearOffName =
1129 needsTearOff ? _namer.staticClosureName(element) : null; 1138 needsTearOff ? _namer.staticClosureName(element) : null;
1130 1139
1131 js.Name callName = null; 1140 js.Name callName = null;
1132 if (needsTearOff) { 1141 if (needsTearOff) {
1133 Selector callSelector = 1142 Selector callSelector =
1134 new Selector.fromElement(element).toCallSelector(); 1143 new Selector.fromElement(element).toCallSelector();
1135 callName = _namer.invocationName(callSelector); 1144 callName = _namer.invocationName(callSelector);
1136 } 1145 }
1137 js.Expression functionType; 1146 js.Expression functionType;
1138 ResolutionDartType type = element.type; 1147 DartType type = _elementEnvironment.getFunctionType(element);
1139 if (needsTearOff || canBeReflected) { 1148 if (needsTearOff || canBeReflected) {
1140 OutputUnit outputUnit = _deferredLoadTask.outputUnitForElement(element); 1149 OutputUnit outputUnit = _deferredLoadTask.outputUnitForMember(element);
1141 functionType = _generateFunctionType(type, outputUnit); 1150 functionType = _generateFunctionType(type, outputUnit);
1142 } 1151 }
1143 1152
1144 int requiredParameterCount; 1153 int requiredParameterCount;
1145 var /* List | Map */ optionalParameterDefaultValues; 1154 var /* List | Map */ optionalParameterDefaultValues;
1146 if (canBeApplied || canBeReflected) { 1155 if (canBeApplied || canBeReflected) {
1147 FunctionSignature signature = element.functionSignature; 1156 // TODO(johnniwinther): Support entities;
1157 MethodElement method = element;
1158 FunctionSignature signature = method.functionSignature;
1148 requiredParameterCount = signature.requiredParameterCount; 1159 requiredParameterCount = signature.requiredParameterCount;
1149 optionalParameterDefaultValues = 1160 optionalParameterDefaultValues =
1150 _computeParameterDefaultValues(signature); 1161 _computeParameterDefaultValues(signature);
1151 } 1162 }
1152 1163
1153 // TODO(floitsch): we shouldn't update the registry in the middle of 1164 // TODO(floitsch): we shouldn't update the registry in the middle of
1154 // building a static method. 1165 // building a static method.
1155 return new StaticDartMethod(element, name, _registry.registerHolder(holder), 1166 return new StaticDartMethod(element, name, _registry.registerHolder(holder),
1156 code, _generateParameterStubs(element, needsTearOff), callName, 1167 code, _generateParameterStubs(element, needsTearOff), callName,
1157 needsTearOff: needsTearOff, 1168 needsTearOff: needsTearOff,
(...skipping 19 matching lines...) Expand all
1177 Constant constant = new Constant(name, holder, constantValue); 1188 Constant constant = new Constant(name, holder, constantValue);
1178 _constants[constantValue] = constant; 1189 _constants[constantValue] = constant;
1179 } 1190 }
1180 } 1191 }
1181 1192
1182 Holder _registerStaticStateHolder() { 1193 Holder _registerStaticStateHolder() {
1183 return _registry.registerHolder(_namer.staticStateHolder, 1194 return _registry.registerHolder(_namer.staticStateHolder,
1184 isStaticStateHolder: true); 1195 isStaticStateHolder: true);
1185 } 1196 }
1186 } 1197 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698