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

Side by Side Diff: pkg/compiler/lib/src/js_backend/backend.dart

Issue 1397043002: Introduce BackendImpact to separate enqueueing from data. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Updated cf. comments. Created 5 years, 2 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of js_backend; 5 part of js_backend;
6 6
7 const VERBOSE_OPTIMIZER_HINTS = false; 7 const VERBOSE_OPTIMIZER_HINTS = false;
8 8
9 class JavaScriptItemCompilationContext extends ItemCompilationContext { 9 class JavaScriptItemCompilationContext extends ItemCompilationContext {
10 final Set<HInstruction> boundsChecked = new Set<HInstruction>(); 10 final Set<HInstruction> boundsChecked = new Set<HInstruction>();
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 FunctionInlineCache inlineCache = new FunctionInlineCache(); 271 FunctionInlineCache inlineCache = new FunctionInlineCache();
272 272
273 LibraryElement jsHelperLibrary; 273 LibraryElement jsHelperLibrary;
274 LibraryElement asyncLibrary; 274 LibraryElement asyncLibrary;
275 LibraryElement interceptorsLibrary; 275 LibraryElement interceptorsLibrary;
276 LibraryElement foreignLibrary; 276 LibraryElement foreignLibrary;
277 LibraryElement isolateHelperLibrary; 277 LibraryElement isolateHelperLibrary;
278 278
279 ClassElement closureClass; 279 ClassElement closureClass;
280 ClassElement boundClosureClass; 280 ClassElement boundClosureClass;
281 Element assertTestMethod;
282 Element assertThrowMethod;
283 Element assertHelperMethod;
284 Element assertUnreachableMethod; 281 Element assertUnreachableMethod;
285 Element invokeOnMethod; 282 Element invokeOnMethod;
286 283
287 ClassElement jsInterceptorClass; 284 ClassElement jsInterceptorClass;
288 ClassElement jsStringClass; 285 ClassElement jsStringClass;
289 ClassElement jsArrayClass; 286 ClassElement jsArrayClass;
290 ClassElement jsNumberClass; 287 ClassElement jsNumberClass;
291 ClassElement jsIntClass; 288 ClassElement jsIntClass;
292 ClassElement jsDoubleClass; 289 ClassElement jsDoubleClass;
293 ClassElement jsNullClass; 290 ClassElement jsNullClass;
(...skipping 13 matching lines...) Expand all
307 ClassElement jsUInt31Class; 304 ClassElement jsUInt31Class;
308 305
309 Element jsIndexableLength; 306 Element jsIndexableLength;
310 Element jsArrayTypedConstructor; 307 Element jsArrayTypedConstructor;
311 Element jsArrayRemoveLast; 308 Element jsArrayRemoveLast;
312 Element jsArrayAdd; 309 Element jsArrayAdd;
313 Element jsStringSplit; 310 Element jsStringSplit;
314 Element jsStringToString; 311 Element jsStringToString;
315 Element jsStringOperatorAdd; 312 Element jsStringOperatorAdd;
316 Element objectEquals; 313 Element objectEquals;
317 Element cachedCheckConcurrentModificationError;
318 314
319 ClassElement typeLiteralClass; 315 ClassElement typeLiteralClass;
320 ClassElement mapLiteralClass; 316 ClassElement mapLiteralClass;
321 ClassElement constMapLiteralClass; 317 ClassElement constMapLiteralClass;
322 ClassElement typeVariableClass; 318 ClassElement typeVariableClass;
323 ConstructorElement mapLiteralConstructor; 319 ConstructorElement mapLiteralConstructor;
324 ConstructorElement mapLiteralConstructorEmpty; 320 ConstructorElement mapLiteralConstructorEmpty;
325 Element mapLiteralUntypedMaker; 321 Element mapLiteralUntypedMaker;
326 Element mapLiteralUntypedEmptyMaker; 322 Element mapLiteralUntypedEmptyMaker;
327 323
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 JavaScriptConstantTask constantCompilerTask; 621 JavaScriptConstantTask constantCompilerTask;
626 622
627 JavaScriptResolutionCallbacks resolutionCallbacks; 623 JavaScriptResolutionCallbacks resolutionCallbacks;
628 624
629 PatchResolverTask patchResolverTask; 625 PatchResolverTask patchResolverTask;
630 626
631 bool enabledNoSuchMethod = false; 627 bool enabledNoSuchMethod = false;
632 628
633 final SourceInformationStrategy sourceInformationStrategy; 629 final SourceInformationStrategy sourceInformationStrategy;
634 630
631 final BackendHelpers helpers;
632 final BackendImpacts impacts;
633
635 JavaScriptBackend(Compiler compiler, 634 JavaScriptBackend(Compiler compiler,
636 {bool generateSourceMap: true, 635 {bool generateSourceMap: true,
637 bool useStartupEmitter: false}) 636 bool useStartupEmitter: false})
638 : namer = determineNamer(compiler), 637 : namer = determineNamer(compiler),
639 oneShotInterceptors = new Map<jsAst.Name, Selector>(), 638 oneShotInterceptors = new Map<jsAst.Name, Selector>(),
640 interceptedElements = new Map<String, Set<Element>>(), 639 interceptedElements = new Map<String, Set<Element>>(),
641 rti = new RuntimeTypes(compiler), 640 rti = new RuntimeTypes(compiler),
642 specializedGetInterceptors = new Map<jsAst.Name, Set<ClassElement>>(), 641 specializedGetInterceptors = new Map<jsAst.Name, Set<ClassElement>>(),
643 annotations = new Annotations(compiler), 642 annotations = new Annotations(compiler),
644 this.sourceInformationStrategy = 643 this.sourceInformationStrategy =
645 generateSourceMap 644 generateSourceMap
646 ? (useNewSourceInfo 645 ? (useNewSourceInfo
647 ? const PositionSourceInformationStrategy() 646 ? const PositionSourceInformationStrategy()
648 : const StartEndSourceInformationStrategy()) 647 : const StartEndSourceInformationStrategy())
649 : const JavaScriptSourceInformationStrategy(), 648 : const JavaScriptSourceInformationStrategy(),
649 helpers = new BackendHelpers(compiler),
650 impacts = new BackendImpacts(compiler),
650 super(compiler) { 651 super(compiler) {
651 emitter = new CodeEmitterTask( 652 emitter = new CodeEmitterTask(
652 compiler, namer, generateSourceMap, useStartupEmitter); 653 compiler, namer, generateSourceMap, useStartupEmitter);
653 typeVariableHandler = new TypeVariableHandler(compiler); 654 typeVariableHandler = new TypeVariableHandler(compiler);
654 customElementsAnalysis = new CustomElementsAnalysis(this); 655 customElementsAnalysis = new CustomElementsAnalysis(this);
655 lookupMapAnalysis = new LookupMapAnalysis(this, reporter); 656 lookupMapAnalysis = new LookupMapAnalysis(this, reporter);
656 noSuchMethodRegistry = new NoSuchMethodRegistry(this); 657 noSuchMethodRegistry = new NoSuchMethodRegistry(this);
657 constantCompilerTask = new JavaScriptConstantTask(compiler); 658 constantCompilerTask = new JavaScriptConstantTask(compiler);
658 resolutionCallbacks = new JavaScriptResolutionCallbacks(this); 659 resolutionCallbacks = new JavaScriptResolutionCallbacks(this);
659 patchResolverTask = new PatchResolverTask(compiler); 660 patchResolverTask = new PatchResolverTask(compiler);
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 registerInstantiatedConstantType(type, registry); 991 registerInstantiatedConstantType(type, registry);
991 992
992 if (constant.isFunction) { 993 if (constant.isFunction) {
993 FunctionConstantValue function = constant; 994 FunctionConstantValue function = constant;
994 registry.registerGetOfStaticFunction(function.element); 995 registry.registerGetOfStaticFunction(function.element);
995 } else if (constant.isInterceptor) { 996 } else if (constant.isInterceptor) {
996 // An interceptor constant references the class's prototype chain. 997 // An interceptor constant references the class's prototype chain.
997 InterceptorConstantValue interceptor = constant; 998 InterceptorConstantValue interceptor = constant;
998 registerInstantiatedConstantType(interceptor.dispatchedType, registry); 999 registerInstantiatedConstantType(interceptor.dispatchedType, registry);
999 } else if (constant.isType) { 1000 } else if (constant.isType) {
1000 enqueueInResolution(getCreateRuntimeType(), registry); 1001 enqueueInResolution(helpers.createRuntimeType, registry);
1001 registry.registerInstantiation(typeImplementation.rawType); 1002 registry.registerInstantiation(typeImplementation.rawType);
1002 } 1003 }
1003 lookupMapAnalysis.registerConstantKey(constant); 1004 lookupMapAnalysis.registerConstantKey(constant);
1004 } 1005 }
1005 1006
1006 void registerInstantiatedConstantType(DartType type, Registry registry) { 1007 void registerInstantiatedConstantType(DartType type, Registry registry) {
1007 DartType instantiatedType = 1008 DartType instantiatedType =
1008 type.isFunctionType ? compiler.functionClass.rawType : type; 1009 type.isFunctionType ? compiler.functionClass.rawType : type;
1009 if (type is InterfaceType) { 1010 if (type is InterfaceType) {
1010 registry.registerInstantiation(instantiatedType); 1011 registry.registerInstantiation(instantiatedType);
1011 if (!type.treatAsRaw && classNeedsRti(type.element)) { 1012 if (!type.treatAsRaw && classNeedsRti(type.element)) {
1012 registry.registerStaticInvocation(getSetRuntimeTypeInfo()); 1013 registry.registerStaticInvocation(helpers.setRuntimeTypeInfo);
1013 } 1014 }
1014 if (type.element == typeImplementation) { 1015 if (type.element == typeImplementation) {
1015 // If we use a type literal in a constant, the compile time 1016 // If we use a type literal in a constant, the compile time
1016 // constant emitter will generate a call to the createRuntimeType 1017 // constant emitter will generate a call to the createRuntimeType
1017 // helper so we register a use of that. 1018 // helper so we register a use of that.
1018 registry.registerStaticInvocation(getCreateRuntimeType()); 1019 registry.registerStaticInvocation(helpers.createRuntimeType);
1019 } 1020 }
1020 } 1021 }
1021 } 1022 }
1022 1023
1023 void registerMetadataConstant(MetadataAnnotation metadata, 1024 void registerMetadataConstant(MetadataAnnotation metadata,
1024 Element annotatedElement, 1025 Element annotatedElement,
1025 Registry registry) { 1026 Registry registry) {
1026 assert(registry.isForResolution); 1027 assert(registry.isForResolution);
1027 ConstantValue constant = constants.getConstantValueForMetadata(metadata); 1028 ConstantValue constant = constants.getConstantValueForMetadata(metadata);
1028 registerCompileTimeConstant(constant, registry, addForEmission: false); 1029 registerCompileTimeConstant(constant, registry, addForEmission: false);
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
1228 computeMembersNeededForReflection(); 1229 computeMembersNeededForReflection();
1229 rti.computeClassesNeedingRti(); 1230 rti.computeClassesNeedingRti();
1230 } 1231 }
1231 1232
1232 onTypeInferenceComplete() { 1233 onTypeInferenceComplete() {
1233 super.onTypeInferenceComplete(); 1234 super.onTypeInferenceComplete();
1234 noSuchMethodRegistry.onTypeInferenceComplete(); 1235 noSuchMethodRegistry.onTypeInferenceComplete();
1235 } 1236 }
1236 1237
1237 void registerGetRuntimeTypeArgument(Registry registry) { 1238 void registerGetRuntimeTypeArgument(Registry registry) {
1238 enqueueInResolution(getGetRuntimeTypeArgument(), registry); 1239 enqueueImpact(
1239 enqueueInResolution(getGetTypeArgumentByIndex(), registry); 1240 compiler.enqueuer.resolution,
1240 enqueueInResolution(getCopyTypeArguments(), registry); 1241 impacts.getRuntimeTypeArgument,
1242 registry);
1241 } 1243 }
1242 1244
1243 void registerCallMethodWithFreeTypeVariables( 1245 void registerCallMethodWithFreeTypeVariables(
1244 Element callMethod, 1246 Element callMethod,
1245 Enqueuer enqueuer, 1247 Enqueuer enqueuer,
1246 Registry registry) { 1248 Registry registry) {
1247 if (enqueuer.isResolutionQueue || methodNeedsRti(callMethod)) { 1249 if (enqueuer.isResolutionQueue || methodNeedsRti(callMethod)) {
1248 registerComputeSignature(enqueuer, registry); 1250 registerComputeSignature(enqueuer, registry);
1249 } 1251 }
1250 } 1252 }
(...skipping 30 matching lines...) Expand all
1281 registerInstantiatedType( 1283 registerInstantiatedType(
1282 closureClass.rawType, 1284 closureClass.rawType,
1283 enqueuer, 1285 enqueuer,
1284 compiler.globalDependencies); 1286 compiler.globalDependencies);
1285 } 1287 }
1286 1288
1287 void registerComputeSignature(Enqueuer enqueuer, Registry registry) { 1289 void registerComputeSignature(Enqueuer enqueuer, Registry registry) {
1288 // Calls to [:computeSignature:] are generated by the emitter and we 1290 // Calls to [:computeSignature:] are generated by the emitter and we
1289 // therefore need to enqueue the used elements in the codegen enqueuer as 1291 // therefore need to enqueue the used elements in the codegen enqueuer as
1290 // well as in the resolution enqueuer. 1292 // well as in the resolution enqueuer.
1291 enqueue(enqueuer, getSetRuntimeTypeInfo(), registry); 1293 enqueueImpact(enqueuer, impacts.computeSignature, registry);
1292 enqueue(enqueuer, getGetRuntimeTypeInfo(), registry);
1293 enqueue(enqueuer, getComputeSignature(), registry);
1294 enqueue(enqueuer, getGetRuntimeTypeArguments(), registry);
1295 enqueueClass(enqueuer, compiler.listClass, registry);
1296 } 1294 }
1297 1295
1298 void registerRuntimeType(Enqueuer enqueuer, Registry registry) { 1296 void registerRuntimeType(Enqueuer enqueuer, Registry registry) {
1299 registerComputeSignature(enqueuer, registry); 1297 registerComputeSignature(enqueuer, registry);
1300 enqueueInResolution(getSetRuntimeTypeInfo(), registry); 1298 enqueueInResolution(helpers.setRuntimeTypeInfo, registry);
1301 enqueueInResolution(getGetRuntimeTypeInfo(), registry);
1302 registerGetRuntimeTypeArgument(registry); 1299 registerGetRuntimeTypeArgument(registry);
1300 enqueueInResolution(helpers.getRuntimeTypeInfo, registry);
1303 enqueueClass(enqueuer, compiler.listClass, registry); 1301 enqueueClass(enqueuer, compiler.listClass, registry);
1304 } 1302 }
1305 1303
1306 void registerIsCheckForCodegen(DartType type, 1304 void registerIsCheckForCodegen(DartType type,
1307 Enqueuer world, 1305 Enqueuer world,
1308 Registry registry) { 1306 Registry registry) {
1309 assert(!registry.isForResolution); 1307 assert(!registry.isForResolution);
1310 type = type.unalias(resolution); 1308 type = type.unalias(resolution);
1311 enqueueClass(world, compiler.boolClass, registry); 1309 enqueueClass(world, compiler.boolClass, registry);
1312 bool inCheckedMode = compiler.enableTypeAssertions; 1310 bool inCheckedMode = compiler.enableTypeAssertions;
(...skipping 24 matching lines...) Expand all
1337 enqueue(world, findHelper('defineProperty'), registry); 1335 enqueue(world, findHelper('defineProperty'), registry);
1338 } 1336 }
1339 } 1337 }
1340 1338
1341 void registerTypeVariableBoundsSubtypeCheck(DartType typeArgument, 1339 void registerTypeVariableBoundsSubtypeCheck(DartType typeArgument,
1342 DartType bound) { 1340 DartType bound) {
1343 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound); 1341 rti.registerTypeVariableBoundsSubtypeCheck(typeArgument, bound);
1344 } 1342 }
1345 1343
1346 void registerCheckDeferredIsLoaded(Registry registry) { 1344 void registerCheckDeferredIsLoaded(Registry registry) {
1347 enqueueInResolution(getCheckDeferredIsLoaded(), registry); 1345 enqueueInResolution(helpers.checkDeferredIsLoaded, registry);
1348 // Also register the types of the arguments passed to this method. 1346 // Also register the types of the arguments passed to this method.
1349 enqueueClass(compiler.enqueuer.resolution, compiler.stringClass, registry); 1347 enqueueClass(compiler.enqueuer.resolution, compiler.stringClass, registry);
1350 } 1348 }
1351 1349
1352 void registerNoSuchMethod(FunctionElement noSuchMethod) { 1350 void registerNoSuchMethod(FunctionElement noSuchMethod) {
1353 noSuchMethodRegistry.registerNoSuchMethod(noSuchMethod); 1351 noSuchMethodRegistry.registerNoSuchMethod(noSuchMethod);
1354 } 1352 }
1355 1353
1356 /// Called when resolving a call to a foreign function. 1354 /// Called when resolving a call to a foreign function.
1357 void registerForeignCall(Send node, 1355 void registerForeignCall(Send node,
(...skipping 23 matching lines...) Expand all
1381 } 1379 }
1382 } 1380 }
1383 } 1381 }
1384 reporter.reportErrorMessage( 1382 reporter.reportErrorMessage(
1385 node, 1383 node,
1386 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT); 1384 MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT);
1387 } 1385 }
1388 } 1386 }
1389 1387
1390 void enableNoSuchMethod(Enqueuer world) { 1388 void enableNoSuchMethod(Enqueuer world) {
1391 enqueue(world, getCreateInvocationMirror(), compiler.globalDependencies); 1389 enqueue(world, helpers.createInvocationMirror, compiler.globalDependencies);
1392 world.registerInvocation( 1390 world.registerInvocation(
1393 new UniverseSelector(Selectors.noSuchMethod_, null)); 1391 new UniverseSelector(Selectors.noSuchMethod_, null));
1394 } 1392 }
1395 1393
1396 void enableIsolateSupport(Enqueuer enqueuer) { 1394 void enableIsolateSupport(Enqueuer enqueuer) {
1397 // TODO(floitsch): We should also ensure that the class IsolateMessage is 1395 // TODO(floitsch): We should also ensure that the class IsolateMessage is
1398 // instantiated. Currently, just enabling isolate support works. 1396 // instantiated. Currently, just enabling isolate support works.
1399 if (compiler.mainFunction != null) { 1397 if (compiler.mainFunction != null) {
1400 // The JavaScript backend implements [Isolate.spawn] by looking up 1398 // The JavaScript backend implements [Isolate.spawn] by looking up
1401 // top-level functions by name. So all top-level function tear-off 1399 // top-level functions by name. So all top-level function tear-off
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
1496 if (cls == null) return; 1494 if (cls == null) return;
1497 registerBackendUse(cls); 1495 registerBackendUse(cls);
1498 helpersUsed.add(cls.declaration); 1496 helpersUsed.add(cls.declaration);
1499 if (cls.declaration != cls.implementation) { 1497 if (cls.declaration != cls.implementation) {
1500 helpersUsed.add(cls.implementation); 1498 helpersUsed.add(cls.implementation);
1501 } 1499 }
1502 cls.ensureResolved(resolution); 1500 cls.ensureResolved(resolution);
1503 registerInstantiatedType(cls.rawType, enqueuer, registry); 1501 registerInstantiatedType(cls.rawType, enqueuer, registry);
1504 } 1502 }
1505 1503
1504 /// Register instantiation of [type] in [enqueuer].
1505 ///
1506 /// This method calls [registerBackendUse].
1507 void enqueueType(Enqueuer enqueuer, InterfaceType type, Registry registry) {
1508 if (type == null) return;
1509 ClassElement cls = type.element;
1510 registerBackendUse(cls);
1511 helpersUsed.add(cls.declaration);
1512 if (cls.declaration != cls.implementation) {
1513 helpersUsed.add(cls.implementation);
1514 }
1515 cls.ensureResolved(resolution);
1516 registerInstantiatedType(type, enqueuer, registry);
1517 }
1518
1519 void enqueueImpact(Enqueuer enqueuer,
1520 BackendImpact impact,
1521 Registry registry) {
1522 for (Element staticUse in impact.staticUses) {
1523 enqueue(enqueuer, staticUse, registry);
1524 }
1525 for (InterfaceType type in impact.instantiatedTypes) {
1526 enqueueType(enqueuer, type, registry);
1527 }
1528 for (ClassElement cls in impact.instantiatedClasses) {
1529 enqueueClass(enqueuer, cls, registry);
1530 }
1531 for (BackendImpact otherImpact in impact.otherImpacts) {
1532 enqueueImpact(enqueuer, otherImpact, registry);
1533 }
1534 }
1535
1506 WorldImpact codegen(CodegenWorkItem work) { 1536 WorldImpact codegen(CodegenWorkItem work) {
1507 Element element = work.element; 1537 Element element = work.element;
1508 if (compiler.elementHasCompileTimeError(element)) { 1538 if (compiler.elementHasCompileTimeError(element)) {
1509 generatedCode[element] = jsAst.js( 1539 generatedCode[element] = jsAst.js(
1510 "function () { throw new Error('Compile time error in $element') }"); 1540 "function () { throw new Error('Compile time error in $element') }");
1511 return const WorldImpact(); 1541 return const WorldImpact();
1512 } 1542 }
1513 var kind = element.kind; 1543 var kind = element.kind;
1514 if (kind == ElementKind.TYPEDEF) { 1544 if (kind == ElementKind.TYPEDEF) {
1515 return const WorldImpact(); 1545 return const WorldImpact();
(...skipping 11 matching lines...) Expand all
1527 // variables. For instance variables, we may need to generate 1557 // variables. For instance variables, we may need to generate
1528 // the checked setter. 1558 // the checked setter.
1529 if (Elements.isStaticOrTopLevel(element)) { 1559 if (Elements.isStaticOrTopLevel(element)) {
1530 return const WorldImpact(); 1560 return const WorldImpact();
1531 } 1561 }
1532 } else { 1562 } else {
1533 // If the constant-handler was not able to produce a result we have to 1563 // If the constant-handler was not able to produce a result we have to
1534 // go through the builder (below) to generate the lazy initializer for 1564 // go through the builder (below) to generate the lazy initializer for
1535 // the static variable. 1565 // the static variable.
1536 // We also need to register the use of the cyclic-error helper. 1566 // We also need to register the use of the cyclic-error helper.
1537 compiler.enqueuer.codegen.registerStaticUse(getCyclicThrowHelper()); 1567 compiler.enqueuer.codegen.registerStaticUse(
1568 helpers.cyclicThrowHelper);
1538 } 1569 }
1539 } 1570 }
1540 1571
1541 generatedCode[element] = functionCompiler.compile(work); 1572 generatedCode[element] = functionCompiler.compile(work);
1542 return const WorldImpact(); 1573 return const WorldImpact();
1543 } 1574 }
1544 1575
1545 native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) { 1576 native.NativeEnqueuer nativeResolutionEnqueuer(Enqueuer world) {
1546 return new native.NativeResolutionEnqueuer(world, compiler); 1577 return new native.NativeResolutionEnqueuer(world, compiler);
1547 } 1578 }
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1786 bool mayGenerateInstanceofCheck(DartType type) { 1817 bool mayGenerateInstanceofCheck(DartType type) {
1787 // We can use an instanceof check for raw types that have no subclass that 1818 // We can use an instanceof check for raw types that have no subclass that
1788 // is mixed-in or in an implements clause. 1819 // is mixed-in or in an implements clause.
1789 1820
1790 if (!type.isRaw) return false; 1821 if (!type.isRaw) return false;
1791 ClassElement classElement = type.element; 1822 ClassElement classElement = type.element;
1792 if (isInterceptorClass(classElement)) return false; 1823 if (isInterceptorClass(classElement)) return false;
1793 return compiler.world.hasOnlySubclasses(classElement); 1824 return compiler.world.hasOnlySubclasses(classElement);
1794 } 1825 }
1795 1826
1796 Element getExceptionUnwrapper() {
1797 return findHelper('unwrapException');
1798 }
1799
1800 Element getThrowRuntimeError() {
1801 return findHelper('throwRuntimeError');
1802 }
1803
1804 Element getThrowTypeError() {
1805 return findHelper('throwTypeError');
1806 }
1807
1808 Element getThrowAbstractClassInstantiationError() {
1809 return findHelper('throwAbstractClassInstantiationError');
1810 }
1811
1812 Element getCheckConcurrentModificationError() {
1813 if (cachedCheckConcurrentModificationError == null) {
1814 cachedCheckConcurrentModificationError =
1815 findHelper('checkConcurrentModificationError');
1816 }
1817 return cachedCheckConcurrentModificationError;
1818 }
1819
1820 Element getThrowConcurrentModificationError() {
1821 return findHelper('throwConcurrentModificationError');
1822 }
1823
1824 Element getThrowIndexOutOfBoundsError() {
1825 return findHelper('ioore');
1826 }
1827
1828 Element getStringInterpolationHelper() {
1829 return findHelper('S');
1830 }
1831
1832 Element getWrapExceptionHelper() {
1833 return findHelper(r'wrapException');
1834 }
1835
1836 Element getThrowExpressionHelper() {
1837 return findHelper('throwExpression');
1838 }
1839
1840 Element getClosureConverter() {
1841 return findHelper('convertDartClosureToJS');
1842 }
1843
1844 Element getTraceFromException() {
1845 return findHelper('getTraceFromException');
1846 }
1847
1848 Element getSetRuntimeTypeInfo() {
1849 return findHelper('setRuntimeTypeInfo');
1850 }
1851
1852 Element getGetRuntimeTypeInfo() {
1853 return findHelper('getRuntimeTypeInfo');
1854 }
1855
1856 Element getGetTypeArgumentByIndex() {
1857 return findHelper('getTypeArgumentByIndex');
1858 }
1859
1860 Element getCopyTypeArguments() {
1861 return findHelper('copyTypeArguments');
1862 }
1863
1864 Element getComputeSignature() {
1865 return findHelper('computeSignature');
1866 }
1867
1868 Element getGetRuntimeTypeArguments() {
1869 return findHelper('getRuntimeTypeArguments');
1870 }
1871
1872 Element getGetRuntimeTypeArgument() {
1873 return findHelper('getRuntimeTypeArgument');
1874 }
1875
1876 Element getRuntimeTypeToString() {
1877 return findHelper('runtimeTypeToString');
1878 }
1879
1880 Element getAssertIsSubtype() {
1881 return findHelper('assertIsSubtype');
1882 }
1883
1884 Element getCheckSubtype() {
1885 return findHelper('checkSubtype');
1886 }
1887
1888 Element getAssertSubtype() {
1889 return findHelper('assertSubtype');
1890 }
1891
1892 Element getSubtypeCast() {
1893 return findHelper('subtypeCast');
1894 }
1895
1896 Element getCheckSubtypeOfRuntimeType() {
1897 return findHelper('checkSubtypeOfRuntimeType');
1898 }
1899
1900 Element getAssertSubtypeOfRuntimeType() {
1901 return findHelper('assertSubtypeOfRuntimeType');
1902 }
1903
1904 Element getSubtypeOfRuntimeTypeCast() {
1905 return findHelper('subtypeOfRuntimeTypeCast');
1906 }
1907
1908 Element getCheckDeferredIsLoaded() {
1909 return findHelper('checkDeferredIsLoaded');
1910 }
1911
1912 Element getThrowNoSuchMethod() {
1913 return findHelper('throwNoSuchMethod');
1914 }
1915
1916 Element getCreateRuntimeType() {
1917 return findHelper('createRuntimeType');
1918 }
1919
1920 Element getFallThroughError() {
1921 return findHelper("getFallThroughError");
1922 }
1923
1924 Element getCreateInvocationMirror() {
1925 return findHelper(Compiler.CREATE_INVOCATION_MIRROR);
1926 }
1927
1928 Element getCyclicThrowHelper() {
1929 return findHelper("throwCyclicInit");
1930 }
1931
1932 Element getAsyncHelper() {
1933 return findAsyncHelper("_asyncHelper");
1934 }
1935
1936 Element getWrapBody() {
1937 return findAsyncHelper("_wrapJsFunctionForAsync");
1938 }
1939
1940 Element getYieldStar() {
1941 ClassElement classElement = findAsyncHelper("_IterationMarker");
1942 classElement.ensureResolved(resolution);
1943 return classElement.lookupLocalMember("yieldStar");
1944 }
1945
1946 Element getYieldSingle() {
1947 ClassElement classElement = findAsyncHelper("_IterationMarker");
1948 classElement.ensureResolved(resolution);
1949 return classElement.lookupLocalMember("yieldSingle");
1950 }
1951
1952 Element getSyncStarUncaughtError() {
1953 ClassElement classElement = findAsyncHelper("_IterationMarker");
1954 classElement.ensureResolved(resolution);
1955 return classElement.lookupLocalMember("uncaughtError");
1956 }
1957
1958 Element getAsyncStarHelper() {
1959 return findAsyncHelper("_asyncStarHelper");
1960 }
1961
1962 Element getStreamOfController() {
1963 return findAsyncHelper("_streamOfController");
1964 }
1965
1966 Element getEndOfIteration() {
1967 ClassElement classElement = findAsyncHelper("_IterationMarker");
1968 classElement.ensureResolved(resolution);
1969 return classElement.lookupLocalMember("endOfIteration");
1970 }
1971
1972 Element getSyncStarIterable() {
1973 ClassElement classElement = findAsyncHelper("_SyncStarIterable");
1974 classElement.ensureResolved(resolution);
1975 return classElement;
1976 }
1977
1978 Element getSyncStarIterableConstructor() {
1979 ClassElement classElement = getSyncStarIterable();
1980 classElement.ensureResolved(resolution);
1981 return classElement.lookupConstructor("");
1982 }
1983
1984 Element getSyncCompleterConstructor() {
1985 ClassElement classElement = find(compiler.asyncLibrary, "Completer");
1986 classElement.ensureResolved(resolution);
1987 return classElement.lookupConstructor("sync");
1988 }
1989
1990 Element getASyncStarController() {
1991 ClassElement classElement =
1992 findAsyncHelper("_AsyncStarStreamController");
1993 classElement.ensureResolved(resolution);
1994 return classElement;
1995 }
1996
1997 Element getASyncStarControllerConstructor() {
1998 ClassElement classElement = getASyncStarController();
1999 return classElement.lookupConstructor("");
2000 }
2001
2002 Element getStreamIteratorConstructor() {
2003 ClassElement classElement = find(compiler.asyncLibrary, "StreamIterator");
2004 classElement.ensureResolved(resolution);
2005 return classElement.lookupConstructor("");
2006 }
2007
2008 bool isNullImplementation(ClassElement cls) { 1827 bool isNullImplementation(ClassElement cls) {
2009 return cls == jsNullClass; 1828 return cls == jsNullClass;
2010 } 1829 }
2011 1830
2012 ClassElement get intImplementation => jsIntClass; 1831 ClassElement get intImplementation => jsIntClass;
2013 ClassElement get uint32Implementation => jsUInt32Class; 1832 ClassElement get uint32Implementation => jsUInt32Class;
2014 ClassElement get uint31Implementation => jsUInt31Class; 1833 ClassElement get uint31Implementation => jsUInt31Class;
2015 ClassElement get positiveIntImplementation => jsPositiveIntClass; 1834 ClassElement get positiveIntImplementation => jsPositiveIntClass;
2016 ClassElement get doubleImplementation => jsDoubleClass; 1835 ClassElement get doubleImplementation => jsDoubleClass;
2017 ClassElement get numImplementation => jsNumberClass; 1836 ClassElement get numImplementation => jsNumberClass;
(...skipping 30 matching lines...) Expand all
2048 enqueueInResolution(compiler.loadLibraryFunction, 1867 enqueueInResolution(compiler.loadLibraryFunction,
2049 compiler.globalDependencies); 1868 compiler.globalDependencies);
2050 } 1869 }
2051 } else if (element == requiresPreambleMarker) { 1870 } else if (element == requiresPreambleMarker) {
2052 requiresPreamble = true; 1871 requiresPreamble = true;
2053 } 1872 }
2054 customElementsAnalysis.registerStaticUse(element, enqueuer); 1873 customElementsAnalysis.registerStaticUse(element, enqueuer);
2055 } 1874 }
2056 1875
2057 /// Called when [:const Symbol(name):] is seen. 1876 /// Called when [:const Symbol(name):] is seen.
2058 void registerConstSymbol(String name, Registry registry) { 1877 void registerConstSymbol(String name) {
2059 symbolsUsed.add(name); 1878 symbolsUsed.add(name);
2060 if (name.endsWith('=')) { 1879 if (name.endsWith('=')) {
2061 symbolsUsed.add(name.substring(0, name.length - 1)); 1880 symbolsUsed.add(name.substring(0, name.length - 1));
2062 } 1881 }
2063 } 1882 }
2064 1883
2065 /// Called when [:new Symbol(...):] is seen. 1884 /// Called when [:new Symbol(...):] is seen.
2066 void registerNewSymbol(Registry registry) { 1885 void registerNewSymbol(Registry registry) {
2067 } 1886 }
2068 1887
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
2177 jsMutableArrayClass = findClass('JSMutableArray'); 1996 jsMutableArrayClass = findClass('JSMutableArray');
2178 jsFixedArrayClass = findClass('JSFixedArray'); 1997 jsFixedArrayClass = findClass('JSFixedArray');
2179 jsExtendableArrayClass = findClass('JSExtendableArray'); 1998 jsExtendableArrayClass = findClass('JSExtendableArray');
2180 jsUnmodifiableArrayClass = findClass('JSUnmodifiableArray'); 1999 jsUnmodifiableArrayClass = findClass('JSUnmodifiableArray');
2181 jsPlainJavaScriptObjectClass = findClass('PlainJavaScriptObject'); 2000 jsPlainJavaScriptObjectClass = findClass('PlainJavaScriptObject');
2182 jsUnknownJavaScriptObjectClass = findClass('UnknownJavaScriptObject'); 2001 jsUnknownJavaScriptObjectClass = findClass('UnknownJavaScriptObject');
2183 jsIndexableClass = findClass('JSIndexable'); 2002 jsIndexableClass = findClass('JSIndexable');
2184 jsMutableIndexableClass = findClass('JSMutableIndexable'); 2003 jsMutableIndexableClass = findClass('JSMutableIndexable');
2185 } else if (uri == DART_JS_HELPER) { 2004 } else if (uri == DART_JS_HELPER) {
2186 initializeHelperClasses(); 2005 initializeHelperClasses();
2187 assertTestMethod = findHelper('assertTest'); 2006 helpers.assertTest = findHelper('assertTest');
2188 assertThrowMethod = findHelper('assertThrow'); 2007 helpers.assertThrow = findHelper('assertThrow');
2189 assertHelperMethod = findHelper('assertHelper'); 2008 helpers.assertHelper = findHelper('assertHelper');
2190 assertUnreachableMethod = findHelper('assertUnreachable'); 2009 assertUnreachableMethod = findHelper('assertUnreachable');
2191 2010
2192 typeLiteralClass = findClass('TypeImpl'); 2011 typeLiteralClass = findClass('TypeImpl');
2193 constMapLiteralClass = findClass('ConstantMap'); 2012 constMapLiteralClass = findClass('ConstantMap');
2194 typeVariableClass = findClass('TypeVariable'); 2013 typeVariableClass = findClass('TypeVariable');
2195 2014
2196 jsIndexingBehaviorInterface = findClass('JavaScriptIndexingBehavior'); 2015 jsIndexingBehaviorInterface = findClass('JavaScriptIndexingBehavior');
2197 2016
2198 noSideEffectsClass = findClass('NoSideEffects'); 2017 noSideEffectsClass = findClass('NoSideEffects');
2199 noThrowsClass = findClass('NoThrows'); 2018 noThrowsClass = findClass('NoThrows');
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after
2809 _registerAsync(enqueuer, registry); 2628 _registerAsync(enqueuer, registry);
2810 } else if (element.asyncMarker == AsyncMarker.SYNC_STAR) { 2629 } else if (element.asyncMarker == AsyncMarker.SYNC_STAR) {
2811 _registerSyncStar(enqueuer, registry); 2630 _registerSyncStar(enqueuer, registry);
2812 } else if (element.asyncMarker == AsyncMarker.ASYNC_STAR) { 2631 } else if (element.asyncMarker == AsyncMarker.ASYNC_STAR) {
2813 _registerAsyncStar(enqueuer, registry); 2632 _registerAsyncStar(enqueuer, registry);
2814 } 2633 }
2815 } 2634 }
2816 2635
2817 void _registerAsync(Enqueuer enqueuer, 2636 void _registerAsync(Enqueuer enqueuer,
2818 Registry registry) { 2637 Registry registry) {
2819 enqueue(enqueuer, getAsyncHelper(), registry); 2638 enqueueImpact(enqueuer, impacts.asyncBody, registry);
2820 enqueue(enqueuer, getSyncCompleterConstructor(), registry);
2821 enqueue(enqueuer, getStreamIteratorConstructor(), registry);
2822 enqueue(enqueuer, getWrapBody(), registry);
2823 } 2639 }
2824 2640
2825 void _registerSyncStar(Enqueuer enqueuer, 2641 void _registerSyncStar(Enqueuer enqueuer,
2826 Registry registry) { 2642 Registry registry) {
2827 ClassElement clsSyncStarIterable = getSyncStarIterable(); 2643 enqueueImpact(enqueuer, impacts.syncStarBody, registry);
2828 clsSyncStarIterable.ensureResolved(compiler.resolution);
2829 registerInstantiatedType(clsSyncStarIterable.rawType, enqueuer, registry);
2830 enqueue(enqueuer, getSyncStarIterableConstructor(), registry);
2831 enqueue(enqueuer, getEndOfIteration(), registry);
2832 enqueue(enqueuer, getYieldStar(), registry);
2833 enqueue(enqueuer, getSyncStarUncaughtError(), registry);
2834 } 2644 }
2835 2645
2836 void _registerAsyncStar(Enqueuer enqueuer, 2646 void _registerAsyncStar(Enqueuer enqueuer,
2837 Registry registry) { 2647 Registry registry) {
2838 ClassElement clsASyncStarController = getASyncStarController(); 2648 enqueueImpact(enqueuer, impacts.asyncStarBody, registry);
2839 clsASyncStarController.ensureResolved(compiler.resolution);
2840 registerInstantiatedType(
2841 clsASyncStarController.rawType, enqueuer, registry);
2842 enqueue(enqueuer, getAsyncStarHelper(), registry);
2843 enqueue(enqueuer, getStreamOfController(), registry);
2844 enqueue(enqueuer, getYieldSingle(), registry);
2845 enqueue(enqueuer, getYieldStar(), registry);
2846 enqueue(enqueuer, getASyncStarControllerConstructor(), registry);
2847 enqueue(enqueuer, getStreamIteratorConstructor(), registry);
2848 enqueue(enqueuer, getWrapBody(), registry);
2849 } 2649 }
2850 2650
2851 @override 2651 @override
2852 bool enableDeferredLoadingIfSupported(Spannable node, Registry registry) { 2652 bool enableDeferredLoadingIfSupported(Spannable node, Registry registry) {
2853 registerCheckDeferredIsLoaded(registry); 2653 registerCheckDeferredIsLoaded(registry);
2854 return true; 2654 return true;
2855 } 2655 }
2856 2656
2857 @override 2657 @override
2858 bool enableCodegenWithErrorsIfSupported(Spannable node) { 2658 bool enableCodegenWithErrorsIfSupported(Spannable node) {
(...skipping 11 matching lines...) Expand all
2870 jsAst.Expression rewriteAsync(FunctionElement element, 2670 jsAst.Expression rewriteAsync(FunctionElement element,
2871 jsAst.Expression code) { 2671 jsAst.Expression code) {
2872 AsyncRewriterBase rewriter = null; 2672 AsyncRewriterBase rewriter = null;
2873 jsAst.Name name = namer.methodPropertyName(element); 2673 jsAst.Name name = namer.methodPropertyName(element);
2874 switch (element.asyncMarker) { 2674 switch (element.asyncMarker) {
2875 case AsyncMarker.ASYNC: 2675 case AsyncMarker.ASYNC:
2876 rewriter = new AsyncRewriter( 2676 rewriter = new AsyncRewriter(
2877 reporter, 2677 reporter,
2878 element, 2678 element,
2879 asyncHelper: 2679 asyncHelper:
2880 emitter.staticFunctionAccess(getAsyncHelper()), 2680 emitter.staticFunctionAccess(helpers.asyncHelper),
2881 wrapBody: 2681 wrapBody:
2882 emitter.staticFunctionAccess(getWrapBody()), 2682 emitter.staticFunctionAccess(helpers.wrapBody),
2883 newCompleter: emitter.staticFunctionAccess( 2683 newCompleter: emitter.staticFunctionAccess(
2884 getSyncCompleterConstructor()), 2684 helpers.syncCompleterConstructor),
2885 safeVariableName: namer.safeVariablePrefixForAsyncRewrite, 2685 safeVariableName: namer.safeVariablePrefixForAsyncRewrite,
2886 bodyName: namer.deriveAsyncBodyName(name)); 2686 bodyName: namer.deriveAsyncBodyName(name));
2887 break; 2687 break;
2888 case AsyncMarker.SYNC_STAR: 2688 case AsyncMarker.SYNC_STAR:
2889 rewriter = new SyncStarRewriter( 2689 rewriter = new SyncStarRewriter(
2890 reporter, 2690 reporter,
2891 element, 2691 element,
2892 endOfIteration: emitter.staticFunctionAccess( 2692 endOfIteration: emitter.staticFunctionAccess(
2893 getEndOfIteration()), 2693 helpers.endOfIteration),
2894 newIterable: emitter.staticFunctionAccess( 2694 newIterable: emitter.staticFunctionAccess(
2895 getSyncStarIterableConstructor()), 2695 helpers.syncStarIterableConstructor),
2896 yieldStarExpression: emitter.staticFunctionAccess( 2696 yieldStarExpression: emitter.staticFunctionAccess(
2897 getYieldStar()), 2697 helpers.yieldStar),
2898 uncaughtErrorExpression: emitter.staticFunctionAccess( 2698 uncaughtErrorExpression: emitter.staticFunctionAccess(
2899 getSyncStarUncaughtError()), 2699 helpers.syncStarUncaughtError),
2900 safeVariableName: namer.safeVariablePrefixForAsyncRewrite, 2700 safeVariableName: namer.safeVariablePrefixForAsyncRewrite,
2901 bodyName: namer.deriveAsyncBodyName(name)); 2701 bodyName: namer.deriveAsyncBodyName(name));
2902 break; 2702 break;
2903 case AsyncMarker.ASYNC_STAR: 2703 case AsyncMarker.ASYNC_STAR:
2904 rewriter = new AsyncStarRewriter( 2704 rewriter = new AsyncStarRewriter(
2905 reporter, 2705 reporter,
2906 element, 2706 element,
2907 asyncStarHelper: emitter.staticFunctionAccess( 2707 asyncStarHelper: emitter.staticFunctionAccess(
2908 getAsyncStarHelper()), 2708 helpers.asyncStarHelper),
2909 streamOfController: emitter.staticFunctionAccess( 2709 streamOfController: emitter.staticFunctionAccess(
2910 getStreamOfController()), 2710 helpers.streamOfController),
2911 wrapBody: 2711 wrapBody:
2912 emitter.staticFunctionAccess(getWrapBody()), 2712 emitter.staticFunctionAccess(helpers.wrapBody),
2913 newController: emitter.staticFunctionAccess( 2713 newController: emitter.staticFunctionAccess(
2914 getASyncStarControllerConstructor()), 2714 helpers.asyncStarControllerConstructor),
2915 safeVariableName: namer.safeVariablePrefixForAsyncRewrite, 2715 safeVariableName: namer.safeVariablePrefixForAsyncRewrite,
2916 yieldExpression: emitter.staticFunctionAccess( 2716 yieldExpression: emitter.staticFunctionAccess(
2917 getYieldSingle()), 2717 helpers.yieldSingle),
2918 yieldStarExpression: emitter.staticFunctionAccess( 2718 yieldStarExpression: emitter.staticFunctionAccess(
2919 getYieldStar()), 2719 helpers.yieldStar),
2920 bodyName: namer.deriveAsyncBodyName(name)); 2720 bodyName: namer.deriveAsyncBodyName(name));
2921 break; 2721 break;
2922 default: 2722 default:
2923 assert(element.asyncMarker == AsyncMarker.SYNC); 2723 assert(element.asyncMarker == AsyncMarker.SYNC);
2924 return code; 2724 return code;
2925 } 2725 }
2926 return rewriter.rewrite(code); 2726 return rewriter.rewrite(code);
2927 } 2727 }
2928 } 2728 }
2929 2729
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2999 return false; 2799 return false;
3000 }); 2800 });
3001 } 2801 }
3002 } 2802 }
3003 2803
3004 class JavaScriptResolutionCallbacks extends ResolutionCallbacks { 2804 class JavaScriptResolutionCallbacks extends ResolutionCallbacks {
3005 final JavaScriptBackend backend; 2805 final JavaScriptBackend backend;
3006 2806
3007 JavaScriptResolutionCallbacks(this.backend); 2807 JavaScriptResolutionCallbacks(this.backend);
3008 2808
2809 BackendImpacts get impacts => backend.impacts;
2810
3009 WorldImpact transformImpact(ResolutionWorldImpact worldImpact) { 2811 WorldImpact transformImpact(ResolutionWorldImpact worldImpact) {
3010 TransformedWorldImpact transformed = 2812 TransformedWorldImpact transformed =
3011 new TransformedWorldImpact(worldImpact); 2813 new TransformedWorldImpact(worldImpact);
3012 for (Feature feature in worldImpact.features) { 2814 for (Feature feature in worldImpact.features) {
3013 switch (feature) { 2815 switch (feature) {
3014 case Feature.ABSTRACT_CLASS_INSTANTIATION: 2816 case Feature.ABSTRACT_CLASS_INSTANTIATION:
3015 onAbstractClassInstantiation(transformed); 2817 registerBackendImpact(
2818 transformed, impacts.abstractClassInstantiation);
3016 break; 2819 break;
3017 case Feature.ASSERT: 2820 case Feature.ASSERT:
3018 onAssert(false, transformed); 2821 registerBackendImpact(transformed, impacts.assertWithoutMessage);
3019 break; 2822 break;
3020 case Feature.ASSERT_WITH_MESSAGE: 2823 case Feature.ASSERT_WITH_MESSAGE:
3021 onAssert(true, transformed); 2824 registerBackendImpact(transformed, impacts.assertWithMessage);
3022 break; 2825 break;
3023 case Feature.ASYNC: 2826 case Feature.ASYNC:
3024 backend._registerAsync( 2827 registerBackendImpact(transformed, impacts.asyncBody);
3025 backend.compiler.enqueuer.resolution, transformed);
3026 break; 2828 break;
3027 case Feature.ASYNC_FOR_IN: 2829 case Feature.ASYNC_FOR_IN:
3028 onAsyncForIn(null, transformed); 2830 registerBackendImpact(transformed, impacts.asyncForIn);
3029 break; 2831 break;
3030 case Feature.ASYNC_STAR: 2832 case Feature.ASYNC_STAR:
3031 backend._registerAsyncStar( 2833 registerBackendImpact(transformed, impacts.asyncStarBody);
3032 backend.compiler.enqueuer.resolution, transformed);
3033 break; 2834 break;
3034 case Feature.CATCH_STATEMENT: 2835 case Feature.CATCH_STATEMENT:
3035 onCatchStatement(transformed); 2836 registerBackendImpact(transformed, impacts.catchStatement);
3036 break; 2837 break;
3037 case Feature.COMPILE_TIME_ERROR: 2838 case Feature.COMPILE_TIME_ERROR:
3038 onCompileTimeError(transformed, null); 2839 if (backend.compiler.generateCodeWithCompileTimeErrors) {
2840 // TODO(johnniwinther): This should have its own uncatchable error.
2841 registerBackendImpact(transformed, impacts.throwRuntimeError);
2842 }
3039 break; 2843 break;
3040 case Feature.FALL_THROUGH_ERROR: 2844 case Feature.FALL_THROUGH_ERROR:
3041 onFallThroughError(transformed); 2845 registerBackendImpact(transformed, impacts.fallThroughError);
3042 break; 2846 break;
3043 case Feature.INC_DEC_OPERATION: 2847 case Feature.INC_DEC_OPERATION:
3044 onIncDecOperation(transformed); 2848 registerBackendImpact(transformed, impacts.incDecOperation);
3045 break; 2849 break;
3046 case Feature.LAZY_FIELD: 2850 case Feature.LAZY_FIELD:
3047 onLazyField(transformed); 2851 registerBackendImpact(transformed, impacts.lazyField);
3048 break;
3049 case Feature.NEW_SYMBOL:
3050 backend.registerNewSymbol(transformed);
3051 break; 2852 break;
3052 case Feature.STACK_TRACE_IN_CATCH: 2853 case Feature.STACK_TRACE_IN_CATCH:
3053 onStackTraceInCatch(transformed); 2854 registerBackendImpact(transformed, impacts.stackTraceInCatch);
3054 break; 2855 break;
3055 case Feature.STRING_INTERPOLATION: 2856 case Feature.STRING_INTERPOLATION:
3056 onStringInterpolation(transformed); 2857 registerBackendImpact(transformed, impacts.stringInterpolation);
3057 break; 2858 break;
3058 case Feature.SUPER_NO_SUCH_METHOD: 2859 case Feature.SUPER_NO_SUCH_METHOD:
3059 onSuperNoSuchMethod(transformed); 2860 registerBackendImpact(transformed, impacts.superNoSuchMethod);
3060 break; 2861 break;
3061 case Feature.SYMBOL_CONSTRUCTOR: 2862 case Feature.SYMBOL_CONSTRUCTOR:
3062 onSymbolConstructor(transformed); 2863 registerBackendImpact(transformed, impacts.symbolConstructor);
3063 break; 2864 break;
3064 case Feature.SYNC_FOR_IN: 2865 case Feature.SYNC_FOR_IN:
3065 onSyncForIn(transformed); 2866 registerBackendImpact(transformed, impacts.syncForIn);
3066 break; 2867 break;
3067 case Feature.SYNC_STAR: 2868 case Feature.SYNC_STAR:
3068 backend._registerSyncStar( 2869 registerBackendImpact(transformed, impacts.syncStarBody);
3069 backend.compiler.enqueuer.resolution, transformed);
3070 break; 2870 break;
3071 case Feature.THROW_EXPRESSION: 2871 case Feature.THROW_EXPRESSION:
3072 onThrowExpression(transformed); 2872 registerBackendImpact(transformed, impacts.throwExpression);
3073 break; 2873 break;
3074 case Feature.THROW_NO_SUCH_METHOD: 2874 case Feature.THROW_NO_SUCH_METHOD:
3075 onThrowNoSuchMethod(transformed); 2875 registerBackendImpact(transformed, impacts.throwNoSuchMethod);
3076 break; 2876 break;
3077 case Feature.THROW_RUNTIME_ERROR: 2877 case Feature.THROW_RUNTIME_ERROR:
3078 onThrowRuntimeError(transformed); 2878 registerBackendImpact(transformed, impacts.throwRuntimeError);
3079 break; 2879 break;
3080 case Feature.TYPE_VARIABLE_BOUNDS_CHECK: 2880 case Feature.TYPE_VARIABLE_BOUNDS_CHECK:
3081 onTypeVariableBoundCheck(transformed); 2881 registerBackendImpact(transformed, impacts.typeVariableBoundCheck);
3082 break; 2882 break;
3083 } 2883 }
3084 } 2884 }
3085 for (DartType type in worldImpact.isChecks) { 2885 for (DartType type in worldImpact.isChecks) {
3086 onIsCheck(type, transformed); 2886 onIsCheck(type, transformed);
3087 } 2887 }
3088 for (DartType type in worldImpact.asCasts) { 2888
3089 onIsCheck(type, transformed); 2889 if (worldImpact.asCasts.isNotEmpty) {
3090 onAsCheck(type, transformed); 2890 for (DartType type in worldImpact.asCasts) {
3091 } 2891 onIsCheck(type, transformed);
2892 }
2893 registerBackendImpact(transformed, impacts.asCheck);
2894 }
2895
3092 if (backend.compiler.enableTypeAssertions) { 2896 if (backend.compiler.enableTypeAssertions) {
3093 for (DartType type in worldImpact.checkedModeChecks) { 2897 for (DartType type in worldImpact.checkedModeChecks) {
3094 onIsCheck(type, transformed); 2898 onIsCheck(type, transformed);
3095 } 2899 }
3096 } 2900 }
2901
3097 for (DartType requiredType in worldImpact.requiredTypes) { 2902 for (DartType requiredType in worldImpact.requiredTypes) {
3098 backend.registerRequiredType(requiredType); 2903 backend.registerRequiredType(requiredType);
3099 } 2904 }
2905
3100 for (MapLiteralUse mapLiteralUse in worldImpact.mapLiterals) { 2906 for (MapLiteralUse mapLiteralUse in worldImpact.mapLiterals) {
3101 // TODO(johnniwinther): Use the [isEmpty] property when factory 2907 // TODO(johnniwinther): Use the [isEmpty] property when factory
3102 // constructors are registered directly. 2908 // constructors are registered directly.
3103 onMapLiteral(transformed, mapLiteralUse.type, mapLiteralUse.isConstant); 2909 if (mapLiteralUse.isConstant) {
3104 } 2910 registerBackendImpact(transformed, impacts.constantMapLiteral);
2911 } else {
2912 transformed.registerInstantiatedType(mapLiteralUse.type);
2913 }
2914 }
2915
3105 for (ListLiteralUse listLiteralUse in worldImpact.listLiterals) { 2916 for (ListLiteralUse listLiteralUse in worldImpact.listLiterals) {
3106 // TODO(johnniwinther): Use the [isConstant] and [isEmpty] property when 2917 // TODO(johnniwinther): Use the [isConstant] and [isEmpty] property when
3107 // factory constructors are registered directly. 2918 // factory constructors are registered directly.
3108 transformed.registerInstantiation(listLiteralUse.type); 2919 transformed.registerInstantiatedType(listLiteralUse.type);
3109 } 2920 }
3110 for (DartType typeLiteral in worldImpact.typeLiterals) { 2921
3111 onTypeLiteral(typeLiteral, transformed); 2922 if (worldImpact.typeLiterals.isNotEmpty) {
3112 transformed.registerInstantiation(backend.compiler.coreTypes.typeType); 2923 transformed.registerInstantiatedType(backend.compiler.coreTypes.typeType);
3113 if (typeLiteral.isTypeVariable) { 2924 registerBackendImpact(transformed, impacts.typeLiteral);
3114 onTypeVariableExpression(transformed, typeLiteral.element); 2925 for (DartType typeLiteral in worldImpact.typeLiterals) {
3115 } 2926 backend.customElementsAnalysis.registerTypeLiteral(typeLiteral);
3116 } 2927 if (typeLiteral.isTypedef) {
2928 backend.compiler.world.allTypedefs.add(typeLiteral.element);
2929 }
2930 if (typeLiteral.isTypeVariable) {
2931 ClassElement cls = typeLiteral.element.enclosingClass;
2932 backend.rti.classesUsingTypeVariableExpression.add(cls);
2933 registerBackendImpact(transformed, impacts.typeVariableExpression);
2934 }
2935 }
2936 }
2937
3117 for (String constSymbolName in worldImpact.constSymbolNames) { 2938 for (String constSymbolName in worldImpact.constSymbolNames) {
3118 backend.registerConstSymbol(constSymbolName, transformed); 2939 backend.registerConstSymbol(constSymbolName);
3119 } 2940 }
2941
3120 for (LocalFunctionElement closure in worldImpact.closures) { 2942 for (LocalFunctionElement closure in worldImpact.closures) {
3121 if (closure.computeType(backend.resolution).containsTypeVariables) { 2943 if (closure.computeType(backend.resolution).containsTypeVariables) {
3122 backend.registerClosureWithFreeTypeVariables( 2944 backend.compiler.enqueuer.resolution.universe
3123 closure, backend.compiler.enqueuer.resolution, transformed); 2945 .closuresWithFreeTypeVariables.add(closure);
2946 registerBackendImpact(transformed, impacts.computeSignature);
3124 } 2947 }
3125 } 2948 }
3126 // TODO(johnniwinther): Remove this when dependency tracking is done on 2949 // TODO(johnniwinther): Remove this when dependency tracking is done on
3127 // the world impact itself. 2950 // the world impact itself.
3128 for (InterfaceType instantiatedType in worldImpact.instantiatedTypes) { 2951 for (InterfaceType instantiatedType in worldImpact.instantiatedTypes) {
3129 transformed.registerInstantiation(instantiatedType); 2952 transformed.registerInstantiatedType(instantiatedType);
3130 } 2953 }
3131 for (Element element in worldImpact.staticUses) { 2954 for (Element element in worldImpact.staticUses) {
3132 transformed.registerStaticInvocation(element); 2955 transformed.registerStaticUse(element);
3133 } 2956 }
3134 2957
3135 return transformed; 2958 return transformed;
3136 } 2959 }
3137 2960
3138 void registerBackendStaticInvocation(Element element, Registry registry) { 2961 void registerBackendImpact(TransformedWorldImpact worldImpact,
3139 registry.registerStaticInvocation(backend.registerBackendUse(element)); 2962 BackendImpact backendImpact) {
2963 for (Element staticUse in backendImpact.staticUses) {
2964 assert(staticUse != null);
2965 backend.registerBackendUse(staticUse);
2966 worldImpact.registerStaticUse(staticUse);
2967 }
2968 for (InterfaceType instantiatedType in backendImpact.instantiatedTypes) {
2969 backend.registerBackendUse(instantiatedType.element);
2970 worldImpact.registerInstantiatedType(instantiatedType);
2971 }
2972 for (ClassElement cls in backendImpact.instantiatedClasses) {
2973 cls.ensureResolved(backend.resolution);
2974 backend.registerBackendUse(cls);
2975 worldImpact.registerInstantiatedType(cls.rawType);
2976 }
2977 for (BackendImpact otherImpact in backendImpact.otherImpacts) {
2978 registerBackendImpact(worldImpact, otherImpact);
2979 }
3140 } 2980 }
3141 2981
3142 void registerBackendInstantiation(ClassElement element, Registry registry) {
3143 backend.registerBackendUse(element);
3144 element.ensureResolved(backend.resolution);
3145 registry.registerInstantiation(element.rawType);
3146 }
3147
3148 void onAssert(bool hasMessage, Registry registry) {
3149 if (hasMessage) {
3150 registerBackendStaticInvocation(backend.assertTestMethod, registry);
3151 registerBackendStaticInvocation(backend.assertThrowMethod, registry);
3152 } else {
3153 registerBackendStaticInvocation(backend.assertHelperMethod, registry);
3154 }
3155 }
3156
3157 void onAsyncForIn(AsyncForIn node, Registry registry) {
3158 registerBackendStaticInvocation(backend.getStreamIteratorConstructor(),
3159 registry);
3160 }
3161
3162 void onStringInterpolation(Registry registry) {
3163 assert(registry.isForResolution);
3164 registerBackendStaticInvocation(
3165 backend.getStringInterpolationHelper(), registry);
3166 }
3167
3168 void onCatchStatement(Registry registry) {
3169 assert(registry.isForResolution);
3170 registerBackendStaticInvocation(backend.getExceptionUnwrapper(), registry);
3171 registerBackendInstantiation(
3172 backend.jsPlainJavaScriptObjectClass, registry);
3173 registerBackendInstantiation(
3174 backend.jsUnknownJavaScriptObjectClass, registry);
3175 }
3176
3177 void onThrowExpression(Registry registry) {
3178 assert(registry.isForResolution);
3179 // We don't know ahead of time whether we will need the throw in a
3180 // statement context or an expression context, so we register both
3181 // here, even though we may not need the throwExpression helper.
3182 registerBackendStaticInvocation(backend.getWrapExceptionHelper(), registry);
3183 registerBackendStaticInvocation(
3184 backend.getThrowExpressionHelper(), registry);
3185 }
3186
3187 void onLazyField(Registry registry) {
3188 assert(registry.isForResolution);
3189 registerBackendStaticInvocation(backend.getCyclicThrowHelper(), registry);
3190 }
3191
3192 void onTypeLiteral(DartType type, Registry registry) {
3193 assert(registry.isForResolution);
3194 registerBackendInstantiation(backend.typeImplementation, registry);
3195 registerBackendStaticInvocation(backend.getCreateRuntimeType(), registry);
3196 // TODO(ahe): Might want to register [element] as an instantiated class
3197 // when reflection is used. However, as long as we disable tree-shaking
3198 // eagerly it doesn't matter.
3199 if (type.isTypedef) {
3200 backend.compiler.world.allTypedefs.add(type.element);
3201 }
3202 backend.customElementsAnalysis.registerTypeLiteral(type, registry);
3203 }
3204
3205 void onStackTraceInCatch(Registry registry) {
3206 assert(registry.isForResolution);
3207 registerBackendStaticInvocation(backend.getTraceFromException(), registry);
3208 }
3209
3210 void onSyncForIn(Registry registry) {
3211 assert(registry.isForResolution);
3212 // The SSA builder recognizes certain for-in loops and can generate calls to
3213 // throwConcurrentModificationError.
3214 registerBackendStaticInvocation(
3215 backend.getCheckConcurrentModificationError(), registry);
3216 }
3217
3218 void onTypeVariableExpression(Registry registry,
3219 TypeVariableElement variable) {
3220 assert(registry.isForResolution);
3221 registerBackendStaticInvocation(backend.getSetRuntimeTypeInfo(), registry);
3222 registerBackendStaticInvocation(backend.getGetRuntimeTypeInfo(), registry);
3223 backend.registerGetRuntimeTypeArgument(registry);
3224 registerBackendInstantiation(backend.compiler.listClass, registry);
3225 registerBackendStaticInvocation(backend.getRuntimeTypeToString(), registry);
3226 registerBackendStaticInvocation(backend.getCreateRuntimeType(), registry);
3227 needsInt(registry, 'Needed for accessing a type variable literal on this.');
3228 ClassElement cls = variable.enclosingClass;
3229 backend.rti.classesUsingTypeVariableExpression.add(cls);
3230 }
3231
3232 // TODO(johnniwinther): Maybe split this into [onAssertType] and [onTestType]. 2982 // TODO(johnniwinther): Maybe split this into [onAssertType] and [onTestType].
3233 void onIsCheck(DartType type, Registry registry) { 2983 void onIsCheck(DartType type, TransformedWorldImpact transformed) {
3234 assert(registry.isForResolution);
3235 type = type.unalias(backend.resolution); 2984 type = type.unalias(backend.resolution);
3236 registerBackendInstantiation(backend.compiler.boolClass, registry); 2985 registerBackendImpact(transformed, impacts.typeCheck);
2986
3237 bool inCheckedMode = backend.compiler.enableTypeAssertions; 2987 bool inCheckedMode = backend.compiler.enableTypeAssertions;
3238 if (inCheckedMode) { 2988 if (inCheckedMode) {
3239 registerBackendStaticInvocation(backend.getThrowRuntimeError(), registry); 2989 registerBackendImpact(transformed, impacts.checkedModeTypeCheck);
3240 } 2990 }
3241 if (type.isMalformed) { 2991 if (type.isMalformed) {
3242 registerBackendStaticInvocation(backend.getThrowTypeError(), registry); 2992 registerBackendImpact(transformed, impacts.malformedTypeCheck);
3243 } 2993 }
3244 if (!type.treatAsRaw || type.containsTypeVariables || type.isFunctionType) { 2994 if (!type.treatAsRaw || type.containsTypeVariables || type.isFunctionType) {
3245 // TODO(johnniwinther): Investigate why this is needed. 2995 registerBackendImpact(transformed, impacts.genericTypeCheck);
3246 registerBackendStaticInvocation(
3247 backend.getSetRuntimeTypeInfo(), registry);
3248 registerBackendStaticInvocation(
3249 backend.getGetRuntimeTypeInfo(), registry);
3250 backend.registerGetRuntimeTypeArgument(registry);
3251 if (inCheckedMode) { 2996 if (inCheckedMode) {
3252 registerBackendStaticInvocation(backend.getAssertSubtype(), registry); 2997 registerBackendImpact(transformed, impacts.genericCheckedModeTypeCheck);
3253 } 2998 }
3254 registerBackendStaticInvocation(backend.getCheckSubtype(), registry);
3255 if (type.isTypeVariable) { 2999 if (type.isTypeVariable) {
3256 registerBackendStaticInvocation( 3000 registerBackendImpact(transformed, impacts.typeVariableTypeCheck);
3257 backend.getCheckSubtypeOfRuntimeType(), registry);
3258 if (inCheckedMode) { 3001 if (inCheckedMode) {
3259 registerBackendStaticInvocation( 3002 registerBackendImpact(transformed,
3260 backend.getAssertSubtypeOfRuntimeType(), registry); 3003 impacts.typeVariableCheckedModeTypeCheck);
3261 } 3004 }
3262 } 3005 }
3263 registerBackendInstantiation(backend.compiler.listClass, registry);
3264 } 3006 }
3265 if (type is FunctionType) { 3007 if (type is FunctionType) {
3266 registerBackendStaticInvocation( 3008 registerBackendImpact(transformed, impacts.functionTypeCheck);
3267 backend.find(backend.jsHelperLibrary, 'functionTypeTestMetaHelper'),
3268 registry);
3269 } 3009 }
3270 if (type.element != null && type.element.isNative) { 3010 if (type.element != null && type.element.isNative) {
3271 // We will neeed to add the "$is" and "$as" properties on the 3011 registerBackendImpact(transformed, impacts.nativeTypeCheck);
3272 // JavaScript object prototype, so we make sure 3012 }
3273 // [:defineProperty:] is compiled.
3274 registerBackendStaticInvocation(
3275 backend.find(backend.jsHelperLibrary, 'defineProperty'), registry);
3276 }
3277 }
3278
3279 void onTypeVariableBoundCheck(Registry registry) {
3280 assert(registry.isForResolution);
3281 registerBackendStaticInvocation(backend.getThrowTypeError(), registry);
3282 registerBackendStaticInvocation(backend.getAssertIsSubtype(), registry);
3283 }
3284
3285 void onAbstractClassInstantiation(Registry registry) {
3286 assert(registry.isForResolution);
3287 registerBackendStaticInvocation(
3288 backend.getThrowAbstractClassInstantiationError(), registry);
3289 // Also register the types of the arguments passed to this method.
3290 needsString(registry, '// Needed to encode the message.');
3291 }
3292
3293 void onFallThroughError(Registry registry) {
3294 assert(registry.isForResolution);
3295 registerBackendStaticInvocation(backend.getFallThroughError(), registry);
3296 }
3297
3298 void onAsCheck(DartType type, Registry registry) {
3299 assert(registry.isForResolution);
3300 registerBackendStaticInvocation(backend.getThrowRuntimeError(), registry);
3301 }
3302
3303 void onThrowNoSuchMethod(Registry registry) {
3304 assert(registry.isForResolution);
3305 registerBackendStaticInvocation(backend.getThrowNoSuchMethod(), registry);
3306 // Also register the types of the arguments passed to this method.
3307 needsList(registry,
3308 'Needed to encode the arguments for throw NoSuchMethodError.');
3309 needsString(registry,
3310 'Needed to encode the name for throw NoSuchMethodError.');
3311 }
3312
3313 void onThrowRuntimeError(Registry registry) {
3314 assert(registry.isForResolution);
3315 registerBackendStaticInvocation(backend.getThrowRuntimeError(), registry);
3316 // Also register the types of the arguments passed to this method.
3317 registerBackendInstantiation(backend.compiler.stringClass, registry);
3318 }
3319
3320 void onCompileTimeError(Registry registry, ErroneousElement error) {
3321 if (backend.compiler.generateCodeWithCompileTimeErrors) {
3322 // TODO(johnniwinther): This should have its own uncatchable error.
3323 onThrowRuntimeError(registry);
3324 }
3325 }
3326
3327 void onSuperNoSuchMethod(Registry registry) {
3328 assert(registry.isForResolution);
3329 registerBackendStaticInvocation(
3330 backend.getCreateInvocationMirror(), registry);
3331 registerBackendStaticInvocation(
3332 backend.compiler.objectClass.lookupLocalMember(
3333 Identifiers.noSuchMethod_),
3334 registry);
3335 needsInt(registry,
3336 'Needed to encode the invocation kind of super.noSuchMethod.');
3337 needsList(registry,
3338 'Needed to encode the arguments of super.noSuchMethod.');
3339 needsString(registry,
3340 'Needed to encode the name of super.noSuchMethod.');
3341 }
3342
3343 void onMapLiteral(Registry registry,
3344 DartType type,
3345 bool isConstant) {
3346 assert(registry.isForResolution);
3347 void enqueue(String name) {
3348 Element e = backend.find(backend.jsHelperLibrary, name);
3349 registerBackendInstantiation(e, registry);
3350 }
3351
3352 if (isConstant) {
3353 enqueue(JavaScriptMapConstant.DART_CLASS);
3354 enqueue(JavaScriptMapConstant.DART_PROTO_CLASS);
3355 enqueue(JavaScriptMapConstant.DART_STRING_CLASS);
3356 enqueue(JavaScriptMapConstant.DART_GENERAL_CLASS);
3357 } else {
3358 registry.registerInstantiation(type);
3359 }
3360 }
3361
3362 /// Called when resolving the `Symbol` constructor.
3363 void onSymbolConstructor(Registry registry) {
3364 assert(registry.isForResolution);
3365 // Make sure that _internals.Symbol.validated is registered.
3366 assert(backend.compiler.symbolValidatedConstructor != null);
3367 registerBackendStaticInvocation(
3368 backend.compiler.symbolValidatedConstructor, registry);
3369 }
3370
3371 /// Called when resolving a prefix or postfix expression.
3372 void onIncDecOperation(Registry registry) {
3373 needsInt(registry, 'Needed for the `+ 1` or `- 1` operation of ++/--.');
3374 }
3375
3376 /// Helper for registering that `int` is needed.
3377 void needsInt(Registry registry, String reason) {
3378 // TODO(johnniwinther): Register [reason] for use in dump-info.
3379 registerBackendInstantiation(backend.compiler.intClass, registry);
3380 }
3381
3382 /// Helper for registering that `List` is needed.
3383 void needsList(Registry registry, String reason) {
3384 // TODO(johnniwinther): Register [reason] for use in dump-info.
3385 registerBackendInstantiation(backend.compiler.listClass, registry);
3386 }
3387
3388 /// Helper for registering that `String` is needed.
3389 void needsString(Registry registry, String reason) {
3390 // TODO(johnniwinther): Register [reason] for use in dump-info.
3391 registerBackendInstantiation(backend.compiler.stringClass, registry);
3392 } 3013 }
3393 } 3014 }
3394 3015
3395 /// Records that [constant] is used by the element behind [registry]. 3016 /// Records that [constant] is used by the element behind [registry].
3396 class Dependency { 3017 class Dependency {
3397 final ConstantValue constant; 3018 final ConstantValue constant;
3398 final Element annotatedElement; 3019 final Element annotatedElement;
3399 3020
3400 const Dependency(this.constant, this.annotatedElement); 3021 const Dependency(this.constant, this.annotatedElement);
3401 } 3022 }
3023
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart ('k') | pkg/compiler/lib/src/js_backend/backend_helpers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698