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 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 | 519 |
520 /// True when we enqueue the loadLibrary code. | 520 /// True when we enqueue the loadLibrary code. |
521 bool isLoadLibraryFunctionResolved = false; | 521 bool isLoadLibraryFunctionResolved = false; |
522 | 522 |
523 /// `true` if access to [BackendHelpers.invokeOnMethod] is supported. | 523 /// `true` if access to [BackendHelpers.invokeOnMethod] is supported. |
524 bool hasInvokeOnSupport = false; | 524 bool hasInvokeOnSupport = false; |
525 | 525 |
526 /// `true` if tear-off are supported for incremental compilation. | 526 /// `true` if tear-off are supported for incremental compilation. |
527 bool hasIncrementalTearOffSupport = false; | 527 bool hasIncrementalTearOffSupport = false; |
528 | 528 |
| 529 /// `true` of `Object.runtimeType` is supported. |
| 530 bool hasRuntimeTypeSupport = false; |
| 531 |
| 532 /// `true` of use of the `dart:isolate` library is supported. |
| 533 bool hasIsolateSupport = false; |
| 534 |
| 535 /// `true` of `Function.apply` is supported. |
| 536 bool hasFunctionApplySupport = false; |
| 537 |
529 /// List of constants from metadata. If metadata must be preserved, | 538 /// List of constants from metadata. If metadata must be preserved, |
530 /// these constants must be registered. | 539 /// these constants must be registered. |
531 final List<Dependency> metadataConstants = <Dependency>[]; | 540 final List<Dependency> metadataConstants = <Dependency>[]; |
532 | 541 |
533 /// Set of elements for which metadata has been registered as dependencies. | 542 /// Set of elements for which metadata has been registered as dependencies. |
534 final Set<Element> _registeredMetadata = new Set<Element>(); | 543 final Set<Element> _registeredMetadata = new Set<Element>(); |
535 | 544 |
536 /// List of elements that the user has requested for reflection. | 545 /// List of elements that the user has requested for reflection. |
537 final Set<Element> targetsUsed = new Set<Element>(); | 546 final Set<Element> targetsUsed = new Set<Element>(); |
538 | 547 |
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1455 impactTransformer.registerBackendImpact( | 1464 impactTransformer.registerBackendImpact( |
1456 impactBuilder, impacts.isolateSupport); | 1465 impactBuilder, impacts.isolateSupport); |
1457 if (forResolution) { | 1466 if (forResolution) { |
1458 impactTransformer.registerBackendImpact( | 1467 impactTransformer.registerBackendImpact( |
1459 impactBuilder, impacts.isolateSupportForResolution); | 1468 impactBuilder, impacts.isolateSupportForResolution); |
1460 } | 1469 } |
1461 return impactBuilder; | 1470 return impactBuilder; |
1462 } | 1471 } |
1463 | 1472 |
1464 bool classNeedsRti(ClassElement cls) { | 1473 bool classNeedsRti(ClassElement cls) { |
1465 if (compiler.resolverWorld.hasRuntimeTypeSupport) return true; | 1474 if (hasRuntimeTypeSupport) return true; |
1466 return rti.classesNeedingRti.contains(cls.declaration); | 1475 return rti.classesNeedingRti.contains(cls.declaration); |
1467 } | 1476 } |
1468 | 1477 |
1469 bool classNeedsRtiField(ClassElement cls) { | 1478 bool classNeedsRtiField(ClassElement cls) { |
1470 if (cls.rawType.typeArguments.isEmpty) return false; | 1479 if (cls.rawType.typeArguments.isEmpty) return false; |
1471 if (compiler.resolverWorld.hasRuntimeTypeSupport) return true; | 1480 if (hasRuntimeTypeSupport) return true; |
1472 return rti.classesNeedingRti.contains(cls.declaration); | 1481 return rti.classesNeedingRti.contains(cls.declaration); |
1473 } | 1482 } |
1474 | 1483 |
1475 bool isComplexNoSuchMethod(FunctionElement element) => | 1484 bool isComplexNoSuchMethod(FunctionElement element) => |
1476 noSuchMethodRegistry.isComplex(element); | 1485 noSuchMethodRegistry.isComplex(element); |
1477 | 1486 |
1478 bool isDefaultEqualityImplementation(Element element) { | 1487 bool isDefaultEqualityImplementation(Element element) { |
1479 assert(element.name == '=='); | 1488 assert(element.name == '=='); |
1480 ClassElement classElement = element.enclosingClass; | 1489 ClassElement classElement = element.enclosingClass; |
1481 return classElement == coreClasses.objectClass || | 1490 return classElement == coreClasses.objectClass || |
1482 classElement == helpers.jsInterceptorClass || | 1491 classElement == helpers.jsInterceptorClass || |
1483 classElement == helpers.jsNullClass; | 1492 classElement == helpers.jsNullClass; |
1484 } | 1493 } |
1485 | 1494 |
1486 bool methodNeedsRti(FunctionElement function) { | 1495 bool methodNeedsRti(FunctionElement function) { |
1487 return rti.methodsNeedingRti.contains(function) || | 1496 return rti.methodsNeedingRti.contains(function) || hasRuntimeTypeSupport; |
1488 compiler.resolverWorld.hasRuntimeTypeSupport; | |
1489 } | 1497 } |
1490 | 1498 |
1491 CodegenEnqueuer get codegenEnqueuer => compiler.enqueuer.codegen; | 1499 CodegenEnqueuer get codegenEnqueuer => compiler.enqueuer.codegen; |
1492 | 1500 |
1493 CodegenEnqueuer createCodegenEnqueuer(CompilerTask task, Compiler compiler) { | 1501 CodegenEnqueuer createCodegenEnqueuer(CompilerTask task, Compiler compiler) { |
1494 return new CodegenEnqueuer( | 1502 return new CodegenEnqueuer( |
1495 task, compiler, const TreeShakingEnqueuerStrategy()); | 1503 task, compiler, const TreeShakingEnqueuerStrategy()); |
1496 } | 1504 } |
1497 | 1505 |
1498 WorldImpact codegen(CodegenWorkItem work) { | 1506 WorldImpact codegen(CodegenWorkItem work) { |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1833 worldImpact, impacts.loadLibrary); | 1841 worldImpact, impacts.loadLibrary); |
1834 } | 1842 } |
1835 } | 1843 } |
1836 } else if (element == helpers.requiresPreambleMarker) { | 1844 } else if (element == helpers.requiresPreambleMarker) { |
1837 requiresPreamble = true; | 1845 requiresPreamble = true; |
1838 } else if (element == helpers.invokeOnMethod && forResolution) { | 1846 } else if (element == helpers.invokeOnMethod && forResolution) { |
1839 hasInvokeOnSupport = true; | 1847 hasInvokeOnSupport = true; |
1840 } | 1848 } |
1841 customElementsAnalysis.registerStaticUse(element, | 1849 customElementsAnalysis.registerStaticUse(element, |
1842 forResolution: forResolution); | 1850 forResolution: forResolution); |
| 1851 |
| 1852 if (forResolution) { |
| 1853 // Enable isolate support if we start using something from the isolate |
| 1854 // library, or timers for the async library. We exclude constant fields, |
| 1855 // which are ending here because their initializing expression is |
| 1856 // compiled. |
| 1857 LibraryElement library = element.library; |
| 1858 if (!hasIsolateSupport && !(element.isField && element.isConst)) { |
| 1859 Uri uri = library.canonicalUri; |
| 1860 if (uri == Uris.dart_isolate) { |
| 1861 hasIsolateSupport = true; |
| 1862 worldImpact |
| 1863 .addImpact(enableIsolateSupport(forResolution: forResolution)); |
| 1864 } else if (uri == Uris.dart_async) { |
| 1865 if (element.name == '_createTimer' || |
| 1866 element.name == '_createPeriodicTimer') { |
| 1867 // The [:Timer:] class uses the event queue of the isolate |
| 1868 // library, so we make sure that event queue is generated. |
| 1869 hasIsolateSupport = true; |
| 1870 worldImpact |
| 1871 .addImpact(enableIsolateSupport(forResolution: forResolution)); |
| 1872 } |
| 1873 } |
| 1874 } |
| 1875 |
| 1876 if (element.isGetter && element.name == Identifiers.runtimeType_) { |
| 1877 // Enable runtime type support if we discover a getter called |
| 1878 // runtimeType. We have to enable runtime type before hitting the |
| 1879 // codegen, so that constructors know whether they need to generate code |
| 1880 // for runtime type. |
| 1881 hasRuntimeTypeSupport = true; |
| 1882 // TODO(ahe): Record precise dependency here. |
| 1883 worldImpact.addImpact(registerRuntimeType()); |
| 1884 } else if (compiler.commonElements.isFunctionApplyMethod(element)) { |
| 1885 hasFunctionApplySupport = true; |
| 1886 } |
| 1887 } |
1843 return worldImpact; | 1888 return worldImpact; |
1844 } | 1889 } |
1845 | 1890 |
1846 /// Called when [:const Symbol(name):] is seen. | 1891 /// Called when [:const Symbol(name):] is seen. |
1847 void registerConstSymbol(String name) { | 1892 void registerConstSymbol(String name) { |
1848 symbolsUsed.add(name); | 1893 symbolsUsed.add(name); |
1849 if (name.endsWith('=')) { | 1894 if (name.endsWith('=')) { |
1850 symbolsUsed.add(name.substring(0, name.length - 1)); | 1895 symbolsUsed.add(name.substring(0, name.length - 1)); |
1851 } | 1896 } |
1852 } | 1897 } |
(...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2387 } | 2432 } |
2388 | 2433 |
2389 entities.forEach(processElementMetadata); | 2434 entities.forEach(processElementMetadata); |
2390 } | 2435 } |
2391 | 2436 |
2392 void onQueueClosed() { | 2437 void onQueueClosed() { |
2393 lookupMapAnalysis.onQueueClosed(); | 2438 lookupMapAnalysis.onQueueClosed(); |
2394 jsInteropAnalysis.onQueueClosed(); | 2439 jsInteropAnalysis.onQueueClosed(); |
2395 } | 2440 } |
2396 | 2441 |
2397 void onCodegenStart() { | 2442 WorldImpact onCodegenStart() { |
2398 lookupMapAnalysis.onCodegenStart(); | 2443 lookupMapAnalysis.onCodegenStart(); |
| 2444 if (hasIsolateSupport) { |
| 2445 return enableIsolateSupport(forResolution: false); |
| 2446 } |
| 2447 return const WorldImpact(); |
2399 } | 2448 } |
2400 | 2449 |
2401 /// Process backend specific annotations. | 2450 /// Process backend specific annotations. |
2402 void processAnnotations(Element element) { | 2451 void processAnnotations(Element element) { |
2403 if (element.isMalformed) { | 2452 if (element.isMalformed) { |
2404 // Elements that are marked as malformed during parsing or resolution | 2453 // Elements that are marked as malformed during parsing or resolution |
2405 // might be registered here. These should just be ignored. | 2454 // might be registered here. These should just be ignored. |
2406 return; | 2455 return; |
2407 } | 2456 } |
2408 | 2457 |
(...skipping 820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3229 ClassElement get mapImplementation => helpers.mapLiteralClass; | 3278 ClassElement get mapImplementation => helpers.mapLiteralClass; |
3230 ClassElement get constMapImplementation => helpers.constMapLiteralClass; | 3279 ClassElement get constMapImplementation => helpers.constMapLiteralClass; |
3231 ClassElement get typeImplementation => helpers.typeLiteralClass; | 3280 ClassElement get typeImplementation => helpers.typeLiteralClass; |
3232 ClassElement get boolImplementation => helpers.jsBoolClass; | 3281 ClassElement get boolImplementation => helpers.jsBoolClass; |
3233 ClassElement get nullImplementation => helpers.jsNullClass; | 3282 ClassElement get nullImplementation => helpers.jsNullClass; |
3234 ClassElement get syncStarIterableImplementation => helpers.syncStarIterable; | 3283 ClassElement get syncStarIterableImplementation => helpers.syncStarIterable; |
3235 ClassElement get asyncFutureImplementation => helpers.futureImplementation; | 3284 ClassElement get asyncFutureImplementation => helpers.futureImplementation; |
3236 ClassElement get asyncStarStreamImplementation => helpers.controllerStream; | 3285 ClassElement get asyncStarStreamImplementation => helpers.controllerStream; |
3237 ClassElement get functionImplementation => helpers.coreClasses.functionClass; | 3286 ClassElement get functionImplementation => helpers.coreClasses.functionClass; |
3238 } | 3287 } |
OLD | NEW |