| 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 |