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

Unified 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/_internal/compiler/implementation/js_emitter/old_emitter/emitter.dart
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/old_emitter/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/old_emitter/emitter.dart
index b7b5e736e514683d2bc7450b50c0bc7dbf844cb1..ff746b282f03c1e6785b835ff63c7a25b8777dcd 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/old_emitter/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/old_emitter/emitter.dart
@@ -83,22 +83,17 @@ class OldEmitter implements Emitter {
Map<OutputUnit, List<jsAst.Expression>> _cspPrecompiledConstructorNames =
new Map<OutputUnit, List<jsAst.Expression>>();
- // True if Isolate.makeConstantList is needed.
- bool hasMakeConstantList = false;
-
/**
* Accumulate properties for classes and libraries, describing their
* static/top-level members.
* Later, these members are emitted when the class or library is emitted.
*
- * For supporting deferred loading we keep one list per output unit.
- *
- * See [getElementDecriptor].
+ * See [getElementDescriptor].
*/
// TODO(ahe): Generate statics with their class, and store only libraries in
// this map.
- final Map<Element, Map<OutputUnit, ClassBuilder>> elementDescriptors
- = new Map<Element, Map<OutputUnit, ClassBuilder>>();
+ final Map<Element, ClassBuilder> elementDescriptors =
+ new Map<Element, ClassBuilder>();
final bool generateSourceMap;
@@ -581,7 +576,7 @@ class OldEmitter implements Emitter {
// isolateProperties themselves.
return js('''
function (oldIsolate) {
- var isolateProperties = oldIsolate.#;
+ var isolateProperties = oldIsolate.#; // isolatePropertiesName
function Isolate() {
var hasOwnProperty = Object.prototype.hasOwnProperty;
for (var staticName in isolateProperties)
@@ -613,16 +608,17 @@ class OldEmitter implements Emitter {
}
Isolate.prototype = oldIsolate.prototype;
Isolate.prototype.constructor = Isolate;
- Isolate.# = isolateProperties;
- if (#)
- Isolate.# = oldIsolate.#;
- if (#)
- Isolate.# = oldIsolate.#;
+ Isolate.# = isolateProperties; // isolatePropertiesName
+ if (#) // needsDefineClass.
+ Isolate.# = oldIsolate.#; // finishClassesProperty * 2
+ if (#) // outputContainsConstantList
+ Isolate.# = oldIsolate.#; // makeConstListProperty * 2
return Isolate;
}''',
[namer.isolatePropertiesName, namer.isolatePropertiesName,
needsDefineClass, finishClassesProperty, finishClassesProperty,
- hasMakeConstantList, makeConstListProperty, makeConstListProperty ]);
+ task.outputContainsConstantList,
+ makeConstListProperty, makeConstListProperty ]);
}
jsAst.Fun get lazyInitializerFunction {
@@ -877,14 +873,8 @@ class OldEmitter implements Emitter {
}
}
- void emitStaticFunctions() {
- bool isStaticFunction(Element element) =>
- !element.isInstanceMember && !element.isField;
-
- Iterable<Element> elements =
- backend.generatedCode.keys.where(isStaticFunction);
-
- for (Element element in Elements.sortedByPosition(elements)) {
+ void emitStaticFunctions(List<Element> staticFunctions) {
+ for (Element element in staticFunctions) {
ClassBuilder builder = new ClassBuilder(element, namer);
containerBuilder.addMember(element, builder);
getElementDescriptor(element).properties.addAll(builder.properties);
@@ -997,7 +987,6 @@ class OldEmitter implements Emitter {
cachedEmittedConstants.add(constant);
}
String name = namer.constantName(constant);
- if (constant.isList) emitMakeConstantListIfNotEmitted(buffer);
jsAst.Expression init = js('#.# = #',
[namer.globalObjectForConstant(constant), name,
constantInitializerExpression(constant)]);
@@ -1010,9 +999,7 @@ class OldEmitter implements Emitter {
}
}
- void emitMakeConstantListIfNotEmitted(CodeBuffer buffer) {
- if (hasMakeConstantList) return;
- hasMakeConstantList = true;
+ void emitMakeConstantList(CodeBuffer buffer) {
buffer.write(
jsAst.prettyPrint(
js.statement(r'''#.# = function(list) {
@@ -1220,9 +1207,7 @@ class OldEmitter implements Emitter {
mainBuffer.add(N);
}
- void writeLibraryDescriptors(
- LibraryElement library,
- Map<OutputUnit, CodeBuffer> libraryDescriptorBuffers) {
+ void writeLibraryDescriptors(CodeBuffer buffer, LibraryElement library) {
var uri = "";
if (!compiler.enableMinification || backend.mustRetainUris) {
uri = library.canonicalUri;
@@ -1230,42 +1215,40 @@ class OldEmitter implements Emitter {
uri = relativize(compiler.outputUri, library.canonicalUri, false);
}
}
- Map<OutputUnit, ClassBuilder> descriptors = elementDescriptors[library];
+ ClassBuilder descriptor = elementDescriptors[library];
+ if (descriptor == null) {
+ // Nothing of the library was emitted.
+ // TODO(floitsch): this should not happen. We currently have an example
+ // with language/prefix6_negative_test.dart where we have an instance
+ // method without its corresponding class.
+ return;
+ }
+
String libraryName =
(!compiler.enableMinification || backend.mustRetainLibraryNames) ?
library.getLibraryName() :
"";
- for (OutputUnit outputUnit in compiler.deferredLoadTask.allOutputUnits) {
- if (!descriptors.containsKey(outputUnit)) continue;
-
- ClassBuilder descriptor = descriptors[outputUnit];
-
- jsAst.Fun metadata = metadataEmitter.buildMetadataFunction(library);
-
- jsAst.ObjectInitializer initializers = descriptor.toObjectInitializer();
-
- CodeBuffer libraryDescriptorBuffer =
- libraryDescriptorBuffers.putIfAbsent(outputUnit,
- () => new CodeBuffer());
-
- compiler.dumpInfoTask.registerElementAst(library, metadata);
- compiler.dumpInfoTask.registerElementAst(library, initializers);
- libraryDescriptorBuffer
- ..write('["$libraryName",$_')
- ..write('"${uri}",$_')
- ..write(metadata == null ? "" : jsAst.prettyPrint(metadata,
- compiler,
- monitor: compiler.dumpInfoTask))
- ..write(',$_')
- ..write(namer.globalObjectFor(library))
- ..write(',$_')
- ..write(jsAst.prettyPrint(initializers,
- compiler,
- monitor: compiler.dumpInfoTask))
- ..write(library == compiler.mainApp ? ',${n}1' : "")
- ..write('],$n');
- }
+ jsAst.Fun metadata = metadataEmitter.buildMetadataFunction(library);
+
+ jsAst.ObjectInitializer initializers = descriptor.toObjectInitializer();
+
+ compiler.dumpInfoTask.registerElementAst(library, metadata);
+ compiler.dumpInfoTask.registerElementAst(library, initializers);
+ buffer
+ ..write('["$libraryName",$_')
+ ..write('"${uri}",$_')
+ ..write(metadata == null ? "" : jsAst.prettyPrint(metadata,
+ compiler,
+ monitor: compiler.dumpInfoTask))
+ ..write(',$_')
+ ..write(namer.globalObjectFor(library))
+ ..write(',$_')
+ ..write(jsAst.prettyPrint(initializers,
+ compiler,
+ monitor: compiler.dumpInfoTask))
+ ..write(library == compiler.mainApp ? ',${n}1' : "")
+ ..write('],$n');
}
void emitPrecompiledConstructor(OutputUnit outputUnit,
@@ -1309,13 +1292,118 @@ class OldEmitter implements Emitter {
}
}
- void emitProgram(Program program) {
- bool isProgramSplit = compiler.deferredLoadTask.isProgramSplit;
- // Maps each output unit to a codebuffers with the library descriptors of
- // the output unit emitted to it.
- Map<OutputUnit, CodeBuffer> libraryDescriptorBuffers =
- new Map<OutputUnit, CodeBuffer>();
+ void emitLibraries(Iterable<LibraryElement> libraries) {
+ if (libraries.isEmpty) return;
+
+ // TODO(karlklose): document what kinds of fields this loop adds to the
+ // library class builder.
+ for (LibraryElement element in libraries) {
+ LibraryElement library = element;
+ ClassBuilder builder = new ClassBuilder(library, namer);
+ if (classEmitter.emitFields(library, builder, null, emitStatics: true)) {
+ jsAst.ObjectInitializer initializer = builder.toObjectInitializer();
+ compiler.dumpInfoTask.registerElementAst(builder.element, initializer);
+ getElementDescriptor(library).properties.addAll(initializer.properties);
+ }
+ }
+ }
+ void emitTypedefs() {
+ OutputUnit mainOutputUnit = compiler.deferredLoadTask.mainOutputUnit;
+
+ // Emit all required typedef declarations into the main output unit.
+ // TODO(karlklose): unify required classes and typedefs to declarations
+ // and have builders for each kind.
+ for (TypedefElement typedef in typedefsNeededForReflection) {
+ OutputUnit mainUnit = compiler.deferredLoadTask.mainOutputUnit;
+ LibraryElement library = typedef.library;
+ // TODO(karlklose): add a TypedefBuilder and move this code there.
+ DartType type = typedef.alias;
+ int typeIndex = metadataEmitter.reifyType(type);
+ String typeReference =
+ encoding.encodeTypedefFieldDescriptor(typeIndex);
+ jsAst.Property descriptor = new jsAst.Property(
+ js.string(namer.classDescriptorProperty),
+ js.string(typeReference));
+ jsAst.Node declaration = new jsAst.ObjectInitializer([descriptor]);
+ String mangledName = namer.getNameX(typedef);
+ String reflectionName = getReflectionName(typedef, mangledName);
+ getElementDescriptor(library)
+ ..addProperty(mangledName, declaration)
+ ..addProperty("+$reflectionName", js.string(''));
+ // Also emit a trivial constructor for CSP mode.
+ String constructorName = mangledName;
+ jsAst.Expression constructorAst = js('function() {}');
+ emitPrecompiledConstructor(mainOutputUnit,
+ constructorName,
+ constructorAst);
+ }
+ }
+
+ void emitMangledNames() {
+ if (!mangledFieldNames.isEmpty) {
+ var keys = mangledFieldNames.keys.toList();
+ keys.sort();
+ var properties = [];
+ for (String key in keys) {
+ var value = js.string('${mangledFieldNames[key]}');
+ properties.add(new jsAst.Property(js.string(key), value));
+ }
+
+ jsAst.Expression mangledNamesAccess =
+ generateEmbeddedGlobalAccess(embeddedNames.MANGLED_NAMES);
+ var map = new jsAst.ObjectInitializer(properties);
+ mainBuffer.write(
+ jsAst.prettyPrint(
+ js.statement('# = #', [mangledNamesAccess, map]),
+ compiler,
+ monitor: compiler.dumpInfoTask));
+ if (compiler.enableMinification) {
+ mainBuffer.write(';');
+ }
+ }
+ if (!mangledGlobalFieldNames.isEmpty) {
+ var keys = mangledGlobalFieldNames.keys.toList();
+ keys.sort();
+ var properties = [];
+ for (String key in keys) {
+ var value = js.string('${mangledGlobalFieldNames[key]}');
+ properties.add(new jsAst.Property(js.string(key), value));
+ }
+ jsAst.Expression mangledGlobalNamesAccess =
+ generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES);
+ var map = new jsAst.ObjectInitializer(properties);
+ mainBuffer.write(
+ jsAst.prettyPrint(
+ js.statement('# = #', [mangledGlobalNamesAccess, map]),
+ compiler,
+ monitor: compiler.dumpInfoTask));
+ if (compiler.enableMinification) {
+ mainBuffer.write(';');
+ }
+ }
+ }
+
+ void checkEverythingEmitted(Iterable<Element> elements) {
+ List<Element> pendingStatics;
+ if (!compiler.hasIncrementalSupport) {
+ pendingStatics =
+ Elements.sortedByPosition(elements.where((e) => !e.isLibrary));
+
+ pendingStatics.forEach((element) =>
+ compiler.reportInfo(
+ element, MessageKind.GENERIC, {'text': 'Pending statics.'}));
+ }
+
+ if (pendingStatics != null && !pendingStatics.isEmpty) {
+ compiler.internalError(pendingStatics.first,
+ 'Pending statics (see above).');
+ }
+ }
+
+ void emitMainOutputUnit(Map<OutputUnit, String> deferredLoadHashes,
+ CodeBuffer nativeBuffer) {
+ bool isProgramSplit = compiler.deferredLoadTask.isProgramSplit;
OutputUnit mainOutputUnit = compiler.deferredLoadTask.mainOutputUnit;
mainBuffer.add(buildGeneratedBy());
@@ -1370,169 +1458,51 @@ class OldEmitter implements Emitter {
'${globalsHolder}.$initName$_=${_}$initName$N');
}
mainBuffer.add('init()$N$n');
- // Shorten the code by using [namer.currentIsolate] as temporary.
- isolateProperties = namer.currentIsolate;
- mainBuffer.add(
- '$isolateProperties$_=$_$isolatePropertiesName$N');
+ mainBuffer.add('$isolateProperties$_=$_$isolatePropertiesName$N');
- emitStaticFunctions();
+ emitStaticFunctions(task.outputStaticLists[mainOutputUnit]);
// Only output the classesCollector if we actually have any classes.
if (!(nativeClasses.isEmpty &&
compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty &&
- outputClassLists.values.every((classList) => classList.isEmpty) &&
- typedefsNeededForReflection.isEmpty)) {
+ outputClassLists.values.every((classList) => classList.isEmpty) &&
+ typedefsNeededForReflection.isEmpty)) {
// Shorten the code by using "$$" as temporary.
classesCollector = r"$$";
mainBuffer.add('var $classesCollector$_=${_}Object.create(null)$N$n');
}
- // Emit native classes on [nativeBuffer].
- final CodeBuffer nativeBuffer = new CodeBuffer();
if (!nativeClasses.isEmpty) {
- addComment('Native classes', nativeBuffer);
addComment('Native classes', mainBuffer);
- nativeEmitter.generateNativeClasses(nativeClasses, mainBuffer,
- additionalProperties);
}
- for (List<ClassElement> outputClassList in outputClassLists.values) {
- for (ClassElement element in outputClassList) {
+ List<ClassElement> classes = task.outputClassLists[mainOutputUnit];
+ if (classes != null) {
+ for (ClassElement element in classes) {
generateClass(element, getElementDescriptor(element));
}
}
- nativeEmitter.finishGenerateNativeClasses();
- nativeEmitter.assembleCode(nativeBuffer);
-
-
- // After this assignment we will produce invalid JavaScript code if we use
- // the classesCollector variable.
- classesCollector = 'classesCollector should not be used from now on';
-
- // TODO(sigurdm): Need to check this for each outputUnit.
- if (!elementDescriptors.isEmpty) {
- var oldClassesCollector = classesCollector;
- classesCollector = r"$$";
- if (compiler.enableMinification) {
- mainBuffer.write(';');
- }
-
- // TODO(karlklose): document what kinds of fields this loop adds to the
- // library class builder.
- for (Element element in elementDescriptors.keys) {
- // TODO(ahe): Should iterate over all libraries. Otherwise, we will
- // not see libraries that only have fields.
- if (element.isLibrary) {
- LibraryElement library = element;
- ClassBuilder builder = new ClassBuilder(library, namer);
- if (classEmitter.emitFields(
- library, builder, null, emitStatics: true)) {
- jsAst.ObjectInitializer initializer =
- builder.toObjectInitializer();
- compiler.dumpInfoTask.registerElementAst(builder.element,
- initializer);
- getElementDescriptor(library)
- .properties.addAll(initializer.properties);
- }
- }
- }
-
- // Emit all required typedef declarations into the main output unit.
- // TODO(karlklose): unify required classes and typedefs to declarations
- // and have builders for each kind.
- for (TypedefElement typedef in typedefsNeededForReflection) {
- OutputUnit mainUnit = compiler.deferredLoadTask.mainOutputUnit;
- LibraryElement library = typedef.library;
- // TODO(karlklose): add a TypedefBuilder and move this code there.
- DartType type = typedef.alias;
- int typeIndex = metadataEmitter.reifyType(type);
- String typeReference =
- encoding.encodeTypedefFieldDescriptor(typeIndex);
- jsAst.Property descriptor = new jsAst.Property(
- js.string(namer.classDescriptorProperty),
- js.string(typeReference));
- jsAst.Node declaration = new jsAst.ObjectInitializer([descriptor]);
- String mangledName = namer.getNameX(typedef);
- String reflectionName = getReflectionName(typedef, mangledName);
- getElementDescriptor(library)
- ..addProperty(mangledName, declaration)
- ..addProperty("+$reflectionName", js.string(''));
- // Also emit a trivial constructor for CSP mode.
- String constructorName = mangledName;
- jsAst.Expression constructorAst = js('function() {}');
- emitPrecompiledConstructor(mainOutputUnit,
- constructorName,
- constructorAst);
- }
-
- if (!mangledFieldNames.isEmpty) {
- var keys = mangledFieldNames.keys.toList();
- keys.sort();
- var properties = [];
- for (String key in keys) {
- var value = js.string('${mangledFieldNames[key]}');
- properties.add(new jsAst.Property(js.string(key), value));
- }
-
- jsAst.Expression mangledNamesAccess =
- generateEmbeddedGlobalAccess(embeddedNames.MANGLED_NAMES);
- var map = new jsAst.ObjectInitializer(properties);
- mainBuffer.write(
- jsAst.prettyPrint(
- js.statement('# = #', [mangledNamesAccess, map]),
- compiler,
- monitor: compiler.dumpInfoTask));
- if (compiler.enableMinification) {
- mainBuffer.write(';');
- }
- }
- if (!mangledGlobalFieldNames.isEmpty) {
- var keys = mangledGlobalFieldNames.keys.toList();
- keys.sort();
- var properties = [];
- for (String key in keys) {
- var value = js.string('${mangledGlobalFieldNames[key]}');
- properties.add(new jsAst.Property(js.string(key), value));
- }
- jsAst.Expression mangledGlobalNamesAccess =
- generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES);
- var map = new jsAst.ObjectInitializer(properties);
- mainBuffer.write(
- jsAst.prettyPrint(
- js.statement('# = #', [mangledGlobalNamesAccess, map]),
- compiler,
- monitor: compiler.dumpInfoTask));
- if (compiler.enableMinification) {
- mainBuffer.write(';');
- }
- }
+ if (compiler.enableMinification) {
+ mainBuffer.write(';');
+ }
- List<Element> sortedElements =
- Elements.sortedByPosition(elementDescriptors.keys);
+ if (elementDescriptors.isNotEmpty) {
+ Iterable<LibraryElement> libraries =
+ task.outputLibraryLists[mainOutputUnit];
+ if (libraries == null) libraries = [];
+ emitLibraries(libraries);
+ emitTypedefs();
+ emitMangledNames();
- Iterable<Element> pendingStatics;
- if (!compiler.hasIncrementalSupport) {
- pendingStatics = sortedElements.where((element) {
- return !element.isLibrary &&
- elementDescriptors[element].values.any((descriptor) =>
- descriptor != null);
- });
+ checkEverythingEmitted(elementDescriptors.keys);
- pendingStatics.forEach((element) =>
- compiler.reportInfo(
- element, MessageKind.GENERIC, {'text': 'Pending statics.'}));
+ CodeBuffer libraryBuffer = new CodeBuffer();
+ for (LibraryElement library in Elements.sortedByPosition(libraries)) {
+ writeLibraryDescriptors(libraryBuffer, library);
+ elementDescriptors.remove(library);
}
- for (LibraryElement library in sortedElements.where((element) =>
- element.isLibrary)) {
- writeLibraryDescriptors(library, libraryDescriptorBuffers);
- elementDescriptors[library] = const {};
- }
- if (pendingStatics != null && !pendingStatics.isEmpty) {
- compiler.internalError(pendingStatics.first,
- 'Pending statics (see above).');
- }
mainBuffer
..write('(')
..write(
@@ -1541,30 +1511,27 @@ class OldEmitter implements Emitter {
compiler))
..write(')')
..write('([$n')
- ..add(libraryDescriptorBuffers[mainOutputUnit])
+ ..add(libraryBuffer)
..write('])$N');
emitFinishClassesInvocationIfNecessary(mainBuffer);
- classesCollector = oldClassesCollector;
}
+
typeTestEmitter.emitRuntimeTypeSupport(mainBuffer, mainOutputUnit);
interceptorEmitter.emitGetInterceptorMethods(mainBuffer);
interceptorEmitter.emitOneShotInterceptors(mainBuffer);
+
+ if (task.outputContainsConstantList) {
+ emitMakeConstantList(mainBuffer);
+ }
+
// Constants in checked mode call into RTI code to set type information
// which may need getInterceptor (and one-shot interceptor) methods, so
// we have to make sure that [emitGetInterceptorMethods] and
// [emitOneShotInterceptors] have been called.
emitCompileTimeConstants(mainBuffer, mainOutputUnit);
- if (isProgramSplit) {
- /// Map from OutputUnit to a hash of its content. The hash uniquely
- /// identifies the code of the output-unit. It does not include
- /// boilerplate JS code, like the sourcemap directives or the hash
- /// itself.
- Map<OutputUnit, String> deferredLoadHashes =
- emitDeferredCode(libraryDescriptorBuffers);
- emitDeferredBoilerPlate(mainBuffer, deferredLoadHashes);
- }
+ emitDeferredBoilerPlate(mainBuffer, deferredLoadHashes);
// Static field initializations require the classes and compile-time
// constants to be set up.
@@ -1573,6 +1540,7 @@ class OldEmitter implements Emitter {
interceptorEmitter.emitMapTypeToInterceptor(mainBuffer);
emitLazilyInitializedStaticFields(mainBuffer);
+ mainBuffer.writeln();
mainBuffer.add(nativeBuffer);
metadataEmitter.emitMetadata(mainBuffer);
@@ -1686,6 +1654,83 @@ class OldEmitter implements Emitter {
..add(cspBuffer.getText())
..close();
}
+ }
+
+ /// Returns a map from OutputUnit to a hash of its content. The hash uniquely
+ /// identifies the code of the output-unit. It does not include
+ /// boilerplate JS code, like the sourcemap directives or the hash
+ /// itself.
+ Map<OutputUnit, String> emitDeferredOutputUnits() {
+ if (!compiler.deferredLoadTask.isProgramSplit) return const {};
+
+ Map<OutputUnit, CodeBuffer> outputBuffers =
+ new Map<OutputUnit, CodeBuffer>();
+
+ for (OutputUnit outputUnit in compiler.deferredLoadTask.allOutputUnits) {
+ if (outputUnit == compiler.deferredLoadTask.mainOutputUnit) continue;
+
+ List<Element> functions = task.outputStaticLists[outputUnit];
+ if (functions != null) {
+ emitStaticFunctions(functions);
+ }
+
+ List<ClassElement> classes = task.outputClassLists[outputUnit];
+ if (classes != null) {
+ for (ClassElement element in classes) {
+ generateClass(element, getElementDescriptor(element));
+ }
+ }
+
+ if (elementDescriptors.isNotEmpty) {
+ Iterable<LibraryElement> libraries =
+ task.outputLibraryLists[outputUnit];
+ if (libraries == null) libraries = [];
+ emitLibraries(libraries);
+
+ CodeBuffer buffer = new CodeBuffer();
+ outputBuffers[outputUnit] = buffer;
+ for (LibraryElement library in Elements.sortedByPosition(libraries)) {
+ writeLibraryDescriptors(buffer, library);
+ elementDescriptors.remove(library);
+ }
+ }
+ }
+
+ return emitDeferredCode(outputBuffers);
+ }
+
+ CodeBuffer buildNativesBuffer() {
+ // Emit native classes on [nativeBuffer].
+ final CodeBuffer nativeBuffer = new CodeBuffer();
+
+ if (nativeClasses.isEmpty) return nativeBuffer;
+
+
+ addComment('Native classes', nativeBuffer);
+
+ nativeEmitter.generateNativeClasses(nativeClasses, mainBuffer,
+ additionalProperties);
+
+ nativeEmitter.finishGenerateNativeClasses();
+ nativeEmitter.assembleCode(nativeBuffer);
+
+ return nativeBuffer;
+ }
+
+ void emitProgram(Program program) {
+ // Shorten the code by using [namer.currentIsolate] as temporary.
+ isolateProperties = namer.currentIsolate;
+
+ classesCollector = r"$$";
+
+ // Emit deferred units first, so we have their hashes.
+ // Map from OutputUnit to a hash of its content. The hash uniquely
+ // identifies the code of the output-unit. It does not include
+ // boilerplate JS code, like the sourcemap directives or the hash
+ // itself.
+ Map<OutputUnit, String> deferredLoadHashes = emitDeferredOutputUnits();
+ CodeBuffer nativeBuffer = buildNativesBuffer();
+ emitMainOutputUnit(deferredLoadHashes, nativeBuffer);
if (backend.requiresPreamble &&
!backend.htmlLibraryIsLoaded) {
@@ -1704,15 +1749,6 @@ class OldEmitter implements Emitter {
return '';
}
- ClassBuilder getElementDescriptorForOutputUnit(Element element,
- OutputUnit outputUnit) {
- Map<OutputUnit, ClassBuilder> descriptors =
- elementDescriptors.putIfAbsent(
- element, () => new Map<OutputUnit, ClassBuilder>());
- return descriptors.putIfAbsent(outputUnit,
- () => new ClassBuilder(element, namer));
- }
-
ClassBuilder getElementDescriptor(Element element) {
Element owner = element.library;
if (!element.isLibrary && !element.isTopLevel && !element.isNative) {
@@ -1729,8 +1765,9 @@ class OldEmitter implements Emitter {
if (owner == null) {
compiler.internalError(element, 'Owner is null.');
}
- return getElementDescriptorForOutputUnit(owner,
- compiler.deferredLoadTask.outputUnitForElement(element));
+ return elementDescriptors.putIfAbsent(
+ owner,
+ () => new ClassBuilder(owner, namer));
}
/// Emits support-code for deferred loading into [buffer].
@@ -1802,20 +1839,17 @@ class OldEmitter implements Emitter {
/// Returns a mapping from outputUnit to a hash of the corresponding hunk that
/// can be used for calling the initializer.
Map<OutputUnit, String> emitDeferredCode(
- Map<OutputUnit, CodeBuffer> libraryDescriptorBuffers) {
+ Map<OutputUnit, CodeBuffer> deferredBuffers) {
Map<OutputUnit, String> hunkHashes = new Map<OutputUnit, String>();
for (OutputUnit outputUnit in compiler.deferredLoadTask.allOutputUnits) {
if (outputUnit == compiler.deferredLoadTask.mainOutputUnit) continue;
- CodeBuffer libraryDescriptorBuffer = libraryDescriptorBuffers[outputUnit];
+ CodeBuffer libraryDescriptorBuffer = deferredBuffers[outputUnit];
CodeBuffer outputBuffer = new CodeBuffer();
- var oldClassesCollector = classesCollector;
- classesCollector = r"$$";
-
outputBuffer..write(buildGeneratedBy())
..write('${deferredInitializers}.current$_=$_'
'function$_(${globalsHolder}) {$N');
@@ -1855,8 +1889,6 @@ class OldEmitter implements Emitter {
}
- classesCollector = oldClassesCollector;
-
// Set the currentIsolate variable to the current isolate (which is
// provided as second argument).
// We need to do this, because we use the same variable for setting up
« 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