Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(131)

Side by Side Diff: pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart

Issue 1072403005: dart2js: fully assemble program before emitting it. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 77
78 /** 78 /**
79 * Accumulate properties for classes and libraries, describing their 79 * Accumulate properties for classes and libraries, describing their
80 * static/top-level members. 80 * static/top-level members.
81 * Later, these members are emitted when the class or library is emitted. 81 * Later, these members are emitted when the class or library is emitted.
82 * 82 *
83 * See [getElementDescriptor]. 83 * See [getElementDescriptor].
84 */ 84 */
85 // TODO(ahe): Generate statics with their class, and store only libraries in 85 // TODO(ahe): Generate statics with their class, and store only libraries in
86 // this map. 86 // this map.
87 final Map<Element, ClassBuilder> elementDescriptors = 87 final Map<Fragment, Map<Element, ClassBuilder>> elementDescriptors =
88 new Map<Element, ClassBuilder>(); 88 new Map<Fragment, Map<Element, ClassBuilder>>();
89 89
90 final bool generateSourceMap; 90 final bool generateSourceMap;
91 91
92 OldEmitter(Compiler compiler, Namer namer, this.generateSourceMap, this.task) 92 OldEmitter(Compiler compiler, Namer namer, this.generateSourceMap, this.task)
93 : this.compiler = compiler, 93 : this.compiler = compiler,
94 this.namer = namer, 94 this.namer = namer,
95 cachedEmittedConstants = compiler.cacheStrategy.newSet(), 95 cachedEmittedConstants = compiler.cacheStrategy.newSet(),
96 cachedClassBuilders = compiler.cacheStrategy.newMap(), 96 cachedClassBuilders = compiler.cacheStrategy.newMap(),
97 cachedElements = compiler.cacheStrategy.newSet() { 97 cachedElements = compiler.cacheStrategy.newSet() {
98 constantEmitter = new ConstantEmitter( 98 constantEmitter = new ConstantEmitter(
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 var \$desc; 427 var \$desc;
428 #; 428 #;
429 return #; 429 return #;
430 };''', 430 };''',
431 [generateEmbeddedGlobalAccess(embeddedNames.PRECOMPILED), 431 [generateEmbeddedGlobalAccess(embeddedNames.PRECOMPILED),
432 cspPrecompiledFunctionFor(outputUnit), 432 cspPrecompiledFunctionFor(outputUnit),
433 new jsAst.ArrayInitializer( 433 new jsAst.ArrayInitializer(
434 cspPrecompiledConstructorNamesFor(outputUnit))]); 434 cspPrecompiledConstructorNamesFor(outputUnit))]);
435 } 435 }
436 436
437 void emitClass(Class cls, ClassBuilder enclosingBuilder) { 437 void assembleClass(Class cls, ClassBuilder enclosingBuilder,
438 Fragment fragment) {
438 ClassElement classElement = cls.element; 439 ClassElement classElement = cls.element;
439 compiler.withCurrentElement(classElement, () { 440 compiler.withCurrentElement(classElement, () {
440 if (compiler.hasIncrementalSupport) { 441 if (compiler.hasIncrementalSupport) {
441 ClassBuilder cachedBuilder = 442 ClassBuilder cachedBuilder =
442 cachedClassBuilders.putIfAbsent(classElement, () { 443 cachedClassBuilders.putIfAbsent(classElement, () {
443 ClassBuilder builder = new ClassBuilder(classElement, namer); 444 ClassBuilder builder = new ClassBuilder(classElement, namer);
444 classEmitter.emitClass(cls, builder); 445 classEmitter.emitClass(cls, builder, fragment);
445 return builder; 446 return builder;
446 }); 447 });
447 invariant(classElement, cachedBuilder.fields.isEmpty); 448 invariant(classElement, cachedBuilder.fields.isEmpty);
448 invariant(classElement, cachedBuilder.superName == null); 449 invariant(classElement, cachedBuilder.superName == null);
449 invariant(classElement, cachedBuilder.functionType == null); 450 invariant(classElement, cachedBuilder.functionType == null);
450 invariant(classElement, cachedBuilder.fieldMetadata == null); 451 invariant(classElement, cachedBuilder.fieldMetadata == null);
451 enclosingBuilder.properties.addAll(cachedBuilder.properties); 452 enclosingBuilder.properties.addAll(cachedBuilder.properties);
452 } else { 453 } else {
453 classEmitter.emitClass(cls, enclosingBuilder); 454 classEmitter.emitClass(cls, enclosingBuilder, fragment);
454 } 455 }
455 }); 456 });
456 } 457 }
457 458
458 void emitStaticFunctions(Iterable<Method> staticFunctions) { 459 void assembleStaticFunctions(Iterable<Method> staticFunctions,
460 Fragment fragment) {
karlklose 2015/04/17 11:26:10 Align parameter.
herhut 2015/04/17 11:37:30 Done.
459 if (staticFunctions == null) return; 461 if (staticFunctions == null) return;
460 462
461 for (Method method in staticFunctions) { 463 for (Method method in staticFunctions) {
462 Element element = method.element; 464 Element element = method.element;
463 // We need to filter out null-elements for the interceptors. 465 // We need to filter out null-elements for the interceptors.
464 // TODO(floitsch): use the precomputed interceptors here. 466 // TODO(floitsch): use the precomputed interceptors here.
465 if (element == null) continue; 467 if (element == null) continue;
466 ClassBuilder builder = new ClassBuilder(element, namer); 468 ClassBuilder builder = new ClassBuilder(element, namer);
467 containerBuilder.addMemberMethod(method, builder); 469 containerBuilder.addMemberMethod(method, builder);
468 getElementDescriptor(element).properties.addAll(builder.properties); 470 getElementDescriptor(element, fragment).properties
471 .addAll(builder.properties);
469 } 472 }
470 } 473 }
471 474
472 void emitStaticNonFinalFieldInitializations(CodeOutput output, 475 void emitStaticNonFinalFieldInitializations(CodeOutput output,
473 OutputUnit outputUnit) { 476 OutputUnit outputUnit) {
474 void emitInitialization(Element element, jsAst.Expression initialValue) { 477 void emitInitialization(Element element, jsAst.Expression initialValue) {
475 jsAst.Expression init = 478 jsAst.Expression init =
476 js('$isolateProperties.# = #', 479 js('$isolateProperties.# = #',
477 [namer.globalPropertyName(element), initialValue]); 480 [namer.globalPropertyName(element), initialValue]);
478 output.addBuffer(jsAst.prettyPrint(init, compiler, 481 output.addBuffer(jsAst.prettyPrint(init, compiler,
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 return object.__proto__ && 947 return object.__proto__ &&
945 object.__proto__.p === cls.prototype.p; 948 object.__proto__.p === cls.prototype.p;
946 })(); 949 })();
947 '''); 950 ''');
948 } 951 }
949 952
950 output.addBuffer(jsAst.prettyPrint(supportsDirectProtoAccess, compiler)); 953 output.addBuffer(jsAst.prettyPrint(supportsDirectProtoAccess, compiler));
951 output.add(N); 954 output.add(N);
952 } 955 }
953 956
954 void writeLibraryDescriptor(CodeOutput output, LibraryElement library) { 957 void writeLibraryDescriptor(CodeOutput output, LibraryElement library,
958 Fragment fragment) {
955 var uri = ""; 959 var uri = "";
956 if (!compiler.enableMinification || backend.mustPreserveUris) { 960 if (!compiler.enableMinification || backend.mustPreserveUris) {
957 uri = library.canonicalUri; 961 uri = library.canonicalUri;
958 if (uri.scheme == 'file' && compiler.outputUri != null) { 962 if (uri.scheme == 'file' && compiler.outputUri != null) {
959 uri = relativize(compiler.outputUri, library.canonicalUri, false); 963 uri = relativize(compiler.outputUri, library.canonicalUri, false);
960 } 964 }
961 } 965 }
962 ClassBuilder descriptor = elementDescriptors[library]; 966 ClassBuilder descriptor = elementDescriptors[fragment][library];
963 if (descriptor == null) { 967 if (descriptor == null) {
964 // Nothing of the library was emitted. 968 // Nothing of the library was emitted.
965 // TODO(floitsch): this should not happen. We currently have an example 969 // TODO(floitsch): this should not happen. We currently have an example
966 // with language/prefix6_negative_test.dart where we have an instance 970 // with language/prefix6_negative_test.dart where we have an instance
967 // method without its corresponding class. 971 // method without its corresponding class.
968 return; 972 return;
969 } 973 }
970 974
971 String libraryName = 975 String libraryName =
972 (!compiler.enableMinification || backend.mustRetainLibraryNames) ? 976 (!compiler.enableMinification || backend.mustRetainLibraryNames) ?
(...skipping 18 matching lines...) Expand all
991 ..add(',$_') 995 ..add(',$_')
992 ..add(namer.globalObjectFor(library)) 996 ..add(namer.globalObjectFor(library))
993 ..add(',$_') 997 ..add(',$_')
994 ..addBuffer(jsAst.prettyPrint(initializers, 998 ..addBuffer(jsAst.prettyPrint(initializers,
995 compiler, 999 compiler,
996 monitor: compiler.dumpInfoTask)) 1000 monitor: compiler.dumpInfoTask))
997 ..add(library == compiler.mainApp ? ',${n}1' : "") 1001 ..add(library == compiler.mainApp ? ',${n}1' : "")
998 ..add('],$n'); 1002 ..add('],$n');
999 } 1003 }
1000 1004
1001 void emitPrecompiledConstructor(OutputUnit outputUnit, 1005 void assemblePrecompiledConstructor(OutputUnit outputUnit,
1002 String constructorName, 1006 String constructorName,
karlklose 2015/04/17 11:26:10 Align parameters.
herhut 2015/04/17 11:37:30 Done.
1003 jsAst.Expression constructorAst, 1007 jsAst.Expression constructorAst,
1004 List<String> fields) { 1008 List<String> fields) {
1005 cspPrecompiledFunctionFor(outputUnit).add( 1009 cspPrecompiledFunctionFor(outputUnit).add(
1006 new jsAst.FunctionDeclaration( 1010 new jsAst.FunctionDeclaration(
1007 new jsAst.VariableDeclaration(constructorName), constructorAst)); 1011 new jsAst.VariableDeclaration(constructorName), constructorAst));
1008 1012
1009 String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME; 1013 String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME;
1010 bool hasIsolateSupport = compiler.hasIsolateSupport; 1014 bool hasIsolateSupport = compiler.hasIsolateSupport;
1011 jsAst.Node fieldNamesArray = 1015 jsAst.Node fieldNamesArray =
1012 hasIsolateSupport ? js.stringArray(fields) : new jsAst.LiteralNull(); 1016 hasIsolateSupport ? js.stringArray(fields) : new jsAst.LiteralNull();
(...skipping 11 matching lines...) Expand all
1024 } 1028 }
1025 }''', 1029 }''',
1026 {"constructorName": constructorName, 1030 {"constructorName": constructorName,
1027 "constructorNameString": js.string(constructorName), 1031 "constructorNameString": js.string(constructorName),
1028 "hasIsolateSupport": hasIsolateSupport, 1032 "hasIsolateSupport": hasIsolateSupport,
1029 "fieldNamesArray": fieldNamesArray})); 1033 "fieldNamesArray": fieldNamesArray}));
1030 1034
1031 cspPrecompiledConstructorNamesFor(outputUnit).add(js('#', constructorName)); 1035 cspPrecompiledConstructorNamesFor(outputUnit).add(js('#', constructorName));
1032 } 1036 }
1033 1037
1034 void emitTypedefs() { 1038 void assembleTypedefs(Program program) {
1035 OutputUnit mainOutputUnit = compiler.deferredLoadTask.mainOutputUnit; 1039 Fragment mainFragment = program.mainFragment;
1040 OutputUnit mainOutputUnit = mainFragment.outputUnit;
1036 1041
1037 // Emit all required typedef declarations into the main output unit. 1042 // Emit all required typedef declarations into the main output unit.
1038 // TODO(karlklose): unify required classes and typedefs to declarations 1043 // TODO(karlklose): unify required classes and typedefs to declarations
1039 // and have builders for each kind. 1044 // and have builders for each kind.
1040 for (TypedefElement typedef in typedefsNeededForReflection) { 1045 for (TypedefElement typedef in typedefsNeededForReflection) {
1041 LibraryElement library = typedef.library; 1046 LibraryElement library = typedef.library;
1042 // TODO(karlklose): add a TypedefBuilder and move this code there. 1047 // TODO(karlklose): add a TypedefBuilder and move this code there.
1043 DartType type = typedef.alias; 1048 DartType type = typedef.alias;
1044 int typeIndex = task.metadataCollector.reifyType(type); 1049 int typeIndex = task.metadataCollector.reifyType(type);
1045 ClassBuilder builder = new ClassBuilder(typedef, namer); 1050 ClassBuilder builder = new ClassBuilder(typedef, namer);
1046 builder.addProperty(embeddedNames.TYPEDEF_TYPE_PROPERTY_NAME, 1051 builder.addProperty(embeddedNames.TYPEDEF_TYPE_PROPERTY_NAME,
1047 js.number(typeIndex)); 1052 js.number(typeIndex));
1048 builder.addProperty(embeddedNames.TYPEDEF_PREDICATE_PROPERTY_NAME, 1053 builder.addProperty(embeddedNames.TYPEDEF_PREDICATE_PROPERTY_NAME,
1049 js.boolean(true)); 1054 js.boolean(true));
1050 1055
1051 // We can be pretty sure that the objectClass is initialized, since 1056 // We can be pretty sure that the objectClass is initialized, since
1052 // typedefs are only emitted with reflection, which requires lots of 1057 // typedefs are only emitted with reflection, which requires lots of
1053 // classes. 1058 // classes.
1054 assert(compiler.objectClass != null); 1059 assert(compiler.objectClass != null);
1055 builder.superName = namer.className(compiler.objectClass); 1060 builder.superName = namer.className(compiler.objectClass);
1056 jsAst.Node declaration = builder.toObjectInitializer(); 1061 jsAst.Node declaration = builder.toObjectInitializer();
1057 String mangledName = namer.globalPropertyName(typedef); 1062 String mangledName = namer.globalPropertyName(typedef);
1058 String reflectionName = getReflectionName(typedef, mangledName); 1063 String reflectionName = getReflectionName(typedef, mangledName);
1059 getElementDescriptor(library) 1064 getElementDescriptor(library, mainFragment)
1060 ..addProperty(mangledName, declaration) 1065 ..addProperty(mangledName, declaration)
1061 ..addProperty("+$reflectionName", js.string('')); 1066 ..addProperty("+$reflectionName", js.string(''));
1062 // Also emit a trivial constructor for CSP mode. 1067 // Also emit a trivial constructor for CSP mode.
1063 String constructorName = mangledName; 1068 String constructorName = mangledName;
1064 jsAst.Expression constructorAst = js('function() {}'); 1069 jsAst.Expression constructorAst = js('function() {}');
1065 List<String> fieldNames = []; 1070 List<String> fieldNames = [];
1066 emitPrecompiledConstructor(mainOutputUnit, 1071 assemblePrecompiledConstructor(mainOutputUnit,
karlklose 2015/04/17 11:26:10 Align arguments.
herhut 2015/04/17 11:37:30 Done.
1067 constructorName, 1072 constructorName,
1068 constructorAst, 1073 constructorAst,
1069 fieldNames); 1074 fieldNames);
1070 } 1075 }
1071 } 1076 }
1072 1077
1073 void emitMangledNames(CodeOutput output) { 1078 void emitMangledNames(CodeOutput output) {
1074 if (!mangledFieldNames.isEmpty) { 1079 if (!mangledFieldNames.isEmpty) {
1075 var keys = mangledFieldNames.keys.toList(); 1080 var keys = mangledFieldNames.keys.toList();
1076 keys.sort(); 1081 keys.sort();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1124 compiler.reportInfo( 1129 compiler.reportInfo(
1125 element, MessageKind.GENERIC, {'text': 'Pending statics.'})); 1130 element, MessageKind.GENERIC, {'text': 'Pending statics.'}));
1126 } 1131 }
1127 1132
1128 if (pendingStatics != null && !pendingStatics.isEmpty) { 1133 if (pendingStatics != null && !pendingStatics.isEmpty) {
1129 compiler.internalError(pendingStatics.first, 1134 compiler.internalError(pendingStatics.first,
1130 'Pending statics (see above).'); 1135 'Pending statics (see above).');
1131 } 1136 }
1132 } 1137 }
1133 1138
1134 void emitLibrary(Library library) { 1139 void assembleLibrary(Library library, Fragment fragment) {
1135 LibraryElement libraryElement = library.element; 1140 LibraryElement libraryElement = library.element;
1136 1141
1137 emitStaticFunctions(library.statics); 1142 assembleStaticFunctions(library.statics, fragment);
1138 1143
1139 ClassBuilder libraryBuilder = getElementDescriptor(libraryElement); 1144 ClassBuilder libraryBuilder =
1145 getElementDescriptor(libraryElement, fragment);
1140 for (Class cls in library.classes) { 1146 for (Class cls in library.classes) {
1141 emitClass(cls, libraryBuilder); 1147 assembleClass(cls, libraryBuilder, fragment);
1142 } 1148 }
1143 1149
1144 classEmitter.emitFields(library, libraryBuilder, emitStatics: true); 1150 classEmitter.emitFields(library, libraryBuilder, emitStatics: true);
1145 } 1151 }
1146 1152
1153 void assembleProgram(Program program) {
1154 for (Fragment fragment in program.fragments) {
1155 for (Library library in fragment.libraries) {
1156 assembleLibrary(library, fragment);
1157 }
1158 }
1159 assembleTypedefs(program);
1160 }
1161
1147 void emitMainOutputUnit(Program program, 1162 void emitMainOutputUnit(Program program,
1148 Map<OutputUnit, String> deferredLoadHashes) { 1163 Map<OutputUnit, String> deferredLoadHashes) {
1149 MainFragment mainFragment = program.fragments.first; 1164 MainFragment mainFragment = program.fragments.first;
1150 OutputUnit mainOutputUnit = mainFragment.outputUnit; 1165 OutputUnit mainOutputUnit = mainFragment.outputUnit;
1151 1166
1152 LineColumnCollector lineColumnCollector; 1167 LineColumnCollector lineColumnCollector;
1153 List<CodeOutputListener> codeOutputListeners; 1168 List<CodeOutputListener> codeOutputListeners;
1154 if (generateSourceMap) { 1169 if (generateSourceMap) {
1155 lineColumnCollector = new LineColumnCollector(); 1170 lineColumnCollector = new LineColumnCollector();
1156 codeOutputListeners = <CodeOutputListener>[lineColumnCollector]; 1171 codeOutputListeners = <CodeOutputListener>[lineColumnCollector];
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1236 mainOutput.add( 1251 mainOutput.add(
1237 '${globalsHolder}.${namer.isolateName}$_=$_${namer.isolateName}$N' 1252 '${globalsHolder}.${namer.isolateName}$_=$_${namer.isolateName}$N'
1238 '${globalsHolder}.$initName$_=${_}$initName$N' 1253 '${globalsHolder}.$initName$_=${_}$initName$N'
1239 '${globalsHolder}.$setupProgramName$_=$_' 1254 '${globalsHolder}.$setupProgramName$_=$_'
1240 '$setupProgramName$N'); 1255 '$setupProgramName$N');
1241 } 1256 }
1242 mainOutput.add('init()$N$n'); 1257 mainOutput.add('init()$N$n');
1243 mainOutput.add('$isolateProperties$_=$_$isolatePropertiesName$N'); 1258 mainOutput.add('$isolateProperties$_=$_$isolatePropertiesName$N');
1244 1259
1245 emitFunctionThatReturnsNull(mainOutput); 1260 emitFunctionThatReturnsNull(mainOutput);
1246 mainFragment.libraries.forEach(emitLibrary);
1247 1261
1248 Iterable<LibraryElement> libraries = 1262 Iterable<LibraryElement> libraries =
1249 task.outputLibraryLists[mainOutputUnit]; 1263 task.outputLibraryLists[mainOutputUnit];
1250 if (libraries == null) libraries = []; 1264 if (libraries == null) libraries = [];
1251 emitTypedefs();
1252 emitMangledNames(mainOutput); 1265 emitMangledNames(mainOutput);
1253 1266
1254 checkEverythingEmitted(elementDescriptors.keys); 1267 Map<Element, ClassBuilder> descriptors = elementDescriptors[mainFragment];
1268 checkEverythingEmitted(descriptors.keys);
1255 1269
1256 CodeBuffer libraryBuffer = new CodeBuffer(); 1270 CodeBuffer libraryBuffer = new CodeBuffer();
1257 for (LibraryElement library in Elements.sortedByPosition(libraries)) { 1271 for (LibraryElement library in Elements.sortedByPosition(libraries)) {
1258 writeLibraryDescriptor(libraryBuffer, library); 1272 writeLibraryDescriptor(libraryBuffer, library, mainFragment);
1259 elementDescriptors.remove(library); 1273 descriptors.remove(library);
1260 } 1274 }
1261 1275
1262 if (elementDescriptors.isNotEmpty) { 1276 if (descriptors.isNotEmpty) {
1263 List<Element> remainingLibraries = elementDescriptors.keys 1277 List<Element> remainingLibraries = descriptors.keys
1264 .where((Element e) => e is LibraryElement) 1278 .where((Element e) => e is LibraryElement)
1265 .toList(); 1279 .toList();
1266 1280
1267 // The remaining descriptors are only accessible through reflection. 1281 // The remaining descriptors are only accessible through reflection.
1268 // The program builder does not collect libraries that only 1282 // The program builder does not collect libraries that only
1269 // contain typedefs that are used for reflection. 1283 // contain typedefs that are used for reflection.
1270 for (LibraryElement element in remainingLibraries) { 1284 for (LibraryElement element in remainingLibraries) {
1271 assert(element is LibraryElement || compiler.hasIncrementalSupport); 1285 assert(element is LibraryElement || compiler.hasIncrementalSupport);
1272 if (element is LibraryElement) { 1286 if (element is LibraryElement) {
1273 writeLibraryDescriptor(libraryBuffer, element); 1287 writeLibraryDescriptor(libraryBuffer, element, mainFragment);
1274 elementDescriptors.remove(element); 1288 descriptors.remove(element);
1275 } 1289 }
1276 } 1290 }
1277 } 1291 }
1278 1292
1279 bool needsNativeSupport = program.needsNativeSupport; 1293 bool needsNativeSupport = program.needsNativeSupport;
1280 mainOutput.addBuffer( 1294 mainOutput.addBuffer(
1281 jsAst.prettyPrint( 1295 jsAst.prettyPrint(
1282 buildSetupProgram(program, compiler, backend, namer, this), 1296 buildSetupProgram(program, compiler, backend, namer, this),
1283 compiler)); 1297 compiler));
1284 1298
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1530 /// itself. 1544 /// itself.
1531 Map<OutputUnit, String> emitDeferredOutputUnits(Program program) { 1545 Map<OutputUnit, String> emitDeferredOutputUnits(Program program) {
1532 if (!program.isSplit) return const {}; 1546 if (!program.isSplit) return const {};
1533 1547
1534 Map<OutputUnit, CodeBuffer> outputBuffers = 1548 Map<OutputUnit, CodeBuffer> outputBuffers =
1535 new Map<OutputUnit, CodeBuffer>(); 1549 new Map<OutputUnit, CodeBuffer>();
1536 1550
1537 for (Fragment fragment in program.deferredFragments) { 1551 for (Fragment fragment in program.deferredFragments) {
1538 OutputUnit outputUnit = fragment.outputUnit; 1552 OutputUnit outputUnit = fragment.outputUnit;
1539 1553
1554 Map<Element, ClassBuilder> descriptors = elementDescriptors[fragment];
1540 1555
1541 fragment.libraries.forEach(emitLibrary); 1556 if (descriptors.isNotEmpty) {
1542
1543 if (elementDescriptors.isNotEmpty) {
1544 Iterable<LibraryElement> libraries = 1557 Iterable<LibraryElement> libraries =
1545 task.outputLibraryLists[outputUnit]; 1558 task.outputLibraryLists[outputUnit];
1546 if (libraries == null) libraries = []; 1559 if (libraries == null) libraries = [];
1547 1560
1548 // TODO(johnniwinther): Avoid creating [CodeBuffer]s. 1561 // TODO(johnniwinther): Avoid creating [CodeBuffer]s.
1549 CodeBuffer buffer = new CodeBuffer(); 1562 CodeBuffer buffer = new CodeBuffer();
1550 outputBuffers[outputUnit] = buffer; 1563 outputBuffers[outputUnit] = buffer;
1551 for (LibraryElement library in Elements.sortedByPosition(libraries)) { 1564 for (LibraryElement library in Elements.sortedByPosition(libraries)) {
1552 writeLibraryDescriptor(buffer, library); 1565 writeLibraryDescriptor(buffer, library, fragment);
1553 elementDescriptors.remove(library); 1566 descriptors.remove(library);
1554 } 1567 }
1555 } 1568 }
1556 } 1569 }
1557 1570
1558 return emitDeferredCode(program, outputBuffers); 1571 return emitDeferredCode(program, outputBuffers);
1559 } 1572 }
1560 1573
1561 int emitProgram(ProgramBuilder programBuilder) { 1574 int emitProgram(ProgramBuilder programBuilder) {
1562 Program program = programBuilder.buildProgram( 1575 Program program = programBuilder.buildProgram(
1563 storeFunctionTypesInMetadata: true); 1576 storeFunctionTypesInMetadata: true);
1564 1577
1578 assembleProgram(program);
1579
1565 // Shorten the code by using [namer.currentIsolate] as temporary. 1580 // Shorten the code by using [namer.currentIsolate] as temporary.
1566 isolateProperties = namer.currentIsolate; 1581 isolateProperties = namer.currentIsolate;
1567 1582
1568 // Emit deferred units first, so we have their hashes. 1583 // Emit deferred units first, so we have their hashes.
1569 // Map from OutputUnit to a hash of its content. The hash uniquely 1584 // Map from OutputUnit to a hash of its content. The hash uniquely
1570 // identifies the code of the output-unit. It does not include 1585 // identifies the code of the output-unit. It does not include
1571 // boilerplate JS code, like the sourcemap directives or the hash 1586 // boilerplate JS code, like the sourcemap directives or the hash
1572 // itself. 1587 // itself.
1573 Map<OutputUnit, String> deferredLoadHashes = 1588 Map<OutputUnit, String> deferredLoadHashes =
1574 emitDeferredOutputUnits(program); 1589 emitDeferredOutputUnits(program);
(...skipping 11 matching lines...) Expand all
1586 if (sourceMapUri != null && fileUri != null) { 1601 if (sourceMapUri != null && fileUri != null) {
1587 String sourceMapFileName = relativize(fileUri, sourceMapUri, false); 1602 String sourceMapFileName = relativize(fileUri, sourceMapUri, false);
1588 return ''' 1603 return '''
1589 1604
1590 //# sourceMappingURL=$sourceMapFileName 1605 //# sourceMappingURL=$sourceMapFileName
1591 '''; 1606 ''';
1592 } 1607 }
1593 return ''; 1608 return '';
1594 } 1609 }
1595 1610
1596 ClassBuilder getElementDescriptor(Element element) { 1611 ClassBuilder getElementDescriptor(Element element, Fragment fragment) {
1597 Element owner = element.library; 1612 Element owner = element.library;
1598 if (!element.isLibrary && !element.isTopLevel && !element.isNative) { 1613 if (!element.isLibrary && !element.isTopLevel && !element.isNative) {
1599 // For static (not top level) elements, record their code in a buffer 1614 // For static (not top level) elements, record their code in a buffer
1600 // specific to the class. For now, not supported for native classes and 1615 // specific to the class. For now, not supported for native classes and
1601 // native elements. 1616 // native elements.
1602 ClassElement cls = 1617 ClassElement cls =
1603 element.enclosingClassOrCompilationUnit.declaration; 1618 element.enclosingClassOrCompilationUnit.declaration;
1604 if (compiler.codegenWorld.directlyInstantiatedClasses.contains(cls) && 1619 if (compiler.codegenWorld.directlyInstantiatedClasses.contains(cls) &&
1605 !cls.isNative && 1620 !cls.isNative &&
1606 compiler.deferredLoadTask.outputUnitForElement(element) == 1621 compiler.deferredLoadTask.outputUnitForElement(element) ==
1607 compiler.deferredLoadTask.outputUnitForElement(cls)) { 1622 compiler.deferredLoadTask.outputUnitForElement(cls)) {
1608 owner = cls; 1623 owner = cls;
1609 } 1624 }
1610 } 1625 }
1611 if (owner == null) { 1626 if (owner == null) {
1612 compiler.internalError(element, 'Owner is null.'); 1627 compiler.internalError(element, 'Owner is null.');
1613 } 1628 }
1614 return elementDescriptors.putIfAbsent( 1629 return elementDescriptors.putIfAbsent(
karlklose 2015/04/17 11:26:10 How about formatting this as: return elementDesc
herhut 2015/04/17 11:37:30 How about this one?
1630 fragment,
1631 () => new Map<Element, ClassBuilder>()).putIfAbsent(
1615 owner, 1632 owner,
1616 () => new ClassBuilder(owner, namer)); 1633 () => new ClassBuilder(owner, namer));
1617 } 1634 }
1618 1635
1619 /// Emits support-code for deferred loading into [output]. 1636 /// Emits support-code for deferred loading into [output].
1620 void emitDeferredBoilerPlate(CodeOutput output, 1637 void emitDeferredBoilerPlate(CodeOutput output,
1621 Map<OutputUnit, String> deferredLoadHashes) { 1638 Map<OutputUnit, String> deferredLoadHashes) {
1622 jsAst.Statement functions = js.statement(''' 1639 jsAst.Statement functions = js.statement('''
1623 { 1640 {
1624 // Function for checking if a hunk is loaded given its hash. 1641 // Function for checking if a hunk is loaded given its hash.
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
1874 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { 1891 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) {
1875 if (element.isInstanceMember) { 1892 if (element.isInstanceMember) {
1876 cachedClassBuilders.remove(element.enclosingClass); 1893 cachedClassBuilders.remove(element.enclosingClass);
1877 1894
1878 nativeEmitter.cachedBuilders.remove(element.enclosingClass); 1895 nativeEmitter.cachedBuilders.remove(element.enclosingClass);
1879 1896
1880 } 1897 }
1881 } 1898 }
1882 } 1899 }
1883 } 1900 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698