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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_emitter/old_emitter/emitter.dart

Issue 656043003: dart2js: restructure emitter. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Full diff Created 6 years, 2 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
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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 * dynamically. This doesn't work in CSP mode, and may impact startup time 76 * dynamically. This doesn't work in CSP mode, and may impact startup time
77 * negatively. So dart2js will emit these functions to a separate file that 77 * negatively. So dart2js will emit these functions to a separate file that
78 * can be optionally included to support CSP mode or for faster startup. 78 * can be optionally included to support CSP mode or for faster startup.
79 */ 79 */
80 Map<OutputUnit, List<jsAst.Node>> _cspPrecompiledFunctions = 80 Map<OutputUnit, List<jsAst.Node>> _cspPrecompiledFunctions =
81 new Map<OutputUnit, List<jsAst.Node>>(); 81 new Map<OutputUnit, List<jsAst.Node>>();
82 82
83 Map<OutputUnit, List<jsAst.Expression>> _cspPrecompiledConstructorNames = 83 Map<OutputUnit, List<jsAst.Expression>> _cspPrecompiledConstructorNames =
84 new Map<OutputUnit, List<jsAst.Expression>>(); 84 new Map<OutputUnit, List<jsAst.Expression>>();
85 85
86 // True if Isolate.makeConstantList is needed.
87 bool hasMakeConstantList = false;
88
89 /** 86 /**
90 * Accumulate properties for classes and libraries, describing their 87 * Accumulate properties for classes and libraries, describing their
91 * static/top-level members. 88 * static/top-level members.
92 * Later, these members are emitted when the class or library is emitted. 89 * Later, these members are emitted when the class or library is emitted.
93 * 90 *
94 * For supporting deferred loading we keep one list per output unit. 91 * See [getElementDescriptor].
95 *
96 * See [getElementDecriptor].
97 */ 92 */
98 // TODO(ahe): Generate statics with their class, and store only libraries in 93 // TODO(ahe): Generate statics with their class, and store only libraries in
99 // this map. 94 // this map.
100 final Map<Element, Map<OutputUnit, ClassBuilder>> elementDescriptors 95 final Map<Element, ClassBuilder> elementDescriptors =
101 = new Map<Element, Map<OutputUnit, ClassBuilder>>(); 96 new Map<Element, ClassBuilder>();
102 97
103 final bool generateSourceMap; 98 final bool generateSourceMap;
104 99
105 OldEmitter(Compiler compiler, Namer namer, this.generateSourceMap, this.task) 100 OldEmitter(Compiler compiler, Namer namer, this.generateSourceMap, this.task)
106 : this.compiler = compiler, 101 : this.compiler = compiler,
107 this.namer = namer, 102 this.namer = namer,
108 constantEmitter = new ConstantEmitter(compiler, namer), 103 constantEmitter = new ConstantEmitter(compiler, namer),
109 cachedEmittedConstants = compiler.cacheStrategy.newSet(), 104 cachedEmittedConstants = compiler.cacheStrategy.newSet(),
110 cachedClassBuilders = compiler.cacheStrategy.newMap(), 105 cachedClassBuilders = compiler.cacheStrategy.newMap(),
111 cachedElements = compiler.cacheStrategy.newSet() { 106 cachedElements = compiler.cacheStrategy.newSet() {
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 } 569 }
575 570
576 jsAst.Fun get finishIsolateConstructorFunction { 571 jsAst.Fun get finishIsolateConstructorFunction {
577 // We replace the old Isolate function with a new one that initializes 572 // We replace the old Isolate function with a new one that initializes
578 // all its fields with the initial (and often final) value of all globals. 573 // all its fields with the initial (and often final) value of all globals.
579 // 574 //
580 // We also copy over old values like the prototype, and the 575 // We also copy over old values like the prototype, and the
581 // isolateProperties themselves. 576 // isolateProperties themselves.
582 return js(''' 577 return js('''
583 function (oldIsolate) { 578 function (oldIsolate) {
584 var isolateProperties = oldIsolate.#; 579 var isolateProperties = oldIsolate.#; // isolatePropertiesName
585 function Isolate() { 580 function Isolate() {
586 var hasOwnProperty = Object.prototype.hasOwnProperty; 581 var hasOwnProperty = Object.prototype.hasOwnProperty;
587 for (var staticName in isolateProperties) 582 for (var staticName in isolateProperties)
588 if (hasOwnProperty.call(isolateProperties, staticName)) 583 if (hasOwnProperty.call(isolateProperties, staticName))
589 this[staticName] = isolateProperties[staticName]; 584 this[staticName] = isolateProperties[staticName];
590 585
591 // Reset lazy initializers to null. 586 // Reset lazy initializers to null.
592 // When forcing the object to fast mode (below) v8 will consider 587 // When forcing the object to fast mode (below) v8 will consider
593 // functions as part the object's map. Since we will change them 588 // functions as part the object's map. Since we will change them
594 // (after the first call to the getter), we would have a map 589 // (after the first call to the getter), we would have a map
(...skipping 11 matching lines...) Expand all
606 new ForceEfficientMap(); 601 new ForceEfficientMap();
607 602
608 // Now, after being a fast map we can set the lazies again. 603 // Now, after being a fast map we can set the lazies again.
609 for (var lazyInit in lazies) { 604 for (var lazyInit in lazies) {
610 var lazyInitName = lazies[lazyInit]; 605 var lazyInitName = lazies[lazyInit];
611 this[lazyInitName] = isolateProperties[lazyInitName]; 606 this[lazyInitName] = isolateProperties[lazyInitName];
612 } 607 }
613 } 608 }
614 Isolate.prototype = oldIsolate.prototype; 609 Isolate.prototype = oldIsolate.prototype;
615 Isolate.prototype.constructor = Isolate; 610 Isolate.prototype.constructor = Isolate;
616 Isolate.# = isolateProperties; 611 Isolate.# = isolateProperties; // isolatePropertiesName
Johnni Winther 2014/10/16 08:04:50 Maybe we should change [js] to take a map of argum
floitsch 2014/10/16 11:53:36 Thought the same thing. I might look into this lat
617 if (#) 612 if (#) // needsDefineClass.
618 Isolate.# = oldIsolate.#; 613 Isolate.# = oldIsolate.#; // finishClassesProperty * 2
619 if (#) 614 if (#) // outputContainsConstantList
620 Isolate.# = oldIsolate.#; 615 Isolate.# = oldIsolate.#; // makeConstListProperty * 2
621 return Isolate; 616 return Isolate;
622 }''', 617 }''',
623 [namer.isolatePropertiesName, namer.isolatePropertiesName, 618 [namer.isolatePropertiesName, namer.isolatePropertiesName,
624 needsDefineClass, finishClassesProperty, finishClassesProperty, 619 needsDefineClass, finishClassesProperty, finishClassesProperty,
625 hasMakeConstantList, makeConstListProperty, makeConstListProperty ]); 620 task.outputContainsConstantList,
621 makeConstListProperty, makeConstListProperty ]);
626 } 622 }
627 623
628 jsAst.Fun get lazyInitializerFunction { 624 jsAst.Fun get lazyInitializerFunction {
629 String isolate = namer.currentIsolate; 625 String isolate = namer.currentIsolate;
630 jsAst.Expression cyclicThrow = 626 jsAst.Expression cyclicThrow =
631 namer.elementAccess(backend.getCyclicThrowHelper()); 627 namer.elementAccess(backend.getCyclicThrowHelper());
632 jsAst.Expression laziesAccess = 628 jsAst.Expression laziesAccess =
633 generateEmbeddedGlobalAccess(embeddedNames.LAZIES); 629 generateEmbeddedGlobalAccess(embeddedNames.LAZIES);
634 630
635 return js(''' 631 return js('''
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
870 if (needsDefineClass) { 866 if (needsDefineClass) {
871 buffer.write('$finishClassesName($classesCollector,' 867 buffer.write('$finishClassesName($classesCollector,'
872 '$_$isolateProperties,' 868 '$_$isolateProperties,'
873 '${_}null)$N'); 869 '${_}null)$N');
874 870
875 // Reset the map. 871 // Reset the map.
876 buffer.write("$classesCollector$_=${_}null$N$n"); 872 buffer.write("$classesCollector$_=${_}null$N$n");
877 } 873 }
878 } 874 }
879 875
880 void emitStaticFunctions() { 876 void emitStaticFunctions(List<Element> staticFunctions) {
881 bool isStaticFunction(Element element) => 877 for (Element element in staticFunctions) {
882 !element.isInstanceMember && !element.isField;
883
884 Iterable<Element> elements =
885 backend.generatedCode.keys.where(isStaticFunction);
886
887 for (Element element in Elements.sortedByPosition(elements)) {
888 ClassBuilder builder = new ClassBuilder(element, namer); 878 ClassBuilder builder = new ClassBuilder(element, namer);
889 containerBuilder.addMember(element, builder); 879 containerBuilder.addMember(element, builder);
890 getElementDescriptor(element).properties.addAll(builder.properties); 880 getElementDescriptor(element).properties.addAll(builder.properties);
891 } 881 }
892 } 882 }
893 883
894 void emitStaticNonFinalFieldInitializations(CodeBuffer buffer) { 884 void emitStaticNonFinalFieldInitializations(CodeBuffer buffer) {
895 JavaScriptConstantCompiler handler = backend.constants; 885 JavaScriptConstantCompiler handler = backend.constants;
896 Iterable<VariableElement> staticNonFinalFields = 886 Iterable<VariableElement> staticNonFinalFields =
897 handler.getStaticNonFinalFieldsForEmission(); 887 handler.getStaticNonFinalFieldsForEmission();
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 bool isMainBuffer = buffer == mainBuffer; 980 bool isMainBuffer = buffer == mainBuffer;
991 if (compiler.hasIncrementalSupport && isMainBuffer) { 981 if (compiler.hasIncrementalSupport && isMainBuffer) {
992 buffer = cachedEmittedConstantsBuffer; 982 buffer = cachedEmittedConstantsBuffer;
993 } 983 }
994 for (ConstantValue constant in constants) { 984 for (ConstantValue constant in constants) {
995 if (compiler.hasIncrementalSupport && isMainBuffer) { 985 if (compiler.hasIncrementalSupport && isMainBuffer) {
996 if (cachedEmittedConstants.contains(constant)) continue; 986 if (cachedEmittedConstants.contains(constant)) continue;
997 cachedEmittedConstants.add(constant); 987 cachedEmittedConstants.add(constant);
998 } 988 }
999 String name = namer.constantName(constant); 989 String name = namer.constantName(constant);
1000 if (constant.isList) emitMakeConstantListIfNotEmitted(buffer);
1001 jsAst.Expression init = js('#.# = #', 990 jsAst.Expression init = js('#.# = #',
1002 [namer.globalObjectForConstant(constant), name, 991 [namer.globalObjectForConstant(constant), name,
1003 constantInitializerExpression(constant)]); 992 constantInitializerExpression(constant)]);
1004 buffer.write(jsAst.prettyPrint(init, compiler, 993 buffer.write(jsAst.prettyPrint(init, compiler,
1005 monitor: compiler.dumpInfoTask)); 994 monitor: compiler.dumpInfoTask));
1006 buffer.write('$N'); 995 buffer.write('$N');
1007 } 996 }
1008 if (compiler.hasIncrementalSupport && isMainBuffer) { 997 if (compiler.hasIncrementalSupport && isMainBuffer) {
1009 mainBuffer.add(cachedEmittedConstantsBuffer); 998 mainBuffer.add(cachedEmittedConstantsBuffer);
1010 } 999 }
1011 } 1000 }
1012 1001
1013 void emitMakeConstantListIfNotEmitted(CodeBuffer buffer) { 1002 void emitMakeConstantList(CodeBuffer buffer) {
1014 if (hasMakeConstantList) return;
1015 hasMakeConstantList = true;
1016 buffer.write( 1003 buffer.write(
1017 jsAst.prettyPrint( 1004 jsAst.prettyPrint(
1018 js.statement(r'''#.# = function(list) { 1005 js.statement(r'''#.# = function(list) {
1019 list.immutable$list = #; 1006 list.immutable$list = #;
1020 list.fixed$length = #; 1007 list.fixed$length = #;
1021 return list; 1008 return list;
1022 }''', 1009 }''',
1023 [namer.isolateName, makeConstListProperty, initName, 1010 [namer.isolateName, makeConstListProperty, initName,
1024 initName]), 1011 initName]),
1025 compiler, monitor: compiler.dumpInfoTask)); 1012 compiler, monitor: compiler.dumpInfoTask));
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
1213 MyClass.prototype = properties; 1200 MyClass.prototype = properties;
1214 new MyClass(); 1201 new MyClass();
1215 #; 1202 #;
1216 return properties; 1203 return properties;
1217 }''', [debugCode]); 1204 }''', [debugCode]);
1218 1205
1219 mainBuffer.add(jsAst.prettyPrint(convertToFastObject, compiler)); 1206 mainBuffer.add(jsAst.prettyPrint(convertToFastObject, compiler));
1220 mainBuffer.add(N); 1207 mainBuffer.add(N);
1221 } 1208 }
1222 1209
1223 void writeLibraryDescriptors( 1210 void writeLibraryDescriptors(CodeBuffer buffer, LibraryElement library) {
1224 LibraryElement library,
1225 Map<OutputUnit, CodeBuffer> libraryDescriptorBuffers) {
1226 var uri = ""; 1211 var uri = "";
1227 if (!compiler.enableMinification || backend.mustRetainUris) { 1212 if (!compiler.enableMinification || backend.mustRetainUris) {
1228 uri = library.canonicalUri; 1213 uri = library.canonicalUri;
1229 if (uri.scheme == 'file' && compiler.outputUri != null) { 1214 if (uri.scheme == 'file' && compiler.outputUri != null) {
1230 uri = relativize(compiler.outputUri, library.canonicalUri, false); 1215 uri = relativize(compiler.outputUri, library.canonicalUri, false);
1231 } 1216 }
1232 } 1217 }
1233 Map<OutputUnit, ClassBuilder> descriptors = elementDescriptors[library]; 1218 ClassBuilder descriptor = elementDescriptors[library];
1219 if (descriptor == null) {
1220 // Nothing of the library was emitted.
1221 // TODO(floitsch): this should not happen. We currently have an example
1222 // with language/prefix6_negative_test.dart where we have an instance
1223 // method without its corresponding class.
1224 return;
1225 }
1226
1234 String libraryName = 1227 String libraryName =
1235 (!compiler.enableMinification || backend.mustRetainLibraryNames) ? 1228 (!compiler.enableMinification || backend.mustRetainLibraryNames) ?
1236 library.getLibraryName() : 1229 library.getLibraryName() :
1237 ""; 1230 "";
1238 1231
1239 for (OutputUnit outputUnit in compiler.deferredLoadTask.allOutputUnits) { 1232 jsAst.Fun metadata = metadataEmitter.buildMetadataFunction(library);
1240 if (!descriptors.containsKey(outputUnit)) continue;
1241 1233
1242 ClassBuilder descriptor = descriptors[outputUnit]; 1234 jsAst.ObjectInitializer initializers = descriptor.toObjectInitializer();
1243 1235
1244 jsAst.Fun metadata = metadataEmitter.buildMetadataFunction(library); 1236 CodeBuffer libraryDescriptorBuffer = buffer;
Johnni Winther 2014/10/16 08:04:50 Remove and use [buffer] below.
floitsch 2014/10/16 11:53:36 Was to make diff easier. Wasn't really worth it...
1245 1237
1246 jsAst.ObjectInitializer initializers = descriptor.toObjectInitializer(); 1238 compiler.dumpInfoTask.registerElementAst(library, metadata);
1247 1239 compiler.dumpInfoTask.registerElementAst(library, initializers);
1248 CodeBuffer libraryDescriptorBuffer = 1240 libraryDescriptorBuffer
1249 libraryDescriptorBuffers.putIfAbsent(outputUnit, 1241 ..write('["$libraryName",$_')
1250 () => new CodeBuffer()); 1242 ..write('"${uri}",$_')
1251 1243 ..write(metadata == null ? "" : jsAst.prettyPrint(metadata,
1252 compiler.dumpInfoTask.registerElementAst(library, metadata); 1244 compiler,
1253 compiler.dumpInfoTask.registerElementAst(library, initializers); 1245 monitor: compiler.dumpInfoTask))
1254 libraryDescriptorBuffer 1246 ..write(',$_')
1255 ..write('["$libraryName",$_') 1247 ..write(namer.globalObjectFor(library))
1256 ..write('"${uri}",$_') 1248 ..write(',$_')
1257 ..write(metadata == null ? "" : jsAst.prettyPrint(metadata, 1249 ..write(jsAst.prettyPrint(initializers,
1258 compiler, 1250 compiler,
1259 monitor: compiler.dumpInfoTask)) 1251 monitor: compiler.dumpInfoTask))
1260 ..write(',$_') 1252 ..write(library == compiler.mainApp ? ',${n}1' : "")
1261 ..write(namer.globalObjectFor(library)) 1253 ..write('],$n');
1262 ..write(',$_')
1263 ..write(jsAst.prettyPrint(initializers,
1264 compiler,
1265 monitor: compiler.dumpInfoTask))
1266 ..write(library == compiler.mainApp ? ',${n}1' : "")
1267 ..write('],$n');
1268 }
1269 } 1254 }
1270 1255
1271 void emitPrecompiledConstructor(OutputUnit outputUnit, 1256 void emitPrecompiledConstructor(OutputUnit outputUnit,
1272 String constructorName, 1257 String constructorName,
1273 jsAst.Expression constructorAst) { 1258 jsAst.Expression constructorAst) {
1274 cspPrecompiledFunctionFor(outputUnit).add( 1259 cspPrecompiledFunctionFor(outputUnit).add(
1275 new jsAst.FunctionDeclaration( 1260 new jsAst.FunctionDeclaration(
1276 new jsAst.VariableDeclaration(constructorName), constructorAst)); 1261 new jsAst.VariableDeclaration(constructorName), constructorAst));
1277 cspPrecompiledFunctionFor(outputUnit).add( 1262 cspPrecompiledFunctionFor(outputUnit).add(
1278 js.statement(r'''{ 1263 js.statement(r'''{
(...skipping 23 matching lines...) Expand all
1302 String outName = outPath.substring(outPath.lastIndexOf('/') + 1); 1287 String outName = outPath.substring(outPath.lastIndexOf('/') + 1);
1303 String extension = addExtension ? ".part.js" : ""; 1288 String extension = addExtension ? ".part.js" : "";
1304 if (outputUnit == compiler.deferredLoadTask.mainOutputUnit) { 1289 if (outputUnit == compiler.deferredLoadTask.mainOutputUnit) {
1305 return "$outName$extension"; 1290 return "$outName$extension";
1306 } else { 1291 } else {
1307 String name = outputUnit.name; 1292 String name = outputUnit.name;
1308 return "${outName}_$name$extension"; 1293 return "${outName}_$name$extension";
1309 } 1294 }
1310 } 1295 }
1311 1296
1312 void emitProgram(Program program) { 1297 void emitLibraries(Iterable<LibraryElement> libraries) {
1298 if (libraries.isEmpty) return;
1299
1300 // TODO(karlklose): document what kinds of fields this loop adds to the
1301 // library class builder.
1302 for (LibraryElement element in libraries) {
1303 LibraryElement library = element;
1304 ClassBuilder builder = new ClassBuilder(library, namer);
1305 if (classEmitter.emitFields(
1306 library, builder, null, emitStatics: true)) {
1307 jsAst.ObjectInitializer initializer =
1308 builder.toObjectInitializer();
Johnni Winther 2014/10/16 08:04:50 Indent by 4.
floitsch 2014/10/16 11:53:36 All the statements here actually fit on one line.
1309 compiler.dumpInfoTask.registerElementAst(builder.element,
1310 initializer);
1311 getElementDescriptor(library)
1312 .properties.addAll(initializer.properties);
1313 }
1314 }
1315 }
1316
1317 void emitTypedefs() {
1318 OutputUnit mainOutputUnit = compiler.deferredLoadTask.mainOutputUnit;
1319
1320 // Emit all required typedef declarations into the main output unit.
1321 // TODO(karlklose): unify required classes and typedefs to declarations
1322 // and have builders for each kind.
1323 for (TypedefElement typedef in typedefsNeededForReflection) {
1324 OutputUnit mainUnit = compiler.deferredLoadTask.mainOutputUnit;
1325 LibraryElement library = typedef.library;
1326 // TODO(karlklose): add a TypedefBuilder and move this code there.
1327 DartType type = typedef.alias;
1328 int typeIndex = metadataEmitter.reifyType(type);
1329 String typeReference =
1330 encoding.encodeTypedefFieldDescriptor(typeIndex);
1331 jsAst.Property descriptor = new jsAst.Property(
1332 js.string(namer.classDescriptorProperty),
1333 js.string(typeReference));
1334 jsAst.Node declaration = new jsAst.ObjectInitializer([descriptor]);
1335 String mangledName = namer.getNameX(typedef);
1336 String reflectionName = getReflectionName(typedef, mangledName);
1337 getElementDescriptor(library)
1338 ..addProperty(mangledName, declaration)
1339 ..addProperty("+$reflectionName", js.string(''));
1340 // Also emit a trivial constructor for CSP mode.
1341 String constructorName = mangledName;
1342 jsAst.Expression constructorAst = js('function() {}');
1343 emitPrecompiledConstructor(mainOutputUnit,
1344 constructorName,
1345 constructorAst);
1346 }
1347 }
1348
1349 void emitMangledNames() {
1350 if (!mangledFieldNames.isEmpty) {
1351 var keys = mangledFieldNames.keys.toList();
1352 keys.sort();
1353 var properties = [];
1354 for (String key in keys) {
1355 var value = js.string('${mangledFieldNames[key]}');
1356 properties.add(new jsAst.Property(js.string(key), value));
1357 }
1358
1359 jsAst.Expression mangledNamesAccess =
1360 generateEmbeddedGlobalAccess(embeddedNames.MANGLED_NAMES);
1361 var map = new jsAst.ObjectInitializer(properties);
1362 mainBuffer.write(
1363 jsAst.prettyPrint(
1364 js.statement('# = #', [mangledNamesAccess, map]),
1365 compiler,
1366 monitor: compiler.dumpInfoTask));
1367 if (compiler.enableMinification) {
1368 mainBuffer.write(';');
1369 }
1370 }
1371 if (!mangledGlobalFieldNames.isEmpty) {
1372 var keys = mangledGlobalFieldNames.keys.toList();
1373 keys.sort();
1374 var properties = [];
1375 for (String key in keys) {
1376 var value = js.string('${mangledGlobalFieldNames[key]}');
1377 properties.add(new jsAst.Property(js.string(key), value));
1378 }
1379 jsAst.Expression mangledGlobalNamesAccess =
1380 generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES);
1381 var map = new jsAst.ObjectInitializer(properties);
1382 mainBuffer.write(
1383 jsAst.prettyPrint(
1384 js.statement('# = #', [mangledGlobalNamesAccess, map]),
1385 compiler,
1386 monitor: compiler.dumpInfoTask));
1387 if (compiler.enableMinification) {
1388 mainBuffer.write(';');
1389 }
1390 }
1391 }
1392
1393 void checkEverythingEmitted(Iterable<Element> elements) {
1394 List<Element> pendingStatics;
1395 if (!compiler.hasIncrementalSupport) {
1396 pendingStatics =
1397 Elements.sortedByPosition(elements.where((e) => !e.isLibrary));
1398
1399 pendingStatics.forEach((element) =>
1400 compiler.reportInfo(
1401 element, MessageKind.GENERIC, {'text': 'Pending statics.'}));
1402 }
1403
1404 if (pendingStatics != null && !pendingStatics.isEmpty) {
1405 compiler.internalError(pendingStatics.first,
1406 'Pending statics (see above).');
1407 }
1408 }
1409
1410 void emitMainOutputUnit(Map<OutputUnit, String> deferredLoadHashes,
1411 CodeBuffer nativeBuffer) {
1313 bool isProgramSplit = compiler.deferredLoadTask.isProgramSplit; 1412 bool isProgramSplit = compiler.deferredLoadTask.isProgramSplit;
1314 // Maps each output unit to a codebuffers with the library descriptors of
1315 // the output unit emitted to it.
1316 Map<OutputUnit, CodeBuffer> libraryDescriptorBuffers =
1317 new Map<OutputUnit, CodeBuffer>();
1318
1319 OutputUnit mainOutputUnit = compiler.deferredLoadTask.mainOutputUnit; 1413 OutputUnit mainOutputUnit = compiler.deferredLoadTask.mainOutputUnit;
1320 1414
1321 mainBuffer.add(buildGeneratedBy()); 1415 mainBuffer.add(buildGeneratedBy());
1322 addComment(HOOKS_API_USAGE, mainBuffer); 1416 addComment(HOOKS_API_USAGE, mainBuffer);
1323 1417
1324 if (isProgramSplit) { 1418 if (isProgramSplit) {
1325 /// For deferred loading we communicate the initializers via this global 1419 /// For deferred loading we communicate the initializers via this global
1326 /// variable. The deferred hunks will add their initialization to this. 1420 /// variable. The deferred hunks will add their initialization to this.
1327 /// The semicolon is important in minified mode, without it the 1421 /// The semicolon is important in minified mode, without it the
1328 /// following parenthesis looks like a call to the object literal. 1422 /// following parenthesis looks like a call to the object literal.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 } 1457 }
1364 1458
1365 mainBuffer.add('function ${namer.isolateName}()$_{}\n'); 1459 mainBuffer.add('function ${namer.isolateName}()$_{}\n');
1366 if (isProgramSplit) { 1460 if (isProgramSplit) {
1367 mainBuffer 1461 mainBuffer
1368 .write('${globalsHolder}.${namer.isolateName}$_=$_' 1462 .write('${globalsHolder}.${namer.isolateName}$_=$_'
1369 '${namer.isolateName}$N' 1463 '${namer.isolateName}$N'
1370 '${globalsHolder}.$initName$_=${_}$initName$N'); 1464 '${globalsHolder}.$initName$_=${_}$initName$N');
1371 } 1465 }
1372 mainBuffer.add('init()$N$n'); 1466 mainBuffer.add('init()$N$n');
1373 // Shorten the code by using [namer.currentIsolate] as temporary. 1467 mainBuffer.add('$isolateProperties$_=$_$isolatePropertiesName$N');
1374 isolateProperties = namer.currentIsolate;
1375 mainBuffer.add(
1376 '$isolateProperties$_=$_$isolatePropertiesName$N');
1377 1468
1378 emitStaticFunctions(); 1469 emitStaticFunctions(task.outputStaticLists[mainOutputUnit]);
1379 1470
1380 // Only output the classesCollector if we actually have any classes. 1471 // Only output the classesCollector if we actually have any classes.
1381 if (!(nativeClasses.isEmpty && 1472 if (!(nativeClasses.isEmpty &&
1382 compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty && 1473 compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty &&
1383 outputClassLists.values.every((classList) => classList.isEmpty) && 1474 outputClassLists.values.every((classList) => classList.isEmpty) &&
1384 typedefsNeededForReflection.isEmpty)) { 1475 typedefsNeededForReflection.isEmpty)) {
1385 // Shorten the code by using "$$" as temporary. 1476 // Shorten the code by using "$$" as temporary.
1386 classesCollector = r"$$"; 1477 classesCollector = r"$$";
1387 mainBuffer.add('var $classesCollector$_=${_}Object.create(null)$N$n'); 1478 mainBuffer.add('var $classesCollector$_=${_}Object.create(null)$N$n');
1388 } 1479 }
1389 1480
1390 // Emit native classes on [nativeBuffer].
1391 final CodeBuffer nativeBuffer = new CodeBuffer();
1392 if (!nativeClasses.isEmpty) { 1481 if (!nativeClasses.isEmpty) {
1393 addComment('Native classes', nativeBuffer);
1394 addComment('Native classes', mainBuffer); 1482 addComment('Native classes', mainBuffer);
1395 nativeEmitter.generateNativeClasses(nativeClasses, mainBuffer,
1396 additionalProperties);
1397 } 1483 }
1398 1484
1399 for (List<ClassElement> outputClassList in outputClassLists.values) { 1485 List<ClassElement> classes = task.outputClassLists[mainOutputUnit];
1400 for (ClassElement element in outputClassList) { 1486 if (classes != null) {
1487 for (ClassElement element in classes) {
1401 generateClass(element, getElementDescriptor(element)); 1488 generateClass(element, getElementDescriptor(element));
1402 } 1489 }
1403 } 1490 }
1404 1491
1405 nativeEmitter.finishGenerateNativeClasses(); 1492 if (compiler.enableMinification) {
1406 nativeEmitter.assembleCode(nativeBuffer); 1493 mainBuffer.write(';');
1494 }
1407 1495
1496 if (elementDescriptors.isNotEmpty) {
1497 Iterable<LibraryElement> libraries =
1498 task.outputLibraryLists[mainOutputUnit];
1499 if (libraries == null) libraries = [];
1500 emitLibraries(libraries);
1501 emitTypedefs();
1502 emitMangledNames();
1408 1503
1409 // After this assignment we will produce invalid JavaScript code if we use 1504 checkEverythingEmitted(elementDescriptors.keys);
1410 // the classesCollector variable.
1411 classesCollector = 'classesCollector should not be used from now on';
1412 1505
1413 // TODO(sigurdm): Need to check this for each outputUnit. 1506 CodeBuffer libraryBuffer = new CodeBuffer();
1414 if (!elementDescriptors.isEmpty) { 1507 for (LibraryElement library in Elements.sortedByPosition(libraries)) {
1415 var oldClassesCollector = classesCollector; 1508 writeLibraryDescriptors(libraryBuffer, library);
1416 classesCollector = r"$$"; 1509 elementDescriptors.remove(library);
1417 if (compiler.enableMinification) {
1418 mainBuffer.write(';');
1419 } 1510 }
1420 1511
1421 // TODO(karlklose): document what kinds of fields this loop adds to the
1422 // library class builder.
1423 for (Element element in elementDescriptors.keys) {
1424 // TODO(ahe): Should iterate over all libraries. Otherwise, we will
1425 // not see libraries that only have fields.
1426 if (element.isLibrary) {
1427 LibraryElement library = element;
1428 ClassBuilder builder = new ClassBuilder(library, namer);
1429 if (classEmitter.emitFields(
1430 library, builder, null, emitStatics: true)) {
1431 jsAst.ObjectInitializer initializer =
1432 builder.toObjectInitializer();
1433 compiler.dumpInfoTask.registerElementAst(builder.element,
1434 initializer);
1435 getElementDescriptor(library)
1436 .properties.addAll(initializer.properties);
1437 }
1438 }
1439 }
1440
1441 // Emit all required typedef declarations into the main output unit.
1442 // TODO(karlklose): unify required classes and typedefs to declarations
1443 // and have builders for each kind.
1444 for (TypedefElement typedef in typedefsNeededForReflection) {
1445 OutputUnit mainUnit = compiler.deferredLoadTask.mainOutputUnit;
1446 LibraryElement library = typedef.library;
1447 // TODO(karlklose): add a TypedefBuilder and move this code there.
1448 DartType type = typedef.alias;
1449 int typeIndex = metadataEmitter.reifyType(type);
1450 String typeReference =
1451 encoding.encodeTypedefFieldDescriptor(typeIndex);
1452 jsAst.Property descriptor = new jsAst.Property(
1453 js.string(namer.classDescriptorProperty),
1454 js.string(typeReference));
1455 jsAst.Node declaration = new jsAst.ObjectInitializer([descriptor]);
1456 String mangledName = namer.getNameX(typedef);
1457 String reflectionName = getReflectionName(typedef, mangledName);
1458 getElementDescriptor(library)
1459 ..addProperty(mangledName, declaration)
1460 ..addProperty("+$reflectionName", js.string(''));
1461 // Also emit a trivial constructor for CSP mode.
1462 String constructorName = mangledName;
1463 jsAst.Expression constructorAst = js('function() {}');
1464 emitPrecompiledConstructor(mainOutputUnit,
1465 constructorName,
1466 constructorAst);
1467 }
1468
1469 if (!mangledFieldNames.isEmpty) {
1470 var keys = mangledFieldNames.keys.toList();
1471 keys.sort();
1472 var properties = [];
1473 for (String key in keys) {
1474 var value = js.string('${mangledFieldNames[key]}');
1475 properties.add(new jsAst.Property(js.string(key), value));
1476 }
1477
1478 jsAst.Expression mangledNamesAccess =
1479 generateEmbeddedGlobalAccess(embeddedNames.MANGLED_NAMES);
1480 var map = new jsAst.ObjectInitializer(properties);
1481 mainBuffer.write(
1482 jsAst.prettyPrint(
1483 js.statement('# = #', [mangledNamesAccess, map]),
1484 compiler,
1485 monitor: compiler.dumpInfoTask));
1486 if (compiler.enableMinification) {
1487 mainBuffer.write(';');
1488 }
1489 }
1490 if (!mangledGlobalFieldNames.isEmpty) {
1491 var keys = mangledGlobalFieldNames.keys.toList();
1492 keys.sort();
1493 var properties = [];
1494 for (String key in keys) {
1495 var value = js.string('${mangledGlobalFieldNames[key]}');
1496 properties.add(new jsAst.Property(js.string(key), value));
1497 }
1498 jsAst.Expression mangledGlobalNamesAccess =
1499 generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES);
1500 var map = new jsAst.ObjectInitializer(properties);
1501 mainBuffer.write(
1502 jsAst.prettyPrint(
1503 js.statement('# = #', [mangledGlobalNamesAccess, map]),
1504 compiler,
1505 monitor: compiler.dumpInfoTask));
1506 if (compiler.enableMinification) {
1507 mainBuffer.write(';');
1508 }
1509 }
1510
1511 List<Element> sortedElements =
1512 Elements.sortedByPosition(elementDescriptors.keys);
1513
1514 Iterable<Element> pendingStatics;
1515 if (!compiler.hasIncrementalSupport) {
1516 pendingStatics = sortedElements.where((element) {
1517 return !element.isLibrary &&
1518 elementDescriptors[element].values.any((descriptor) =>
1519 descriptor != null);
1520 });
1521
1522 pendingStatics.forEach((element) =>
1523 compiler.reportInfo(
1524 element, MessageKind.GENERIC, {'text': 'Pending statics.'}));
1525 }
1526
1527 for (LibraryElement library in sortedElements.where((element) =>
1528 element.isLibrary)) {
1529 writeLibraryDescriptors(library, libraryDescriptorBuffers);
1530 elementDescriptors[library] = const {};
1531 }
1532 if (pendingStatics != null && !pendingStatics.isEmpty) {
1533 compiler.internalError(pendingStatics.first,
1534 'Pending statics (see above).');
1535 }
1536 mainBuffer 1512 mainBuffer
1537 ..write('(') 1513 ..write('(')
1538 ..write( 1514 ..write(
1539 jsAst.prettyPrint( 1515 jsAst.prettyPrint(
1540 getReflectionDataParser(classesCollector, backend), 1516 getReflectionDataParser(classesCollector, backend),
1541 compiler)) 1517 compiler))
1542 ..write(')') 1518 ..write(')')
1543 ..write('([$n') 1519 ..write('([$n')
1544 ..add(libraryDescriptorBuffers[mainOutputUnit]) 1520 ..add(libraryBuffer)
1545 ..write('])$N'); 1521 ..write('])$N');
1546 1522
1547 emitFinishClassesInvocationIfNecessary(mainBuffer); 1523 emitFinishClassesInvocationIfNecessary(mainBuffer);
1548 classesCollector = oldClassesCollector;
1549 } 1524 }
1525
1550 typeTestEmitter.emitRuntimeTypeSupport(mainBuffer, mainOutputUnit); 1526 typeTestEmitter.emitRuntimeTypeSupport(mainBuffer, mainOutputUnit);
1551 interceptorEmitter.emitGetInterceptorMethods(mainBuffer); 1527 interceptorEmitter.emitGetInterceptorMethods(mainBuffer);
1552 interceptorEmitter.emitOneShotInterceptors(mainBuffer); 1528 interceptorEmitter.emitOneShotInterceptors(mainBuffer);
1529
1530 if (task.outputContainsConstantList) {
1531 emitMakeConstantList(mainBuffer);
1532 }
1533
1553 // Constants in checked mode call into RTI code to set type information 1534 // Constants in checked mode call into RTI code to set type information
1554 // which may need getInterceptor (and one-shot interceptor) methods, so 1535 // which may need getInterceptor (and one-shot interceptor) methods, so
1555 // we have to make sure that [emitGetInterceptorMethods] and 1536 // we have to make sure that [emitGetInterceptorMethods] and
1556 // [emitOneShotInterceptors] have been called. 1537 // [emitOneShotInterceptors] have been called.
1557 emitCompileTimeConstants(mainBuffer, mainOutputUnit); 1538 emitCompileTimeConstants(mainBuffer, mainOutputUnit);
1558 1539
1559 if (isProgramSplit) { 1540 emitDeferredBoilerPlate(mainBuffer, deferredLoadHashes);
1560 /// Map from OutputUnit to a hash of its content. The hash uniquely
1561 /// identifies the code of the output-unit. It does not include
1562 /// boilerplate JS code, like the sourcemap directives or the hash
1563 /// itself.
1564 Map<OutputUnit, String> deferredLoadHashes =
1565 emitDeferredCode(libraryDescriptorBuffers);
1566 emitDeferredBoilerPlate(mainBuffer, deferredLoadHashes);
1567 }
1568 1541
1569 // Static field initializations require the classes and compile-time 1542 // Static field initializations require the classes and compile-time
1570 // constants to be set up. 1543 // constants to be set up.
1571 emitStaticNonFinalFieldInitializations(mainBuffer); 1544 emitStaticNonFinalFieldInitializations(mainBuffer);
1572 interceptorEmitter.emitInterceptedNames(mainBuffer); 1545 interceptorEmitter.emitInterceptedNames(mainBuffer);
1573 interceptorEmitter.emitMapTypeToInterceptor(mainBuffer); 1546 interceptorEmitter.emitMapTypeToInterceptor(mainBuffer);
1574 emitLazilyInitializedStaticFields(mainBuffer); 1547 emitLazilyInitializedStaticFields(mainBuffer);
1575 1548
1549 mainBuffer.writeln();
1576 mainBuffer.add(nativeBuffer); 1550 mainBuffer.add(nativeBuffer);
1577 1551
1578 metadataEmitter.emitMetadata(mainBuffer); 1552 metadataEmitter.emitMetadata(mainBuffer);
1579 1553
1580 isolateProperties = isolatePropertiesName; 1554 isolateProperties = isolatePropertiesName;
1581 // The following code should not use the short-hand for the 1555 // The following code should not use the short-hand for the
1582 // initialStatics. 1556 // initialStatics.
1583 mainBuffer.add('${namer.currentIsolate}$_=${_}null$N'); 1557 mainBuffer.add('${namer.currentIsolate}$_=${_}null$N');
1584 1558
1585 emitFinishIsolateConstructorInvocation(mainBuffer); 1559 emitFinishIsolateConstructorInvocation(mainBuffer);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1679 1653
1680 cspBuffer.write( 1654 cspBuffer.write(
1681 jsAst.prettyPrint( 1655 jsAst.prettyPrint(
1682 precompiledFunctionAst, compiler, 1656 precompiledFunctionAst, compiler,
1683 allowVariableMinification: false).getText()); 1657 allowVariableMinification: false).getText());
1684 1658
1685 compiler.outputProvider('', 'precompiled.js') 1659 compiler.outputProvider('', 'precompiled.js')
1686 ..add(cspBuffer.getText()) 1660 ..add(cspBuffer.getText())
1687 ..close(); 1661 ..close();
1688 } 1662 }
1663 }
1664
1665 /// Returns a map from OutputUnit to a hash of its content. The hash uniquely
1666 /// identifies the code of the output-unit. It does not include
1667 /// boilerplate JS code, like the sourcemap directives or the hash
1668 /// itself.
1669 Map<OutputUnit, String> emitDeferredOutputUnits() {
1670 if (!compiler.deferredLoadTask.isProgramSplit) return const {};
1671
1672 Map<OutputUnit, CodeBuffer> outputBuffers =
1673 new Map<OutputUnit, CodeBuffer>();
1674
1675 for (OutputUnit outputUnit in compiler.deferredLoadTask.allOutputUnits) {
1676 if (outputUnit == compiler.deferredLoadTask.mainOutputUnit) continue;
1677
1678 List<Element> functions = task.outputStaticLists[outputUnit];
1679 if (functions != null) {
1680 emitStaticFunctions(functions);
1681 }
1682
1683 List<ClassElement> classes = task.outputClassLists[outputUnit];
1684 if (classes != null) {
1685 for (ClassElement element in classes) {
1686 generateClass(element, getElementDescriptor(element));
1687 }
1688 }
1689
1690 if (elementDescriptors.isNotEmpty) {
1691 Iterable<LibraryElement> libraries =
1692 task.outputLibraryLists[outputUnit];
1693 if (libraries == null) libraries = [];
1694 emitLibraries(libraries);
1695
1696 CodeBuffer buffer = new CodeBuffer();
1697 outputBuffers[outputUnit] = buffer;
1698 for (LibraryElement library in Elements.sortedByPosition(libraries)) {
1699 writeLibraryDescriptors(buffer, library);
1700 elementDescriptors.remove(library);
1701 }
1702 }
1703 }
1704
1705 return emitDeferredCode(outputBuffers);
1706 }
1707
1708 CodeBuffer buildNativesBuffer() {
1709 // Emit native classes on [nativeBuffer].
1710 final CodeBuffer nativeBuffer = new CodeBuffer();
1711
1712 if (nativeClasses.isEmpty) return nativeBuffer;
1713
1714
1715 addComment('Native classes', nativeBuffer);
1716
1717 nativeEmitter.generateNativeClasses(nativeClasses, mainBuffer,
1718 additionalProperties);
1719
1720 nativeEmitter.finishGenerateNativeClasses();
1721 nativeEmitter.assembleCode(nativeBuffer);
1722
1723 return nativeBuffer;
1724 }
1725
1726 void emitProgram(Program program) {
1727 // Shorten the code by using [namer.currentIsolate] as temporary.
1728 isolateProperties = namer.currentIsolate;
1729
1730 classesCollector = r"$$";
1731
1732 // Emit deferred units first, so we have their hashes.
1733 // Map from OutputUnit to a hash of its content. The hash uniquely
1734 // identifies the code of the output-unit. It does not include
1735 // boilerplate JS code, like the sourcemap directives or the hash
1736 // itself.
1737 Map<OutputUnit, String> deferredLoadHashes = emitDeferredOutputUnits();
1738 CodeBuffer nativeBuffer = buildNativesBuffer();
1739 emitMainOutputUnit(deferredLoadHashes, nativeBuffer);
1689 1740
1690 if (backend.requiresPreamble && 1741 if (backend.requiresPreamble &&
1691 !backend.htmlLibraryIsLoaded) { 1742 !backend.htmlLibraryIsLoaded) {
1692 compiler.reportHint(NO_LOCATION_SPANNABLE, MessageKind.PREAMBLE); 1743 compiler.reportHint(NO_LOCATION_SPANNABLE, MessageKind.PREAMBLE);
1693 } 1744 }
1694 } 1745 }
1695 1746
1696 String generateSourceMapTag(Uri sourceMapUri, Uri fileUri) { 1747 String generateSourceMapTag(Uri sourceMapUri, Uri fileUri) {
1697 if (sourceMapUri != null && fileUri != null) { 1748 if (sourceMapUri != null && fileUri != null) {
1698 String sourceMapFileName = relativize(fileUri, sourceMapUri, false); 1749 String sourceMapFileName = relativize(fileUri, sourceMapUri, false);
1699 return ''' 1750 return '''
1700 1751
1701 //# sourceMappingURL=$sourceMapFileName 1752 //# sourceMappingURL=$sourceMapFileName
1702 '''; 1753 ''';
1703 } 1754 }
1704 return ''; 1755 return '';
1705 } 1756 }
1706 1757
1707 ClassBuilder getElementDescriptorForOutputUnit(Element element,
1708 OutputUnit outputUnit) {
1709 Map<OutputUnit, ClassBuilder> descriptors =
1710 elementDescriptors.putIfAbsent(
1711 element, () => new Map<OutputUnit, ClassBuilder>());
1712 return descriptors.putIfAbsent(outputUnit,
1713 () => new ClassBuilder(element, namer));
1714 }
1715
1716 ClassBuilder getElementDescriptor(Element element) { 1758 ClassBuilder getElementDescriptor(Element element) {
1717 Element owner = element.library; 1759 Element owner = element.library;
1718 if (!element.isLibrary && !element.isTopLevel && !element.isNative) { 1760 if (!element.isLibrary && !element.isTopLevel && !element.isNative) {
1719 // For static (not top level) elements, record their code in a buffer 1761 // For static (not top level) elements, record their code in a buffer
1720 // specific to the class. For now, not supported for native classes and 1762 // specific to the class. For now, not supported for native classes and
1721 // native elements. 1763 // native elements.
1722 ClassElement cls = 1764 ClassElement cls =
1723 element.enclosingClassOrCompilationUnit.declaration; 1765 element.enclosingClassOrCompilationUnit.declaration;
1724 if (compiler.codegenWorld.instantiatedClasses.contains(cls) 1766 if (compiler.codegenWorld.instantiatedClasses.contains(cls)
1725 && !cls.isNative) { 1767 && !cls.isNative) {
1726 owner = cls; 1768 owner = cls;
1727 } 1769 }
1728 } 1770 }
1729 if (owner == null) { 1771 if (owner == null) {
1730 compiler.internalError(element, 'Owner is null.'); 1772 compiler.internalError(element, 'Owner is null.');
1731 } 1773 }
1732 return getElementDescriptorForOutputUnit(owner, 1774 return elementDescriptors.putIfAbsent(
1733 compiler.deferredLoadTask.outputUnitForElement(element)); 1775 owner,
1776 () => new ClassBuilder(owner, namer));
1734 } 1777 }
1735 1778
1736 /// Emits support-code for deferred loading into [buffer]. 1779 /// Emits support-code for deferred loading into [buffer].
1737 void emitDeferredBoilerPlate(CodeBuffer buffer, 1780 void emitDeferredBoilerPlate(CodeBuffer buffer,
1738 Map<OutputUnit, String> deferredLoadHashes) { 1781 Map<OutputUnit, String> deferredLoadHashes) {
1739 // Function for checking if a hunk is loaded given its hash. 1782 // Function for checking if a hunk is loaded given its hash.
1740 buffer.write(jsAst.prettyPrint( 1783 buffer.write(jsAst.prettyPrint(
1741 js('# = function(hunkHash) {' 1784 js('# = function(hunkHash) {'
1742 ' return !!$deferredInitializers[hunkHash];' 1785 ' return !!$deferredInitializers[hunkHash];'
1743 '}', generateEmbeddedGlobalAccess(embeddedNames.IS_HUNK_LOADED)), 1786 '}', generateEmbeddedGlobalAccess(embeddedNames.IS_HUNK_LOADED)),
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1795 1838
1796 emitMapping(embeddedNames.DEFERRED_LIBRARY_URIS, deferredLibraryUris); 1839 emitMapping(embeddedNames.DEFERRED_LIBRARY_URIS, deferredLibraryUris);
1797 emitMapping(embeddedNames.DEFERRED_LIBRARY_HASHES, 1840 emitMapping(embeddedNames.DEFERRED_LIBRARY_HASHES,
1798 deferredLibraryHashes); 1841 deferredLibraryHashes);
1799 } 1842 }
1800 1843
1801 /// Emits code for all output units except the main. 1844 /// Emits code for all output units except the main.
1802 /// Returns a mapping from outputUnit to a hash of the corresponding hunk that 1845 /// Returns a mapping from outputUnit to a hash of the corresponding hunk that
1803 /// can be used for calling the initializer. 1846 /// can be used for calling the initializer.
1804 Map<OutputUnit, String> emitDeferredCode( 1847 Map<OutputUnit, String> emitDeferredCode(
1805 Map<OutputUnit, CodeBuffer> libraryDescriptorBuffers) { 1848 Map<OutputUnit, CodeBuffer> deferredBuffers) {
1806 1849
1807 Map<OutputUnit, String> hunkHashes = new Map<OutputUnit, String>(); 1850 Map<OutputUnit, String> hunkHashes = new Map<OutputUnit, String>();
1808 1851
1809 for (OutputUnit outputUnit in compiler.deferredLoadTask.allOutputUnits) { 1852 for (OutputUnit outputUnit in compiler.deferredLoadTask.allOutputUnits) {
1810 if (outputUnit == compiler.deferredLoadTask.mainOutputUnit) continue; 1853 if (outputUnit == compiler.deferredLoadTask.mainOutputUnit) continue;
1811 1854
1812 CodeBuffer libraryDescriptorBuffer = libraryDescriptorBuffers[outputUnit]; 1855 CodeBuffer libraryDescriptorBuffer = deferredBuffers[outputUnit];
1813 1856
1814 CodeBuffer outputBuffer = new CodeBuffer(); 1857 CodeBuffer outputBuffer = new CodeBuffer();
1815 1858
1816 var oldClassesCollector = classesCollector;
1817 classesCollector = r"$$";
1818
1819 outputBuffer..write(buildGeneratedBy()) 1859 outputBuffer..write(buildGeneratedBy())
1820 ..write('${deferredInitializers}.current$_=$_' 1860 ..write('${deferredInitializers}.current$_=$_'
1821 'function$_(${globalsHolder}) {$N'); 1861 'function$_(${globalsHolder}) {$N');
1822 for (String globalObject in Namer.reservedGlobalObjectNames) { 1862 for (String globalObject in Namer.reservedGlobalObjectNames) {
1823 outputBuffer 1863 outputBuffer
1824 .write('var $globalObject$_=$_' 1864 .write('var $globalObject$_=$_'
1825 '${globalsHolder}.$globalObject$N'); 1865 '${globalsHolder}.$globalObject$N');
1826 } 1866 }
1827 outputBuffer 1867 outputBuffer
1828 ..write('var init$_=$_${globalsHolder}.init$N') 1868 ..write('var init$_=$_${globalsHolder}.init$N')
(...skipping 19 matching lines...) Expand all
1848 ..write('])$N'); 1888 ..write('])$N');
1849 1889
1850 if (outputClassLists.containsKey(outputUnit)) { 1890 if (outputClassLists.containsKey(outputUnit)) {
1851 outputBuffer.write( 1891 outputBuffer.write(
1852 '$finishClassesName($classesCollector,$_${namer.currentIsolate},' 1892 '$finishClassesName($classesCollector,$_${namer.currentIsolate},'
1853 '$_$isolatePropertiesName)$N'); 1893 '$_$isolatePropertiesName)$N');
1854 } 1894 }
1855 1895
1856 } 1896 }
1857 1897
1858 classesCollector = oldClassesCollector;
1859
1860 // Set the currentIsolate variable to the current isolate (which is 1898 // Set the currentIsolate variable to the current isolate (which is
1861 // provided as second argument). 1899 // provided as second argument).
1862 // We need to do this, because we use the same variable for setting up 1900 // We need to do this, because we use the same variable for setting up
1863 // the isolate-properties and for storing the current isolate. During 1901 // the isolate-properties and for storing the current isolate. During
1864 // the setup (the code above this lines) we must set the variable to 1902 // the setup (the code above this lines) we must set the variable to
1865 // the isolate-properties. 1903 // the isolate-properties.
1866 // After we have done the setup (finishing with `finishClasses`) it must 1904 // After we have done the setup (finishing with `finishClasses`) it must
1867 // point to the current Isolate. Otherwise all methods/functions 1905 // point to the current Isolate. Otherwise all methods/functions
1868 // accessing isolate variables will access the wrong object. 1906 // accessing isolate variables will access the wrong object.
1869 outputBuffer.write("${namer.currentIsolate}$_=${_}arguments[1]$N"); 1907 outputBuffer.write("${namer.currentIsolate}$_=${_}arguments[1]$N");
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1955 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) { 1993 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) {
1956 if (element.isInstanceMember) { 1994 if (element.isInstanceMember) {
1957 cachedClassBuilders.remove(element.enclosingClass); 1995 cachedClassBuilders.remove(element.enclosingClass);
1958 1996
1959 nativeEmitter.cachedBuilders.remove(element.enclosingClass); 1997 nativeEmitter.cachedBuilders.remove(element.enclosingClass);
1960 1998
1961 } 1999 }
1962 } 2000 }
1963 } 2001 }
1964 } 2002 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698