Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 dart2js.js_emitter; | 5 part of dart2js.js_emitter; |
| 6 | 6 |
| 7 | 7 |
| 8 class OldEmitter implements Emitter { | 8 class OldEmitter implements Emitter { |
| 9 final Compiler compiler; | 9 final Compiler compiler; |
| 10 final CodeEmitterTask task; | 10 final CodeEmitterTask task; |
| (...skipping 1607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1618 })(holder, stub, existingStub, existing, method)); | 1618 })(holder, stub, existingStub, existing, method)); |
| 1619 } | 1619 } |
| 1620 } else { | 1620 } else { |
| 1621 method = arrayOrFunction; | 1621 method = arrayOrFunction; |
| 1622 holder[name] = method; | 1622 holder[name] = method; |
| 1623 } | 1623 } |
| 1624 if (isStatic) globalFunctionsAccess[name] = method; | 1624 if (isStatic) globalFunctionsAccess[name] = method; |
| 1625 }"""); | 1625 }"""); |
| 1626 } | 1626 } |
| 1627 | 1627 |
| 1628 /// Returns a map from OutputUnit to a hash of its content. The hash uniquely | 1628 Map<OutputUnit, jsAst.Expression> buildDescriptorsForOutputUnits( |
| 1629 /// identifies the code of the output-unit. It does not include | 1629 Program program) { |
| 1630 /// boilerplate JS code, like the sourcemap directives or the hash | |
| 1631 /// itself. | |
| 1632 Map<OutputUnit, String> emitDeferredOutputUnits(Program program) { | |
| 1633 if (!program.isSplit) return const {}; | |
| 1634 | |
| 1635 Map<OutputUnit, jsAst.Expression> outputs = | 1630 Map<OutputUnit, jsAst.Expression> outputs = |
| 1636 new Map<OutputUnit, jsAst.Expression>(); | 1631 new Map<OutputUnit, jsAst.Expression>(); |
|
karlklose
2015/05/22 07:27:49
Undo change here an din l. 1640.
herhut
2015/05/22 07:57:20
Done.
| |
| 1637 | 1632 |
| 1638 for (Fragment fragment in program.deferredFragments) { | 1633 for (Fragment fragment in program.deferredFragments) { |
| 1639 OutputUnit outputUnit = fragment.outputUnit; | 1634 OutputUnit outputUnit = fragment.outputUnit; |
| 1640 | 1635 |
| 1641 Map<Element, ClassBuilder> descriptors = elementDescriptors[fragment]; | 1636 Map<Element, ClassBuilder> descriptors = elementDescriptors[fragment]; |
| 1642 | 1637 |
| 1643 if (descriptors != null && descriptors.isNotEmpty) { | 1638 if (descriptors != null && descriptors.isNotEmpty) { |
| 1644 Iterable<LibraryElement> libraries = | 1639 Iterable<LibraryElement> libraries = |
| 1645 task.outputLibraryLists[outputUnit]; | 1640 task.outputLibraryLists[outputUnit]; |
| 1646 if (libraries == null) libraries = []; | 1641 if (libraries == null) libraries = []; |
| 1647 | 1642 |
| 1648 // TODO(johnniwinther): Avoid creating [CodeBuffer]s. | 1643 // TODO(johnniwinther): Avoid creating [CodeBuffer]s. |
| 1649 List<jsAst.Expression> parts = <jsAst.Expression>[]; | 1644 List<jsAst.Expression> parts = <jsAst.Expression>[]; |
| 1650 for (LibraryElement library in Elements.sortedByPosition(libraries)) { | 1645 for (LibraryElement library in Elements.sortedByPosition(libraries)) { |
| 1651 parts.add(generateLibraryDescriptor(library, fragment)); | 1646 parts.add(generateLibraryDescriptor(library, fragment)); |
| 1652 descriptors.remove(library); | 1647 descriptors.remove(library); |
| 1653 } | 1648 } |
| 1654 | 1649 |
| 1655 outputs[outputUnit] = new jsAst.ArrayInitializer(parts); | 1650 outputs[outputUnit] = new jsAst.ArrayInitializer(parts); |
| 1656 } | 1651 } |
| 1657 } | 1652 } |
| 1658 | 1653 |
| 1659 return emitDeferredCode(program, outputs); | 1654 return outputs; |
| 1660 } | 1655 } |
| 1661 | 1656 |
| 1662 int emitProgram(ProgramBuilder programBuilder) { | 1657 int emitProgram(ProgramBuilder programBuilder) { |
| 1663 Program program = programBuilder.buildProgram( | 1658 Program program = programBuilder.buildProgram( |
| 1664 storeFunctionTypesInMetadata: true); | 1659 storeFunctionTypesInMetadata: true); |
| 1665 | 1660 |
| 1666 assembleProgram(program); | 1661 assembleProgram(program); |
| 1667 | 1662 |
| 1663 // Construct the ASTs for all deferred output units. | |
| 1664 Map<OutputUnit, jsAst.Program> deferredParts = | |
| 1665 buildOutputAstForDeferredCode(program); | |
| 1666 | |
| 1668 // Emit deferred units first, so we have their hashes. | 1667 // Emit deferred units first, so we have their hashes. |
| 1669 // Map from OutputUnit to a hash of its content. The hash uniquely | 1668 // Map from OutputUnit to a hash of its content. The hash uniquely |
| 1670 // identifies the code of the output-unit. It does not include | 1669 // identifies the code of the output-unit. It does not include |
| 1671 // boilerplate JS code, like the sourcemap directives or the hash | 1670 // boilerplate JS code, like the sourcemap directives or the hash |
| 1672 // itself. | 1671 // itself. |
| 1673 Map<OutputUnit, String> deferredLoadHashes = | 1672 Map<OutputUnit, String> deferredLoadHashes = |
| 1674 emitDeferredOutputUnits(program); | 1673 emitDeferredOutputUnits(deferredParts); |
| 1675 emitMainOutputUnit(program, deferredLoadHashes); | 1674 emitMainOutputUnit(program, deferredLoadHashes); |
| 1676 | 1675 |
| 1677 if (backend.requiresPreamble && | 1676 if (backend.requiresPreamble && |
| 1678 !backend.htmlLibraryIsLoaded) { | 1677 !backend.htmlLibraryIsLoaded) { |
| 1679 compiler.reportHint(NO_LOCATION_SPANNABLE, MessageKind.PREAMBLE); | 1678 compiler.reportHint(NO_LOCATION_SPANNABLE, MessageKind.PREAMBLE); |
| 1680 } | 1679 } |
| 1681 // Return the total program size. | 1680 // Return the total program size. |
| 1682 return outputBuffers.values.fold(0, (a, b) => a + b.length); | 1681 return outputBuffers.values.fold(0, (a, b) => a + b.length); |
| 1683 } | 1682 } |
| 1684 | 1683 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1784 parts.add(js.statement("# = #", [globalName, initializer])); | 1783 parts.add(js.statement("# = #", [globalName, initializer])); |
| 1785 } | 1784 } |
| 1786 | 1785 |
| 1787 emitMapping(embeddedNames.DEFERRED_LIBRARY_URIS, deferredLibraryUris); | 1786 emitMapping(embeddedNames.DEFERRED_LIBRARY_URIS, deferredLibraryUris); |
| 1788 emitMapping(embeddedNames.DEFERRED_LIBRARY_HASHES, | 1787 emitMapping(embeddedNames.DEFERRED_LIBRARY_HASHES, |
| 1789 deferredLibraryHashes); | 1788 deferredLibraryHashes); |
| 1790 | 1789 |
| 1791 return new jsAst.Block(parts); | 1790 return new jsAst.Block(parts); |
| 1792 } | 1791 } |
| 1793 | 1792 |
| 1794 /// Emits code for all output units except the main. | 1793 Map <OutputUnit, jsAst.Program> buildOutputAstForDeferredCode( |
| 1795 /// Returns a mapping from outputUnit to a hash of the corresponding hunk that | 1794 Program program) { |
| 1796 /// can be used for calling the initializer. | 1795 if (!program.isSplit) return const {}; |
|
karlklose
2015/05/22 07:27:49
Add type arguments to map literal.
herhut
2015/05/22 07:57:20
Done.
| |
| 1797 Map<OutputUnit, String> emitDeferredCode( | |
| 1798 Program program, | |
| 1799 Map<OutputUnit, jsAst.Expression> deferredAsts) { | |
| 1800 | 1796 |
| 1801 Map<OutputUnit, String> hunkHashes = new Map<OutputUnit, String>(); | 1797 Map<OutputUnit, jsAst.Program> result = |
| 1798 new Map<OutputUnit, jsAst.Program>(); | |
| 1799 | |
| 1800 Map<OutputUnit, jsAst.Expression> deferredAsts = | |
| 1801 buildDescriptorsForOutputUnits(program); | |
| 1802 | 1802 |
| 1803 for (Fragment fragment in program.deferredFragments) { | 1803 for (Fragment fragment in program.deferredFragments) { |
| 1804 OutputUnit outputUnit = fragment.outputUnit; | 1804 OutputUnit outputUnit = fragment.outputUnit; |
| 1805 | |
| 1806 jsAst.Expression libraryDescriptor = deferredAsts[outputUnit]; | 1805 jsAst.Expression libraryDescriptor = deferredAsts[outputUnit]; |
| 1807 | |
| 1808 List<CodeOutputListener> outputListeners = <CodeOutputListener>[]; | |
| 1809 Hasher hasher = new Hasher(); | |
| 1810 outputListeners.add(hasher); | |
| 1811 | |
| 1812 LineColumnCollector lineColumnCollector; | |
| 1813 if (generateSourceMap) { | |
| 1814 lineColumnCollector = new LineColumnCollector(); | |
| 1815 outputListeners.add(lineColumnCollector); | |
| 1816 } | |
| 1817 | |
| 1818 String partPrefix = | |
| 1819 backend.deferredPartFileName(outputUnit.name, addExtension: false); | |
| 1820 CodeOutput output = new StreamCodeOutput( | |
| 1821 compiler.outputProvider(partPrefix, 'part.js'), | |
| 1822 outputListeners); | |
| 1823 | |
| 1824 outputBuffers[outputUnit] = output; | |
| 1825 | |
| 1826 List<jsAst.Statement> body = <jsAst.Statement>[]; | 1806 List<jsAst.Statement> body = <jsAst.Statement>[]; |
| 1827 | 1807 |
| 1828 // No renaming in the top-level function to save the locals for the | 1808 // No renaming in the top-level function to save the locals for the |
| 1829 // nested context where they will be used more. | 1809 // nested context where they will be used more. |
| 1830 body.add(js.comment("/* ::norenaming:: ")); | 1810 body.add(js.comment("/* ::norenaming:: ")); |
| 1831 | 1811 |
| 1832 for (String globalObject in Namer.reservedGlobalObjectNames) { | 1812 for (String globalObject in Namer.reservedGlobalObjectNames) { |
| 1833 body.add(js.statement('var #object = ${globalsHolder}.#object;', | 1813 body.add(js.statement('var #object = ${globalsHolder}.#object;', |
| 1834 {'object': globalObject})); | 1814 {'object': globalObject})); |
| 1835 } | 1815 } |
| 1836 body..add(js.statement('var init = ${globalsHolder}.init;')) | 1816 body..add(js.statement('var init = ${globalsHolder}.init;')) |
| 1837 ..add(js.statement('var $setupProgramName = ' | 1817 ..add(js.statement('var $setupProgramName = ' |
| 1838 '$globalsHolder.$setupProgramName;')) | 1818 '$globalsHolder.$setupProgramName;')) |
| 1839 ..add(js.statement('var ${namer.isolateName} = ' | 1819 ..add(js.statement('var ${namer.isolateName} = ' |
| 1840 '${globalsHolder}.${namer.isolateName};')); | 1820 '${globalsHolder}.${namer.isolateName};')); |
|
karlklose
2015/05/22 07:27:49
Undo changes here and in l. 1822.
herhut
2015/05/22 07:57:20
Done.
| |
| 1841 String typesAccess = | 1821 String typesAccess = |
| 1842 generateEmbeddedGlobalAccessString(embeddedNames.TYPES); | 1822 generateEmbeddedGlobalAccessString(embeddedNames.TYPES); |
| 1843 if (libraryDescriptor != null) { | 1823 if (libraryDescriptor != null) { |
| 1844 // The argument to reflectionDataParser is assigned to a temporary | 1824 // The argument to reflectionDataParser is assigned to a temporary |
| 1845 // 'dart' so that 'dart.' will appear as the prefix to dart methods | 1825 // 'dart' so that 'dart.' will appear as the prefix to dart methods |
| 1846 // in stack traces and profile entries. | 1826 // in stack traces and profile entries. |
| 1847 body.add(js.statement('var dart = #', libraryDescriptor)); | 1827 body.add(js.statement('var dart = #', libraryDescriptor)); |
| 1848 | 1828 |
| 1849 if (compiler.useContentSecurityPolicy) { | 1829 if (compiler.useContentSecurityPolicy) { |
| 1850 body.add(buildCspPrecompiledFunctionFor(outputUnit)); | 1830 body.add(buildCspPrecompiledFunctionFor(outputUnit)); |
| 1851 } | 1831 } |
| 1852 body.add( | 1832 body.add( |
| 1853 js.statement('$setupProgramName(dart, ${typesAccess}.length);')); | 1833 js.statement('$setupProgramName(dart, ${typesAccess}.length);')); |
| 1854 } | 1834 } |
| 1855 | 1835 |
| 1856 if (task.metadataCollector.types[outputUnit] != null) { | 1836 if (task.metadataCollector.types[outputUnit] != null) { |
| 1857 body..add(buildMetadata(program, outputUnit)) | 1837 body..add(buildMetadata(program, outputUnit)) |
| 1858 ..add(js.statement('${typesAccess}.push.apply(${typesAccess}, ' | 1838 ..add(js.statement('${typesAccess}.push.apply(${typesAccess}, ' |
| 1859 '${namer.deferredTypesName});')); | 1839 '${namer.deferredTypesName});')); |
| 1860 } | 1840 } |
| 1861 | 1841 |
| 1862 // Set the currentIsolate variable to the current isolate (which is | 1842 // Set the currentIsolate variable to the current isolate (which is |
| 1863 // provided as second argument). | 1843 // provided as second argument). |
| 1864 body.add(js.statement("${namer.currentIsolate} = arguments[1];")); | 1844 body.add(js.statement("${namer.currentIsolate} = arguments[1];")); |
| 1865 | 1845 |
| 1866 body.add(buildCompileTimeConstants(fragment.constants, | 1846 body.add(buildCompileTimeConstants(fragment.constants, |
| 1867 isMainFragment: false)); | 1847 isMainFragment: false)); |
| 1868 body.add(buildStaticNonFinalFieldInitializations(outputUnit)); | 1848 body.add(buildStaticNonFinalFieldInitializations(outputUnit)); |
| 1869 | 1849 |
| 1870 List<jsAst.Statement> statements = <jsAst.Statement>[]; | 1850 List<jsAst.Statement> statements = <jsAst.Statement>[]; |
| 1871 | 1851 |
| 1872 statements..add(buildGeneratedBy()) | 1852 statements |
| 1853 ..add(buildGeneratedBy()) | |
| 1873 ..add(js.statement('${deferredInitializers}.current = ' | 1854 ..add(js.statement('${deferredInitializers}.current = ' |
| 1874 """function (${globalsHolder}) { | 1855 """function (${globalsHolder}) { |
| 1875 # | 1856 # |
| 1876 } | 1857 } |
| 1877 """, [body])); | 1858 """, [body])); |
| 1878 | 1859 |
| 1879 output.addBuffer(jsAst.prettyPrint(new jsAst.Program(statements), | 1860 result[outputUnit] = new jsAst.Program(statements); |
| 1861 } | |
| 1862 | |
| 1863 return result; | |
| 1864 } | |
| 1865 | |
| 1866 /// Returns a map from OutputUnit to a hash of its content. The hash uniquely | |
| 1867 /// identifies the code of the output-unit. It does not include | |
| 1868 /// boilerplate JS code, like the sourcemap directives or the hash | |
| 1869 /// itself. | |
| 1870 Map<OutputUnit, String> emitDeferredOutputUnits( | |
| 1871 Map<OutputUnit, jsAst.Program> outputAsts) { | |
| 1872 | |
| 1873 Map<OutputUnit, String> hunkHashes = new Map<OutputUnit, String>(); | |
| 1874 | |
| 1875 for (OutputUnit outputUnit in outputAsts.keys) { | |
| 1876 List<CodeOutputListener> outputListeners = <CodeOutputListener>[]; | |
| 1877 Hasher hasher = new Hasher(); | |
| 1878 outputListeners.add(hasher); | |
| 1879 | |
| 1880 LineColumnCollector lineColumnCollector; | |
| 1881 if (generateSourceMap) { | |
| 1882 lineColumnCollector = new LineColumnCollector(); | |
| 1883 outputListeners.add(lineColumnCollector); | |
| 1884 } | |
| 1885 | |
| 1886 String partPrefix = | |
| 1887 backend.deferredPartFileName(outputUnit.name, addExtension: false); | |
| 1888 CodeOutput output = new StreamCodeOutput( | |
| 1889 compiler.outputProvider(partPrefix, 'part.js'), | |
| 1890 outputListeners); | |
| 1891 | |
| 1892 outputBuffers[outputUnit] = output; | |
| 1893 | |
| 1894 output.addBuffer(jsAst.prettyPrint(outputAsts[outputUnit], | |
| 1880 compiler, | 1895 compiler, |
| 1881 monitor: compiler.dumpInfoTask)); | 1896 monitor: compiler.dumpInfoTask)); |
| 1882 | 1897 |
| 1883 // Make a unique hash of the code (before the sourcemaps are added) | 1898 // Make a unique hash of the code (before the sourcemaps are added) |
| 1884 // This will be used to retrieve the initializing function from the global | 1899 // This will be used to retrieve the initializing function from the global |
| 1885 // variable. | 1900 // variable. |
| 1886 String hash = hasher.getHash(); | 1901 String hash = hasher.getHash(); |
| 1887 | 1902 |
| 1888 output.add('$N${deferredInitializers}["$hash"]$_=$_' | 1903 output.add('$N${deferredInitializers}["$hash"]$_=$_' |
| 1889 '${deferredInitializers}.current$N'); | 1904 '${deferredInitializers}.current$N'); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1965 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 1980 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
| 1966 if (element.isInstanceMember) { | 1981 if (element.isInstanceMember) { |
| 1967 cachedClassBuilders.remove(element.enclosingClass); | 1982 cachedClassBuilders.remove(element.enclosingClass); |
| 1968 | 1983 |
| 1969 nativeEmitter.cachedBuilders.remove(element.enclosingClass); | 1984 nativeEmitter.cachedBuilders.remove(element.enclosingClass); |
| 1970 | 1985 |
| 1971 } | 1986 } |
| 1972 } | 1987 } |
| 1973 } | 1988 } |
| 1974 } | 1989 } |
| OLD | NEW |