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

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

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