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 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 const bool USE_CPS_IR = const bool.fromEnvironment("USE_CPS_IR"); | 9 const bool USE_CPS_IR = const bool.fromEnvironment("USE_CPS_IR"); |
10 | 10 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 /// to inline always. Any function in this list must be inlinable with | 86 /// to inline always. Any function in this list must be inlinable with |
87 /// respect to the conditions used in [InlineWeeder.canInline], except for | 87 /// respect to the conditions used in [InlineWeeder.canInline], except for |
88 /// size/complexity heuristics. | 88 /// size/complexity heuristics. |
89 static const Map<String, List<String>> ALWAYS_INLINE = | 89 static const Map<String, List<String>> ALWAYS_INLINE = |
90 const <String, List<String>> { | 90 const <String, List<String>> { |
91 'IterableMixinWorkaround': const <String>['forEach'], | 91 'IterableMixinWorkaround': const <String>['forEach'], |
92 }; | 92 }; |
93 | 93 |
94 String get patchVersion => USE_NEW_EMITTER ? 'new' : 'old'; | 94 String get patchVersion => USE_NEW_EMITTER ? 'new' : 'old'; |
95 | 95 |
| 96 final Annotations annotations = new Annotations(); |
| 97 |
96 /// List of [FunctionElement]s that we want to inline always. This list is | 98 /// List of [FunctionElement]s that we want to inline always. This list is |
97 /// filled when resolution is complete by looking up in [internalLibrary]. | 99 /// filled when resolution is complete by looking up in [internalLibrary]. |
98 List<FunctionElement> functionsToAlwaysInline; | 100 List<FunctionElement> functionsToAlwaysInline; |
99 | 101 |
100 /// Reference to the internal library to lookup functions to always inline. | 102 /// Reference to the internal library to lookup functions to always inline. |
101 LibraryElement internalLibrary; | 103 LibraryElement internalLibrary; |
102 | 104 |
103 | 105 |
104 /// Set of classes that need to be considered for reflection although not | 106 /// Set of classes that need to be considered for reflection although not |
105 /// otherwise visible during resolution. | 107 /// otherwise visible during resolution. |
(...skipping 1692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1798 } else if (uri == DART_JS_MIRRORS) { | 1800 } else if (uri == DART_JS_MIRRORS) { |
1799 disableTreeShakingMarker = find(library, 'disableTreeShaking'); | 1801 disableTreeShakingMarker = find(library, 'disableTreeShaking'); |
1800 preserveMetadataMarker = find(library, 'preserveMetadata'); | 1802 preserveMetadataMarker = find(library, 'preserveMetadata'); |
1801 preserveUrisMarker = find(library, 'preserveUris'); | 1803 preserveUrisMarker = find(library, 'preserveUris'); |
1802 preserveLibraryNamesMarker = find(library, 'preserveLibraryNames'); | 1804 preserveLibraryNamesMarker = find(library, 'preserveLibraryNames'); |
1803 } else if (uri == DART_JS_NAMES) { | 1805 } else if (uri == DART_JS_NAMES) { |
1804 preserveNamesMarker = find(library, 'preserveNames'); | 1806 preserveNamesMarker = find(library, 'preserveNames'); |
1805 } else if (uri == DART_HTML) { | 1807 } else if (uri == DART_HTML) { |
1806 htmlLibraryIsLoaded = true; | 1808 htmlLibraryIsLoaded = true; |
1807 } | 1809 } |
| 1810 annotations.onLibraryScanned(library); |
1808 }); | 1811 }); |
1809 } | 1812 } |
1810 | 1813 |
1811 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { | 1814 Future onLibrariesLoaded(LoadedLibraries loadedLibraries) { |
1812 if (!loadedLibraries.containsLibrary(Compiler.DART_CORE)) { | 1815 if (!loadedLibraries.containsLibrary(Compiler.DART_CORE)) { |
1813 return new Future.value(); | 1816 return new Future.value(); |
1814 } | 1817 } |
1815 | 1818 |
1816 assert(loadedLibraries.containsLibrary(Compiler.DART_CORE)); | 1819 assert(loadedLibraries.containsLibrary(Compiler.DART_CORE)); |
1817 assert(loadedLibraries.containsLibrary(DART_INTERCEPTORS)); | 1820 assert(loadedLibraries.containsLibrary(DART_INTERCEPTORS)); |
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2326 assert(name != ""); | 2329 assert(name != ""); |
2327 String outPath = compiler.outputUri != null | 2330 String outPath = compiler.outputUri != null |
2328 ? compiler.outputUri.path | 2331 ? compiler.outputUri.path |
2329 : "out"; | 2332 : "out"; |
2330 String outName = outPath.substring(outPath.lastIndexOf('/') + 1); | 2333 String outName = outPath.substring(outPath.lastIndexOf('/') + 1); |
2331 String extension = addExtension ? ".part.js" : ""; | 2334 String extension = addExtension ? ".part.js" : ""; |
2332 return "${outName}_$name$extension"; | 2335 return "${outName}_$name$extension"; |
2333 } | 2336 } |
2334 } | 2337 } |
2335 | 2338 |
| 2339 /// Handling of special annotations for tests. |
| 2340 class Annotations { |
| 2341 static final Uri PACKAGE_EXPECT = |
| 2342 new Uri(scheme: 'package', path: 'expect/expect.dart'); |
| 2343 |
| 2344 ClassElement expectNoInliningClass; |
| 2345 ClassElement expectTrustTypeAnnotationsClass; |
| 2346 ClassElement expectAssumeDynamicClass; |
| 2347 |
| 2348 void onLibraryScanned(LibraryElement library) { |
| 2349 if (library.canonicalUri == PACKAGE_EXPECT) { |
| 2350 expectNoInliningClass = library.find('NoInlining'); |
| 2351 expectTrustTypeAnnotationsClass = library.find('TrustTypeAnnotations'); |
| 2352 expectAssumeDynamicClass = library.find('AssumeDynamic'); |
| 2353 if (expectNoInliningClass == null || |
| 2354 expectTrustTypeAnnotationsClass == null || |
| 2355 expectAssumeDynamicClass == null) { |
| 2356 // This is not the package you're looking for. |
| 2357 expectNoInliningClass = null; |
| 2358 expectTrustTypeAnnotationsClass = null; |
| 2359 expectAssumeDynamicClass = null; |
| 2360 } |
| 2361 } |
| 2362 } |
| 2363 |
| 2364 /// Returns `true` if inlining is disabled for [element]. |
| 2365 bool noInlining(Element element) { |
| 2366 return _hasAnnotation(element, expectNoInliningClass); |
| 2367 } |
| 2368 |
| 2369 /// Returns `true` if parameter and returns types should be trusted for |
| 2370 /// [element]. |
| 2371 bool trustTypeAnnotations(Element element) { |
| 2372 return _hasAnnotation(element, expectTrustTypeAnnotationsClass); |
| 2373 } |
| 2374 |
| 2375 /// Returns `true` if inference of parameter types is disabled for [element]. |
| 2376 bool assumeDynamic(Element element) { |
| 2377 return _hasAnnotation(element, expectAssumeDynamicClass); |
| 2378 } |
| 2379 |
| 2380 /// Returns `true` if [element] is annotated with [annotationClass]. |
| 2381 bool _hasAnnotation(Element element, ClassElement annotationClass) { |
| 2382 if (annotationClass == null) return false; |
| 2383 for (Link<MetadataAnnotation> link = element.metadata; |
| 2384 !link.isEmpty; |
| 2385 link = link.tail) { |
| 2386 ConstantValue value = link.head.constant.value; |
| 2387 if (value.isConstructedObject) { |
| 2388 ConstructedConstantValue constructedConstant = value; |
| 2389 if (constructedConstant.type.element == annotationClass) { |
| 2390 return true; |
| 2391 } |
| 2392 } |
| 2393 } |
| 2394 return false; |
| 2395 } |
| 2396 } |
| 2397 |
2336 class JavaScriptResolutionCallbacks extends ResolutionCallbacks { | 2398 class JavaScriptResolutionCallbacks extends ResolutionCallbacks { |
2337 final JavaScriptBackend backend; | 2399 final JavaScriptBackend backend; |
2338 | 2400 |
2339 JavaScriptResolutionCallbacks(this.backend); | 2401 JavaScriptResolutionCallbacks(this.backend); |
2340 | 2402 |
2341 void registerBackendStaticInvocation(Element element, Registry registry) { | 2403 void registerBackendStaticInvocation(Element element, Registry registry) { |
2342 registry.registerStaticInvocation(backend.registerBackendUse(element)); | 2404 registry.registerStaticInvocation(backend.registerBackendUse(element)); |
2343 } | 2405 } |
2344 | 2406 |
2345 void registerBackendInstantiation(ClassElement element, Registry registry) { | 2407 void registerBackendInstantiation(ClassElement element, Registry registry) { |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2530 } | 2592 } |
2531 } | 2593 } |
2532 | 2594 |
2533 /// Records that [constant] is used by the element behind [registry]. | 2595 /// Records that [constant] is used by the element behind [registry]. |
2534 class Dependency { | 2596 class Dependency { |
2535 final ConstantValue constant; | 2597 final ConstantValue constant; |
2536 final Element annotatedElement; | 2598 final Element annotatedElement; |
2537 | 2599 |
2538 const Dependency(this.constant, this.annotatedElement); | 2600 const Dependency(this.constant, this.annotatedElement); |
2539 } | 2601 } |
OLD | NEW |