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

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: Fix 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) {
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 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
946 return object.__proto__ && 949 return object.__proto__ &&
947 object.__proto__.p === cls.prototype.p; 950 object.__proto__.p === cls.prototype.p;
948 })(); 951 })();
949 '''); 952 ''');
950 } 953 }
951 954
952 output.addBuffer(jsAst.prettyPrint(supportsDirectProtoAccess, compiler)); 955 output.addBuffer(jsAst.prettyPrint(supportsDirectProtoAccess, compiler));
953 output.add(N); 956 output.add(N);
954 } 957 }
955 958
956 void writeLibraryDescriptor(CodeOutput output, LibraryElement library) { 959 void writeLibraryDescriptor(CodeOutput output, LibraryElement library,
960 Fragment fragment) {
957 var uri = ""; 961 var uri = "";
958 if (!compiler.enableMinification || backend.mustPreserveUris) { 962 if (!compiler.enableMinification || backend.mustPreserveUris) {
959 uri = library.canonicalUri; 963 uri = library.canonicalUri;
960 if (uri.scheme == 'file' && compiler.outputUri != null) { 964 if (uri.scheme == 'file' && compiler.outputUri != null) {
961 uri = relativize(compiler.outputUri, library.canonicalUri, false); 965 uri = relativize(compiler.outputUri, library.canonicalUri, false);
962 } 966 }
963 } 967 }
964 ClassBuilder descriptor = elementDescriptors[library]; 968 ClassBuilder descriptor = elementDescriptors[fragment][library];
965 if (descriptor == null) { 969 if (descriptor == null) {
966 // Nothing of the library was emitted. 970 // Nothing of the library was emitted.
967 // TODO(floitsch): this should not happen. We currently have an example 971 // TODO(floitsch): this should not happen. We currently have an example
968 // with language/prefix6_negative_test.dart where we have an instance 972 // with language/prefix6_negative_test.dart where we have an instance
969 // method without its corresponding class. 973 // method without its corresponding class.
970 return; 974 return;
971 } 975 }
972 976
973 String libraryName = 977 String libraryName =
974 (!compiler.enableMinification || backend.mustRetainLibraryNames) ? 978 (!compiler.enableMinification || backend.mustRetainLibraryNames) ?
(...skipping 18 matching lines...) Expand all
993 ..add(',$_') 997 ..add(',$_')
994 ..add(namer.globalObjectFor(library)) 998 ..add(namer.globalObjectFor(library))
995 ..add(',$_') 999 ..add(',$_')
996 ..addBuffer(jsAst.prettyPrint(initializers, 1000 ..addBuffer(jsAst.prettyPrint(initializers,
997 compiler, 1001 compiler,
998 monitor: compiler.dumpInfoTask)) 1002 monitor: compiler.dumpInfoTask))
999 ..add(library == compiler.mainApp ? ',${n}1' : "") 1003 ..add(library == compiler.mainApp ? ',${n}1' : "")
1000 ..add('],$n'); 1004 ..add('],$n');
1001 } 1005 }
1002 1006
1003 void emitPrecompiledConstructor(OutputUnit outputUnit, 1007 void assemblePrecompiledConstructor(OutputUnit outputUnit,
1004 String constructorName, 1008 String constructorName,
1005 jsAst.Expression constructorAst, 1009 jsAst.Expression constructorAst,
1006 List<String> fields) { 1010 List<String> fields) {
1007 cspPrecompiledFunctionFor(outputUnit).add( 1011 cspPrecompiledFunctionFor(outputUnit).add(
1008 new jsAst.FunctionDeclaration( 1012 new jsAst.FunctionDeclaration(
1009 new jsAst.VariableDeclaration(constructorName), constructorAst)); 1013 new jsAst.VariableDeclaration(constructorName), constructorAst));
1010 1014
1011 String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME; 1015 String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME;
1012 bool hasIsolateSupport = compiler.hasIsolateSupport; 1016 bool hasIsolateSupport = compiler.hasIsolateSupport;
1013 jsAst.Node fieldNamesArray = 1017 jsAst.Node fieldNamesArray =
1014 hasIsolateSupport ? js.stringArray(fields) : new jsAst.LiteralNull(); 1018 hasIsolateSupport ? js.stringArray(fields) : new jsAst.LiteralNull();
1015 1019
1016 cspPrecompiledFunctionFor(outputUnit).add(js.statement(r''' 1020 cspPrecompiledFunctionFor(outputUnit).add(js.statement(r'''
1017 { 1021 {
1018 #constructorName.builtin$cls = #constructorNameString; 1022 #constructorName.builtin$cls = #constructorNameString;
1019 if (!"name" in #constructorName) 1023 if (!"name" in #constructorName)
1020 #constructorName.name = #constructorNameString; 1024 #constructorName.name = #constructorNameString;
1021 $desc = $collectedClasses.#constructorName[1]; 1025 $desc = $collectedClasses.#constructorName[1];
1022 #constructorName.prototype = $desc; 1026 #constructorName.prototype = $desc;
1023 ''' /* next string is not a raw string */ ''' 1027 ''' /* next string is not a raw string */ '''
1024 if (#hasIsolateSupport) { 1028 if (#hasIsolateSupport) {
1025 #constructorName.$fieldNamesProperty = #fieldNamesArray; 1029 #constructorName.$fieldNamesProperty = #fieldNamesArray;
1026 } 1030 }
1027 }''', 1031 }''',
1028 {"constructorName": constructorName, 1032 {"constructorName": constructorName,
1029 "constructorNameString": js.string(constructorName), 1033 "constructorNameString": js.string(constructorName),
1030 "hasIsolateSupport": hasIsolateSupport, 1034 "hasIsolateSupport": hasIsolateSupport,
1031 "fieldNamesArray": fieldNamesArray})); 1035 "fieldNamesArray": fieldNamesArray}));
1032 1036
1033 cspPrecompiledConstructorNamesFor(outputUnit).add(js('#', constructorName)); 1037 cspPrecompiledConstructorNamesFor(outputUnit).add(js('#', constructorName));
1034 } 1038 }
1035 1039
1036 void emitTypedefs() { 1040 void assembleTypedefs(Program program) {
1037 OutputUnit mainOutputUnit = compiler.deferredLoadTask.mainOutputUnit; 1041 Fragment mainFragment = program.mainFragment;
1042 OutputUnit mainOutputUnit = mainFragment.outputUnit;
1038 1043
1039 // Emit all required typedef declarations into the main output unit. 1044 // Emit all required typedef declarations into the main output unit.
1040 // TODO(karlklose): unify required classes and typedefs to declarations 1045 // TODO(karlklose): unify required classes and typedefs to declarations
1041 // and have builders for each kind. 1046 // and have builders for each kind.
1042 for (TypedefElement typedef in typedefsNeededForReflection) { 1047 for (TypedefElement typedef in typedefsNeededForReflection) {
1043 LibraryElement library = typedef.library; 1048 LibraryElement library = typedef.library;
1044 // TODO(karlklose): add a TypedefBuilder and move this code there. 1049 // TODO(karlklose): add a TypedefBuilder and move this code there.
1045 DartType type = typedef.alias; 1050 DartType type = typedef.alias;
1046 // TODO(zarah): reify type variables once reflection on type arguments of 1051 // TODO(zarah): reify type variables once reflection on type arguments of
1047 // typedefs is supported. 1052 // typedefs is supported.
1048 int typeIndex = 1053 int typeIndex =
1049 task.metadataCollector.reifyType(type, ignoreTypeVariables: true); 1054 task.metadataCollector.reifyType(type, ignoreTypeVariables: true);
1050 ClassBuilder builder = new ClassBuilder(typedef, namer); 1055 ClassBuilder builder = new ClassBuilder(typedef, namer);
1051 builder.addProperty(embeddedNames.TYPEDEF_TYPE_PROPERTY_NAME, 1056 builder.addProperty(embeddedNames.TYPEDEF_TYPE_PROPERTY_NAME,
1052 js.number(typeIndex)); 1057 js.number(typeIndex));
1053 builder.addProperty(embeddedNames.TYPEDEF_PREDICATE_PROPERTY_NAME, 1058 builder.addProperty(embeddedNames.TYPEDEF_PREDICATE_PROPERTY_NAME,
1054 js.boolean(true)); 1059 js.boolean(true));
1055 1060
1056 // We can be pretty sure that the objectClass is initialized, since 1061 // We can be pretty sure that the objectClass is initialized, since
1057 // typedefs are only emitted with reflection, which requires lots of 1062 // typedefs are only emitted with reflection, which requires lots of
1058 // classes. 1063 // classes.
1059 assert(compiler.objectClass != null); 1064 assert(compiler.objectClass != null);
1060 builder.superName = namer.className(compiler.objectClass); 1065 builder.superName = namer.className(compiler.objectClass);
1061 jsAst.Node declaration = builder.toObjectInitializer(); 1066 jsAst.Node declaration = builder.toObjectInitializer();
1062 String mangledName = namer.globalPropertyName(typedef); 1067 String mangledName = namer.globalPropertyName(typedef);
1063 String reflectionName = getReflectionName(typedef, mangledName); 1068 String reflectionName = getReflectionName(typedef, mangledName);
1064 getElementDescriptor(library) 1069 getElementDescriptor(library, mainFragment)
1065 ..addProperty(mangledName, declaration) 1070 ..addProperty(mangledName, declaration)
1066 ..addProperty("+$reflectionName", js.string('')); 1071 ..addProperty("+$reflectionName", js.string(''));
1067 // Also emit a trivial constructor for CSP mode. 1072 // Also emit a trivial constructor for CSP mode.
1068 String constructorName = mangledName; 1073 String constructorName = mangledName;
1069 jsAst.Expression constructorAst = js('function() {}'); 1074 jsAst.Expression constructorAst = js('function() {}');
1070 List<String> fieldNames = []; 1075 List<String> fieldNames = [];
1071 emitPrecompiledConstructor(mainOutputUnit, 1076 assemblePrecompiledConstructor(mainOutputUnit,
1072 constructorName, 1077 constructorName,
1073 constructorAst, 1078 constructorAst,
1074 fieldNames); 1079 fieldNames);
1075 } 1080 }
1076 } 1081 }
1077 1082
1078 void emitMangledNames(CodeOutput output) { 1083 void emitMangledNames(CodeOutput output) {
1079 if (!mangledFieldNames.isEmpty) { 1084 if (!mangledFieldNames.isEmpty) {
1080 var keys = mangledFieldNames.keys.toList(); 1085 var keys = mangledFieldNames.keys.toList();
1081 keys.sort(); 1086 keys.sort();
1082 var properties = []; 1087 var properties = [];
1083 for (String key in keys) { 1088 for (String key in keys) {
1084 var value = js.string('${mangledFieldNames[key]}'); 1089 var value = js.string('${mangledFieldNames[key]}');
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1129 compiler.reportInfo( 1134 compiler.reportInfo(
1130 element, MessageKind.GENERIC, {'text': 'Pending statics.'})); 1135 element, MessageKind.GENERIC, {'text': 'Pending statics.'}));
1131 } 1136 }
1132 1137
1133 if (pendingStatics != null && !pendingStatics.isEmpty) { 1138 if (pendingStatics != null && !pendingStatics.isEmpty) {
1134 compiler.internalError(pendingStatics.first, 1139 compiler.internalError(pendingStatics.first,
1135 'Pending statics (see above).'); 1140 'Pending statics (see above).');
1136 } 1141 }
1137 } 1142 }
1138 1143
1139 void emitLibrary(Library library) { 1144 void assembleLibrary(Library library, Fragment fragment) {
1140 LibraryElement libraryElement = library.element; 1145 LibraryElement libraryElement = library.element;
1141 1146
1142 emitStaticFunctions(library.statics); 1147 assembleStaticFunctions(library.statics, fragment);
1143 1148
1144 ClassBuilder libraryBuilder = getElementDescriptor(libraryElement); 1149 ClassBuilder libraryBuilder =
1150 getElementDescriptor(libraryElement, fragment);
1145 for (Class cls in library.classes) { 1151 for (Class cls in library.classes) {
1146 emitClass(cls, libraryBuilder); 1152 assembleClass(cls, libraryBuilder, fragment);
1147 } 1153 }
1148 1154
1149 classEmitter.emitFields(library, libraryBuilder, emitStatics: true); 1155 classEmitter.emitFields(library, libraryBuilder, emitStatics: true);
1150 } 1156 }
1151 1157
1158 void assembleProgram(Program program) {
1159 for (Fragment fragment in program.fragments) {
1160 for (Library library in fragment.libraries) {
1161 assembleLibrary(library, fragment);
1162 }
1163 }
1164 assembleTypedefs(program);
1165 }
1166
1152 void emitMainOutputUnit(Program program, 1167 void emitMainOutputUnit(Program program,
1153 Map<OutputUnit, String> deferredLoadHashes) { 1168 Map<OutputUnit, String> deferredLoadHashes) {
1154 MainFragment mainFragment = program.fragments.first; 1169 MainFragment mainFragment = program.fragments.first;
1155 OutputUnit mainOutputUnit = mainFragment.outputUnit; 1170 OutputUnit mainOutputUnit = mainFragment.outputUnit;
1156 1171
1157 LineColumnCollector lineColumnCollector; 1172 LineColumnCollector lineColumnCollector;
1158 List<CodeOutputListener> codeOutputListeners; 1173 List<CodeOutputListener> codeOutputListeners;
1159 if (generateSourceMap) { 1174 if (generateSourceMap) {
1160 lineColumnCollector = new LineColumnCollector(); 1175 lineColumnCollector = new LineColumnCollector();
1161 codeOutputListeners = <CodeOutputListener>[lineColumnCollector]; 1176 codeOutputListeners = <CodeOutputListener>[lineColumnCollector];
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1241 mainOutput.add( 1256 mainOutput.add(
1242 '${globalsHolder}.${namer.isolateName}$_=$_${namer.isolateName}$N' 1257 '${globalsHolder}.${namer.isolateName}$_=$_${namer.isolateName}$N'
1243 '${globalsHolder}.$initName$_=${_}$initName$N' 1258 '${globalsHolder}.$initName$_=${_}$initName$N'
1244 '${globalsHolder}.$setupProgramName$_=$_' 1259 '${globalsHolder}.$setupProgramName$_=$_'
1245 '$setupProgramName$N'); 1260 '$setupProgramName$N');
1246 } 1261 }
1247 mainOutput.add('init()$N$n'); 1262 mainOutput.add('init()$N$n');
1248 mainOutput.add('$isolateProperties$_=$_$isolatePropertiesName$N'); 1263 mainOutput.add('$isolateProperties$_=$_$isolatePropertiesName$N');
1249 1264
1250 emitFunctionThatReturnsNull(mainOutput); 1265 emitFunctionThatReturnsNull(mainOutput);
1251 mainFragment.libraries.forEach(emitLibrary);
1252 1266
1253 Iterable<LibraryElement> libraries = 1267 Iterable<LibraryElement> libraries =
1254 task.outputLibraryLists[mainOutputUnit]; 1268 task.outputLibraryLists[mainOutputUnit];
1255 if (libraries == null) libraries = []; 1269 if (libraries == null) libraries = [];
1256 emitTypedefs();
1257 emitMangledNames(mainOutput); 1270 emitMangledNames(mainOutput);
1258 1271
1259 checkEverythingEmitted(elementDescriptors.keys); 1272 Map<Element, ClassBuilder> descriptors = elementDescriptors[mainFragment];
1273 checkEverythingEmitted(descriptors.keys);
1260 1274
1261 CodeBuffer libraryBuffer = new CodeBuffer(); 1275 CodeBuffer libraryBuffer = new CodeBuffer();
1262 for (LibraryElement library in Elements.sortedByPosition(libraries)) { 1276 for (LibraryElement library in Elements.sortedByPosition(libraries)) {
1263 writeLibraryDescriptor(libraryBuffer, library); 1277 writeLibraryDescriptor(libraryBuffer, library, mainFragment);
1264 elementDescriptors.remove(library); 1278 descriptors.remove(library);
1265 } 1279 }
1266 1280
1267 if (elementDescriptors.isNotEmpty) { 1281 if (descriptors.isNotEmpty) {
1268 List<Element> remainingLibraries = elementDescriptors.keys 1282 List<Element> remainingLibraries = descriptors.keys
1269 .where((Element e) => e is LibraryElement) 1283 .where((Element e) => e is LibraryElement)
1270 .toList(); 1284 .toList();
1271 1285
1272 // The remaining descriptors are only accessible through reflection. 1286 // The remaining descriptors are only accessible through reflection.
1273 // The program builder does not collect libraries that only 1287 // The program builder does not collect libraries that only
1274 // contain typedefs that are used for reflection. 1288 // contain typedefs that are used for reflection.
1275 for (LibraryElement element in remainingLibraries) { 1289 for (LibraryElement element in remainingLibraries) {
1276 assert(element is LibraryElement || compiler.hasIncrementalSupport); 1290 assert(element is LibraryElement || compiler.hasIncrementalSupport);
1277 if (element is LibraryElement) { 1291 if (element is LibraryElement) {
1278 writeLibraryDescriptor(libraryBuffer, element); 1292 writeLibraryDescriptor(libraryBuffer, element, mainFragment);
1279 elementDescriptors.remove(element); 1293 descriptors.remove(element);
1280 } 1294 }
1281 } 1295 }
1282 } 1296 }
1283 1297
1284 bool needsNativeSupport = program.needsNativeSupport; 1298 bool needsNativeSupport = program.needsNativeSupport;
1285 mainOutput.addBuffer( 1299 mainOutput.addBuffer(
1286 jsAst.prettyPrint( 1300 jsAst.prettyPrint(
1287 buildSetupProgram(program, compiler, backend, namer, this), 1301 buildSetupProgram(program, compiler, backend, namer, this),
1288 compiler)); 1302 compiler));
1289 1303
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1535 /// itself. 1549 /// itself.
1536 Map<OutputUnit, String> emitDeferredOutputUnits(Program program) { 1550 Map<OutputUnit, String> emitDeferredOutputUnits(Program program) {
1537 if (!program.isSplit) return const {}; 1551 if (!program.isSplit) return const {};
1538 1552
1539 Map<OutputUnit, CodeBuffer> outputBuffers = 1553 Map<OutputUnit, CodeBuffer> outputBuffers =
1540 new Map<OutputUnit, CodeBuffer>(); 1554 new Map<OutputUnit, CodeBuffer>();
1541 1555
1542 for (Fragment fragment in program.deferredFragments) { 1556 for (Fragment fragment in program.deferredFragments) {
1543 OutputUnit outputUnit = fragment.outputUnit; 1557 OutputUnit outputUnit = fragment.outputUnit;
1544 1558
1559 Map<Element, ClassBuilder> descriptors = elementDescriptors[fragment];
1545 1560
1546 fragment.libraries.forEach(emitLibrary); 1561 if (descriptors != null && descriptors.isNotEmpty) {
1547
1548 if (elementDescriptors.isNotEmpty) {
1549 Iterable<LibraryElement> libraries = 1562 Iterable<LibraryElement> libraries =
1550 task.outputLibraryLists[outputUnit]; 1563 task.outputLibraryLists[outputUnit];
1551 if (libraries == null) libraries = []; 1564 if (libraries == null) libraries = [];
1552 1565
1553 // TODO(johnniwinther): Avoid creating [CodeBuffer]s. 1566 // TODO(johnniwinther): Avoid creating [CodeBuffer]s.
1554 CodeBuffer buffer = new CodeBuffer(); 1567 CodeBuffer buffer = new CodeBuffer();
1555 outputBuffers[outputUnit] = buffer; 1568 outputBuffers[outputUnit] = buffer;
1556 for (LibraryElement library in Elements.sortedByPosition(libraries)) { 1569 for (LibraryElement library in Elements.sortedByPosition(libraries)) {
1557 writeLibraryDescriptor(buffer, library); 1570 writeLibraryDescriptor(buffer, library, fragment);
1558 elementDescriptors.remove(library); 1571 descriptors.remove(library);
1559 } 1572 }
1560 } 1573 }
1561 } 1574 }
1562 1575
1563 return emitDeferredCode(program, outputBuffers); 1576 return emitDeferredCode(program, outputBuffers);
1564 } 1577 }
1565 1578
1566 int emitProgram(ProgramBuilder programBuilder) { 1579 int emitProgram(ProgramBuilder programBuilder) {
1567 Program program = programBuilder.buildProgram( 1580 Program program = programBuilder.buildProgram(
1568 storeFunctionTypesInMetadata: true); 1581 storeFunctionTypesInMetadata: true);
1569 1582
1583 assembleProgram(program);
1584
1570 // Shorten the code by using [namer.currentIsolate] as temporary. 1585 // Shorten the code by using [namer.currentIsolate] as temporary.
1571 isolateProperties = namer.currentIsolate; 1586 isolateProperties = namer.currentIsolate;
1572 1587
1573 // Emit deferred units first, so we have their hashes. 1588 // Emit deferred units first, so we have their hashes.
1574 // Map from OutputUnit to a hash of its content. The hash uniquely 1589 // Map from OutputUnit to a hash of its content. The hash uniquely
1575 // identifies the code of the output-unit. It does not include 1590 // identifies the code of the output-unit. It does not include
1576 // boilerplate JS code, like the sourcemap directives or the hash 1591 // boilerplate JS code, like the sourcemap directives or the hash
1577 // itself. 1592 // itself.
1578 Map<OutputUnit, String> deferredLoadHashes = 1593 Map<OutputUnit, String> deferredLoadHashes =
1579 emitDeferredOutputUnits(program); 1594 emitDeferredOutputUnits(program);
(...skipping 11 matching lines...) Expand all
1591 if (sourceMapUri != null && fileUri != null) { 1606 if (sourceMapUri != null && fileUri != null) {
1592 String sourceMapFileName = relativize(fileUri, sourceMapUri, false); 1607 String sourceMapFileName = relativize(fileUri, sourceMapUri, false);
1593 return ''' 1608 return '''
1594 1609
1595 //# sourceMappingURL=$sourceMapFileName 1610 //# sourceMappingURL=$sourceMapFileName
1596 '''; 1611 ''';
1597 } 1612 }
1598 return ''; 1613 return '';
1599 } 1614 }
1600 1615
1601 ClassBuilder getElementDescriptor(Element element) { 1616 ClassBuilder getElementDescriptor(Element element, Fragment fragment) {
1602 Element owner = element.library; 1617 Element owner = element.library;
1603 if (!element.isLibrary && !element.isTopLevel && !element.isNative) { 1618 if (!element.isLibrary && !element.isTopLevel && !element.isNative) {
1604 // For static (not top level) elements, record their code in a buffer 1619 // For static (not top level) elements, record their code in a buffer
1605 // specific to the class. For now, not supported for native classes and 1620 // specific to the class. For now, not supported for native classes and
1606 // native elements. 1621 // native elements.
1607 ClassElement cls = 1622 ClassElement cls =
1608 element.enclosingClassOrCompilationUnit.declaration; 1623 element.enclosingClassOrCompilationUnit.declaration;
1609 if (compiler.codegenWorld.directlyInstantiatedClasses.contains(cls) && 1624 if (compiler.codegenWorld.directlyInstantiatedClasses.contains(cls) &&
1610 !cls.isNative && 1625 !cls.isNative &&
1611 compiler.deferredLoadTask.outputUnitForElement(element) == 1626 compiler.deferredLoadTask.outputUnitForElement(element) ==
1612 compiler.deferredLoadTask.outputUnitForElement(cls)) { 1627 compiler.deferredLoadTask.outputUnitForElement(cls)) {
1613 owner = cls; 1628 owner = cls;
1614 } 1629 }
1615 } 1630 }
1616 if (owner == null) { 1631 if (owner == null) {
1617 compiler.internalError(element, 'Owner is null.'); 1632 compiler.internalError(element, 'Owner is null.');
1618 } 1633 }
1619 return elementDescriptors.putIfAbsent( 1634 return elementDescriptors
1620 owner, 1635 .putIfAbsent(fragment, () => new Map<Element, ClassBuilder>())
1621 () => new ClassBuilder(owner, namer)); 1636 .putIfAbsent(owner, () => new ClassBuilder(owner, namer));
1622 } 1637 }
1623 1638
1624 /// Emits support-code for deferred loading into [output]. 1639 /// Emits support-code for deferred loading into [output].
1625 void emitDeferredBoilerPlate(CodeOutput output, 1640 void emitDeferredBoilerPlate(CodeOutput output,
1626 Map<OutputUnit, String> deferredLoadHashes) { 1641 Map<OutputUnit, String> deferredLoadHashes) {
1627 jsAst.Statement functions = js.statement(''' 1642 jsAst.Statement functions = js.statement('''
1628 { 1643 {
1629 // Function for checking if a hunk is loaded given its hash. 1644 // Function for checking if a hunk is loaded given its hash.
1630 #isHunkLoaded = function(hunkHash) { 1645 #isHunkLoaded = function(hunkHash) {
1631 return !!$deferredInitializers[hunkHash]; 1646 return !!$deferredInitializers[hunkHash];
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
1879 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { 1894 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) {
1880 if (element.isInstanceMember) { 1895 if (element.isInstanceMember) {
1881 cachedClassBuilders.remove(element.enclosingClass); 1896 cachedClassBuilders.remove(element.enclosingClass);
1882 1897
1883 nativeEmitter.cachedBuilders.remove(element.enclosingClass); 1898 nativeEmitter.cachedBuilders.remove(element.enclosingClass);
1884 1899
1885 } 1900 }
1886 } 1901 }
1887 } 1902 }
1888 } 1903 }
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