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 992 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1003 return object.__proto__ && | 1003 return object.__proto__ && |
1004 object.__proto__.p === cls.prototype.p; | 1004 object.__proto__.p === cls.prototype.p; |
1005 })(); | 1005 })(); |
1006 '''); | 1006 '''); |
1007 } | 1007 } |
1008 | 1008 |
1009 output.addBuffer(jsAst.prettyPrint(supportsDirectProtoAccess, compiler)); | 1009 output.addBuffer(jsAst.prettyPrint(supportsDirectProtoAccess, compiler)); |
1010 output.add(N); | 1010 output.add(N); |
1011 } | 1011 } |
1012 | 1012 |
1013 void writeLibraryDescriptor(CodeOutput output, LibraryElement library, | 1013 jsAst.Expression generateLibraryDescriptor(LibraryElement library, |
1014 Fragment fragment) { | 1014 Fragment fragment) { |
1015 var uri = ""; | 1015 var uri = ""; |
1016 if (!compiler.enableMinification || backend.mustPreserveUris) { | 1016 if (!compiler.enableMinification || backend.mustPreserveUris) { |
1017 uri = library.canonicalUri; | 1017 uri = library.canonicalUri; |
1018 if (uri.scheme == 'file' && compiler.outputUri != null) { | 1018 if (uri.scheme == 'file' && compiler.outputUri != null) { |
1019 uri = relativize(compiler.outputUri, library.canonicalUri, false); | 1019 uri = relativize(compiler.outputUri, library.canonicalUri, false); |
1020 } | 1020 } |
1021 } | 1021 } |
1022 ClassBuilder descriptor = elementDescriptors[fragment][library]; | |
1023 if (descriptor == null) { | |
1024 // Nothing of the library was emitted. | |
1025 // TODO(floitsch): this should not happen. We currently have an example | |
1026 // with language/prefix6_negative_test.dart where we have an instance | |
1027 // method without its corresponding class. | |
1028 return; | |
1029 } | |
1030 | 1022 |
1031 String libraryName = | 1023 String libraryName = |
1032 (!compiler.enableMinification || backend.mustRetainLibraryNames) ? | 1024 (!compiler.enableMinification || backend.mustRetainLibraryNames) ? |
1033 library.getLibraryName() : | 1025 library.getLibraryName() : |
1034 ""; | 1026 ""; |
1035 | 1027 |
1036 jsAst.Fun metadata = task.metadataCollector.buildMetadataFunction(library); | 1028 jsAst.Fun metadata = task.metadataCollector.buildMetadataFunction(library); |
1037 | 1029 |
1038 jsAst.ObjectInitializer initializers = descriptor.toObjectInitializer(); | 1030 ClassBuilder descriptor = elementDescriptors[fragment][library]; |
| 1031 |
| 1032 jsAst.ObjectInitializer initializer; |
| 1033 if (descriptor == null) { |
| 1034 // Nothing of the library was emitted. |
| 1035 // TODO(floitsch): this should not happen. We currently have an example |
| 1036 // with language/prefix6_negative_test.dart where we have an instance |
| 1037 // method without its corresponding class. |
| 1038 initializer = new jsAst.ObjectInitializer([]); |
| 1039 } else { |
| 1040 initializer = descriptor.toObjectInitializer(); |
| 1041 } |
1039 | 1042 |
1040 compiler.dumpInfoTask.registerElementAst(library, metadata); | 1043 compiler.dumpInfoTask.registerElementAst(library, metadata); |
1041 compiler.dumpInfoTask.registerElementAst(library, initializers); | 1044 compiler.dumpInfoTask.registerElementAst(library, initializer); |
1042 output | 1045 |
1043 ..add('["$libraryName",$_') | 1046 List<jsAst.Expression> parts = <jsAst.Expression>[]; |
1044 ..add('"${uri}",$_'); | 1047 parts..add(js.string(libraryName)) |
1045 if (metadata != null) { | 1048 ..add(js.string(uri.toString())) |
1046 output.addBuffer(jsAst.prettyPrint(metadata, | 1049 ..add(metadata == null ? new jsAst.ArrayHole() : metadata) |
1047 compiler, | 1050 ..add(js.name(namer.globalObjectFor(library))) |
1048 monitor: compiler.dumpInfoTask)); | 1051 ..add(initializer); |
| 1052 if (library == compiler.mainApp) { |
| 1053 parts.add(js.number(1)); |
1049 } | 1054 } |
1050 output | 1055 |
1051 ..add(',$_') | 1056 return new jsAst.ArrayInitializer(parts); |
1052 ..add(namer.globalObjectFor(library)) | |
1053 ..add(',$_') | |
1054 ..addBuffer(jsAst.prettyPrint(initializers, | |
1055 compiler, | |
1056 monitor: compiler.dumpInfoTask)) | |
1057 ..add(library == compiler.mainApp ? ',${n}1' : "") | |
1058 ..add('],$n'); | |
1059 } | 1057 } |
1060 | 1058 |
1061 void assemblePrecompiledConstructor(OutputUnit outputUnit, | 1059 void assemblePrecompiledConstructor(OutputUnit outputUnit, |
1062 String constructorName, | 1060 String constructorName, |
1063 jsAst.Expression constructorAst, | 1061 jsAst.Expression constructorAst, |
1064 List<String> fields) { | 1062 List<String> fields) { |
1065 cspPrecompiledFunctionFor(outputUnit).add( | 1063 cspPrecompiledFunctionFor(outputUnit).add( |
1066 new jsAst.FunctionDeclaration( | 1064 new jsAst.FunctionDeclaration( |
1067 new jsAst.VariableDeclaration(constructorName), constructorAst)); | 1065 new jsAst.VariableDeclaration(constructorName), constructorAst)); |
1068 | 1066 |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1322 Iterable<LibraryElement> libraries = | 1320 Iterable<LibraryElement> libraries = |
1323 task.outputLibraryLists[mainOutputUnit]; | 1321 task.outputLibraryLists[mainOutputUnit]; |
1324 if (libraries == null) libraries = []; | 1322 if (libraries == null) libraries = []; |
1325 emitMangledNames(mainOutput); | 1323 emitMangledNames(mainOutput); |
1326 | 1324 |
1327 Map<Element, ClassBuilder> descriptors = elementDescriptors[mainFragment]; | 1325 Map<Element, ClassBuilder> descriptors = elementDescriptors[mainFragment]; |
1328 if (descriptors == null) descriptors = const {}; | 1326 if (descriptors == null) descriptors = const {}; |
1329 | 1327 |
1330 checkEverythingEmitted(descriptors.keys); | 1328 checkEverythingEmitted(descriptors.keys); |
1331 | 1329 |
1332 CodeBuffer libraryBuffer = new CodeBuffer(); | 1330 List<jsAst.Expression> parts = <jsAst.Expression>[]; |
1333 for (LibraryElement library in Elements.sortedByPosition(libraries)) { | 1331 for (LibraryElement library in Elements.sortedByPosition(libraries)) { |
1334 writeLibraryDescriptor(libraryBuffer, library, mainFragment); | 1332 parts.add(generateLibraryDescriptor(library, mainFragment)); |
1335 descriptors.remove(library); | 1333 descriptors.remove(library); |
1336 } | 1334 } |
1337 | 1335 |
1338 if (descriptors.isNotEmpty) { | 1336 if (descriptors.isNotEmpty) { |
1339 List<Element> remainingLibraries = descriptors.keys | 1337 List<Element> remainingLibraries = descriptors.keys |
1340 .where((Element e) => e is LibraryElement) | 1338 .where((Element e) => e is LibraryElement) |
1341 .toList(); | 1339 .toList(); |
1342 | 1340 |
1343 // The remaining descriptors are only accessible through reflection. | 1341 // The remaining descriptors are only accessible through reflection. |
1344 // The program builder does not collect libraries that only | 1342 // The program builder does not collect libraries that only |
1345 // contain typedefs that are used for reflection. | 1343 // contain typedefs that are used for reflection. |
1346 for (LibraryElement element in remainingLibraries) { | 1344 for (LibraryElement element in remainingLibraries) { |
1347 assert(element is LibraryElement || compiler.hasIncrementalSupport); | 1345 assert(element is LibraryElement || compiler.hasIncrementalSupport); |
1348 if (element is LibraryElement) { | 1346 if (element is LibraryElement) { |
1349 writeLibraryDescriptor(libraryBuffer, element, mainFragment); | 1347 parts.add(generateLibraryDescriptor(element, mainFragment)); |
1350 descriptors.remove(element); | 1348 descriptors.remove(element); |
1351 } | 1349 } |
1352 } | 1350 } |
1353 } | 1351 } |
| 1352 jsAst.ArrayInitializer descriptorsAst = new jsAst.ArrayInitializer(parts); |
1354 | 1353 |
1355 bool needsNativeSupport = program.needsNativeSupport; | 1354 bool needsNativeSupport = program.needsNativeSupport; |
1356 mainOutput.addBuffer( | 1355 mainOutput.addBuffer( |
1357 jsAst.prettyPrint( | 1356 jsAst.prettyPrint( |
1358 buildSetupProgram(program, compiler, backend, namer, this), | 1357 buildSetupProgram(program, compiler, backend, namer, this), |
1359 compiler)); | 1358 compiler)); |
1360 | 1359 |
1361 // The argument to reflectionDataParser is assigned to a temporary 'dart' | 1360 // The argument to reflectionDataParser is assigned to a temporary 'dart' |
1362 // so that 'dart.' will appear as the prefix to dart methods in stack | 1361 // so that 'dart.' will appear as the prefix to dart methods in stack |
1363 // traces and profile entries. | 1362 // traces and profile entries. |
1364 mainOutput..add('var dart = [$n') | 1363 mainOutput..add('var dart =') |
1365 ..addBuffer(libraryBuffer) | 1364 ..addBuffer(jsAst.prettyPrint(descriptorsAst, compiler)) |
1366 ..add(']$N'); | 1365 ..add('$N'); |
1367 if (compiler.useContentSecurityPolicy) { | 1366 if (compiler.useContentSecurityPolicy) { |
1368 jsAst.Statement precompiledFunctionAst = | 1367 jsAst.Statement precompiledFunctionAst = |
1369 buildCspPrecompiledFunctionFor(mainOutputUnit); | 1368 buildCspPrecompiledFunctionFor(mainOutputUnit); |
1370 mainOutput.addBuffer( | 1369 mainOutput.addBuffer( |
1371 jsAst.prettyPrint( | 1370 jsAst.prettyPrint( |
1372 precompiledFunctionAst, | 1371 precompiledFunctionAst, |
1373 compiler, | 1372 compiler, |
1374 monitor: compiler.dumpInfoTask, | 1373 monitor: compiler.dumpInfoTask, |
1375 allowVariableMinification: false)); | 1374 allowVariableMinification: false)); |
1376 mainOutput.add(N); | 1375 mainOutput.add(N); |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1600 }"""); | 1599 }"""); |
1601 } | 1600 } |
1602 | 1601 |
1603 /// Returns a map from OutputUnit to a hash of its content. The hash uniquely | 1602 /// Returns a map from OutputUnit to a hash of its content. The hash uniquely |
1604 /// identifies the code of the output-unit. It does not include | 1603 /// identifies the code of the output-unit. It does not include |
1605 /// boilerplate JS code, like the sourcemap directives or the hash | 1604 /// boilerplate JS code, like the sourcemap directives or the hash |
1606 /// itself. | 1605 /// itself. |
1607 Map<OutputUnit, String> emitDeferredOutputUnits(Program program) { | 1606 Map<OutputUnit, String> emitDeferredOutputUnits(Program program) { |
1608 if (!program.isSplit) return const {}; | 1607 if (!program.isSplit) return const {}; |
1609 | 1608 |
1610 Map<OutputUnit, CodeBuffer> outputBuffers = | 1609 Map<OutputUnit, jsAst.Expression> outputs = |
1611 new Map<OutputUnit, CodeBuffer>(); | 1610 new Map<OutputUnit, jsAst.Expression>(); |
1612 | 1611 |
1613 for (Fragment fragment in program.deferredFragments) { | 1612 for (Fragment fragment in program.deferredFragments) { |
1614 OutputUnit outputUnit = fragment.outputUnit; | 1613 OutputUnit outputUnit = fragment.outputUnit; |
1615 | 1614 |
1616 Map<Element, ClassBuilder> descriptors = elementDescriptors[fragment]; | 1615 Map<Element, ClassBuilder> descriptors = elementDescriptors[fragment]; |
1617 | 1616 |
1618 if (descriptors != null && descriptors.isNotEmpty) { | 1617 if (descriptors != null && descriptors.isNotEmpty) { |
1619 Iterable<LibraryElement> libraries = | 1618 Iterable<LibraryElement> libraries = |
1620 task.outputLibraryLists[outputUnit]; | 1619 task.outputLibraryLists[outputUnit]; |
1621 if (libraries == null) libraries = []; | 1620 if (libraries == null) libraries = []; |
1622 | 1621 |
1623 // TODO(johnniwinther): Avoid creating [CodeBuffer]s. | 1622 // TODO(johnniwinther): Avoid creating [CodeBuffer]s. |
1624 CodeBuffer buffer = new CodeBuffer(); | 1623 List<jsAst.Expression> parts = <jsAst.Expression>[]; |
1625 outputBuffers[outputUnit] = buffer; | |
1626 for (LibraryElement library in Elements.sortedByPosition(libraries)) { | 1624 for (LibraryElement library in Elements.sortedByPosition(libraries)) { |
1627 writeLibraryDescriptor(buffer, library, fragment); | 1625 parts.add(generateLibraryDescriptor(library, fragment)); |
1628 descriptors.remove(library); | 1626 descriptors.remove(library); |
1629 } | 1627 } |
| 1628 |
| 1629 outputs[outputUnit] = new jsAst.ArrayInitializer(parts); |
1630 } | 1630 } |
1631 } | 1631 } |
1632 | 1632 |
1633 return emitDeferredCode(program, outputBuffers); | 1633 return emitDeferredCode(program, outputs); |
1634 } | 1634 } |
1635 | 1635 |
1636 int emitProgram(ProgramBuilder programBuilder) { | 1636 int emitProgram(ProgramBuilder programBuilder) { |
1637 Program program = programBuilder.buildProgram( | 1637 Program program = programBuilder.buildProgram( |
1638 storeFunctionTypesInMetadata: true); | 1638 storeFunctionTypesInMetadata: true); |
1639 | 1639 |
1640 assembleProgram(program); | 1640 assembleProgram(program); |
1641 | 1641 |
1642 // Shorten the code by using [namer.currentIsolate] as temporary. | 1642 // Shorten the code by using [namer.currentIsolate] as temporary. |
1643 isolateProperties = namer.currentIsolate; | 1643 isolateProperties = namer.currentIsolate; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1766 emitMapping(embeddedNames.DEFERRED_LIBRARY_URIS, deferredLibraryUris); | 1766 emitMapping(embeddedNames.DEFERRED_LIBRARY_URIS, deferredLibraryUris); |
1767 emitMapping(embeddedNames.DEFERRED_LIBRARY_HASHES, | 1767 emitMapping(embeddedNames.DEFERRED_LIBRARY_HASHES, |
1768 deferredLibraryHashes); | 1768 deferredLibraryHashes); |
1769 } | 1769 } |
1770 | 1770 |
1771 /// Emits code for all output units except the main. | 1771 /// Emits code for all output units except the main. |
1772 /// Returns a mapping from outputUnit to a hash of the corresponding hunk that | 1772 /// Returns a mapping from outputUnit to a hash of the corresponding hunk that |
1773 /// can be used for calling the initializer. | 1773 /// can be used for calling the initializer. |
1774 Map<OutputUnit, String> emitDeferredCode( | 1774 Map<OutputUnit, String> emitDeferredCode( |
1775 Program program, | 1775 Program program, |
1776 Map<OutputUnit, CodeBuffer> deferredBuffers) { | 1776 Map<OutputUnit, jsAst.Expression> deferredAsts) { |
1777 | 1777 |
1778 Map<OutputUnit, String> hunkHashes = new Map<OutputUnit, String>(); | 1778 Map<OutputUnit, String> hunkHashes = new Map<OutputUnit, String>(); |
1779 | 1779 |
1780 for (Fragment fragment in program.deferredFragments) { | 1780 for (Fragment fragment in program.deferredFragments) { |
1781 OutputUnit outputUnit = fragment.outputUnit; | 1781 OutputUnit outputUnit = fragment.outputUnit; |
1782 | 1782 |
1783 CodeOutput libraryDescriptorBuffer = deferredBuffers[outputUnit]; | 1783 jsAst.Expression libraryDescriptor = deferredAsts[outputUnit]; |
1784 | 1784 |
1785 List<CodeOutputListener> outputListeners = <CodeOutputListener>[]; | 1785 List<CodeOutputListener> outputListeners = <CodeOutputListener>[]; |
1786 Hasher hasher = new Hasher(); | 1786 Hasher hasher = new Hasher(); |
1787 outputListeners.add(hasher); | 1787 outputListeners.add(hasher); |
1788 | 1788 |
1789 LineColumnCollector lineColumnCollector; | 1789 LineColumnCollector lineColumnCollector; |
1790 if (generateSourceMap) { | 1790 if (generateSourceMap) { |
1791 lineColumnCollector = new LineColumnCollector(); | 1791 lineColumnCollector = new LineColumnCollector(); |
1792 outputListeners.add(lineColumnCollector); | 1792 outputListeners.add(lineColumnCollector); |
1793 } | 1793 } |
(...skipping 16 matching lines...) Expand all Loading... |
1810 '${globalsHolder}.$globalObject$N'); | 1810 '${globalsHolder}.$globalObject$N'); |
1811 } | 1811 } |
1812 output | 1812 output |
1813 ..add('var init$_=$_${globalsHolder}.init$N') | 1813 ..add('var init$_=$_${globalsHolder}.init$N') |
1814 ..add('var $setupProgramName$_=$_' | 1814 ..add('var $setupProgramName$_=$_' |
1815 '$globalsHolder.$setupProgramName$N') | 1815 '$globalsHolder.$setupProgramName$N') |
1816 ..add('var ${namer.isolateName}$_=$_' | 1816 ..add('var ${namer.isolateName}$_=$_' |
1817 '${globalsHolder}.${namer.isolateName}$N'); | 1817 '${globalsHolder}.${namer.isolateName}$N'); |
1818 String typesAccess = | 1818 String typesAccess = |
1819 generateEmbeddedGlobalAccessString(embeddedNames.TYPES); | 1819 generateEmbeddedGlobalAccessString(embeddedNames.TYPES); |
1820 if (libraryDescriptorBuffer != null) { | 1820 if (libraryDescriptor != null) { |
1821 // TODO(ahe): This defines a lot of properties on the | 1821 // TODO(ahe): This defines a lot of properties on the |
1822 // Isolate.prototype object. We know this will turn it into a | 1822 // Isolate.prototype object. We know this will turn it into a |
1823 // slow object in V8, so instead we should do something similar | 1823 // slow object in V8, so instead we should do something similar |
1824 // to Isolate.$finishIsolateConstructor. | 1824 // to Isolate.$finishIsolateConstructor. |
1825 output | 1825 output |
1826 ..add('var ${namer.currentIsolate}$_=$_$isolatePropertiesName$N') | 1826 ..add('var ${namer.currentIsolate}$_=$_$isolatePropertiesName$N') |
1827 // The argument to reflectionDataParser is assigned to a temporary | 1827 // The argument to reflectionDataParser is assigned to a temporary |
1828 // 'dart' so that 'dart.' will appear as the prefix to dart methods | 1828 // 'dart' so that 'dart.' will appear as the prefix to dart methods |
1829 // in stack traces and profile entries. | 1829 // in stack traces and profile entries. |
1830 ..add('var dart = [$n ') | 1830 ..add('var dart = $n ') |
1831 ..addBuffer(libraryDescriptorBuffer) | 1831 ..addBuffer(jsAst.prettyPrint(libraryDescriptor, compiler)) |
1832 ..add(']$N'); | 1832 ..add('$N'); |
1833 | 1833 |
1834 if (compiler.useContentSecurityPolicy) { | 1834 if (compiler.useContentSecurityPolicy) { |
1835 jsAst.Statement precompiledFunctionAst = | 1835 jsAst.Statement precompiledFunctionAst = |
1836 buildCspPrecompiledFunctionFor(outputUnit); | 1836 buildCspPrecompiledFunctionFor(outputUnit); |
1837 | 1837 |
1838 output.addBuffer( | 1838 output.addBuffer( |
1839 jsAst.prettyPrint( | 1839 jsAst.prettyPrint( |
1840 precompiledFunctionAst, compiler, | 1840 precompiledFunctionAst, compiler, |
1841 monitor: compiler.dumpInfoTask, | 1841 monitor: compiler.dumpInfoTask, |
1842 allowVariableMinification: false)); | 1842 allowVariableMinification: false)); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1951 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 1951 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
1952 if (element.isInstanceMember) { | 1952 if (element.isInstanceMember) { |
1953 cachedClassBuilders.remove(element.enclosingClass); | 1953 cachedClassBuilders.remove(element.enclosingClass); |
1954 | 1954 |
1955 nativeEmitter.cachedBuilders.remove(element.enclosingClass); | 1955 nativeEmitter.cachedBuilders.remove(element.enclosingClass); |
1956 | 1956 |
1957 } | 1957 } |
1958 } | 1958 } |
1959 } | 1959 } |
1960 } | 1960 } |
OLD | NEW |