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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 import 'backend_helpers.dart'; | 67 import 'backend_helpers.dart'; |
68 import 'backend_impact.dart'; | 68 import 'backend_impact.dart'; |
69 import 'backend_serialization.dart' show JavaScriptBackendSerialization; | 69 import 'backend_serialization.dart' show JavaScriptBackendSerialization; |
70 import 'checked_mode_helpers.dart'; | 70 import 'checked_mode_helpers.dart'; |
71 import 'constant_handler_javascript.dart'; | 71 import 'constant_handler_javascript.dart'; |
72 import 'custom_elements_analysis.dart'; | 72 import 'custom_elements_analysis.dart'; |
73 import 'enqueuer.dart'; | 73 import 'enqueuer.dart'; |
74 import 'js_interop_analysis.dart' show JsInteropAnalysis; | 74 import 'js_interop_analysis.dart' show JsInteropAnalysis; |
75 import '../kernel/task.dart'; | 75 import '../kernel/task.dart'; |
76 import 'lookup_map_analysis.dart' show LookupMapAnalysis; | 76 import 'lookup_map_analysis.dart' show LookupMapAnalysis; |
| 77 import 'mirrors_analysis.dart'; |
77 import 'namer.dart'; | 78 import 'namer.dart'; |
78 import 'native_data.dart' show NativeData; | 79 import 'native_data.dart' show NativeData; |
79 import 'no_such_method_registry.dart'; | 80 import 'no_such_method_registry.dart'; |
80 import 'patch_resolver.dart'; | 81 import 'patch_resolver.dart'; |
81 import 'type_variable_handler.dart'; | 82 import 'type_variable_handler.dart'; |
82 | 83 |
83 part 'runtime_types.dart'; | 84 part 'runtime_types.dart'; |
84 | 85 |
85 const VERBOSE_OPTIMIZER_HINTS = false; | 86 const VERBOSE_OPTIMIZER_HINTS = false; |
86 | 87 |
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 | 566 |
566 /// Codegen support for tree-shaking entries of `LookupMap`. | 567 /// Codegen support for tree-shaking entries of `LookupMap`. |
567 LookupMapAnalysis lookupMapAnalysis; | 568 LookupMapAnalysis lookupMapAnalysis; |
568 | 569 |
569 /// Codegen support for typed JavaScript interop. | 570 /// Codegen support for typed JavaScript interop. |
570 JsInteropAnalysis jsInteropAnalysis; | 571 JsInteropAnalysis jsInteropAnalysis; |
571 | 572 |
572 /// Support for classifying `noSuchMethod` implementations. | 573 /// Support for classifying `noSuchMethod` implementations. |
573 NoSuchMethodRegistry noSuchMethodRegistry; | 574 NoSuchMethodRegistry noSuchMethodRegistry; |
574 | 575 |
| 576 /// Resolution and codegen support for computing reflectable elements. |
| 577 MirrorsAnalysis mirrorsAnalysis; |
| 578 |
575 /// Builds kernel representation for the program. | 579 /// Builds kernel representation for the program. |
576 KernelTask kernelTask; | 580 KernelTask kernelTask; |
577 | 581 |
578 JavaScriptConstantTask constantCompilerTask; | 582 JavaScriptConstantTask constantCompilerTask; |
579 | 583 |
580 JavaScriptImpactTransformer impactTransformer; | 584 JavaScriptImpactTransformer impactTransformer; |
581 | 585 |
582 PatchResolverTask patchResolverTask; | 586 PatchResolverTask patchResolverTask; |
583 | 587 |
584 bool enabledNoSuchMethod = false; | 588 bool enabledNoSuchMethod = false; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
621 helpers = new BackendHelpers(compiler), | 625 helpers = new BackendHelpers(compiler), |
622 impacts = new BackendImpacts(compiler), | 626 impacts = new BackendImpacts(compiler), |
623 frontend = new JSFrontendAccess(compiler), | 627 frontend = new JSFrontendAccess(compiler), |
624 super(compiler) { | 628 super(compiler) { |
625 emitter = new CodeEmitterTask( | 629 emitter = new CodeEmitterTask( |
626 compiler, namer, generateSourceMap, useStartupEmitter); | 630 compiler, namer, generateSourceMap, useStartupEmitter); |
627 typeVariableHandler = new TypeVariableHandler(compiler); | 631 typeVariableHandler = new TypeVariableHandler(compiler); |
628 customElementsAnalysis = new CustomElementsAnalysis(this); | 632 customElementsAnalysis = new CustomElementsAnalysis(this); |
629 lookupMapAnalysis = new LookupMapAnalysis(this, reporter); | 633 lookupMapAnalysis = new LookupMapAnalysis(this, reporter); |
630 jsInteropAnalysis = new JsInteropAnalysis(this); | 634 jsInteropAnalysis = new JsInteropAnalysis(this); |
| 635 mirrorsAnalysis = new MirrorsAnalysis(this, compiler.resolution); |
631 | 636 |
632 noSuchMethodRegistry = new NoSuchMethodRegistry(this); | 637 noSuchMethodRegistry = new NoSuchMethodRegistry(this); |
633 kernelTask = new KernelTask(compiler); | 638 kernelTask = new KernelTask(compiler); |
634 constantCompilerTask = new JavaScriptConstantTask(compiler); | 639 constantCompilerTask = new JavaScriptConstantTask(compiler); |
635 impactTransformer = new JavaScriptImpactTransformer(this); | 640 impactTransformer = new JavaScriptImpactTransformer(this); |
636 patchResolverTask = new PatchResolverTask(compiler); | 641 patchResolverTask = new PatchResolverTask(compiler); |
637 functionCompiler = | 642 functionCompiler = |
638 new SsaFunctionCompiler(this, sourceInformationStrategy, useKernel); | 643 new SsaFunctionCompiler(this, sourceInformationStrategy, useKernel); |
639 serialization = new JavaScriptBackendSerialization(this); | 644 serialization = new JavaScriptBackendSerialization(this); |
640 backendClasses = new JavaScriptBackendClasses(helpers); | 645 backendClasses = new JavaScriptBackendClasses(helpers); |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1046 // Walk superclass chain to find mixins. | 1051 // Walk superclass chain to find mixins. |
1047 for (; cls != null; cls = cls.superclass) { | 1052 for (; cls != null; cls = cls.superclass) { |
1048 if (cls.isMixinApplication) { | 1053 if (cls.isMixinApplication) { |
1049 MixinApplicationElement mixinApplication = cls; | 1054 MixinApplicationElement mixinApplication = cls; |
1050 classesMixedIntoInterceptedClasses.add(mixinApplication.mixin); | 1055 classesMixedIntoInterceptedClasses.add(mixinApplication.mixin); |
1051 } | 1056 } |
1052 } | 1057 } |
1053 } | 1058 } |
1054 } | 1059 } |
1055 | 1060 |
1056 void addInterceptors(ClassElement cls, Enqueuer enqueuer, Registry registry) { | 1061 void addInterceptors(ClassElement cls, Enqueuer enqueuer) { |
1057 if (enqueuer.isResolutionQueue) { | 1062 if (enqueuer.isResolutionQueue) { |
1058 _interceptedClasses.add(helpers.jsInterceptorClass); | 1063 _interceptedClasses.add(helpers.jsInterceptorClass); |
1059 _interceptedClasses.add(cls); | 1064 _interceptedClasses.add(cls); |
1060 cls.ensureResolved(resolution); | 1065 cls.ensureResolved(resolution); |
1061 cls.forEachMember((ClassElement classElement, Element member) { | 1066 cls.forEachMember((ClassElement classElement, Element member) { |
1062 // All methods on [Object] are shadowed by [Interceptor]. | 1067 // All methods on [Object] are shadowed by [Interceptor]. |
1063 if (classElement == coreClasses.objectClass) return; | 1068 if (classElement == coreClasses.objectClass) return; |
1064 Set<Element> set = interceptedElements.putIfAbsent( | 1069 Set<Element> set = interceptedElements.putIfAbsent( |
1065 member.name, () => new Set<Element>()); | 1070 member.name, () => new Set<Element>()); |
1066 set.add(member); | 1071 set.add(member); |
1067 }, includeSuperAndInjectedMembers: true); | 1072 }, includeSuperAndInjectedMembers: true); |
1068 } | 1073 } |
1069 enqueueClass(enqueuer, cls, registry); | 1074 enqueueClass(enqueuer, cls); |
1070 } | 1075 } |
1071 | 1076 |
1072 Set<ClassElement> get interceptedClasses { | 1077 Set<ClassElement> get interceptedClasses { |
1073 assert(compiler.enqueuer.resolution.queueIsClosed); | 1078 assert(compiler.enqueuer.resolution.queueIsClosed); |
1074 return _interceptedClasses; | 1079 return _interceptedClasses; |
1075 } | 1080 } |
1076 | 1081 |
1077 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { | 1082 void registerSpecializedGetInterceptor(Set<ClassElement> classes) { |
1078 jsAst.Name name = namer.nameForGetInterceptor(classes); | 1083 jsAst.Name name = namer.nameForGetInterceptor(classes); |
1079 if (classes.contains(helpers.jsInterceptorClass)) { | 1084 if (classes.contains(helpers.jsInterceptorClass)) { |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1152 // constant emitter will generate a call to the createRuntimeType | 1157 // constant emitter will generate a call to the createRuntimeType |
1153 // helper so we register a use of that. | 1158 // helper so we register a use of that. |
1154 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( | 1159 impactBuilder.registerStaticUse(new StaticUse.staticInvoke( |
1155 // TODO(johnniwinther): Find the right [CallStructure]. | 1160 // TODO(johnniwinther): Find the right [CallStructure]. |
1156 helpers.createRuntimeType, | 1161 helpers.createRuntimeType, |
1157 null)); | 1162 null)); |
1158 } | 1163 } |
1159 } | 1164 } |
1160 } | 1165 } |
1161 | 1166 |
1162 void registerInstantiatedClass( | 1167 void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) { |
1163 ClassElement cls, Enqueuer enqueuer, Registry registry) { | 1168 _processClass(cls, enqueuer); |
1164 _processClass(cls, enqueuer, registry); | |
1165 } | 1169 } |
1166 | 1170 |
1167 void registerImplementedClass( | 1171 void registerImplementedClass(ClassElement cls, Enqueuer enqueuer) { |
1168 ClassElement cls, Enqueuer enqueuer, Registry registry) { | 1172 _processClass(cls, enqueuer); |
1169 _processClass(cls, enqueuer, registry); | |
1170 } | 1173 } |
1171 | 1174 |
1172 void _processClass(ClassElement cls, Enqueuer enqueuer, Registry registry) { | 1175 void _processClass(ClassElement cls, Enqueuer enqueuer) { |
1173 if (!cls.typeVariables.isEmpty) { | 1176 if (!cls.typeVariables.isEmpty) { |
1174 typeVariableHandler.registerClassWithTypeVariables( | 1177 typeVariableHandler.registerClassWithTypeVariables(cls, enqueuer); |
1175 cls, enqueuer, registry); | |
1176 } | 1178 } |
1177 | 1179 |
1178 // Register any helper that will be needed by the backend. | 1180 // Register any helper that will be needed by the backend. |
1179 if (enqueuer.isResolutionQueue) { | 1181 if (enqueuer.isResolutionQueue) { |
1180 if (cls == coreClasses.intClass || | 1182 if (cls == coreClasses.intClass || |
1181 cls == coreClasses.doubleClass || | 1183 cls == coreClasses.doubleClass || |
1182 cls == coreClasses.numClass) { | 1184 cls == coreClasses.numClass) { |
1183 // The backend will try to optimize number operations and use the | 1185 // The backend will try to optimize number operations and use the |
1184 // `iae` helper directly. | 1186 // `iae` helper directly. |
1185 enqueue(enqueuer, helpers.throwIllegalArgumentException, registry); | 1187 enqueue(enqueuer, helpers.throwIllegalArgumentException); |
1186 } else if (cls == coreClasses.listClass || | 1188 } else if (cls == coreClasses.listClass || |
1187 cls == coreClasses.stringClass) { | 1189 cls == coreClasses.stringClass) { |
1188 // The backend will try to optimize array and string access and use the | 1190 // The backend will try to optimize array and string access and use the |
1189 // `ioore` and `iae` helpers directly. | 1191 // `ioore` and `iae` helpers directly. |
1190 enqueue(enqueuer, helpers.throwIndexOutOfRangeException, registry); | 1192 enqueue(enqueuer, helpers.throwIndexOutOfRangeException); |
1191 enqueue(enqueuer, helpers.throwIllegalArgumentException, registry); | 1193 enqueue(enqueuer, helpers.throwIllegalArgumentException); |
1192 } else if (cls == coreClasses.functionClass) { | 1194 } else if (cls == coreClasses.functionClass) { |
1193 enqueueClass(enqueuer, helpers.closureClass, registry); | 1195 enqueueClass(enqueuer, helpers.closureClass); |
1194 } else if (cls == coreClasses.mapClass) { | 1196 } else if (cls == coreClasses.mapClass) { |
1195 // The backend will use a literal list to initialize the entries | 1197 // The backend will use a literal list to initialize the entries |
1196 // of the map. | 1198 // of the map. |
1197 enqueueClass(enqueuer, coreClasses.listClass, registry); | 1199 enqueueClass(enqueuer, coreClasses.listClass); |
1198 enqueueClass(enqueuer, helpers.mapLiteralClass, registry); | 1200 enqueueClass(enqueuer, helpers.mapLiteralClass); |
1199 // For map literals, the dependency between the implementation class | 1201 // For map literals, the dependency between the implementation class |
1200 // and [Map] is not visible, so we have to add it manually. | 1202 // and [Map] is not visible, so we have to add it manually. |
1201 rti.registerRtiDependency(helpers.mapLiteralClass, cls); | 1203 rti.registerRtiDependency(helpers.mapLiteralClass, cls); |
1202 } else if (cls == helpers.boundClosureClass) { | 1204 } else if (cls == helpers.boundClosureClass) { |
1203 // TODO(johnniwinther): Is this a noop? | 1205 // TODO(johnniwinther): Is this a noop? |
1204 enqueueClass(enqueuer, helpers.boundClosureClass, registry); | 1206 enqueueClass(enqueuer, helpers.boundClosureClass); |
1205 } else if (isNativeOrExtendsNative(cls)) { | 1207 } else if (isNativeOrExtendsNative(cls)) { |
1206 enqueue(enqueuer, helpers.getNativeInterceptorMethod, registry); | 1208 enqueue(enqueuer, helpers.getNativeInterceptorMethod); |
1207 enqueueClass( | 1209 enqueueClass(enqueuer, helpers.jsInterceptorClass); |
1208 enqueuer, helpers.jsInterceptorClass, compiler.globalDependencies); | 1210 enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass); |
1209 enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass, registry); | 1211 enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass); |
1210 enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass, registry); | 1212 enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass); |
1211 enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass, registry); | |
1212 } else if (cls == helpers.mapLiteralClass) { | 1213 } else if (cls == helpers.mapLiteralClass) { |
1213 // For map literals, the dependency between the implementation class | 1214 // For map literals, the dependency between the implementation class |
1214 // and [Map] is not visible, so we have to add it manually. | 1215 // and [Map] is not visible, so we have to add it manually. |
1215 Element getFactory(String name, int arity) { | 1216 Element getFactory(String name, int arity) { |
1216 // The constructor is on the patch class, but dart2js unit tests don't | 1217 // The constructor is on the patch class, but dart2js unit tests don't |
1217 // have a patch class. | 1218 // have a patch class. |
1218 ClassElement implementation = cls.implementation; | 1219 ClassElement implementation = cls.implementation; |
1219 ConstructorElement ctor = implementation.lookupConstructor(name); | 1220 ConstructorElement ctor = implementation.lookupConstructor(name); |
1220 if (ctor == null || | 1221 if (ctor == null || |
1221 (Name.isPrivateName(name) && | 1222 (Name.isPrivateName(name) && |
(...skipping 16 matching lines...) Expand all Loading... |
1238 reporter.internalError( | 1239 reporter.internalError( |
1239 helpers.mapLiteralClass, | 1240 helpers.mapLiteralClass, |
1240 "Map literal class ${helpers.mapLiteralClass} missing " | 1241 "Map literal class ${helpers.mapLiteralClass} missing " |
1241 "'$name' static member function"); | 1242 "'$name' static member function"); |
1242 } | 1243 } |
1243 return element; | 1244 return element; |
1244 } | 1245 } |
1245 | 1246 |
1246 helpers.mapLiteralConstructor = getFactory('_literal', 1); | 1247 helpers.mapLiteralConstructor = getFactory('_literal', 1); |
1247 helpers.mapLiteralConstructorEmpty = getFactory('_empty', 0); | 1248 helpers.mapLiteralConstructorEmpty = getFactory('_empty', 0); |
1248 enqueueInResolution(helpers.mapLiteralConstructor, registry); | 1249 enqueue(enqueuer, helpers.mapLiteralConstructor); |
1249 enqueueInResolution(helpers.mapLiteralConstructorEmpty, registry); | 1250 enqueue(enqueuer, helpers.mapLiteralConstructorEmpty); |
1250 | 1251 |
1251 helpers.mapLiteralUntypedMaker = getMember('_makeLiteral'); | 1252 helpers.mapLiteralUntypedMaker = getMember('_makeLiteral'); |
1252 helpers.mapLiteralUntypedEmptyMaker = getMember('_makeEmpty'); | 1253 helpers.mapLiteralUntypedEmptyMaker = getMember('_makeEmpty'); |
1253 enqueueInResolution(helpers.mapLiteralUntypedMaker, registry); | 1254 enqueue(enqueuer, helpers.mapLiteralUntypedMaker); |
1254 enqueueInResolution(helpers.mapLiteralUntypedEmptyMaker, registry); | 1255 enqueue(enqueuer, helpers.mapLiteralUntypedEmptyMaker); |
1255 } | 1256 } |
1256 } | 1257 } |
1257 if (cls == helpers.closureClass) { | 1258 if (cls == helpers.closureClass) { |
1258 enqueue(enqueuer, helpers.closureFromTearOff, registry); | 1259 enqueue(enqueuer, helpers.closureFromTearOff); |
1259 } | 1260 } |
1260 if (cls == coreClasses.stringClass || cls == helpers.jsStringClass) { | 1261 if (cls == coreClasses.stringClass || cls == helpers.jsStringClass) { |
1261 addInterceptors(helpers.jsStringClass, enqueuer, registry); | 1262 addInterceptors(helpers.jsStringClass, enqueuer); |
1262 } else if (cls == coreClasses.listClass || | 1263 } else if (cls == coreClasses.listClass || |
1263 cls == helpers.jsArrayClass || | 1264 cls == helpers.jsArrayClass || |
1264 cls == helpers.jsFixedArrayClass || | 1265 cls == helpers.jsFixedArrayClass || |
1265 cls == helpers.jsExtendableArrayClass || | 1266 cls == helpers.jsExtendableArrayClass || |
1266 cls == helpers.jsUnmodifiableArrayClass) { | 1267 cls == helpers.jsUnmodifiableArrayClass) { |
1267 addInterceptors(helpers.jsArrayClass, enqueuer, registry); | 1268 addInterceptors(helpers.jsArrayClass, enqueuer); |
1268 addInterceptors(helpers.jsMutableArrayClass, enqueuer, registry); | 1269 addInterceptors(helpers.jsMutableArrayClass, enqueuer); |
1269 addInterceptors(helpers.jsFixedArrayClass, enqueuer, registry); | 1270 addInterceptors(helpers.jsFixedArrayClass, enqueuer); |
1270 addInterceptors(helpers.jsExtendableArrayClass, enqueuer, registry); | 1271 addInterceptors(helpers.jsExtendableArrayClass, enqueuer); |
1271 addInterceptors(helpers.jsUnmodifiableArrayClass, enqueuer, registry); | 1272 addInterceptors(helpers.jsUnmodifiableArrayClass, enqueuer); |
1272 // Literal lists can be translated into calls to these functions: | 1273 if (enqueuer.isResolutionQueue) { |
1273 enqueueInResolution(helpers.jsArrayTypedConstructor, registry); | 1274 // Literal lists can be translated into calls to these functions: |
1274 enqueueInResolution(helpers.setRuntimeTypeInfo, registry); | 1275 enqueue(enqueuer, helpers.jsArrayTypedConstructor); |
1275 enqueueInResolution(helpers.getTypeArgumentByIndex, registry); | 1276 enqueue(enqueuer, helpers.setRuntimeTypeInfo); |
| 1277 enqueue(enqueuer, helpers.getTypeArgumentByIndex); |
| 1278 } |
1276 } else if (cls == coreClasses.intClass || cls == helpers.jsIntClass) { | 1279 } else if (cls == coreClasses.intClass || cls == helpers.jsIntClass) { |
1277 addInterceptors(helpers.jsIntClass, enqueuer, registry); | 1280 addInterceptors(helpers.jsIntClass, enqueuer); |
1278 addInterceptors(helpers.jsPositiveIntClass, enqueuer, registry); | 1281 addInterceptors(helpers.jsPositiveIntClass, enqueuer); |
1279 addInterceptors(helpers.jsUInt32Class, enqueuer, registry); | 1282 addInterceptors(helpers.jsUInt32Class, enqueuer); |
1280 addInterceptors(helpers.jsUInt31Class, enqueuer, registry); | 1283 addInterceptors(helpers.jsUInt31Class, enqueuer); |
1281 addInterceptors(helpers.jsNumberClass, enqueuer, registry); | 1284 addInterceptors(helpers.jsNumberClass, enqueuer); |
1282 } else if (cls == coreClasses.doubleClass || cls == helpers.jsDoubleClass) { | 1285 } else if (cls == coreClasses.doubleClass || cls == helpers.jsDoubleClass) { |
1283 addInterceptors(helpers.jsDoubleClass, enqueuer, registry); | 1286 addInterceptors(helpers.jsDoubleClass, enqueuer); |
1284 addInterceptors(helpers.jsNumberClass, enqueuer, registry); | 1287 addInterceptors(helpers.jsNumberClass, enqueuer); |
1285 } else if (cls == coreClasses.boolClass || cls == helpers.jsBoolClass) { | 1288 } else if (cls == coreClasses.boolClass || cls == helpers.jsBoolClass) { |
1286 addInterceptors(helpers.jsBoolClass, enqueuer, registry); | 1289 addInterceptors(helpers.jsBoolClass, enqueuer); |
1287 } else if (cls == coreClasses.nullClass || cls == helpers.jsNullClass) { | 1290 } else if (cls == coreClasses.nullClass || cls == helpers.jsNullClass) { |
1288 addInterceptors(helpers.jsNullClass, enqueuer, registry); | 1291 addInterceptors(helpers.jsNullClass, enqueuer); |
1289 } else if (cls == coreClasses.numClass || cls == helpers.jsNumberClass) { | 1292 } else if (cls == coreClasses.numClass || cls == helpers.jsNumberClass) { |
1290 addInterceptors(helpers.jsIntClass, enqueuer, registry); | 1293 addInterceptors(helpers.jsIntClass, enqueuer); |
1291 addInterceptors(helpers.jsPositiveIntClass, enqueuer, registry); | 1294 addInterceptors(helpers.jsPositiveIntClass, enqueuer); |
1292 addInterceptors(helpers.jsUInt32Class, enqueuer, registry); | 1295 addInterceptors(helpers.jsUInt32Class, enqueuer); |
1293 addInterceptors(helpers.jsUInt31Class, enqueuer, registry); | 1296 addInterceptors(helpers.jsUInt31Class, enqueuer); |
1294 addInterceptors(helpers.jsDoubleClass, enqueuer, registry); | 1297 addInterceptors(helpers.jsDoubleClass, enqueuer); |
1295 addInterceptors(helpers.jsNumberClass, enqueuer, registry); | 1298 addInterceptors(helpers.jsNumberClass, enqueuer); |
1296 } else if (cls == helpers.jsJavaScriptObjectClass) { | 1299 } else if (cls == helpers.jsJavaScriptObjectClass) { |
1297 addInterceptors(helpers.jsJavaScriptObjectClass, enqueuer, registry); | 1300 addInterceptors(helpers.jsJavaScriptObjectClass, enqueuer); |
1298 } else if (cls == helpers.jsPlainJavaScriptObjectClass) { | 1301 } else if (cls == helpers.jsPlainJavaScriptObjectClass) { |
1299 addInterceptors(helpers.jsPlainJavaScriptObjectClass, enqueuer, registry); | 1302 addInterceptors(helpers.jsPlainJavaScriptObjectClass, enqueuer); |
1300 } else if (cls == helpers.jsUnknownJavaScriptObjectClass) { | 1303 } else if (cls == helpers.jsUnknownJavaScriptObjectClass) { |
1301 addInterceptors( | 1304 addInterceptors(helpers.jsUnknownJavaScriptObjectClass, enqueuer); |
1302 helpers.jsUnknownJavaScriptObjectClass, enqueuer, registry); | |
1303 } else if (cls == helpers.jsJavaScriptFunctionClass) { | 1305 } else if (cls == helpers.jsJavaScriptFunctionClass) { |
1304 addInterceptors(helpers.jsJavaScriptFunctionClass, enqueuer, registry); | 1306 addInterceptors(helpers.jsJavaScriptFunctionClass, enqueuer); |
1305 } else if (isNativeOrExtendsNative(cls)) { | 1307 } else if (isNativeOrExtendsNative(cls)) { |
1306 addInterceptorsForNativeClassMembers(cls, enqueuer); | 1308 addInterceptorsForNativeClassMembers(cls, enqueuer); |
1307 } else if (cls == helpers.jsIndexingBehaviorInterface) { | 1309 } else if (cls == helpers.jsIndexingBehaviorInterface) { |
1308 // These two helpers are used by the emitter and the codegen. | 1310 // These two helpers are used by the emitter and the codegen. |
1309 // Because we cannot enqueue elements at the time of emission, | 1311 // Because we cannot enqueue elements at the time of emission, |
1310 // we make sure they are always generated. | 1312 // we make sure they are always generated. |
1311 enqueue(enqueuer, helpers.isJsIndexable, registry); | 1313 enqueue(enqueuer, helpers.isJsIndexable); |
1312 } | 1314 } |
1313 | 1315 |
1314 customElementsAnalysis.registerInstantiatedClass(cls, | 1316 customElementsAnalysis.registerInstantiatedClass(cls, |
1315 forResolution: enqueuer.isResolutionQueue); | 1317 forResolution: enqueuer.isResolutionQueue); |
1316 if (!enqueuer.isResolutionQueue) { | 1318 if (!enqueuer.isResolutionQueue) { |
1317 lookupMapAnalysis.registerInstantiatedClass(cls); | 1319 lookupMapAnalysis.registerInstantiatedClass(cls); |
1318 } | 1320 } |
1319 } | 1321 } |
1320 | 1322 |
1321 void registerInstantiatedType( | 1323 void registerInstantiatedType(InterfaceType type) { |
1322 InterfaceType type, Enqueuer enqueuer, Registry registry, | |
1323 {bool mirrorUsage: false}) { | |
1324 lookupMapAnalysis.registerInstantiatedType(type); | 1324 lookupMapAnalysis.registerInstantiatedType(type); |
1325 super.registerInstantiatedType(type, enqueuer, registry, | |
1326 mirrorUsage: mirrorUsage); | |
1327 } | 1325 } |
1328 | 1326 |
1329 void enqueueHelpers(ResolutionEnqueuer world, Registry registry) { | 1327 void enqueueHelpers(ResolutionEnqueuer enqueuer) { |
1330 assert(helpers.interceptorsLibrary != null); | 1328 assert(helpers.interceptorsLibrary != null); |
1331 // TODO(ngeoffray): Not enqueuing those two classes currently make | 1329 // TODO(ngeoffray): Not enqueuing those two classes currently make |
1332 // the compiler potentially crash. However, any reasonable program | 1330 // the compiler potentially crash. However, any reasonable program |
1333 // will instantiate those two classes. | 1331 // will instantiate those two classes. |
1334 addInterceptors(helpers.jsBoolClass, world, registry); | 1332 addInterceptors(helpers.jsBoolClass, enqueuer); |
1335 addInterceptors(helpers.jsNullClass, world, registry); | 1333 addInterceptors(helpers.jsNullClass, enqueuer); |
1336 if (compiler.options.enableTypeAssertions) { | 1334 if (compiler.options.enableTypeAssertions) { |
1337 // Unconditionally register the helper that checks if the | 1335 // Unconditionally register the helper that checks if the |
1338 // expression in an if/while/for is a boolean. | 1336 // expression in an if/while/for is a boolean. |
1339 // TODO(ngeoffray): Should we have the resolver register those instead? | 1337 // TODO(ngeoffray): Should we have the resolver register those instead? |
1340 Element e = helpers.boolConversionCheck; | 1338 Element e = helpers.boolConversionCheck; |
1341 if (e != null) enqueue(world, e, registry); | 1339 if (e != null) enqueue(enqueuer, e); |
1342 } | 1340 } |
1343 | 1341 |
1344 if (TRACE_CALLS) { | 1342 if (TRACE_CALLS) { |
1345 traceHelper = TRACE_METHOD == 'console' | 1343 traceHelper = TRACE_METHOD == 'console' |
1346 ? helpers.consoleTraceHelper | 1344 ? helpers.consoleTraceHelper |
1347 : helpers.postTraceHelper; | 1345 : helpers.postTraceHelper; |
1348 assert(traceHelper != null); | 1346 assert(traceHelper != null); |
1349 enqueueInResolution(traceHelper, registry); | 1347 enqueue(enqueuer, traceHelper); |
1350 } | 1348 } |
1351 enqueueInResolution(helpers.assertUnreachableMethod, registry); | 1349 enqueue(enqueuer, helpers.assertUnreachableMethod); |
1352 registerCheckedModeHelpers(registry); | 1350 registerCheckedModeHelpers(enqueuer); |
1353 } | 1351 } |
1354 | 1352 |
1355 onResolutionComplete() { | 1353 onResolutionComplete() { |
1356 super.onResolutionComplete(); | 1354 super.onResolutionComplete(); |
1357 computeMembersNeededForReflection(); | 1355 computeMembersNeededForReflection(); |
1358 rti.computeClassesNeedingRti(); | 1356 rti.computeClassesNeedingRti(); |
1359 _registeredMetadata.clear(); | 1357 _registeredMetadata.clear(); |
1360 } | 1358 } |
1361 | 1359 |
1362 onTypeInferenceComplete() { | 1360 onTypeInferenceComplete() { |
1363 super.onTypeInferenceComplete(); | 1361 super.onTypeInferenceComplete(); |
1364 noSuchMethodRegistry.onTypeInferenceComplete(); | 1362 noSuchMethodRegistry.onTypeInferenceComplete(); |
1365 } | 1363 } |
1366 | 1364 |
1367 void registerGetRuntimeTypeArgument(Registry registry) { | 1365 void registerGetRuntimeTypeArgument() { |
1368 enqueueImpact( | 1366 enqueueImpact(compiler.enqueuer.resolution, impacts.getRuntimeTypeArgument); |
1369 compiler.enqueuer.resolution, impacts.getRuntimeTypeArgument, registry); | |
1370 } | 1367 } |
1371 | 1368 |
1372 void registerCallMethodWithFreeTypeVariables( | 1369 void registerCallMethodWithFreeTypeVariables( |
1373 Element callMethod, Enqueuer enqueuer, Registry registry) { | 1370 Element callMethod, Enqueuer enqueuer) { |
1374 if (enqueuer.isResolutionQueue || methodNeedsRti(callMethod)) { | 1371 if (enqueuer.isResolutionQueue || methodNeedsRti(callMethod)) { |
1375 registerComputeSignature(enqueuer, registry); | 1372 registerComputeSignature(enqueuer); |
1376 } | 1373 } |
1377 } | 1374 } |
1378 | 1375 |
1379 void registerClosureWithFreeTypeVariables( | 1376 void registerClosureWithFreeTypeVariables( |
1380 Element closure, Enqueuer enqueuer, Registry registry) { | 1377 Element closure, Enqueuer enqueuer) { |
1381 if (enqueuer.isResolutionQueue || methodNeedsRti(closure)) { | 1378 if (enqueuer.isResolutionQueue || methodNeedsRti(closure)) { |
1382 registerComputeSignature(enqueuer, registry); | 1379 registerComputeSignature(enqueuer); |
1383 } | 1380 } |
1384 } | 1381 } |
1385 | 1382 |
1386 void registerBoundClosure(Enqueuer enqueuer) { | 1383 void registerBoundClosure(Enqueuer enqueuer) { |
1387 helpers.boundClosureClass.ensureResolved(resolution); | 1384 helpers.boundClosureClass.ensureResolved(resolution); |
1388 registerInstantiatedType( | 1385 enqueuer.registerInstantiatedType(helpers.boundClosureClass.rawType); |
1389 helpers.boundClosureClass.rawType, | |
1390 enqueuer, | |
1391 // Precise dependency is not important here. | |
1392 compiler.globalDependencies); | |
1393 } | 1386 } |
1394 | 1387 |
1395 void registerGetOfStaticFunction(Enqueuer enqueuer) { | 1388 void registerGetOfStaticFunction(Enqueuer enqueuer) { |
1396 helpers.closureClass.ensureResolved(resolution); | 1389 helpers.closureClass.ensureResolved(resolution); |
1397 registerInstantiatedType( | 1390 enqueuer.registerInstantiatedType(helpers.closureClass.rawType); |
1398 helpers.closureClass.rawType, enqueuer, compiler.globalDependencies); | |
1399 } | 1391 } |
1400 | 1392 |
1401 void registerComputeSignature(Enqueuer enqueuer, Registry registry) { | 1393 void registerComputeSignature(Enqueuer enqueuer) { |
1402 // Calls to [:computeSignature:] are generated by the emitter and we | 1394 // Calls to [:computeSignature:] are generated by the emitter and we |
1403 // therefore need to enqueue the used elements in the codegen enqueuer as | 1395 // therefore need to enqueue the used elements in the codegen enqueuer as |
1404 // well as in the resolution enqueuer. | 1396 // well as in the resolution enqueuer. |
1405 enqueueImpact(enqueuer, impacts.computeSignature, registry); | 1397 enqueueImpact(enqueuer, impacts.computeSignature); |
1406 } | 1398 } |
1407 | 1399 |
1408 void registerRuntimeType(Enqueuer enqueuer, Registry registry) { | 1400 void registerRuntimeType(ResolutionEnqueuer enqueuer) { |
1409 registerComputeSignature(enqueuer, registry); | 1401 registerComputeSignature(enqueuer); |
1410 enqueueInResolution(helpers.setRuntimeTypeInfo, registry); | 1402 enqueue(enqueuer, helpers.setRuntimeTypeInfo); |
1411 registerGetRuntimeTypeArgument(registry); | 1403 registerGetRuntimeTypeArgument(); |
1412 enqueueInResolution(helpers.getRuntimeTypeInfo, registry); | 1404 enqueue(enqueuer, helpers.getRuntimeTypeInfo); |
1413 enqueueClass(enqueuer, coreClasses.listClass, registry); | 1405 enqueueClass(enqueuer, coreClasses.listClass); |
1414 } | 1406 } |
1415 | 1407 |
1416 void registerTypeVariableBoundsSubtypeCheck( | 1408 void registerTypeVariableBoundsSubtypeCheck( |
1417 DartType typeArgument, DartType bound) { | 1409 DartType typeArgument, DartType bound) { |
1418 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound); | 1410 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound); |
1419 } | 1411 } |
1420 | 1412 |
1421 void registerCheckDeferredIsLoaded(Registry registry) { | 1413 void registerCheckDeferredIsLoaded(ResolutionEnqueuer enqueuer) { |
1422 enqueueInResolution(helpers.checkDeferredIsLoaded, registry); | 1414 enqueue(enqueuer, helpers.checkDeferredIsLoaded); |
1423 // Also register the types of the arguments passed to this method. | 1415 // Also register the types of the arguments passed to this method. |
1424 enqueueClass( | 1416 enqueueClass(enqueuer, coreClasses.stringClass); |
1425 compiler.enqueuer.resolution, coreClasses.stringClass, registry); | |
1426 } | 1417 } |
1427 | 1418 |
1428 void registerNoSuchMethod(FunctionElement noSuchMethod) { | 1419 void registerNoSuchMethod(FunctionElement noSuchMethod) { |
1429 noSuchMethodRegistry.registerNoSuchMethod(noSuchMethod); | 1420 noSuchMethodRegistry.registerNoSuchMethod(noSuchMethod); |
1430 } | 1421 } |
1431 | 1422 |
1432 /// Called when resolving a call to a foreign function. | 1423 /// Called when resolving a call to a foreign function. |
1433 native.NativeBehavior resolveForeignCall(Send node, Element element, | 1424 native.NativeBehavior resolveForeignCall(Send node, Element element, |
1434 CallStructure callStructure, ForeignResolver resolver) { | 1425 CallStructure callStructure, ForeignResolver resolver) { |
1435 native.NativeResolutionEnqueuer nativeEnqueuer = | 1426 native.NativeResolutionEnqueuer nativeEnqueuer = |
(...skipping 21 matching lines...) Expand all Loading... |
1457 } | 1448 } |
1458 } | 1449 } |
1459 reporter.reportErrorMessage( | 1450 reporter.reportErrorMessage( |
1460 node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); | 1451 node, MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); |
1461 } | 1452 } |
1462 // No native behavior for this call. | 1453 // No native behavior for this call. |
1463 return null; | 1454 return null; |
1464 } | 1455 } |
1465 | 1456 |
1466 void enableNoSuchMethod(Enqueuer world) { | 1457 void enableNoSuchMethod(Enqueuer world) { |
1467 enqueue(world, helpers.createInvocationMirror, compiler.globalDependencies); | 1458 enqueue(world, helpers.createInvocationMirror); |
1468 world.registerDynamicUse(new DynamicUse(Selectors.noSuchMethod_, null)); | 1459 world.registerDynamicUse(new DynamicUse(Selectors.noSuchMethod_, null)); |
1469 } | 1460 } |
1470 | 1461 |
1471 void enableIsolateSupport(Enqueuer enqueuer) { | 1462 void enableIsolateSupport(Enqueuer enqueuer) { |
1472 // TODO(floitsch): We should also ensure that the class IsolateMessage is | 1463 // TODO(floitsch): We should also ensure that the class IsolateMessage is |
1473 // instantiated. Currently, just enabling isolate support works. | 1464 // instantiated. Currently, just enabling isolate support works. |
1474 if (compiler.mainFunction != null) { | 1465 if (compiler.mainFunction != null) { |
1475 // The JavaScript backend implements [Isolate.spawn] by looking up | 1466 // The JavaScript backend implements [Isolate.spawn] by looking up |
1476 // top-level functions by name. So all top-level function tear-off | 1467 // top-level functions by name. So all top-level function tear-off |
1477 // closures have a private name field. | 1468 // closures have a private name field. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1520 } | 1511 } |
1521 | 1512 |
1522 bool methodNeedsRti(FunctionElement function) { | 1513 bool methodNeedsRti(FunctionElement function) { |
1523 return rti.methodsNeedingRti.contains(function) || | 1514 return rti.methodsNeedingRti.contains(function) || |
1524 compiler.enabledRuntimeType; | 1515 compiler.enabledRuntimeType; |
1525 } | 1516 } |
1526 | 1517 |
1527 /// Enqueue [e] in [enqueuer]. | 1518 /// Enqueue [e] in [enqueuer]. |
1528 /// | 1519 /// |
1529 /// This method calls [registerBackendUse]. | 1520 /// This method calls [registerBackendUse]. |
1530 void enqueue(Enqueuer enqueuer, Element e, Registry registry) { | 1521 void enqueue(Enqueuer enqueuer, Element e) { |
1531 if (e == null) return; | 1522 if (e == null) return; |
1532 registerBackendUse(e); | 1523 registerBackendUse(e); |
1533 enqueuer.addToWorkList(e); | 1524 enqueuer.addToWorkList(e); |
1534 registry.registerDependency(e); | 1525 compiler.globalDependencies.registerDependency(e); |
1535 } | |
1536 | |
1537 /// Enqueue [e] in the resolution enqueuer. | |
1538 /// | |
1539 /// This method calls [registerBackendUse]. | |
1540 void enqueueInResolution(Element e, Registry registry) { | |
1541 if (e == null) return; | |
1542 ResolutionEnqueuer enqueuer = compiler.enqueuer.resolution; | |
1543 enqueue(enqueuer, e, registry); | |
1544 } | 1526 } |
1545 | 1527 |
1546 /// Register instantiation of [cls] in [enqueuer]. | 1528 /// Register instantiation of [cls] in [enqueuer]. |
1547 /// | 1529 /// |
1548 /// This method calls [registerBackendUse]. | 1530 /// This method calls [registerBackendUse]. |
1549 void enqueueClass(Enqueuer enqueuer, ClassElement cls, Registry registry) { | 1531 void enqueueClass(Enqueuer enqueuer, ClassElement cls) { |
1550 if (cls == null) return; | 1532 if (cls == null) return; |
1551 registerBackendUse(cls); | 1533 registerBackendUse(cls); |
1552 helpersUsed.add(cls.declaration); | 1534 helpersUsed.add(cls.declaration); |
1553 if (cls.declaration != cls.implementation) { | 1535 if (cls.declaration != cls.implementation) { |
1554 helpersUsed.add(cls.implementation); | 1536 helpersUsed.add(cls.implementation); |
1555 } | 1537 } |
1556 cls.ensureResolved(resolution); | 1538 cls.ensureResolved(resolution); |
1557 registerInstantiatedType(cls.rawType, enqueuer, registry); | 1539 enqueuer.registerInstantiatedType(cls.rawType); |
1558 } | 1540 } |
1559 | 1541 |
1560 /// Register instantiation of [type] in [enqueuer]. | 1542 /// Register instantiation of [type] in [enqueuer]. |
1561 /// | 1543 /// |
1562 /// This method calls [registerBackendUse]. | 1544 /// This method calls [registerBackendUse]. |
1563 void enqueueType(Enqueuer enqueuer, InterfaceType type, Registry registry) { | 1545 void enqueueType(Enqueuer enqueuer, InterfaceType type) { |
1564 if (type == null) return; | 1546 if (type == null) return; |
1565 ClassElement cls = type.element; | 1547 ClassElement cls = type.element; |
1566 registerBackendUse(cls); | 1548 registerBackendUse(cls); |
1567 helpersUsed.add(cls.declaration); | 1549 helpersUsed.add(cls.declaration); |
1568 if (cls.declaration != cls.implementation) { | 1550 if (cls.declaration != cls.implementation) { |
1569 helpersUsed.add(cls.implementation); | 1551 helpersUsed.add(cls.implementation); |
1570 } | 1552 } |
1571 cls.ensureResolved(resolution); | 1553 cls.ensureResolved(resolution); |
1572 registerInstantiatedType(type, enqueuer, registry); | 1554 enqueuer.registerInstantiatedType(type); |
1573 } | 1555 } |
1574 | 1556 |
1575 void enqueueImpact( | 1557 void enqueueImpact(Enqueuer enqueuer, BackendImpact impact) { |
1576 Enqueuer enqueuer, BackendImpact impact, Registry registry) { | |
1577 for (Element staticUse in impact.staticUses) { | 1558 for (Element staticUse in impact.staticUses) { |
1578 enqueue(enqueuer, staticUse, registry); | 1559 enqueue(enqueuer, staticUse); |
1579 } | 1560 } |
1580 for (InterfaceType type in impact.instantiatedTypes) { | 1561 for (InterfaceType type in impact.instantiatedTypes) { |
1581 enqueueType(enqueuer, type, registry); | 1562 enqueueType(enqueuer, type); |
1582 } | 1563 } |
1583 for (ClassElement cls in impact.instantiatedClasses) { | 1564 for (ClassElement cls in impact.instantiatedClasses) { |
1584 enqueueClass(enqueuer, cls, registry); | 1565 enqueueClass(enqueuer, cls); |
1585 } | 1566 } |
1586 for (BackendImpact otherImpact in impact.otherImpacts) { | 1567 for (BackendImpact otherImpact in impact.otherImpacts) { |
1587 enqueueImpact(enqueuer, otherImpact, registry); | 1568 enqueueImpact(enqueuer, otherImpact); |
1588 } | 1569 } |
1589 } | 1570 } |
1590 | 1571 |
1591 CodegenEnqueuer get codegenEnqueuer => compiler.enqueuer.codegen; | 1572 CodegenEnqueuer get codegenEnqueuer => compiler.enqueuer.codegen; |
1592 | 1573 |
1593 CodegenEnqueuer createCodegenEnqueuer(Compiler compiler) { | 1574 CodegenEnqueuer createCodegenEnqueuer(Compiler compiler) { |
1594 return new CodegenEnqueuer(compiler, const TreeShakingEnqueuerStrategy()); | 1575 return new CodegenEnqueuer(compiler, const TreeShakingEnqueuerStrategy()); |
1595 } | 1576 } |
1596 | 1577 |
1597 WorldImpact codegen(CodegenWorkItem work) { | 1578 WorldImpact codegen(CodegenWorkItem work) { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1659 sourceInformationStrategy.buildSourceMappedMarker()); | 1640 sourceInformationStrategy.buildSourceMappedMarker()); |
1660 } | 1641 } |
1661 generatedCode[element] = function; | 1642 generatedCode[element] = function; |
1662 WorldImpact worldImpact = | 1643 WorldImpact worldImpact = |
1663 impactTransformer.transformCodegenImpact(work.registry.worldImpact); | 1644 impactTransformer.transformCodegenImpact(work.registry.worldImpact); |
1664 compiler.dumpInfoTask.registerImpact(element, worldImpact); | 1645 compiler.dumpInfoTask.registerImpact(element, worldImpact); |
1665 return worldImpact; | 1646 return worldImpact; |
1666 } | 1647 } |
1667 | 1648 |
1668 native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) { | 1649 native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) { |
1669 return new native.NativeResolutionEnqueuer(world, compiler); | 1650 return new native.NativeResolutionEnqueuer(compiler); |
1670 } | 1651 } |
1671 | 1652 |
1672 native.NativeEnqueuer nativeCodegenEnqueuer(Enqueuer world) { | 1653 native.NativeEnqueuer nativeCodegenEnqueuer(Enqueuer world) { |
1673 return new native.NativeCodegenEnqueuer(world, compiler, emitter); | 1654 return new native.NativeCodegenEnqueuer(compiler, emitter); |
1674 } | 1655 } |
1675 | 1656 |
1676 ClassElement defaultSuperclass(ClassElement element) { | 1657 ClassElement defaultSuperclass(ClassElement element) { |
1677 if (isJsInterop(element)) { | 1658 if (isJsInterop(element)) { |
1678 return helpers.jsJavaScriptObjectClass; | 1659 return helpers.jsJavaScriptObjectClass; |
1679 } | 1660 } |
1680 // Native classes inherit from Interceptor. | 1661 // Native classes inherit from Interceptor. |
1681 return isNative(element) | 1662 return isNative(element) |
1682 ? helpers.jsInterceptorClass | 1663 ? helpers.jsInterceptorClass |
1683 : coreClasses.objectClass; | 1664 : coreClasses.objectClass; |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1863 // interceptors? | 1844 // interceptors? |
1864 return typeCast ? 'interceptedTypeCast' : 'interceptedTypeCheck'; | 1845 return typeCast ? 'interceptedTypeCast' : 'interceptedTypeCheck'; |
1865 } else { | 1846 } else { |
1866 return typeCast ? 'propertyTypeCast' : 'propertyTypeCheck'; | 1847 return typeCast ? 'propertyTypeCast' : 'propertyTypeCheck'; |
1867 } | 1848 } |
1868 } | 1849 } |
1869 } | 1850 } |
1870 } | 1851 } |
1871 } | 1852 } |
1872 | 1853 |
1873 void registerCheckedModeHelpers(Registry registry) { | 1854 void registerCheckedModeHelpers(ResolutionEnqueuer enqueuer) { |
1874 // We register all the helpers in the resolution queue. | 1855 // We register all the helpers in the resolution queue. |
1875 // TODO(13155): Find a way to register fewer helpers. | 1856 // TODO(13155): Find a way to register fewer helpers. |
1876 for (CheckedModeHelper helper in checkedModeHelpers) { | 1857 for (CheckedModeHelper helper in checkedModeHelpers) { |
1877 enqueueInResolution(helper.getStaticUse(compiler).element, registry); | 1858 enqueue(enqueuer, helper.getStaticUse(compiler).element); |
1878 } | 1859 } |
1879 } | 1860 } |
1880 | 1861 |
1881 /** | 1862 /** |
1882 * Returns [:true:] if the checking of [type] is performed directly on the | 1863 * Returns [:true:] if the checking of [type] is performed directly on the |
1883 * object and not on an interceptor. | 1864 * object and not on an interceptor. |
1884 */ | 1865 */ |
1885 bool hasDirectCheckFor(DartType type) { | 1866 bool hasDirectCheckFor(DartType type) { |
1886 Element element = type.element; | 1867 Element element = type.element; |
1887 return element == coreClasses.stringClass || | 1868 return element == coreClasses.stringClass || |
(...skipping 11 matching lines...) Expand all Loading... |
1899 bool mayGenerateInstanceofCheck(DartType type) { | 1880 bool mayGenerateInstanceofCheck(DartType type) { |
1900 // We can use an instanceof check for raw types that have no subclass that | 1881 // We can use an instanceof check for raw types that have no subclass that |
1901 // is mixed-in or in an implements clause. | 1882 // is mixed-in or in an implements clause. |
1902 | 1883 |
1903 if (!type.isRaw) return false; | 1884 if (!type.isRaw) return false; |
1904 ClassElement classElement = type.element; | 1885 ClassElement classElement = type.element; |
1905 if (isInterceptorClass(classElement)) return false; | 1886 if (isInterceptorClass(classElement)) return false; |
1906 return compiler.closedWorld.hasOnlySubclasses(classElement); | 1887 return compiler.closedWorld.hasOnlySubclasses(classElement); |
1907 } | 1888 } |
1908 | 1889 |
1909 void registerStaticUse(Element element, {bool forResolution}) { | 1890 void registerStaticUse(Enqueuer enqueuer, Element element) { |
1910 if (element == helpers.disableTreeShakingMarker) { | 1891 if (element == helpers.disableTreeShakingMarker) { |
1911 isTreeShakingDisabled = true; | 1892 isTreeShakingDisabled = true; |
1912 } else if (element == helpers.preserveNamesMarker) { | 1893 } else if (element == helpers.preserveNamesMarker) { |
1913 mustPreserveNames = true; | 1894 mustPreserveNames = true; |
1914 } else if (element == helpers.preserveMetadataMarker) { | 1895 } else if (element == helpers.preserveMetadataMarker) { |
1915 mustRetainMetadata = true; | 1896 mustRetainMetadata = true; |
1916 } else if (element == helpers.preserveUrisMarker) { | 1897 } else if (element == helpers.preserveUrisMarker) { |
1917 if (compiler.options.preserveUris) mustPreserveUris = true; | 1898 if (compiler.options.preserveUris) mustPreserveUris = true; |
1918 } else if (element == helpers.preserveLibraryNamesMarker) { | 1899 } else if (element == helpers.preserveLibraryNamesMarker) { |
1919 mustRetainLibraryNames = true; | 1900 mustRetainLibraryNames = true; |
1920 } else if (element == helpers.getIsolateAffinityTagMarker) { | 1901 } else if (element == helpers.getIsolateAffinityTagMarker) { |
1921 needToInitializeIsolateAffinityTag = true; | 1902 needToInitializeIsolateAffinityTag = true; |
1922 } else if (element.isDeferredLoaderGetter) { | 1903 } else if (element.isDeferredLoaderGetter) { |
1923 // TODO(sigurdm): Create a function registerLoadLibraryAccess. | 1904 // TODO(sigurdm): Create a function registerLoadLibraryAccess. |
1924 if (!isLoadLibraryFunctionResolved) { | 1905 if (!isLoadLibraryFunctionResolved) { |
1925 isLoadLibraryFunctionResolved = true; | 1906 isLoadLibraryFunctionResolved = true; |
1926 enqueueInResolution( | 1907 if (enqueuer.isResolutionQueue) { |
1927 helpers.loadLibraryWrapper, compiler.globalDependencies); | 1908 enqueue(enqueuer, helpers.loadLibraryWrapper); |
| 1909 } |
1928 } | 1910 } |
1929 } else if (element == helpers.requiresPreambleMarker) { | 1911 } else if (element == helpers.requiresPreambleMarker) { |
1930 requiresPreamble = true; | 1912 requiresPreamble = true; |
1931 } | 1913 } |
1932 customElementsAnalysis.registerStaticUse(element, | 1914 customElementsAnalysis.registerStaticUse(element, |
1933 forResolution: forResolution); | 1915 forResolution: enqueuer.isResolutionQueue); |
1934 } | 1916 } |
1935 | 1917 |
1936 /// Called when [:const Symbol(name):] is seen. | 1918 /// Called when [:const Symbol(name):] is seen. |
1937 void registerConstSymbol(String name) { | 1919 void registerConstSymbol(String name) { |
1938 symbolsUsed.add(name); | 1920 symbolsUsed.add(name); |
1939 if (name.endsWith('=')) { | 1921 if (name.endsWith('=')) { |
1940 symbolsUsed.add(name.substring(0, name.length - 1)); | 1922 symbolsUsed.add(name.substring(0, name.length - 1)); |
1941 } | 1923 } |
1942 } | 1924 } |
1943 | 1925 |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2388 registerBackendUse(e); | 2370 registerBackendUse(e); |
2389 enqueuer.addToWorkList(e); | 2371 enqueuer.addToWorkList(e); |
2390 } | 2372 } |
2391 } | 2373 } |
2392 | 2374 |
2393 if (!enqueuer.isResolutionQueue && preMirrorsMethodCount == 0) { | 2375 if (!enqueuer.isResolutionQueue && preMirrorsMethodCount == 0) { |
2394 preMirrorsMethodCount = generatedCode.length; | 2376 preMirrorsMethodCount = generatedCode.length; |
2395 } | 2377 } |
2396 | 2378 |
2397 if (isTreeShakingDisabled) { | 2379 if (isTreeShakingDisabled) { |
2398 enqueuer.enqueueReflectiveElements(recentClasses); | 2380 mirrorsAnalysis.enqueueReflectiveElements( |
| 2381 enqueuer, recentClasses, compiler.libraryLoader.libraries); |
2399 } else if (!targetsUsed.isEmpty && enqueuer.isResolutionQueue) { | 2382 } else if (!targetsUsed.isEmpty && enqueuer.isResolutionQueue) { |
2400 // Add all static elements (not classes) that have been requested for | 2383 // Add all static elements (not classes) that have been requested for |
2401 // reflection. If there is no mirror-usage these are probably not | 2384 // reflection. If there is no mirror-usage these are probably not |
2402 // necessary, but the backend relies on them being resolved. | 2385 // necessary, but the backend relies on them being resolved. |
2403 enqueuer.enqueueReflectiveStaticFields(_findStaticFieldTargets()); | 2386 mirrorsAnalysis.enqueueReflectiveStaticFields( |
| 2387 enqueuer, _findStaticFieldTargets()); |
2404 } | 2388 } |
2405 | 2389 |
2406 if (mustPreserveNames) reporter.log('Preserving names.'); | 2390 if (mustPreserveNames) reporter.log('Preserving names.'); |
2407 | 2391 |
2408 if (mustRetainMetadata) { | 2392 if (mustRetainMetadata) { |
2409 reporter.log('Retaining metadata.'); | 2393 reporter.log('Retaining metadata.'); |
2410 | 2394 |
2411 compiler.libraryLoader.libraries.forEach(retainMetadataOf); | 2395 compiler.libraryLoader.libraries.forEach(retainMetadataOf); |
2412 | 2396 |
2413 StagedWorldImpactBuilder impactBuilder = enqueuer.isResolutionQueue | 2397 StagedWorldImpactBuilder impactBuilder = enqueuer.isResolutionQueue |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2600 assert(name != ""); | 2584 assert(name != ""); |
2601 String outPath = compiler.options.outputUri != null | 2585 String outPath = compiler.options.outputUri != null |
2602 ? compiler.options.outputUri.path | 2586 ? compiler.options.outputUri.path |
2603 : "out"; | 2587 : "out"; |
2604 String outName = outPath.substring(outPath.lastIndexOf('/') + 1); | 2588 String outName = outPath.substring(outPath.lastIndexOf('/') + 1); |
2605 String extension = addExtension ? ".part.js" : ""; | 2589 String extension = addExtension ? ".part.js" : ""; |
2606 return "${outName}_$name$extension"; | 2590 return "${outName}_$name$extension"; |
2607 } | 2591 } |
2608 | 2592 |
2609 @override | 2593 @override |
2610 bool enableDeferredLoadingIfSupported(Spannable node, Registry registry) { | 2594 bool enableDeferredLoadingIfSupported( |
2611 registerCheckDeferredIsLoaded(registry); | 2595 ResolutionEnqueuer enqueuer, Spannable node) { |
| 2596 registerCheckDeferredIsLoaded(enqueuer); |
2612 return true; | 2597 return true; |
2613 } | 2598 } |
2614 | 2599 |
2615 @override | 2600 @override |
2616 bool enableCodegenWithErrorsIfSupported(Spannable node) => true; | 2601 bool enableCodegenWithErrorsIfSupported(Spannable node) => true; |
2617 | 2602 |
2618 jsAst.Expression rewriteAsync( | 2603 jsAst.Expression rewriteAsync( |
2619 FunctionElement element, jsAst.Expression code) { | 2604 FunctionElement element, jsAst.Expression code) { |
2620 AsyncRewriterBase rewriter = null; | 2605 AsyncRewriterBase rewriter = null; |
2621 jsAst.Name name = namer.methodPropertyName(element); | 2606 jsAst.Name name = namer.methodPropertyName(element); |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2785 } | 2770 } |
2786 } | 2771 } |
2787 | 2772 |
2788 class JavaScriptImpactTransformer extends ImpactTransformer { | 2773 class JavaScriptImpactTransformer extends ImpactTransformer { |
2789 final JavaScriptBackend backend; | 2774 final JavaScriptBackend backend; |
2790 | 2775 |
2791 JavaScriptImpactTransformer(this.backend); | 2776 JavaScriptImpactTransformer(this.backend); |
2792 | 2777 |
2793 BackendImpacts get impacts => backend.impacts; | 2778 BackendImpacts get impacts => backend.impacts; |
2794 | 2779 |
2795 // TODO(johnniwinther): Avoid this dependency. | |
2796 ResolutionEnqueuer get resolutionEnqueuer { | |
2797 return backend.compiler.enqueuer.resolution; | |
2798 } | |
2799 | |
2800 @override | 2780 @override |
2801 WorldImpact transformResolutionImpact(ResolutionImpact worldImpact) { | 2781 WorldImpact transformResolutionImpact( |
| 2782 ResolutionEnqueuer enqueuer, ResolutionImpact worldImpact) { |
2802 TransformedWorldImpact transformed = | 2783 TransformedWorldImpact transformed = |
2803 new TransformedWorldImpact(worldImpact); | 2784 new TransformedWorldImpact(worldImpact); |
2804 for (Feature feature in worldImpact.features) { | 2785 for (Feature feature in worldImpact.features) { |
2805 switch (feature) { | 2786 switch (feature) { |
2806 case Feature.ABSTRACT_CLASS_INSTANTIATION: | 2787 case Feature.ABSTRACT_CLASS_INSTANTIATION: |
2807 registerBackendImpact( | 2788 registerBackendImpact( |
2808 transformed, impacts.abstractClassInstantiation); | 2789 transformed, impacts.abstractClassInstantiation); |
2809 break; | 2790 break; |
2810 case Feature.ASSERT: | 2791 case Feature.ASSERT: |
2811 registerBackendImpact(transformed, impacts.assertWithoutMessage); | 2792 registerBackendImpact(transformed, impacts.assertWithoutMessage); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2878 break; | 2859 break; |
2879 } | 2860 } |
2880 } | 2861 } |
2881 | 2862 |
2882 bool hasAsCast = false; | 2863 bool hasAsCast = false; |
2883 bool hasTypeLiteral = false; | 2864 bool hasTypeLiteral = false; |
2884 for (TypeUse typeUse in worldImpact.typeUses) { | 2865 for (TypeUse typeUse in worldImpact.typeUses) { |
2885 DartType type = typeUse.type; | 2866 DartType type = typeUse.type; |
2886 switch (typeUse.kind) { | 2867 switch (typeUse.kind) { |
2887 case TypeUseKind.INSTANTIATION: | 2868 case TypeUseKind.INSTANTIATION: |
| 2869 case TypeUseKind.MIRROR_INSTANTIATION: |
| 2870 case TypeUseKind.NATIVE_INSTANTIATION: |
2888 registerRequiredType(type); | 2871 registerRequiredType(type); |
2889 break; | 2872 break; |
2890 case TypeUseKind.IS_CHECK: | 2873 case TypeUseKind.IS_CHECK: |
2891 onIsCheck(type, transformed); | 2874 onIsCheck(type, transformed); |
2892 break; | 2875 break; |
2893 case TypeUseKind.AS_CAST: | 2876 case TypeUseKind.AS_CAST: |
2894 onIsCheck(type, transformed); | 2877 onIsCheck(type, transformed); |
2895 hasAsCast = true; | 2878 hasAsCast = true; |
2896 break; | 2879 break; |
2897 case TypeUseKind.CHECKED_MODE_CHECK: | 2880 case TypeUseKind.CHECKED_MODE_CHECK: |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2958 backend.registerConstSymbol(constSymbolName); | 2941 backend.registerConstSymbol(constSymbolName); |
2959 } | 2942 } |
2960 } | 2943 } |
2961 | 2944 |
2962 for (StaticUse staticUse in worldImpact.staticUses) { | 2945 for (StaticUse staticUse in worldImpact.staticUses) { |
2963 switch (staticUse.kind) { | 2946 switch (staticUse.kind) { |
2964 case StaticUseKind.CLOSURE: | 2947 case StaticUseKind.CLOSURE: |
2965 registerBackendImpact(transformed, impacts.closure); | 2948 registerBackendImpact(transformed, impacts.closure); |
2966 LocalFunctionElement closure = staticUse.element; | 2949 LocalFunctionElement closure = staticUse.element; |
2967 if (closure.type.containsTypeVariables) { | 2950 if (closure.type.containsTypeVariables) { |
2968 resolutionEnqueuer.universe.closuresWithFreeTypeVariables | |
2969 .add(closure); | |
2970 registerBackendImpact(transformed, impacts.computeSignature); | 2951 registerBackendImpact(transformed, impacts.computeSignature); |
2971 } | 2952 } |
2972 break; | 2953 break; |
2973 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: | 2954 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: |
2974 case StaticUseKind.CONSTRUCTOR_INVOKE: | 2955 case StaticUseKind.CONSTRUCTOR_INVOKE: |
2975 registerRequiredType(staticUse.type); | 2956 registerRequiredType(staticUse.type); |
2976 break; | 2957 break; |
2977 default: | 2958 default: |
2978 } | 2959 } |
2979 } | 2960 } |
(...skipping 15 matching lines...) Expand all Loading... |
2995 case ConstantExpressionKind.STRING: | 2976 case ConstantExpressionKind.STRING: |
2996 registerBackendImpact(transformed, impacts.stringLiteral); | 2977 registerBackendImpact(transformed, impacts.stringLiteral); |
2997 break; | 2978 break; |
2998 default: | 2979 default: |
2999 assert(invariant(NO_LOCATION_SPANNABLE, false, | 2980 assert(invariant(NO_LOCATION_SPANNABLE, false, |
3000 message: "Unexpected constant literal: ${constant.kind}.")); | 2981 message: "Unexpected constant literal: ${constant.kind}.")); |
3001 } | 2982 } |
3002 } | 2983 } |
3003 | 2984 |
3004 for (native.NativeBehavior behavior in worldImpact.nativeData) { | 2985 for (native.NativeBehavior behavior in worldImpact.nativeData) { |
3005 resolutionEnqueuer.nativeEnqueuer | 2986 enqueuer.nativeEnqueuer |
3006 .registerNativeBehavior(behavior, worldImpact); | 2987 .registerNativeBehavior(transformed, behavior, worldImpact); |
3007 } | 2988 } |
3008 | 2989 |
3009 return transformed; | 2990 return transformed; |
3010 } | 2991 } |
3011 | 2992 |
3012 void registerBackendImpact( | 2993 void registerBackendImpact( |
3013 TransformedWorldImpact worldImpact, BackendImpact backendImpact) { | 2994 TransformedWorldImpact worldImpact, BackendImpact backendImpact) { |
3014 for (Element staticUse in backendImpact.staticUses) { | 2995 for (Element staticUse in backendImpact.staticUses) { |
3015 assert(staticUse != null); | 2996 assert(staticUse != null); |
3016 backend.registerBackendUse(staticUse); | 2997 backend.registerBackendUse(staticUse); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3096 | 3077 |
3097 void onIsCheckForCodegen(DartType type, TransformedWorldImpact transformed) { | 3078 void onIsCheckForCodegen(DartType type, TransformedWorldImpact transformed) { |
3098 type = type.unaliased; | 3079 type = type.unaliased; |
3099 registerBackendImpact(transformed, impacts.typeCheck); | 3080 registerBackendImpact(transformed, impacts.typeCheck); |
3100 | 3081 |
3101 bool inCheckedMode = backend.compiler.options.enableTypeAssertions; | 3082 bool inCheckedMode = backend.compiler.options.enableTypeAssertions; |
3102 // [registerIsCheck] is also called for checked mode checks, so we | 3083 // [registerIsCheck] is also called for checked mode checks, so we |
3103 // need to register checked mode helpers. | 3084 // need to register checked mode helpers. |
3104 if (inCheckedMode) { | 3085 if (inCheckedMode) { |
3105 // All helpers are added to resolution queue in enqueueHelpers. These | 3086 // All helpers are added to resolution queue in enqueueHelpers. These |
3106 // calls to enqueueInResolution serve as assertions that the helper was | 3087 // calls to [enqueue] with the resolution enqueuer serve as assertions |
3107 // in fact added. | 3088 // that the helper was in fact added. |
3108 // TODO(13155): Find a way to enqueue helpers lazily. | 3089 // TODO(13155): Find a way to enqueue helpers lazily. |
3109 CheckedModeHelper helper = | 3090 CheckedModeHelper helper = |
3110 backend.getCheckedModeHelper(type, typeCast: false); | 3091 backend.getCheckedModeHelper(type, typeCast: false); |
3111 if (helper != null) { | 3092 if (helper != null) { |
3112 StaticUse staticUse = helper.getStaticUse(backend.compiler); | 3093 StaticUse staticUse = helper.getStaticUse(backend.compiler); |
3113 transformed.registerStaticUse(staticUse); | 3094 transformed.registerStaticUse(staticUse); |
3114 backend.registerBackendUse(staticUse.element); | 3095 backend.registerBackendUse(staticUse.element); |
3115 } | 3096 } |
3116 // We also need the native variant of the check (for DOM types). | 3097 // We also need the native variant of the check (for DOM types). |
3117 helper = backend.getNativeCheckedModeHelper(type, typeCast: false); | 3098 helper = backend.getNativeCheckedModeHelper(type, typeCast: false); |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3288 ClassElement get mapImplementation => helpers.mapLiteralClass; | 3269 ClassElement get mapImplementation => helpers.mapLiteralClass; |
3289 ClassElement get constMapImplementation => helpers.constMapLiteralClass; | 3270 ClassElement get constMapImplementation => helpers.constMapLiteralClass; |
3290 ClassElement get typeImplementation => helpers.typeLiteralClass; | 3271 ClassElement get typeImplementation => helpers.typeLiteralClass; |
3291 ClassElement get boolImplementation => helpers.jsBoolClass; | 3272 ClassElement get boolImplementation => helpers.jsBoolClass; |
3292 ClassElement get nullImplementation => helpers.jsNullClass; | 3273 ClassElement get nullImplementation => helpers.jsNullClass; |
3293 ClassElement get syncStarIterableImplementation => helpers.syncStarIterable; | 3274 ClassElement get syncStarIterableImplementation => helpers.syncStarIterable; |
3294 ClassElement get asyncFutureImplementation => helpers.futureImplementation; | 3275 ClassElement get asyncFutureImplementation => helpers.futureImplementation; |
3295 ClassElement get asyncStarStreamImplementation => helpers.controllerStream; | 3276 ClassElement get asyncStarStreamImplementation => helpers.controllerStream; |
3296 ClassElement get functionImplementation => helpers.coreClasses.functionClass; | 3277 ClassElement get functionImplementation => helpers.coreClasses.functionClass; |
3297 } | 3278 } |
OLD | NEW |