| 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 29 matching lines...) Expand all Loading... |
| 40 | 40 |
| 41 /** Shorter access to [isolatePropertiesName]. Both here in the code, as | 41 /** Shorter access to [isolatePropertiesName]. Both here in the code, as |
| 42 well as in the generated code. */ | 42 well as in the generated code. */ |
| 43 String isolateProperties; | 43 String isolateProperties; |
| 44 String classesCollector; | 44 String classesCollector; |
| 45 Set<ClassElement> get neededClasses => task.neededClasses; | 45 Set<ClassElement> get neededClasses => task.neededClasses; |
| 46 Map<OutputUnit, List<ClassElement>> get outputClassLists | 46 Map<OutputUnit, List<ClassElement>> get outputClassLists |
| 47 => task.outputClassLists; | 47 => task.outputClassLists; |
| 48 Map<OutputUnit, List<ConstantValue>> get outputConstantLists | 48 Map<OutputUnit, List<ConstantValue>> get outputConstantLists |
| 49 => task.outputConstantLists; | 49 => task.outputConstantLists; |
| 50 List<ClassElement> get nativeClasses => task.nativeClasses; | |
| 51 final Map<String, String> mangledFieldNames = <String, String>{}; | 50 final Map<String, String> mangledFieldNames = <String, String>{}; |
| 52 final Map<String, String> mangledGlobalFieldNames = <String, String>{}; | 51 final Map<String, String> mangledGlobalFieldNames = <String, String>{}; |
| 53 final Set<String> recordedMangledNames = new Set<String>(); | 52 final Set<String> recordedMangledNames = new Set<String>(); |
| 54 | 53 |
| 55 Map<Class, Map<String, jsAst.Expression>> additionalProperties; | 54 Map<Class, Map<String, jsAst.Expression>> additionalProperties; |
| 56 | 55 |
| 57 List<TypedefElement> get typedefsNeededForReflection => | 56 List<TypedefElement> get typedefsNeededForReflection => |
| 58 task.typedefsNeededForReflection; | 57 task.typedefsNeededForReflection; |
| 59 | 58 |
| 60 JavaScriptBackend get backend => compiler.backend; | 59 JavaScriptBackend get backend => compiler.backend; |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 }; | 440 }; |
| 442 }() | 441 }() |
| 443 '''); | 442 '''); |
| 444 if (compiler.hasIncrementalSupport) { | 443 if (compiler.hasIncrementalSupport) { |
| 445 result = js( | 444 result = js( |
| 446 r'#.inheritFrom = #', [namer.accessIncrementalHelper, result]); | 445 r'#.inheritFrom = #', [namer.accessIncrementalHelper, result]); |
| 447 } | 446 } |
| 448 return js(r'var inheritFrom = #', [result]); | 447 return js(r'var inheritFrom = #', [result]); |
| 449 } | 448 } |
| 450 | 449 |
| 451 jsAst.Statement buildFinishClass() { | 450 jsAst.Statement buildFinishClass(bool hasNativeClasses) { |
| 452 String specProperty = '"${namer.nativeSpecProperty}"'; // "%" | 451 String specProperty = '"${namer.nativeSpecProperty}"'; // "%" |
| 453 | 452 |
| 454 jsAst.Expression finishedClassesAccess = | 453 jsAst.Expression finishedClassesAccess = |
| 455 generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES); | 454 generateEmbeddedGlobalAccess(embeddedNames.FINISHED_CLASSES); |
| 456 jsAst.Expression interceptorsByTagAccess = | 455 jsAst.Expression interceptorsByTagAccess = |
| 457 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG); | 456 generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG); |
| 458 jsAst.Expression leafTagsAccess = | 457 jsAst.Expression leafTagsAccess = |
| 459 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS); | 458 generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS); |
| 460 | 459 |
| 461 return js.statement(''' | 460 return js.statement(''' |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 #interceptorsByTagAccess[tags[i]] = constructor; | 547 #interceptorsByTagAccess[tags[i]] = constructor; |
| 549 #leafTagsAccess[tags[i]] = false; | 548 #leafTagsAccess[tags[i]] = false; |
| 550 } | 549 } |
| 551 } | 550 } |
| 552 } | 551 } |
| 553 } | 552 } |
| 554 } | 553 } |
| 555 } | 554 } |
| 556 }''', {'finishedClassesAccess': finishedClassesAccess, | 555 }''', {'finishedClassesAccess': finishedClassesAccess, |
| 557 'needsMixinSupport': needsMixinSupport, | 556 'needsMixinSupport': needsMixinSupport, |
| 558 'hasNativeClasses': nativeClasses.isNotEmpty, | 557 'hasNativeClasses': hasNativeClasses, |
| 559 'nativeSuperclassTagName': embeddedNames.NATIVE_SUPERCLASS_TAG_NAME, | 558 'nativeSuperclassTagName': embeddedNames.NATIVE_SUPERCLASS_TAG_NAME, |
| 560 'interceptorsByTagAccess': interceptorsByTagAccess, | 559 'interceptorsByTagAccess': interceptorsByTagAccess, |
| 561 'leafTagsAccess': leafTagsAccess, | 560 'leafTagsAccess': leafTagsAccess, |
| 562 'allowNativesSubclassing': true}); | 561 'allowNativesSubclassing': true}); |
| 563 } | 562 } |
| 564 | 563 |
| 565 void emitFinishIsolateConstructorInvocation(CodeOutput output) { | 564 void emitFinishIsolateConstructorInvocation(CodeOutput output) { |
| 566 String isolate = namer.isolateName; | 565 String isolate = namer.isolateName; |
| 567 output.add("$isolate = $finishIsolateConstructorName($isolate)$N"); | 566 output.add("$isolate = $finishIsolateConstructorName($isolate)$N"); |
| 568 } | 567 } |
| (...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1367 | 1366 |
| 1368 ClassBuilder libraryBuilder = getElementDescriptor(libraryElement); | 1367 ClassBuilder libraryBuilder = getElementDescriptor(libraryElement); |
| 1369 for (Class cls in library.classes) { | 1368 for (Class cls in library.classes) { |
| 1370 emitClass(cls, libraryBuilder); | 1369 emitClass(cls, libraryBuilder); |
| 1371 } | 1370 } |
| 1372 | 1371 |
| 1373 classEmitter.emitFields(library, libraryBuilder, emitStatics: true); | 1372 classEmitter.emitFields(library, libraryBuilder, emitStatics: true); |
| 1374 } | 1373 } |
| 1375 | 1374 |
| 1376 void emitMainOutputUnit(Program program, | 1375 void emitMainOutputUnit(Program program, |
| 1377 Map<OutputUnit, String> deferredLoadHashes, | 1376 Map<OutputUnit, String> deferredLoadHashes) { |
| 1378 CodeBuffer nativeBuffer) { | |
| 1379 Fragment mainFragment = program.fragments.first; | 1377 Fragment mainFragment = program.fragments.first; |
| 1380 OutputUnit mainOutputUnit = mainFragment.outputUnit; | 1378 OutputUnit mainOutputUnit = mainFragment.outputUnit; |
| 1381 | 1379 |
| 1382 LineColumnCollector lineColumnCollector; | 1380 LineColumnCollector lineColumnCollector; |
| 1383 List<CodeOutputListener> codeOutputListeners; | 1381 List<CodeOutputListener> codeOutputListeners; |
| 1384 if (generateSourceMap) { | 1382 if (generateSourceMap) { |
| 1385 lineColumnCollector = new LineColumnCollector(); | 1383 lineColumnCollector = new LineColumnCollector(); |
| 1386 codeOutputListeners = <CodeOutputListener>[lineColumnCollector]; | 1384 codeOutputListeners = <CodeOutputListener>[lineColumnCollector]; |
| 1387 } | 1385 } |
| 1388 | 1386 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1481 emitMangledNames(mainOutput); | 1479 emitMangledNames(mainOutput); |
| 1482 | 1480 |
| 1483 checkEverythingEmitted(elementDescriptors.keys); | 1481 checkEverythingEmitted(elementDescriptors.keys); |
| 1484 | 1482 |
| 1485 CodeBuffer libraryBuffer = new CodeBuffer(); | 1483 CodeBuffer libraryBuffer = new CodeBuffer(); |
| 1486 for (LibraryElement library in Elements.sortedByPosition(libraries)) { | 1484 for (LibraryElement library in Elements.sortedByPosition(libraries)) { |
| 1487 writeLibraryDescriptors(libraryBuffer, library); | 1485 writeLibraryDescriptors(libraryBuffer, library); |
| 1488 elementDescriptors.remove(library); | 1486 elementDescriptors.remove(library); |
| 1489 } | 1487 } |
| 1490 | 1488 |
| 1489 bool hasNativeClasses = program.outputContainsNativeClasses; |
| 1491 mainOutput | 1490 mainOutput |
| 1492 ..addBuffer( | 1491 ..addBuffer( |
| 1493 jsAst.prettyPrint( | 1492 jsAst.prettyPrint( |
| 1494 getReflectionDataParser(this, backend), | 1493 getReflectionDataParser(this, backend, hasNativeClasses), |
| 1495 compiler)) | 1494 compiler)) |
| 1496 ..add(n); | 1495 ..add(n); |
| 1497 | 1496 |
| 1498 // The argument to reflectionDataParser is assigned to a temporary 'dart' | 1497 // The argument to reflectionDataParser is assigned to a temporary 'dart' |
| 1499 // so that 'dart.' will appear as the prefix to dart methods in stack | 1498 // so that 'dart.' will appear as the prefix to dart methods in stack |
| 1500 // traces and profile entries. | 1499 // traces and profile entries. |
| 1501 mainOutput..add('var dart = [$n') | 1500 mainOutput..add('var dart = [$n') |
| 1502 ..addBuffer(libraryBuffer) | 1501 ..addBuffer(libraryBuffer) |
| 1503 ..add(']$N') | 1502 ..add(']$N') |
| 1504 ..add('$parseReflectionDataName(dart)$N'); | 1503 ..add('$parseReflectionDataName(dart)$N'); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1523 outputDeferredMap(); | 1522 outputDeferredMap(); |
| 1524 } | 1523 } |
| 1525 | 1524 |
| 1526 // Static field initializations require the classes and compile-time | 1525 // Static field initializations require the classes and compile-time |
| 1527 // constants to be set up. | 1526 // constants to be set up. |
| 1528 emitStaticNonFinalFieldInitializations(mainOutput, mainOutputUnit); | 1527 emitStaticNonFinalFieldInitializations(mainOutput, mainOutputUnit); |
| 1529 interceptorEmitter.emitMapTypeToInterceptor(mainOutput); | 1528 interceptorEmitter.emitMapTypeToInterceptor(mainOutput); |
| 1530 emitLazilyInitializedStaticFields(mainOutput); | 1529 emitLazilyInitializedStaticFields(mainOutput); |
| 1531 | 1530 |
| 1532 mainOutput.add('\n'); | 1531 mainOutput.add('\n'); |
| 1533 mainOutput.addBuffer(nativeBuffer); | |
| 1534 | 1532 |
| 1535 metadataEmitter.emitMetadata(mainOutput); | 1533 metadataEmitter.emitMetadata(mainOutput); |
| 1536 | 1534 |
| 1537 isolateProperties = isolatePropertiesName; | 1535 isolateProperties = isolatePropertiesName; |
| 1538 // The following code should not use the short-hand for the | 1536 // The following code should not use the short-hand for the |
| 1539 // initialStatics. | 1537 // initialStatics. |
| 1540 mainOutput.add('${namer.currentIsolate}$_=${_}null$N'); | 1538 mainOutput.add('${namer.currentIsolate}$_=${_}null$N'); |
| 1541 | 1539 |
| 1542 emitFinishIsolateConstructorInvocation(mainOutput); | 1540 emitFinishIsolateConstructorInvocation(mainOutput); |
| 1543 mainOutput.add( | 1541 mainOutput.add( |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1757 for (LibraryElement library in Elements.sortedByPosition(libraries)) { | 1755 for (LibraryElement library in Elements.sortedByPosition(libraries)) { |
| 1758 writeLibraryDescriptors(buffer, library); | 1756 writeLibraryDescriptors(buffer, library); |
| 1759 elementDescriptors.remove(library); | 1757 elementDescriptors.remove(library); |
| 1760 } | 1758 } |
| 1761 } | 1759 } |
| 1762 } | 1760 } |
| 1763 | 1761 |
| 1764 return emitDeferredCode(program, outputBuffers); | 1762 return emitDeferredCode(program, outputBuffers); |
| 1765 } | 1763 } |
| 1766 | 1764 |
| 1767 CodeBuffer buildNativesBuffer(Program program) { | |
| 1768 // Emit native classes on [nativeBuffer]. | |
| 1769 // TODO(johnniwinther): Avoid creating a [CodeBuffer]. | |
| 1770 final CodeBuffer nativeBuffer = new CodeBuffer(); | |
| 1771 | |
| 1772 if (program.nativeClasses.isEmpty) return nativeBuffer; | |
| 1773 | |
| 1774 | |
| 1775 addComment('Native classes', nativeBuffer); | |
| 1776 | |
| 1777 for (Class cls in program.nativeClasses) { | |
| 1778 assert(cls.isNative); | |
| 1779 ClassBuilder enclosingBuilder = getElementDescriptor(cls.element); | |
| 1780 emitClass(cls, enclosingBuilder); | |
| 1781 } | |
| 1782 | |
| 1783 nativeEmitter.finishGenerateNativeClasses(); | |
| 1784 nativeEmitter.assembleCode(nativeBuffer); | |
| 1785 | |
| 1786 return nativeBuffer; | |
| 1787 } | |
| 1788 | |
| 1789 int emitProgram(ProgramBuilder programBuilder) { | 1765 int emitProgram(ProgramBuilder programBuilder) { |
| 1790 Program program = programBuilder.buildProgram( | 1766 Program program = programBuilder.buildProgram( |
| 1791 storeFunctionTypesInMetadata: true); | 1767 storeFunctionTypesInMetadata: true); |
| 1792 | 1768 |
| 1793 additionalProperties = program.additionalProperties; | 1769 additionalProperties = program.additionalProperties; |
| 1794 | 1770 |
| 1795 // Shorten the code by using [namer.currentIsolate] as temporary. | 1771 // Shorten the code by using [namer.currentIsolate] as temporary. |
| 1796 isolateProperties = namer.currentIsolate; | 1772 isolateProperties = namer.currentIsolate; |
| 1797 | 1773 |
| 1798 // Emit deferred units first, so we have their hashes. | 1774 // Emit deferred units first, so we have their hashes. |
| 1799 // Map from OutputUnit to a hash of its content. The hash uniquely | 1775 // Map from OutputUnit to a hash of its content. The hash uniquely |
| 1800 // identifies the code of the output-unit. It does not include | 1776 // identifies the code of the output-unit. It does not include |
| 1801 // boilerplate JS code, like the sourcemap directives or the hash | 1777 // boilerplate JS code, like the sourcemap directives or the hash |
| 1802 // itself. | 1778 // itself. |
| 1803 Map<OutputUnit, String> deferredLoadHashes = | 1779 Map<OutputUnit, String> deferredLoadHashes = |
| 1804 emitDeferredOutputUnits(program); | 1780 emitDeferredOutputUnits(program); |
| 1805 CodeBuffer nativeBuffer = buildNativesBuffer(program); | 1781 emitMainOutputUnit(program, deferredLoadHashes); |
| 1806 emitMainOutputUnit(program, deferredLoadHashes, nativeBuffer); | |
| 1807 | 1782 |
| 1808 if (backend.requiresPreamble && | 1783 if (backend.requiresPreamble && |
| 1809 !backend.htmlLibraryIsLoaded) { | 1784 !backend.htmlLibraryIsLoaded) { |
| 1810 compiler.reportHint(NO_LOCATION_SPANNABLE, MessageKind.PREAMBLE); | 1785 compiler.reportHint(NO_LOCATION_SPANNABLE, MessageKind.PREAMBLE); |
| 1811 } | 1786 } |
| 1812 // Return the total program size. | 1787 // Return the total program size. |
| 1813 return outputBuffers.values.fold(0, (a, b) => a + b.length); | 1788 return outputBuffers.values.fold(0, (a, b) => a + b.length); |
| 1814 } | 1789 } |
| 1815 | 1790 |
| 1816 String generateSourceMapTag(Uri sourceMapUri, Uri fileUri) { | 1791 String generateSourceMapTag(Uri sourceMapUri, Uri fileUri) { |
| (...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2096 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { | 2071 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { |
| 2097 if (element.isInstanceMember) { | 2072 if (element.isInstanceMember) { |
| 2098 cachedClassBuilders.remove(element.enclosingClass); | 2073 cachedClassBuilders.remove(element.enclosingClass); |
| 2099 | 2074 |
| 2100 nativeEmitter.cachedBuilders.remove(element.enclosingClass); | 2075 nativeEmitter.cachedBuilders.remove(element.enclosingClass); |
| 2101 | 2076 |
| 2102 } | 2077 } |
| 2103 } | 2078 } |
| 2104 } | 2079 } |
| 2105 } | 2080 } |
| OLD | NEW |