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

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: Address comments. 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
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/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 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
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 compiler.dumpInfoTask.registerElementAst(library, metadata);
1245 1237 compiler.dumpInfoTask.registerElementAst(library, initializers);
1246 jsAst.ObjectInitializer initializers = descriptor.toObjectInitializer(); 1238 buffer
1247 1239 ..write('["$libraryName",$_')
1248 CodeBuffer libraryDescriptorBuffer = 1240 ..write('"${uri}",$_')
1249 libraryDescriptorBuffers.putIfAbsent(outputUnit, 1241 ..write(metadata == null ? "" : jsAst.prettyPrint(metadata,
1250 () => new CodeBuffer()); 1242 compiler,
1251 1243 monitor: compiler.dumpInfoTask))
1252 compiler.dumpInfoTask.registerElementAst(library, metadata); 1244 ..write(',$_')
1253 compiler.dumpInfoTask.registerElementAst(library, initializers); 1245 ..write(namer.globalObjectFor(library))
1254 libraryDescriptorBuffer 1246 ..write(',$_')
1255 ..write('["$libraryName",$_') 1247 ..write(jsAst.prettyPrint(initializers,
1256 ..write('"${uri}",$_') 1248 compiler,
1257 ..write(metadata == null ? "" : jsAst.prettyPrint(metadata, 1249 monitor: compiler.dumpInfoTask))
1258 compiler, 1250 ..write(library == compiler.mainApp ? ',${n}1' : "")
1259 monitor: compiler.dumpInfoTask)) 1251 ..write('],$n');
1260 ..write(',$_')
1261 ..write(namer.globalObjectFor(library))
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 } 1252 }
1270 1253
1271 void emitPrecompiledConstructor(OutputUnit outputUnit, 1254 void emitPrecompiledConstructor(OutputUnit outputUnit,
1272 String constructorName, 1255 String constructorName,
1273 jsAst.Expression constructorAst) { 1256 jsAst.Expression constructorAst) {
1274 cspPrecompiledFunctionFor(outputUnit).add( 1257 cspPrecompiledFunctionFor(outputUnit).add(
1275 new jsAst.FunctionDeclaration( 1258 new jsAst.FunctionDeclaration(
1276 new jsAst.VariableDeclaration(constructorName), constructorAst)); 1259 new jsAst.VariableDeclaration(constructorName), constructorAst));
1277 cspPrecompiledFunctionFor(outputUnit).add( 1260 cspPrecompiledFunctionFor(outputUnit).add(
1278 js.statement(r'''{ 1261 js.statement(r'''{
(...skipping 23 matching lines...) Expand all
1302 String outName = outPath.substring(outPath.lastIndexOf('/') + 1); 1285 String outName = outPath.substring(outPath.lastIndexOf('/') + 1);
1303 String extension = addExtension ? ".part.js" : ""; 1286 String extension = addExtension ? ".part.js" : "";
1304 if (outputUnit == compiler.deferredLoadTask.mainOutputUnit) { 1287 if (outputUnit == compiler.deferredLoadTask.mainOutputUnit) {
1305 return "$outName$extension"; 1288 return "$outName$extension";
1306 } else { 1289 } else {
1307 String name = outputUnit.name; 1290 String name = outputUnit.name;
1308 return "${outName}_$name$extension"; 1291 return "${outName}_$name$extension";
1309 } 1292 }
1310 } 1293 }
1311 1294
1312 void emitProgram(Program program) { 1295 void emitLibraries(Iterable<LibraryElement> libraries) {
1296 if (libraries.isEmpty) return;
1297
1298 // TODO(karlklose): document what kinds of fields this loop adds to the
1299 // library class builder.
1300 for (LibraryElement element in libraries) {
1301 LibraryElement library = element;
1302 ClassBuilder builder = new ClassBuilder(library, namer);
1303 if (classEmitter.emitFields(library, builder, null, emitStatics: true)) {
1304 jsAst.ObjectInitializer initializer = builder.toObjectInitializer();
1305 compiler.dumpInfoTask.registerElementAst(builder.element, initializer);
1306 getElementDescriptor(library).properties.addAll(initializer.properties);
1307 }
1308 }
1309 }
1310
1311 void emitTypedefs() {
1312 OutputUnit mainOutputUnit = compiler.deferredLoadTask.mainOutputUnit;
1313
1314 // Emit all required typedef declarations into the main output unit.
1315 // TODO(karlklose): unify required classes and typedefs to declarations
1316 // and have builders for each kind.
1317 for (TypedefElement typedef in typedefsNeededForReflection) {
1318 OutputUnit mainUnit = compiler.deferredLoadTask.mainOutputUnit;
1319 LibraryElement library = typedef.library;
1320 // TODO(karlklose): add a TypedefBuilder and move this code there.
1321 DartType type = typedef.alias;
1322 int typeIndex = metadataEmitter.reifyType(type);
1323 String typeReference =
1324 encoding.encodeTypedefFieldDescriptor(typeIndex);
1325 jsAst.Property descriptor = new jsAst.Property(
1326 js.string(namer.classDescriptorProperty),
1327 js.string(typeReference));
1328 jsAst.Node declaration = new jsAst.ObjectInitializer([descriptor]);
1329 String mangledName = namer.getNameX(typedef);
1330 String reflectionName = getReflectionName(typedef, mangledName);
1331 getElementDescriptor(library)
1332 ..addProperty(mangledName, declaration)
1333 ..addProperty("+$reflectionName", js.string(''));
1334 // Also emit a trivial constructor for CSP mode.
1335 String constructorName = mangledName;
1336 jsAst.Expression constructorAst = js('function() {}');
1337 emitPrecompiledConstructor(mainOutputUnit,
1338 constructorName,
1339 constructorAst);
1340 }
1341 }
1342
1343 void emitMangledNames() {
1344 if (!mangledFieldNames.isEmpty) {
1345 var keys = mangledFieldNames.keys.toList();
1346 keys.sort();
1347 var properties = [];
1348 for (String key in keys) {
1349 var value = js.string('${mangledFieldNames[key]}');
1350 properties.add(new jsAst.Property(js.string(key), value));
1351 }
1352
1353 jsAst.Expression mangledNamesAccess =
1354 generateEmbeddedGlobalAccess(embeddedNames.MANGLED_NAMES);
1355 var map = new jsAst.ObjectInitializer(properties);
1356 mainBuffer.write(
1357 jsAst.prettyPrint(
1358 js.statement('# = #', [mangledNamesAccess, map]),
1359 compiler,
1360 monitor: compiler.dumpInfoTask));
1361 if (compiler.enableMinification) {
1362 mainBuffer.write(';');
1363 }
1364 }
1365 if (!mangledGlobalFieldNames.isEmpty) {
1366 var keys = mangledGlobalFieldNames.keys.toList();
1367 keys.sort();
1368 var properties = [];
1369 for (String key in keys) {
1370 var value = js.string('${mangledGlobalFieldNames[key]}');
1371 properties.add(new jsAst.Property(js.string(key), value));
1372 }
1373 jsAst.Expression mangledGlobalNamesAccess =
1374 generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES);
1375 var map = new jsAst.ObjectInitializer(properties);
1376 mainBuffer.write(
1377 jsAst.prettyPrint(
1378 js.statement('# = #', [mangledGlobalNamesAccess, map]),
1379 compiler,
1380 monitor: compiler.dumpInfoTask));
1381 if (compiler.enableMinification) {
1382 mainBuffer.write(';');
1383 }
1384 }
1385 }
1386
1387 void checkEverythingEmitted(Iterable<Element> elements) {
1388 List<Element> pendingStatics;
1389 if (!compiler.hasIncrementalSupport) {
1390 pendingStatics =
1391 Elements.sortedByPosition(elements.where((e) => !e.isLibrary));
1392
1393 pendingStatics.forEach((element) =>
1394 compiler.reportInfo(
1395 element, MessageKind.GENERIC, {'text': 'Pending statics.'}));
1396 }
1397
1398 if (pendingStatics != null && !pendingStatics.isEmpty) {
1399 compiler.internalError(pendingStatics.first,
1400 'Pending statics (see above).');
1401 }
1402 }
1403
1404 void emitMainOutputUnit(Map<OutputUnit, String> deferredLoadHashes,
1405 CodeBuffer nativeBuffer) {
1313 bool isProgramSplit = compiler.deferredLoadTask.isProgramSplit; 1406 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; 1407 OutputUnit mainOutputUnit = compiler.deferredLoadTask.mainOutputUnit;
1320 1408
1321 mainBuffer.add(buildGeneratedBy()); 1409 mainBuffer.add(buildGeneratedBy());
1322 addComment(HOOKS_API_USAGE, mainBuffer); 1410 addComment(HOOKS_API_USAGE, mainBuffer);
1323 1411
1324 if (isProgramSplit) { 1412 if (isProgramSplit) {
1325 /// For deferred loading we communicate the initializers via this global 1413 /// For deferred loading we communicate the initializers via this global
1326 /// variable. The deferred hunks will add their initialization to this. 1414 /// variable. The deferred hunks will add their initialization to this.
1327 /// The semicolon is important in minified mode, without it the 1415 /// The semicolon is important in minified mode, without it the
1328 /// following parenthesis looks like a call to the object literal. 1416 /// following parenthesis looks like a call to the object literal.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 } 1451 }
1364 1452
1365 mainBuffer.add('function ${namer.isolateName}()$_{}\n'); 1453 mainBuffer.add('function ${namer.isolateName}()$_{}\n');
1366 if (isProgramSplit) { 1454 if (isProgramSplit) {
1367 mainBuffer 1455 mainBuffer
1368 .write('${globalsHolder}.${namer.isolateName}$_=$_' 1456 .write('${globalsHolder}.${namer.isolateName}$_=$_'
1369 '${namer.isolateName}$N' 1457 '${namer.isolateName}$N'
1370 '${globalsHolder}.$initName$_=${_}$initName$N'); 1458 '${globalsHolder}.$initName$_=${_}$initName$N');
1371 } 1459 }
1372 mainBuffer.add('init()$N$n'); 1460 mainBuffer.add('init()$N$n');
1373 // Shorten the code by using [namer.currentIsolate] as temporary. 1461 mainBuffer.add('$isolateProperties$_=$_$isolatePropertiesName$N');
1374 isolateProperties = namer.currentIsolate;
1375 mainBuffer.add(
1376 '$isolateProperties$_=$_$isolatePropertiesName$N');
1377 1462
1378 emitStaticFunctions(); 1463 emitStaticFunctions(task.outputStaticLists[mainOutputUnit]);
1379 1464
1380 // Only output the classesCollector if we actually have any classes. 1465 // Only output the classesCollector if we actually have any classes.
1381 if (!(nativeClasses.isEmpty && 1466 if (!(nativeClasses.isEmpty &&
1382 compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty && 1467 compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty &&
1383 outputClassLists.values.every((classList) => classList.isEmpty) && 1468 outputClassLists.values.every((classList) => classList.isEmpty) &&
1384 typedefsNeededForReflection.isEmpty)) { 1469 typedefsNeededForReflection.isEmpty)) {
1385 // Shorten the code by using "$$" as temporary. 1470 // Shorten the code by using "$$" as temporary.
1386 classesCollector = r"$$"; 1471 classesCollector = r"$$";
1387 mainBuffer.add('var $classesCollector$_=${_}Object.create(null)$N$n'); 1472 mainBuffer.add('var $classesCollector$_=${_}Object.create(null)$N$n');
1388 } 1473 }
1389 1474
1390 // Emit native classes on [nativeBuffer].
1391 final CodeBuffer nativeBuffer = new CodeBuffer();
1392 if (!nativeClasses.isEmpty) { 1475 if (!nativeClasses.isEmpty) {
1393 addComment('Native classes', nativeBuffer);
1394 addComment('Native classes', mainBuffer); 1476 addComment('Native classes', mainBuffer);
1395 nativeEmitter.generateNativeClasses(nativeClasses, mainBuffer,
1396 additionalProperties);
1397 } 1477 }
1398 1478
1399 for (List<ClassElement> outputClassList in outputClassLists.values) { 1479 List<ClassElement> classes = task.outputClassLists[mainOutputUnit];
1400 for (ClassElement element in outputClassList) { 1480 if (classes != null) {
1481 for (ClassElement element in classes) {
1401 generateClass(element, getElementDescriptor(element)); 1482 generateClass(element, getElementDescriptor(element));
1402 } 1483 }
1403 } 1484 }
1404 1485
1405 nativeEmitter.finishGenerateNativeClasses(); 1486 if (compiler.enableMinification) {
1406 nativeEmitter.assembleCode(nativeBuffer); 1487 mainBuffer.write(';');
1488 }
1407 1489
1490 if (elementDescriptors.isNotEmpty) {
1491 Iterable<LibraryElement> libraries =
1492 task.outputLibraryLists[mainOutputUnit];
1493 if (libraries == null) libraries = [];
1494 emitLibraries(libraries);
1495 emitTypedefs();
1496 emitMangledNames();
1408 1497
1409 // After this assignment we will produce invalid JavaScript code if we use 1498 checkEverythingEmitted(elementDescriptors.keys);
1410 // the classesCollector variable.
1411 classesCollector = 'classesCollector should not be used from now on';
1412 1499
1413 // TODO(sigurdm): Need to check this for each outputUnit. 1500 CodeBuffer libraryBuffer = new CodeBuffer();
1414 if (!elementDescriptors.isEmpty) { 1501 for (LibraryElement library in Elements.sortedByPosition(libraries)) {
1415 var oldClassesCollector = classesCollector; 1502 writeLibraryDescriptors(libraryBuffer, library);
1416 classesCollector = r"$$"; 1503 elementDescriptors.remove(library);
1417 if (compiler.enableMinification) {
1418 mainBuffer.write(';');
1419 } 1504 }
1420 1505
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 1506 mainBuffer
1537 ..write('(') 1507 ..write('(')
1538 ..write( 1508 ..write(
1539 jsAst.prettyPrint( 1509 jsAst.prettyPrint(
1540 getReflectionDataParser(classesCollector, backend), 1510 getReflectionDataParser(classesCollector, backend),
1541 compiler)) 1511 compiler))
1542 ..write(')') 1512 ..write(')')
1543 ..write('([$n') 1513 ..write('([$n')
1544 ..add(libraryDescriptorBuffers[mainOutputUnit]) 1514 ..add(libraryBuffer)
1545 ..write('])$N'); 1515 ..write('])$N');
1546 1516
1547 emitFinishClassesInvocationIfNecessary(mainBuffer); 1517 emitFinishClassesInvocationIfNecessary(mainBuffer);
1548 classesCollector = oldClassesCollector;
1549 } 1518 }
1519
1550 typeTestEmitter.emitRuntimeTypeSupport(mainBuffer, mainOutputUnit); 1520 typeTestEmitter.emitRuntimeTypeSupport(mainBuffer, mainOutputUnit);
1551 interceptorEmitter.emitGetInterceptorMethods(mainBuffer); 1521 interceptorEmitter.emitGetInterceptorMethods(mainBuffer);
1552 interceptorEmitter.emitOneShotInterceptors(mainBuffer); 1522 interceptorEmitter.emitOneShotInterceptors(mainBuffer);
1523
1524 if (task.outputContainsConstantList) {
1525 emitMakeConstantList(mainBuffer);
1526 }
1527
1553 // Constants in checked mode call into RTI code to set type information 1528 // Constants in checked mode call into RTI code to set type information
1554 // which may need getInterceptor (and one-shot interceptor) methods, so 1529 // which may need getInterceptor (and one-shot interceptor) methods, so
1555 // we have to make sure that [emitGetInterceptorMethods] and 1530 // we have to make sure that [emitGetInterceptorMethods] and
1556 // [emitOneShotInterceptors] have been called. 1531 // [emitOneShotInterceptors] have been called.
1557 emitCompileTimeConstants(mainBuffer, mainOutputUnit); 1532 emitCompileTimeConstants(mainBuffer, mainOutputUnit);
1558 1533
1559 if (isProgramSplit) { 1534 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 1535
1569 // Static field initializations require the classes and compile-time 1536 // Static field initializations require the classes and compile-time
1570 // constants to be set up. 1537 // constants to be set up.
1571 emitStaticNonFinalFieldInitializations(mainBuffer); 1538 emitStaticNonFinalFieldInitializations(mainBuffer);
1572 interceptorEmitter.emitInterceptedNames(mainBuffer); 1539 interceptorEmitter.emitInterceptedNames(mainBuffer);
1573 interceptorEmitter.emitMapTypeToInterceptor(mainBuffer); 1540 interceptorEmitter.emitMapTypeToInterceptor(mainBuffer);
1574 emitLazilyInitializedStaticFields(mainBuffer); 1541 emitLazilyInitializedStaticFields(mainBuffer);
1575 1542
1543 mainBuffer.writeln();
1576 mainBuffer.add(nativeBuffer); 1544 mainBuffer.add(nativeBuffer);
1577 1545
1578 metadataEmitter.emitMetadata(mainBuffer); 1546 metadataEmitter.emitMetadata(mainBuffer);
1579 1547
1580 isolateProperties = isolatePropertiesName; 1548 isolateProperties = isolatePropertiesName;
1581 // The following code should not use the short-hand for the 1549 // The following code should not use the short-hand for the
1582 // initialStatics. 1550 // initialStatics.
1583 mainBuffer.add('${namer.currentIsolate}$_=${_}null$N'); 1551 mainBuffer.add('${namer.currentIsolate}$_=${_}null$N');
1584 1552
1585 emitFinishIsolateConstructorInvocation(mainBuffer); 1553 emitFinishIsolateConstructorInvocation(mainBuffer);
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1679 1647
1680 cspBuffer.write( 1648 cspBuffer.write(
1681 jsAst.prettyPrint( 1649 jsAst.prettyPrint(
1682 precompiledFunctionAst, compiler, 1650 precompiledFunctionAst, compiler,
1683 allowVariableMinification: false).getText()); 1651 allowVariableMinification: false).getText());
1684 1652
1685 compiler.outputProvider('', 'precompiled.js') 1653 compiler.outputProvider('', 'precompiled.js')
1686 ..add(cspBuffer.getText()) 1654 ..add(cspBuffer.getText())
1687 ..close(); 1655 ..close();
1688 } 1656 }
1657 }
1658
1659 /// Returns a map from OutputUnit to a hash of its content. The hash uniquely
1660 /// identifies the code of the output-unit. It does not include
1661 /// boilerplate JS code, like the sourcemap directives or the hash
1662 /// itself.
1663 Map<OutputUnit, String> emitDeferredOutputUnits() {
1664 if (!compiler.deferredLoadTask.isProgramSplit) return const {};
1665
1666 Map<OutputUnit, CodeBuffer> outputBuffers =
1667 new Map<OutputUnit, CodeBuffer>();
1668
1669 for (OutputUnit outputUnit in compiler.deferredLoadTask.allOutputUnits) {
1670 if (outputUnit == compiler.deferredLoadTask.mainOutputUnit) continue;
1671
1672 List<Element> functions = task.outputStaticLists[outputUnit];
1673 if (functions != null) {
1674 emitStaticFunctions(functions);
1675 }
1676
1677 List<ClassElement> classes = task.outputClassLists[outputUnit];
1678 if (classes != null) {
1679 for (ClassElement element in classes) {
1680 generateClass(element, getElementDescriptor(element));
1681 }
1682 }
1683
1684 if (elementDescriptors.isNotEmpty) {
1685 Iterable<LibraryElement> libraries =
1686 task.outputLibraryLists[outputUnit];
1687 if (libraries == null) libraries = [];
1688 emitLibraries(libraries);
1689
1690 CodeBuffer buffer = new CodeBuffer();
1691 outputBuffers[outputUnit] = buffer;
1692 for (LibraryElement library in Elements.sortedByPosition(libraries)) {
1693 writeLibraryDescriptors(buffer, library);
1694 elementDescriptors.remove(library);
1695 }
1696 }
1697 }
1698
1699 return emitDeferredCode(outputBuffers);
1700 }
1701
1702 CodeBuffer buildNativesBuffer() {
1703 // Emit native classes on [nativeBuffer].
1704 final CodeBuffer nativeBuffer = new CodeBuffer();
1705
1706 if (nativeClasses.isEmpty) return nativeBuffer;
1707
1708
1709 addComment('Native classes', nativeBuffer);
1710
1711 nativeEmitter.generateNativeClasses(nativeClasses, mainBuffer,
1712 additionalProperties);
1713
1714 nativeEmitter.finishGenerateNativeClasses();
1715 nativeEmitter.assembleCode(nativeBuffer);
1716
1717 return nativeBuffer;
1718 }
1719
1720 void emitProgram(Program program) {
1721 // Shorten the code by using [namer.currentIsolate] as temporary.
1722 isolateProperties = namer.currentIsolate;
1723
1724 classesCollector = r"$$";
1725
1726 // Emit deferred units first, so we have their hashes.
1727 // Map from OutputUnit to a hash of its content. The hash uniquely
1728 // identifies the code of the output-unit. It does not include
1729 // boilerplate JS code, like the sourcemap directives or the hash
1730 // itself.
1731 Map<OutputUnit, String> deferredLoadHashes = emitDeferredOutputUnits();
1732 CodeBuffer nativeBuffer = buildNativesBuffer();
1733 emitMainOutputUnit(deferredLoadHashes, nativeBuffer);
1689 1734
1690 if (backend.requiresPreamble && 1735 if (backend.requiresPreamble &&
1691 !backend.htmlLibraryIsLoaded) { 1736 !backend.htmlLibraryIsLoaded) {
1692 compiler.reportHint(NO_LOCATION_SPANNABLE, MessageKind.PREAMBLE); 1737 compiler.reportHint(NO_LOCATION_SPANNABLE, MessageKind.PREAMBLE);
1693 } 1738 }
1694 } 1739 }
1695 1740
1696 String generateSourceMapTag(Uri sourceMapUri, Uri fileUri) { 1741 String generateSourceMapTag(Uri sourceMapUri, Uri fileUri) {
1697 if (sourceMapUri != null && fileUri != null) { 1742 if (sourceMapUri != null && fileUri != null) {
1698 String sourceMapFileName = relativize(fileUri, sourceMapUri, false); 1743 String sourceMapFileName = relativize(fileUri, sourceMapUri, false);
1699 return ''' 1744 return '''
1700 1745
1701 //# sourceMappingURL=$sourceMapFileName 1746 //# sourceMappingURL=$sourceMapFileName
1702 '''; 1747 ''';
1703 } 1748 }
1704 return ''; 1749 return '';
1705 } 1750 }
1706 1751
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) { 1752 ClassBuilder getElementDescriptor(Element element) {
1717 Element owner = element.library; 1753 Element owner = element.library;
1718 if (!element.isLibrary && !element.isTopLevel && !element.isNative) { 1754 if (!element.isLibrary && !element.isTopLevel && !element.isNative) {
1719 // For static (not top level) elements, record their code in a buffer 1755 // 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 1756 // specific to the class. For now, not supported for native classes and
1721 // native elements. 1757 // native elements.
1722 ClassElement cls = 1758 ClassElement cls =
1723 element.enclosingClassOrCompilationUnit.declaration; 1759 element.enclosingClassOrCompilationUnit.declaration;
1724 if (compiler.codegenWorld.directlyInstantiatedClasses.contains(cls) 1760 if (compiler.codegenWorld.directlyInstantiatedClasses.contains(cls)
1725 && !cls.isNative) { 1761 && !cls.isNative) {
1726 owner = cls; 1762 owner = cls;
1727 } 1763 }
1728 } 1764 }
1729 if (owner == null) { 1765 if (owner == null) {
1730 compiler.internalError(element, 'Owner is null.'); 1766 compiler.internalError(element, 'Owner is null.');
1731 } 1767 }
1732 return getElementDescriptorForOutputUnit(owner, 1768 return elementDescriptors.putIfAbsent(
1733 compiler.deferredLoadTask.outputUnitForElement(element)); 1769 owner,
1770 () => new ClassBuilder(owner, namer));
1734 } 1771 }
1735 1772
1736 /// Emits support-code for deferred loading into [buffer]. 1773 /// Emits support-code for deferred loading into [buffer].
1737 void emitDeferredBoilerPlate(CodeBuffer buffer, 1774 void emitDeferredBoilerPlate(CodeBuffer buffer,
1738 Map<OutputUnit, String> deferredLoadHashes) { 1775 Map<OutputUnit, String> deferredLoadHashes) {
1739 // Function for checking if a hunk is loaded given its hash. 1776 // Function for checking if a hunk is loaded given its hash.
1740 buffer.write(jsAst.prettyPrint( 1777 buffer.write(jsAst.prettyPrint(
1741 js('# = function(hunkHash) {' 1778 js('# = function(hunkHash) {'
1742 ' return !!$deferredInitializers[hunkHash];' 1779 ' return !!$deferredInitializers[hunkHash];'
1743 '}', generateEmbeddedGlobalAccess(embeddedNames.IS_HUNK_LOADED)), 1780 '}', generateEmbeddedGlobalAccess(embeddedNames.IS_HUNK_LOADED)),
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1795 1832
1796 emitMapping(embeddedNames.DEFERRED_LIBRARY_URIS, deferredLibraryUris); 1833 emitMapping(embeddedNames.DEFERRED_LIBRARY_URIS, deferredLibraryUris);
1797 emitMapping(embeddedNames.DEFERRED_LIBRARY_HASHES, 1834 emitMapping(embeddedNames.DEFERRED_LIBRARY_HASHES,
1798 deferredLibraryHashes); 1835 deferredLibraryHashes);
1799 } 1836 }
1800 1837
1801 /// Emits code for all output units except the main. 1838 /// Emits code for all output units except the main.
1802 /// Returns a mapping from outputUnit to a hash of the corresponding hunk that 1839 /// Returns a mapping from outputUnit to a hash of the corresponding hunk that
1803 /// can be used for calling the initializer. 1840 /// can be used for calling the initializer.
1804 Map<OutputUnit, String> emitDeferredCode( 1841 Map<OutputUnit, String> emitDeferredCode(
1805 Map<OutputUnit, CodeBuffer> libraryDescriptorBuffers) { 1842 Map<OutputUnit, CodeBuffer> deferredBuffers) {
1806 1843
1807 Map<OutputUnit, String> hunkHashes = new Map<OutputUnit, String>(); 1844 Map<OutputUnit, String> hunkHashes = new Map<OutputUnit, String>();
1808 1845
1809 for (OutputUnit outputUnit in compiler.deferredLoadTask.allOutputUnits) { 1846 for (OutputUnit outputUnit in compiler.deferredLoadTask.allOutputUnits) {
1810 if (outputUnit == compiler.deferredLoadTask.mainOutputUnit) continue; 1847 if (outputUnit == compiler.deferredLoadTask.mainOutputUnit) continue;
1811 1848
1812 CodeBuffer libraryDescriptorBuffer = libraryDescriptorBuffers[outputUnit]; 1849 CodeBuffer libraryDescriptorBuffer = deferredBuffers[outputUnit];
1813 1850
1814 CodeBuffer outputBuffer = new CodeBuffer(); 1851 CodeBuffer outputBuffer = new CodeBuffer();
1815 1852
1816 var oldClassesCollector = classesCollector;
1817 classesCollector = r"$$";
1818
1819 outputBuffer..write(buildGeneratedBy()) 1853 outputBuffer..write(buildGeneratedBy())
1820 ..write('${deferredInitializers}.current$_=$_' 1854 ..write('${deferredInitializers}.current$_=$_'
1821 'function$_(${globalsHolder}) {$N'); 1855 'function$_(${globalsHolder}) {$N');
1822 for (String globalObject in Namer.reservedGlobalObjectNames) { 1856 for (String globalObject in Namer.reservedGlobalObjectNames) {
1823 outputBuffer 1857 outputBuffer
1824 .write('var $globalObject$_=$_' 1858 .write('var $globalObject$_=$_'
1825 '${globalsHolder}.$globalObject$N'); 1859 '${globalsHolder}.$globalObject$N');
1826 } 1860 }
1827 outputBuffer 1861 outputBuffer
1828 ..write('var init$_=$_${globalsHolder}.init$N') 1862 ..write('var init$_=$_${globalsHolder}.init$N')
(...skipping 19 matching lines...) Expand all
1848 ..write('])$N'); 1882 ..write('])$N');
1849 1883
1850 if (outputClassLists.containsKey(outputUnit)) { 1884 if (outputClassLists.containsKey(outputUnit)) {
1851 outputBuffer.write( 1885 outputBuffer.write(
1852 '$finishClassesName($classesCollector,$_${namer.currentIsolate},' 1886 '$finishClassesName($classesCollector,$_${namer.currentIsolate},'
1853 '$_$isolatePropertiesName)$N'); 1887 '$_$isolatePropertiesName)$N');
1854 } 1888 }
1855 1889
1856 } 1890 }
1857 1891
1858 classesCollector = oldClassesCollector;
1859
1860 // Set the currentIsolate variable to the current isolate (which is 1892 // Set the currentIsolate variable to the current isolate (which is
1861 // provided as second argument). 1893 // provided as second argument).
1862 // We need to do this, because we use the same variable for setting up 1894 // 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 1895 // the isolate-properties and for storing the current isolate. During
1864 // the setup (the code above this lines) we must set the variable to 1896 // the setup (the code above this lines) we must set the variable to
1865 // the isolate-properties. 1897 // the isolate-properties.
1866 // After we have done the setup (finishing with `finishClasses`) it must 1898 // After we have done the setup (finishing with `finishClasses`) it must
1867 // point to the current Isolate. Otherwise all methods/functions 1899 // point to the current Isolate. Otherwise all methods/functions
1868 // accessing isolate variables will access the wrong object. 1900 // accessing isolate variables will access the wrong object.
1869 outputBuffer.write("${namer.currentIsolate}$_=${_}arguments[1]$N"); 1901 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) { 1987 for (Element element in compiler.enqueuer.codegen.newlyEnqueuedElements) {
1956 if (element.isInstanceMember) { 1988 if (element.isInstanceMember) {
1957 cachedClassBuilders.remove(element.enclosingClass); 1989 cachedClassBuilders.remove(element.enclosingClass);
1958 1990
1959 nativeEmitter.cachedBuilders.remove(element.enclosingClass); 1991 nativeEmitter.cachedBuilders.remove(element.enclosingClass);
1960 1992
1961 } 1993 }
1962 } 1994 }
1963 } 1995 }
1964 } 1996 }
OLDNEW
« no previous file with comments | « sdk/lib/_internal/compiler/implementation/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