| 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 class JavaScriptItemCompilationContext extends ItemCompilationContext { | 7 class JavaScriptItemCompilationContext extends ItemCompilationContext { |
| 8 final Set<HInstruction> boundsChecked; | 8 final Set<HInstruction> boundsChecked; |
| 9 | 9 |
| 10 JavaScriptItemCompilationContext() | 10 JavaScriptItemCompilationContext() |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 | 312 |
| 313 /// True if a call to preserveNames has been seen. | 313 /// True if a call to preserveNames has been seen. |
| 314 bool mustPreserveNames = false; | 314 bool mustPreserveNames = false; |
| 315 | 315 |
| 316 /// True if a call to disableTreeShaking has been seen. | 316 /// True if a call to disableTreeShaking has been seen. |
| 317 bool isTreeShakingDisabled = false; | 317 bool isTreeShakingDisabled = false; |
| 318 | 318 |
| 319 /// True if there isn't sufficient @MirrorsUsed data. | 319 /// True if there isn't sufficient @MirrorsUsed data. |
| 320 bool hasInsufficientMirrorsUsed = false; | 320 bool hasInsufficientMirrorsUsed = false; |
| 321 | 321 |
| 322 /// List of instantiated types from metadata. If metadata must be preserved, | 322 /// List of constants from metadata. If metadata must be preserved, |
| 323 /// these types must registered. | 323 /// these constants must be registered. |
| 324 final List<Dependency> metadataInstantiatedTypes = <Dependency>[]; | 324 final List<Dependency> metadataConstants = <Dependency>[]; |
| 325 | |
| 326 /// List of elements used from metadata. If metadata must be preserved, | |
| 327 /// these elements must be compiled. | |
| 328 final List<Element> metadataStaticUse = <Element>[]; | |
| 329 | |
| 330 /// List of tear-off functions referenced from metadata. If metadata must be | |
| 331 /// preserved, these elements must be compiled. | |
| 332 final List<FunctionElement> metadataGetOfStaticFunction = <FunctionElement>[]; | |
| 333 | 325 |
| 334 /// List of symbols that the user has requested for reflection. | 326 /// List of symbols that the user has requested for reflection. |
| 335 final Set<String> symbolsUsed = new Set<String>(); | 327 final Set<String> symbolsUsed = new Set<String>(); |
| 336 | 328 |
| 337 /// List of elements that the user has requested for reflection. | 329 /// List of elements that the user has requested for reflection. |
| 338 final Set<Element> targetsUsed = new Set<Element>(); | 330 final Set<Element> targetsUsed = new Set<Element>(); |
| 339 | 331 |
| 340 /// List of annotations provided by user that indicate that the annotated | 332 /// List of annotations provided by user that indicate that the annotated |
| 341 /// element must be retained. | 333 /// element must be retained. |
| 342 final Set<Element> metaTargetsUsed = new Set<Element>(); | 334 final Set<Element> metaTargetsUsed = new Set<Element>(); |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 String name = namer.getInterceptorName(getInterceptorMethod, classes); | 730 String name = namer.getInterceptorName(getInterceptorMethod, classes); |
| 739 if (classes.contains(jsInterceptorClass)) { | 731 if (classes.contains(jsInterceptorClass)) { |
| 740 // We can't use a specialized [getInterceptorMethod], so we make | 732 // We can't use a specialized [getInterceptorMethod], so we make |
| 741 // sure we emit the one with all checks. | 733 // sure we emit the one with all checks. |
| 742 specializedGetInterceptors[name] = interceptedClasses; | 734 specializedGetInterceptors[name] = interceptedClasses; |
| 743 } else { | 735 } else { |
| 744 specializedGetInterceptors[name] = classes; | 736 specializedGetInterceptors[name] = classes; |
| 745 } | 737 } |
| 746 } | 738 } |
| 747 | 739 |
| 740 Constant registerCompileTimeConstant(Constant constant, |
| 741 TreeElements elements) { |
| 742 registerCompileTimeConstantInternal(constant, elements); |
| 743 for (Constant dependency in constant.getDependencies()) { |
| 744 registerCompileTimeConstant(dependency, elements); |
| 745 } |
| 746 } |
| 747 |
| 748 void registerCompileTimeConstantInternal(Constant constant, |
| 749 TreeElements elements) { |
| 750 DartType type = constant.computeType(compiler); |
| 751 registerInstantiatedConstantType(type, elements); |
| 752 |
| 753 if (constant.isFunction()) { |
| 754 FunctionConstant function = constant; |
| 755 compiler.enqueuer.codegen.registerGetOfStaticFunction(function.element); |
| 756 } else if (constant.isInterceptor()) { |
| 757 // An interceptor constant references the class's prototype chain. |
| 758 InterceptorConstant interceptor = constant; |
| 759 registerInstantiatedConstantType(interceptor.dispatchedType, elements); |
| 760 } |
| 761 } |
| 762 |
| 763 void registerInstantiatedConstantType(DartType type, TreeElements elements) { |
| 764 Enqueuer enqueuer = compiler.enqueuer.codegen; |
| 765 enqueuer.registerInstantiatedType(type, elements); |
| 766 if (type is InterfaceType && !type.treatAsRaw && |
| 767 classNeedsRti(type.element)) { |
| 768 enqueuer.registerStaticUse(getSetRuntimeTypeInfo()); |
| 769 } |
| 770 if (type.element == typeImplementation) { |
| 771 // If we use a type literal in a constant, the compile time |
| 772 // constant emitter will generate a call to the createRuntimeType |
| 773 // helper so we register a use of that. |
| 774 enqueuer.registerStaticUse(getCreateRuntimeType()); |
| 775 } |
| 776 } |
| 777 |
| 778 void registerMetadataConstant(Constant constant, TreeElements elements) { |
| 779 if (mustRetainMetadata) { |
| 780 registerCompileTimeConstant(constant, elements); |
| 781 } else { |
| 782 metadataConstants.add(new Dependency(constant, elements)); |
| 783 } |
| 784 } |
| 785 |
| 748 void registerInstantiatedClass(ClassElement cls, | 786 void registerInstantiatedClass(ClassElement cls, |
| 749 Enqueuer enqueuer, | 787 Enqueuer enqueuer, |
| 750 TreeElements elements) { | 788 TreeElements elements) { |
| 751 if (!seenAnyClass) { | 789 if (!seenAnyClass) { |
| 752 seenAnyClass = true; | 790 seenAnyClass = true; |
| 753 if (enqueuer.isResolutionQueue) { | 791 if (enqueuer.isResolutionQueue) { |
| 754 // TODO(9577): Make it so that these are not needed when there are no | 792 // TODO(9577): Make it so that these are not needed when there are no |
| 755 // native classes. | 793 // native classes. |
| 756 enqueue(enqueuer, getNativeInterceptorMethod, elements); | 794 enqueue(enqueuer, getNativeInterceptorMethod, elements); |
| 757 enqueue(enqueuer, defineNativeMethodsFinishMethod, elements); | 795 enqueue(enqueuer, defineNativeMethodsFinishMethod, elements); |
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1180 | 1218 |
| 1181 void codegen(CodegenWorkItem work) { | 1219 void codegen(CodegenWorkItem work) { |
| 1182 Element element = work.element; | 1220 Element element = work.element; |
| 1183 var kind = element.kind; | 1221 var kind = element.kind; |
| 1184 if (kind == ElementKind.TYPEDEF) return; | 1222 if (kind == ElementKind.TYPEDEF) return; |
| 1185 if (element.isConstructor() && element.getEnclosingClass() == jsNullClass) { | 1223 if (element.isConstructor() && element.getEnclosingClass() == jsNullClass) { |
| 1186 // Work around a problem compiling JSNull's constructor. | 1224 // Work around a problem compiling JSNull's constructor. |
| 1187 return; | 1225 return; |
| 1188 } | 1226 } |
| 1189 if (kind.category == ElementCategory.VARIABLE) { | 1227 if (kind.category == ElementCategory.VARIABLE) { |
| 1190 Constant initialValue = compiler.constantHandler.compileWorkItem(work); | 1228 Constant initialValue = |
| 1229 compiler.constantHandler.getConstantForVariable(element); |
| 1191 if (initialValue != null) { | 1230 if (initialValue != null) { |
| 1231 registerCompileTimeConstant(initialValue, work.resolutionTree); |
| 1232 compiler.constantHandler.addCompileTimeConstantForEmission( |
| 1233 initialValue); |
| 1192 return; | 1234 return; |
| 1193 } else { | 1235 } else { |
| 1194 // If the constant-handler was not able to produce a result we have to | 1236 // If the constant-handler was not able to produce a result we have to |
| 1195 // go through the builder (below) to generate the lazy initializer for | 1237 // go through the builder (below) to generate the lazy initializer for |
| 1196 // the static variable. | 1238 // the static variable. |
| 1197 // We also need to register the use of the cyclic-error helper. | 1239 // We also need to register the use of the cyclic-error helper. |
| 1198 compiler.enqueuer.codegen.registerStaticUse(getCyclicThrowHelper()); | 1240 compiler.enqueuer.codegen.registerStaticUse(getCyclicThrowHelper()); |
| 1199 } | 1241 } |
| 1200 } | 1242 } |
| 1201 | 1243 |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1605 if (name == const SourceString('')) return false; | 1647 if (name == const SourceString('')) return false; |
| 1606 return symbolsUsed.contains(name.slowToString()); | 1648 return symbolsUsed.contains(name.slowToString()); |
| 1607 } | 1649 } |
| 1608 | 1650 |
| 1609 bool get rememberLazies => isTreeShakingDisabled; | 1651 bool get rememberLazies => isTreeShakingDisabled; |
| 1610 | 1652 |
| 1611 bool retainMetadataOf(Element element) { | 1653 bool retainMetadataOf(Element element) { |
| 1612 if (mustRetainMetadata) hasRetainedMetadata = true; | 1654 if (mustRetainMetadata) hasRetainedMetadata = true; |
| 1613 if (mustRetainMetadata && isNeededForReflection(element)) { | 1655 if (mustRetainMetadata && isNeededForReflection(element)) { |
| 1614 for (MetadataAnnotation metadata in element.metadata) { | 1656 for (MetadataAnnotation metadata in element.metadata) { |
| 1615 metadata.ensureResolved(compiler) | 1657 metadata.ensureResolved(compiler); |
| 1616 .value.accept(new ConstantCopier(compiler.constantHandler)); | 1658 compiler.constantHandler.addCompileTimeConstantForEmission( |
| 1659 metadata.value); |
| 1617 } | 1660 } |
| 1618 return true; | 1661 return true; |
| 1619 } | 1662 } |
| 1620 return false; | 1663 return false; |
| 1621 } | 1664 } |
| 1622 | 1665 |
| 1623 Future onLibraryLoaded(LibraryElement library, Uri uri) { | 1666 Future onLibraryLoaded(LibraryElement library, Uri uri) { |
| 1624 if (uri == Uri.parse('dart:_js_mirrors')) { | 1667 if (uri == Uri.parse('dart:_js_mirrors')) { |
| 1625 disableTreeShakingMarker = | 1668 disableTreeShakingMarker = |
| 1626 library.find(const SourceString('disableTreeShaking')); | 1669 library.find(const SourceString('disableTreeShaking')); |
| 1627 preserveMetadataMarker = | 1670 preserveMetadataMarker = |
| 1628 library.find(const SourceString('preserveMetadata')); | 1671 library.find(const SourceString('preserveMetadata')); |
| 1629 } else if (uri == Uri.parse('dart:_js_names')) { | 1672 } else if (uri == Uri.parse('dart:_js_names')) { |
| 1630 preserveNamesMarker = | 1673 preserveNamesMarker = |
| 1631 library.find(const SourceString('preserveNames')); | 1674 library.find(const SourceString('preserveNames')); |
| 1632 } | 1675 } |
| 1633 return new Future.value(); | 1676 return new Future.value(); |
| 1634 } | 1677 } |
| 1635 | 1678 |
| 1636 void registerMetadataInstantiatedType(DartType type, TreeElements elements) { | |
| 1637 if (mustRetainMetadata) { | |
| 1638 compiler.constantHandler.registerInstantiatedType(type, elements); | |
| 1639 } else { | |
| 1640 metadataInstantiatedTypes.add(new Dependency(type, elements)); | |
| 1641 } | |
| 1642 } | |
| 1643 | |
| 1644 void registerMetadataStaticUse(Element element) { | |
| 1645 if (mustRetainMetadata) { | |
| 1646 compiler.constantHandler.registerStaticUse(element); | |
| 1647 } else { | |
| 1648 metadataStaticUse.add(element); | |
| 1649 } | |
| 1650 } | |
| 1651 | |
| 1652 void registerMetadataGetOfStaticFunction(FunctionElement element) { | |
| 1653 if (mustRetainMetadata) { | |
| 1654 compiler.constantHandler.registerGetOfStaticFunction(element); | |
| 1655 } else { | |
| 1656 metadataGetOfStaticFunction.add(element); | |
| 1657 } | |
| 1658 } | |
| 1659 | |
| 1660 void registerMirrorUsage(Set<String> symbols, | 1679 void registerMirrorUsage(Set<String> symbols, |
| 1661 Set<Element> targets, | 1680 Set<Element> targets, |
| 1662 Set<Element> metaTargets) { | 1681 Set<Element> metaTargets) { |
| 1663 if (symbols == null && targets == null && metaTargets == null) { | 1682 if (symbols == null && targets == null && metaTargets == null) { |
| 1664 // The user didn't specify anything, or there are imports of | 1683 // The user didn't specify anything, or there are imports of |
| 1665 // 'dart:mirrors' without @MirrorsUsed. | 1684 // 'dart:mirrors' without @MirrorsUsed. |
| 1666 hasInsufficientMirrorsUsed = true; | 1685 hasInsufficientMirrorsUsed = true; |
| 1667 return; | 1686 return; |
| 1668 } | 1687 } |
| 1669 if (symbols != null) symbolsUsed.addAll(symbols); | 1688 if (symbols != null) symbolsUsed.addAll(symbols); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1770 } | 1789 } |
| 1771 | 1790 |
| 1772 if (isTreeShakingDisabled) enqueuer.enqueueEverything(); | 1791 if (isTreeShakingDisabled) enqueuer.enqueueEverything(); |
| 1773 | 1792 |
| 1774 if (mustPreserveNames) compiler.log('Preserving names.'); | 1793 if (mustPreserveNames) compiler.log('Preserving names.'); |
| 1775 | 1794 |
| 1776 if (mustRetainMetadata) { | 1795 if (mustRetainMetadata) { |
| 1777 compiler.log('Retaining metadata.'); | 1796 compiler.log('Retaining metadata.'); |
| 1778 | 1797 |
| 1779 compiler.libraries.values.forEach(retainMetadataOf); | 1798 compiler.libraries.values.forEach(retainMetadataOf); |
| 1780 for (Dependency dependency in metadataInstantiatedTypes) { | 1799 for (Dependency dependency in metadataConstants) { |
| 1781 registerMetadataInstantiatedType(dependency.type, dependency.user); | 1800 registerCompileTimeConstant( |
| 1801 dependency.constant, dependency.user); |
| 1782 } | 1802 } |
| 1783 metadataInstantiatedTypes.clear(); | 1803 metadataConstants.clear(); |
| 1784 for (Element e in metadataStaticUse) { | |
| 1785 registerMetadataStaticUse(e); | |
| 1786 } | |
| 1787 metadataStaticUse.clear(); | |
| 1788 for (Element e in metadataGetOfStaticFunction) { | |
| 1789 registerMetadataGetOfStaticFunction(e); | |
| 1790 } | |
| 1791 metadataGetOfStaticFunction.clear(); | |
| 1792 } | 1804 } |
| 1793 } | 1805 } |
| 1794 } | 1806 } |
| 1795 | 1807 |
| 1796 /// Records that [type] is used by [user.element]. | 1808 /// Records that [constant] is used by [user.element]. |
| 1797 class Dependency { | 1809 class Dependency { |
| 1798 final DartType type; | 1810 final Constant constant; |
| 1799 final TreeElements user; | 1811 final TreeElements user; |
| 1800 | 1812 |
| 1801 const Dependency(this.type, this.user); | 1813 const Dependency(this.constant, this.user); |
| 1802 } | 1814 } |
| 1803 | 1815 |
| 1804 /// Used to copy metadata to the the actual constant handler. | 1816 /// Used to copy metadata to the the actual constant handler. |
| 1805 class ConstantCopier implements ConstantVisitor { | 1817 class ConstantCopier implements ConstantVisitor { |
| 1806 final ConstantHandler target; | 1818 final ConstantHandler target; |
| 1807 | 1819 |
| 1808 ConstantCopier(this.target); | 1820 ConstantCopier(this.target); |
| 1809 | 1821 |
| 1810 void copy(/* Constant or List<Constant> */ value) { | 1822 void copy(/* Constant or List<Constant> */ value) { |
| 1811 if (value is Constant) { | 1823 if (value is Constant) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1842 copy(constant.values); | 1854 copy(constant.values); |
| 1843 copy(constant.protoValue); | 1855 copy(constant.protoValue); |
| 1844 copy(constant); | 1856 copy(constant); |
| 1845 } | 1857 } |
| 1846 | 1858 |
| 1847 void visitConstructed(ConstructedConstant constant) { | 1859 void visitConstructed(ConstructedConstant constant) { |
| 1848 copy(constant.fields); | 1860 copy(constant.fields); |
| 1849 copy(constant); | 1861 copy(constant); |
| 1850 } | 1862 } |
| 1851 } | 1863 } |
| OLD | NEW |