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

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

Issue 830703004: Emit to StreamCodeOutput instead of CodeBuffer. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Updated cf. comments Created 5 years, 11 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
Index: pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
index 9dd74c0d4658aac86bc380ebb3856769278a9d35..7f9d2e092fc7333727537d1818b76c7eb11578ef 100644
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
@@ -16,6 +16,7 @@ class OldEmitter implements Emitter {
final InterceptorEmitter interceptorEmitter = new InterceptorEmitter();
final MetadataEmitter metadataEmitter = new MetadataEmitter();
+ // TODO(johnniwinther): Wrap these fields in a caching strategy.
final Set<ConstantValue> cachedEmittedConstants;
final CodeBuffer cachedEmittedConstantsBuffer = new CodeBuffer();
final Map<Element, ClassBuilder> cachedClassBuilders;
@@ -30,8 +31,7 @@ class OldEmitter implements Emitter {
TypeTestRegistry get typeTestRegistry => task.typeTestRegistry;
// The full code that is written to each hunk part-file.
- Map<OutputUnit, CodeBuffer> outputBuffers = new Map<OutputUnit, CodeBuffer>();
- final CodeBuffer deferredConstants = new CodeBuffer();
+ Map<OutputUnit, CodeOutput> outputBuffers = new Map<OutputUnit, CodeOutput>();
/** Shorter access to [isolatePropertiesName]. Both here in the code, as
well as in the generated code. */
@@ -61,14 +61,6 @@ class OldEmitter implements Emitter {
String get n => compiler.enableMinification ? "" : "\n";
String get N => compiler.enableMinification ? "\n" : ";\n";
- CodeBuffer getBuffer(OutputUnit outputUnit) {
- return outputBuffers.putIfAbsent(outputUnit, () => new CodeBuffer());
- }
-
- CodeBuffer get mainBuffer {
- return getBuffer(compiler.deferredLoadTask.mainOutputUnit);
- }
-
/**
* List of expressions and statements that will be included in the
* precompiled function.
@@ -133,8 +125,8 @@ class OldEmitter implements Emitter {
_cspPrecompiledConstructorNames.clear();
}
- void addComment(String comment, CodeBuffer buffer) {
- buffer.write(jsAst.prettyPrint(js.comment(comment), compiler));
+ void addComment(String comment, CodeOutput output) {
+ output.addBuffer(jsAst.prettyPrint(js.comment(comment), compiler));
}
@override
@@ -330,14 +322,14 @@ class OldEmitter implements Emitter {
jsAst.Expression defineClass = js('''
function(name, fields) {
var accessors = [];
-
+
var str = "function " + name + "(";
var body = "";
if (#hasIsolateSupport) { var fieldNames = ""; }
-
+
for (var i = 0; i < fields.length; i++) {
if(i != 0) str += ", ";
-
+
var field = generateAccessor(fields[i], accessors, name);
if (#hasIsolateSupport) { fieldNames += "'" + field + "',"; }
var parameter = "parameter_" + field;
@@ -356,7 +348,7 @@ class OldEmitter implements Emitter {
str += name + ".$fieldNamesProperty=[" + fieldNames + "];\\n";
}
str += accessors.join("");
-
+
return str;
}''', { 'hasIsolateSupport': hasIsolateSupport });
@@ -576,9 +568,9 @@ class OldEmitter implements Emitter {
'allowNativesSubclassing': true});
}
- void emitFinishIsolateConstructorInvocation(CodeBuffer buffer) {
+ void emitFinishIsolateConstructorInvocation(CodeOutput output) {
String isolate = namer.isolateName;
- buffer.write("$isolate = $finishIsolateConstructorName($isolate)$N");
+ output.add("$isolate = $finishIsolateConstructorName($isolate)$N");
}
/// In minified mode we want to keep the name for the most common core types.
@@ -758,7 +750,7 @@ class OldEmitter implements Emitter {
}
}
- void emitStaticNonFinalFieldInitializations(CodeBuffer buffer,
+ void emitStaticNonFinalFieldInitializations(CodeOutput output,
OutputUnit outputUnit) {
JavaScriptConstantCompiler handler = backend.constants;
Iterable<VariableElement> staticNonFinalFields =
@@ -788,14 +780,14 @@ class OldEmitter implements Emitter {
jsAst.Expression init =
js('$isolateProperties.# = #',
[namer.getNameOfGlobalField(element), initialValue]);
- buffer.write(jsAst.prettyPrint(init, compiler,
- monitor: compiler.dumpInfoTask));
- buffer.write('$N');
+ output.addBuffer(jsAst.prettyPrint(init, compiler,
+ monitor: compiler.dumpInfoTask));
+ output.add('$N');
});
}
}
- void emitLazilyInitializedStaticFields(CodeBuffer buffer) {
+ void emitLazilyInitializedStaticFields(CodeOutput output) {
JavaScriptConstantCompiler handler = backend.constants;
List<VariableElement> lazyFields =
handler.getLazilyInitializedFieldsForEmission();
@@ -805,9 +797,9 @@ class OldEmitter implements Emitter {
jsAst.Expression init =
buildLazilyInitializedStaticField(element, isolateProperties);
if (init == null) continue;
- buffer.write(
+ output.addBuffer(
jsAst.prettyPrint(init, compiler, monitor: compiler.dumpInfoTask));
- buffer.write("$N");
+ output.add("$N");
}
}
}
@@ -866,25 +858,25 @@ class OldEmitter implements Emitter {
return namer.constantName(a).compareTo(namer.constantName(b));
}
- void emitCompileTimeConstants(CodeBuffer buffer, OutputUnit outputUnit) {
+ void emitCompileTimeConstants(CodeOutput output, OutputUnit outputUnit) {
List<ConstantValue> constants = outputConstantLists[outputUnit];
if (constants == null) return;
- bool isMainBuffer = buffer == mainBuffer;
- if (compiler.hasIncrementalSupport && isMainBuffer) {
- buffer = cachedEmittedConstantsBuffer;
+ CodeOutput constantOutput = output;
+ if (compiler.hasIncrementalSupport && outputUnit.isMainOutput) {
+ constantOutput = cachedEmittedConstantsBuffer;
}
for (ConstantValue constant in constants) {
- if (compiler.hasIncrementalSupport && isMainBuffer) {
+ if (compiler.hasIncrementalSupport && outputUnit.isMainOutput) {
if (cachedEmittedConstants.contains(constant)) continue;
cachedEmittedConstants.add(constant);
}
jsAst.Expression init = buildConstantInitializer(constant);
- buffer.write(jsAst.prettyPrint(init, compiler,
- monitor: compiler.dumpInfoTask));
- buffer.write('$N');
+ constantOutput.addBuffer(jsAst.prettyPrint(init, compiler,
+ monitor: compiler.dumpInfoTask));
+ constantOutput.add('$N');
}
- if (compiler.hasIncrementalSupport && isMainBuffer) {
- mainBuffer.write(cachedEmittedConstantsBuffer);
+ if (compiler.hasIncrementalSupport && outputUnit.isMainOutput) {
+ output.addBuffer(constantOutput);
}
}
@@ -901,8 +893,8 @@ class OldEmitter implements Emitter {
'${namer.isolateName}.$makeConstListProperty(#)');
}
- void emitMakeConstantList(CodeBuffer buffer) {
- buffer.write(
+ void emitMakeConstantList(CodeOutput output) {
+ output.addBuffer(
jsAst.prettyPrint(
// Functions are stored in the hidden class and not as properties in
// the object. We never actually look at the value, but only want
@@ -914,7 +906,7 @@ class OldEmitter implements Emitter {
}''',
[namer.isolateName, makeConstListProperty]),
compiler, monitor: compiler.dumpInfoTask));
- buffer.write(N);
+ output.add(N);
}
/// Returns the code equivalent to:
@@ -987,7 +979,7 @@ class OldEmitter implements Emitter {
return 'ZxYxX';
}
- emitMain(CodeBuffer buffer) {
+ emitMain(CodeOutput output) {
if (compiler.isMockCompilation) return;
Element main = compiler.mainFunction;
jsAst.Expression mainCallClosure = null;
@@ -1004,23 +996,23 @@ class OldEmitter implements Emitter {
}
if (backend.needToInitializeIsolateAffinityTag) {
- buffer.write(
+ output.addBuffer(
jsAst.prettyPrint(generateIsolateAffinityTagInitialization(),
compiler, monitor: compiler.dumpInfoTask));
- buffer.write(N);
+ output.add(N);
}
if (backend.needToInitializeDispatchProperty) {
assert(backend.needToInitializeIsolateAffinityTag);
- buffer.write(
+ output.addBuffer(
jsAst.prettyPrint(generateDispatchPropertyNameInitialization(),
compiler, monitor: compiler.dumpInfoTask));
- buffer.write(N);
+ output.add(N);
}
jsAst.Expression currentScriptAccess =
generateEmbeddedGlobalAccess(embeddedNames.CURRENT_SCRIPT);
- addComment('BEGIN invoke [main].', buffer);
+ addComment('BEGIN invoke [main].', output);
// This code finds the currently executing script by listening to the
// onload event of all script tags and getting the first script which
// finishes. Since onload is called immediately after execution this should
@@ -1057,14 +1049,14 @@ class OldEmitter implements Emitter {
})''', {'currentScript': currentScriptAccess,
'mainCallClosure': mainCallClosure});
- buffer.write(';');
- buffer.write(jsAst.prettyPrint(invokeMain,
- compiler, monitor: compiler.dumpInfoTask));
- buffer.write(N);
- addComment('END invoke [main].', buffer);
+ output.add(';');
+ output.addBuffer(jsAst.prettyPrint(invokeMain,
+ compiler, monitor: compiler.dumpInfoTask));
+ output.add(N);
+ addComment('END invoke [main].', output);
}
- void emitInitFunction(CodeBuffer buffer) {
+ void emitInitFunction(CodeOutput output) {
String isolate = namer.currentIsolate;
jsAst.Expression allClassesAccess =
generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES);
@@ -1094,17 +1086,17 @@ class OldEmitter implements Emitter {
getterName, lazyValue) {
if (!#lazies) #lazies = Object.create(null);
#lazies[fieldName] = getterName;
-
+
var sentinelUndefined = {};
var sentinelInProgress = {};
prototype[fieldName] = sentinelUndefined;
-
+
prototype[getterName] = function () {
var result = $isolate[fieldName];
try {
if (result === sentinelUndefined) {
$isolate[fieldName] = sentinelInProgress;
-
+
try {
result = $isolate[fieldName] = lazyValue();
} finally {
@@ -1117,7 +1109,7 @@ class OldEmitter implements Emitter {
if (result === sentinelInProgress)
#cyclicThrow(staticName);
}
-
+
return result;
} finally {
$isolate[getterName] = function() { return this[fieldName]; };
@@ -1175,7 +1167,7 @@ class OldEmitter implements Emitter {
}
return Isolate;
}
-
+
}''', {'allClasses': allClassesAccess,
'interceptorsByTag': interceptorsByTagAccess,
'leafTags': leafTagsAccess,
@@ -1188,12 +1180,14 @@ class OldEmitter implements Emitter {
'hasIncrementalSupport': compiler.hasIncrementalSupport,
'lazyInitializerProperty': lazyInitializerProperty,});
- buffer.write(jsAst.prettyPrint(decl,
- compiler, monitor: compiler.dumpInfoTask).getText());
- if (compiler.enableMinification) buffer.write('\n');
+ output.addBuffer(
+ jsAst.prettyPrint(decl, compiler, monitor: compiler.dumpInfoTask));
+ if (compiler.enableMinification) {
+ output.add('\n');
+ }
}
- void emitConvertToFastObjectFunction() {
+ void emitConvertToFastObjectFunction(CodeOutput output) {
List<jsAst.Statement> debugCode = <jsAst.Statement>[];
if (DEBUG_FAST_OBJECTS) {
debugCode.add(js.statement(r'''
@@ -1220,11 +1214,11 @@ class OldEmitter implements Emitter {
return properties;
}''', [debugCode]);
- mainBuffer.write(jsAst.prettyPrint(convertToFastObject, compiler));
- mainBuffer.write(N);
+ output.addBuffer(jsAst.prettyPrint(convertToFastObject, compiler));
+ output.add(N);
}
- void writeLibraryDescriptors(CodeBuffer buffer, LibraryElement library) {
+ void writeLibraryDescriptors(CodeOutput output, LibraryElement library) {
var uri = "";
if (!compiler.enableMinification || backend.mustPreserveUris) {
uri = library.canonicalUri;
@@ -1252,20 +1246,23 @@ class OldEmitter implements Emitter {
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');
+ output
+ ..add('["$libraryName",$_')
+ ..add('"${uri}",$_');
+ if (metadata != null) {
+ output.addBuffer(jsAst.prettyPrint(metadata,
+ compiler,
+ monitor: compiler.dumpInfoTask));
+ }
+ output
+ ..add(',$_')
+ ..add(namer.globalObjectFor(library))
+ ..add(',$_')
+ ..addBuffer(jsAst.prettyPrint(initializers,
+ compiler,
+ monitor: compiler.dumpInfoTask))
+ ..add(library == compiler.mainApp ? ',${n}1' : "")
+ ..add('],$n');
}
void emitPrecompiledConstructor(OutputUnit outputUnit,
@@ -1292,7 +1289,7 @@ class OldEmitter implements Emitter {
''' /* next string is not a raw string */ '''
if (#hasIsolateSupport) {
#constructorName.$fieldNamesProperty = #fieldNamesArray;
- }
+ }
}''',
{"constructorName": constructorName,
"constructorNameString": js.string(constructorName),
@@ -1374,7 +1371,7 @@ class OldEmitter implements Emitter {
}
}
- void emitMangledNames() {
+ void emitMangledNames(CodeOutput mainBuffer) {
if (!mangledFieldNames.isEmpty) {
var keys = mangledFieldNames.keys.toList();
keys.sort();
@@ -1387,13 +1384,13 @@ class OldEmitter implements Emitter {
jsAst.Expression mangledNamesAccess =
generateEmbeddedGlobalAccess(embeddedNames.MANGLED_NAMES);
var map = new jsAst.ObjectInitializer(properties);
- mainBuffer.write(
+ mainBuffer.addBuffer(
jsAst.prettyPrint(
js.statement('# = #', [mangledNamesAccess, map]),
compiler,
monitor: compiler.dumpInfoTask));
if (compiler.enableMinification) {
- mainBuffer.write(';');
+ mainBuffer.add(';');
}
}
if (!mangledGlobalFieldNames.isEmpty) {
@@ -1407,13 +1404,13 @@ class OldEmitter implements Emitter {
jsAst.Expression mangledGlobalNamesAccess =
generateEmbeddedGlobalAccess(embeddedNames.MANGLED_GLOBAL_NAMES);
var map = new jsAst.ObjectInitializer(properties);
- mainBuffer.write(
+ mainBuffer.addBuffer(
jsAst.prettyPrint(
js.statement('# = #', [mangledGlobalNamesAccess, map]),
compiler,
monitor: compiler.dumpInfoTask));
if (compiler.enableMinification) {
- mainBuffer.write(';');
+ mainBuffer.add(';');
}
}
}
@@ -1437,27 +1434,39 @@ class OldEmitter implements Emitter {
void emitMainOutputUnit(Map<OutputUnit, String> deferredLoadHashes,
CodeBuffer nativeBuffer) {
- bool isProgramSplit = compiler.deferredLoadTask.isProgramSplit;
+ LineColumnCollector lineColumnCollector;
+ List<CodeOutputListener> codeOutputListeners;
+ if (generateSourceMap) {
+ lineColumnCollector = new LineColumnCollector();
+ codeOutputListeners = <CodeOutputListener>[lineColumnCollector];
+ }
+
OutputUnit mainOutputUnit = compiler.deferredLoadTask.mainOutputUnit;
+ CodeOutput mainOutput =
+ new StreamCodeOutput(compiler.outputProvider('', 'js'),
+ codeOutputListeners);
+ outputBuffers[mainOutputUnit] = mainOutput;
+
+ bool isProgramSplit = compiler.deferredLoadTask.isProgramSplit;
- mainBuffer.write(buildGeneratedBy());
- addComment(HOOKS_API_USAGE, mainBuffer);
+ mainOutput.add(buildGeneratedBy());
+ addComment(HOOKS_API_USAGE, mainOutput);
if (isProgramSplit) {
/// For deferred loading we communicate the initializers via this global
/// variable. The deferred hunks will add their initialization to this.
/// The semicolon is important in minified mode, without it the
/// following parenthesis looks like a call to the object literal.
- mainBuffer..write(
+ mainOutput.add(
'self.${deferredInitializers} = self.${deferredInitializers} || '
'Object.create(null);$n');
}
// Using a named function here produces easier to read stack traces in
// Chrome/V8.
- mainBuffer.write('(function(${namer.currentIsolate})$_{\n');
+ mainOutput.add('(function(${namer.currentIsolate})$_{\n');
if (compiler.hasIncrementalSupport) {
- mainBuffer.write(jsAst.prettyPrint(js.statement(
+ mainOutput.addBuffer(jsAst.prettyPrint(js.statement(
"""
{
#helper = #helper || Object.create(null);
@@ -1477,9 +1486,9 @@ class OldEmitter implements Emitter {
if (isProgramSplit) {
/// We collect all the global state of the, so it can be passed to the
/// initializer of deferred files.
- mainBuffer.write('var ${globalsHolder}$_=${_}Object.create(null)$N');
+ mainOutput.add('var ${globalsHolder}$_=${_}Object.create(null)$N');
}
- mainBuffer.write('function dart()$_{$n'
+ mainOutput.add('function dart()$_{$n'
'${_}${_}this.x$_=${_}0$N'
'${_}${_}delete this.x$N'
'}$n');
@@ -1489,22 +1498,22 @@ class OldEmitter implements Emitter {
// to these objects. Later on, we attempt to turn these objects into
// fast objects by calling "convertToFastObject" (see
// [emitConvertToFastObjectFunction]).
- mainBuffer.write('var ${globalObject}$_=${_}');
+ mainOutput.add('var ${globalObject}$_=${_}');
if(isProgramSplit) {
- mainBuffer.write('${globalsHolder}.$globalObject$_=${_}');
+ mainOutput.add('${globalsHolder}.$globalObject$_=${_}');
}
- mainBuffer.write('new dart$N');
+ mainOutput.add('new dart$N');
}
- mainBuffer.write('function ${namer.isolateName}()$_{}\n');
+ mainOutput.add('function ${namer.isolateName}()$_{}\n');
if (isProgramSplit) {
- mainBuffer
- .write('${globalsHolder}.${namer.isolateName}$_=$_'
- '${namer.isolateName}$N'
- '${globalsHolder}.$initName$_=${_}$initName$N');
+ mainOutput
+ .add('${globalsHolder}.${namer.isolateName}$_=$_'
+ '${namer.isolateName}$N'
+ '${globalsHolder}.$initName$_=${_}$initName$N');
}
- mainBuffer.write('init()$N$n');
- mainBuffer.write('$isolateProperties$_=$_$isolatePropertiesName$N');
+ mainOutput.add('init()$N$n');
+ mainOutput.add('$isolateProperties$_=$_$isolatePropertiesName$N');
emitStaticFunctions(task.outputStaticLists[mainOutputUnit]);
@@ -1516,7 +1525,7 @@ class OldEmitter implements Emitter {
}
if (compiler.enableMinification) {
- mainBuffer.write(';');
+ mainOutput.add(';');
}
if (elementDescriptors.isNotEmpty) {
@@ -1525,70 +1534,67 @@ class OldEmitter implements Emitter {
if (libraries == null) libraries = [];
emitLibraries(libraries);
emitTypedefs();
- emitMangledNames();
+ emitMangledNames(mainOutput);
checkEverythingEmitted(elementDescriptors.keys);
- CodeBuffer libraryBuffer = new CodeBuffer();
- for (LibraryElement library in Elements.sortedByPosition(libraries)) {
- writeLibraryDescriptors(libraryBuffer, library);
- elementDescriptors.remove(library);
- }
-
- mainBuffer
- ..write('(')
- ..write(
+ mainOutput
+ ..add('(')
+ ..addBuffer(
jsAst.prettyPrint(
getReflectionDataParser(this, backend),
compiler))
- ..write(')')
- ..write('([$n')
- ..write(libraryBuffer)
- ..write('])$N');
+ ..add(')')
+ ..add('([$n');
+ for (LibraryElement library in Elements.sortedByPosition(libraries)) {
+ writeLibraryDescriptors(mainOutput, library);
+ elementDescriptors.remove(library);
+ }
+ mainOutput.add('])$N');
}
- interceptorEmitter.emitGetInterceptorMethods(mainBuffer);
- interceptorEmitter.emitOneShotInterceptors(mainBuffer);
+ interceptorEmitter.emitGetInterceptorMethods(mainOutput);
+ interceptorEmitter.emitOneShotInterceptors(mainOutput);
if (task.outputContainsConstantList) {
- emitMakeConstantList(mainBuffer);
+ emitMakeConstantList(mainOutput);
}
// 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);
+ emitCompileTimeConstants(mainOutput, mainOutputUnit);
- emitDeferredBoilerPlate(mainBuffer, deferredLoadHashes);
+ emitDeferredBoilerPlate(mainOutput, deferredLoadHashes);
// Static field initializations require the classes and compile-time
// constants to be set up.
- emitStaticNonFinalFieldInitializations(mainBuffer, mainOutputUnit);
- interceptorEmitter.emitInterceptedNames(mainBuffer);
- interceptorEmitter.emitMapTypeToInterceptor(mainBuffer);
- emitLazilyInitializedStaticFields(mainBuffer);
+ emitStaticNonFinalFieldInitializations(mainOutput, mainOutputUnit);
+ interceptorEmitter.emitInterceptedNames(mainOutput);
+ interceptorEmitter.emitMapTypeToInterceptor(mainOutput);
+ emitLazilyInitializedStaticFields(mainOutput);
- mainBuffer.writeln();
- mainBuffer.write(nativeBuffer);
+ mainOutput.add('\n');
+ mainOutput.addBuffer(nativeBuffer);
- metadataEmitter.emitMetadata(mainBuffer);
+ metadataEmitter.emitMetadata(mainOutput);
isolateProperties = isolatePropertiesName;
// The following code should not use the short-hand for the
// initialStatics.
- mainBuffer.write('${namer.currentIsolate}$_=${_}null$N');
+ mainOutput.add('${namer.currentIsolate}$_=${_}null$N');
- emitFinishIsolateConstructorInvocation(mainBuffer);
- mainBuffer.write(
+ emitFinishIsolateConstructorInvocation(mainOutput);
+ mainOutput.add(
'${namer.currentIsolate}$_=${_}new ${namer.isolateName}()$N');
- emitConvertToFastObjectFunction();
+ emitConvertToFastObjectFunction(mainOutput);
for (String globalObject in Namer.reservedGlobalObjectNames) {
- mainBuffer.write('$globalObject = convertToFastObject($globalObject)$N');
+ mainOutput.add('$globalObject = convertToFastObject($globalObject)$N');
}
if (DEBUG_FAST_OBJECTS) {
- mainBuffer.write(r'''
+ mainOutput.add(r'''
// The following only works on V8 when run with option
// "--allow-natives-syntax". We use'new Function' because the
// miniparser does not understand V8 native syntax.
@@ -1617,7 +1623,7 @@ class OldEmitter implements Emitter {
}
''');
for (String object in Namer.userGlobalObjects) {
- mainBuffer.write('''
+ mainOutput.add('''
if (typeof print === "function") {
print("Size of $object: "
+ String(Object.getOwnPropertyNames($object).length)
@@ -1629,31 +1635,30 @@ class OldEmitter implements Emitter {
jsAst.FunctionDeclaration precompiledFunctionAst =
buildCspPrecompiledFunctionFor(mainOutputUnit);
- emitInitFunction(mainBuffer);
- emitMain(mainBuffer);
- mainBuffer.write('})()\n');
+ emitInitFunction(mainOutput);
+ emitMain(mainOutput);
+ mainOutput.add('})()\n');
if (compiler.useContentSecurityPolicy) {
- mainBuffer.write(
+ mainOutput.addBuffer(
jsAst.prettyPrint(
precompiledFunctionAst,
compiler,
monitor: compiler.dumpInfoTask,
- allowVariableMinification: false).getText());
+ allowVariableMinification: false));
}
- String assembledCode = mainBuffer.getText();
if (generateSourceMap) {
- outputSourceMap(assembledCode, mainBuffer, '',
- compiler.sourceMapUri, compiler.outputUri);
- mainBuffer.write(
+ mainOutput.add(
generateSourceMapTag(compiler.sourceMapUri, compiler.outputUri));
- assembledCode = mainBuffer.getText();
}
- compiler.outputProvider('', 'js')
- ..add(assembledCode)
- ..close();
+ mainOutput.close();
+
+ if (generateSourceMap) {
+ outputSourceMap(mainOutput, lineColumnCollector, '',
+ compiler.sourceMapUri, compiler.outputUri);
+ }
}
/// Used by incremental compilation to patch up the prototype of
@@ -1802,6 +1807,7 @@ function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) {
if (libraries == null) libraries = [];
emitLibraries(libraries);
+ // TODO(johnniwinther): Avoid creating [CodeBuffer]s.
CodeBuffer buffer = new CodeBuffer();
outputBuffers[outputUnit] = buffer;
for (LibraryElement library in Elements.sortedByPosition(libraries)) {
@@ -1816,6 +1822,7 @@ function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) {
CodeBuffer buildNativesBuffer() {
// Emit native classes on [nativeBuffer].
+ // TODO(johnniwinther): Avoid creating a [CodeBuffer].
final CodeBuffer nativeBuffer = new CodeBuffer();
if (nativeClasses.isEmpty) return nativeBuffer;
@@ -1823,8 +1830,7 @@ function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) {
addComment('Native classes', nativeBuffer);
- nativeEmitter.generateNativeClasses(nativeClasses, mainBuffer,
- additionalProperties);
+ nativeEmitter.generateNativeClasses(nativeClasses, additionalProperties);
nativeEmitter.finishGenerateNativeClasses();
nativeEmitter.assembleCode(nativeBuffer);
@@ -1849,7 +1855,6 @@ function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) {
!backend.htmlLibraryIsLoaded) {
compiler.reportHint(NO_LOCATION_SPANNABLE, MessageKind.PREAMBLE);
}
-
// Return the total program size.
return outputBuffers.values.fold(0, (a, b) => a + b.length);
}
@@ -1888,18 +1893,18 @@ function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) {
() => new ClassBuilder(owner, namer));
}
- /// Emits support-code for deferred loading into [buffer].
- void emitDeferredBoilerPlate(CodeBuffer buffer,
+ /// Emits support-code for deferred loading into [output].
+ void emitDeferredBoilerPlate(CodeOutput output,
Map<OutputUnit, String> deferredLoadHashes) {
// Function for checking if a hunk is loaded given its hash.
- buffer.write(jsAst.prettyPrint(
+ output.addBuffer(jsAst.prettyPrint(
js('# = function(hunkHash) {'
' return !!$deferredInitializers[hunkHash];'
'}', generateEmbeddedGlobalAccess(embeddedNames.IS_HUNK_LOADED)),
compiler, monitor: compiler.dumpInfoTask));
- buffer.write('$N');
+ output.add('$N');
// Function for initializing a loaded hunk, given its hash.
- buffer.write(jsAst.prettyPrint(
+ output.addBuffer(jsAst.prettyPrint(
js('# = function(hunkHash) {'
' $deferredInitializers[hunkHash]('
'$globalsHolder, ${namer.currentIsolate})'
@@ -1907,7 +1912,7 @@ function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) {
generateEmbeddedGlobalAccess(
embeddedNames.INITIALIZE_LOADED_HUNK)),
compiler, monitor: compiler.dumpInfoTask));
- buffer.write('$N');
+ output.add('$N');
// Write a javascript mapping from Deferred import load ids (derrived
// from the import prefix.) to a list of lists of uris of hunks to load,
// and a corresponding mapping to a list of hashes used by
@@ -1941,11 +1946,10 @@ function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) {
new jsAst.ObjectInitializer(properties, isOneLiner: true);
jsAst.Node globalName = generateEmbeddedGlobalAccess(name);
- buffer.write(jsAst.prettyPrint(
+ output.addBuffer(jsAst.prettyPrint(
js("# = #", [globalName, initializer]),
compiler, monitor: compiler.dumpInfoTask));
- buffer.write('$N');
-
+ output.add('$N');
}
emitMapping(embeddedNames.DEFERRED_LIBRARY_URIS, deferredLibraryUris);
@@ -1964,39 +1968,54 @@ function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) {
for (OutputUnit outputUnit in compiler.deferredLoadTask.allOutputUnits) {
if (outputUnit == compiler.deferredLoadTask.mainOutputUnit) continue;
- CodeBuffer libraryDescriptorBuffer = deferredBuffers[outputUnit];
+ CodeOutput libraryDescriptorBuffer = deferredBuffers[outputUnit];
- CodeBuffer outputBuffer = new CodeBuffer();
+ List<CodeOutputListener> outputListeners = <CodeOutputListener>[];
+ Hasher hasher = new Hasher();
+ outputListeners.add(hasher);
- outputBuffer..write(buildGeneratedBy())
- ..write('${deferredInitializers}.current$_=$_'
- 'function$_(${globalsHolder}) {$N');
+ LineColumnCollector lineColumnCollector;
+ if (generateSourceMap) {
+ lineColumnCollector = new LineColumnCollector();
+ outputListeners.add(lineColumnCollector);
+ }
+
+ String partPrefix = deferredPartFileName(outputUnit, addExtension: false);
+ CodeOutput output = new StreamCodeOutput(
+ compiler.outputProvider(partPrefix, 'part.js'),
+ outputListeners);
+
+ outputBuffers[outputUnit] = output;
+
+ output
+ ..add(buildGeneratedBy())
+ ..add('${deferredInitializers}.current$_=$_'
+ 'function$_(${globalsHolder}) {$N');
for (String globalObject in Namer.reservedGlobalObjectNames) {
- outputBuffer
- .write('var $globalObject$_=$_'
- '${globalsHolder}.$globalObject$N');
+ output
+ .add('var $globalObject$_=$_'
+ '${globalsHolder}.$globalObject$N');
}
- outputBuffer
- ..write('var init$_=$_${globalsHolder}.init$N')
- ..write('var ${namer.isolateName}$_=$_'
+ output
+ ..add('var init$_=$_${globalsHolder}.init$N')
+ ..add('var ${namer.isolateName}$_=$_'
'${globalsHolder}.${namer.isolateName}$N');
if (libraryDescriptorBuffer != null) {
// TODO(ahe): This defines a lot of properties on the
// Isolate.prototype object. We know this will turn it into a
// slow object in V8, so instead we should do something similar
// to Isolate.$finishIsolateConstructor.
- outputBuffer
- ..write('var ${namer.currentIsolate}$_=$_$isolatePropertiesName;$n')
- ..write('(')
- ..write(
+ output
+ ..add('var ${namer.currentIsolate}$_=$_$isolatePropertiesName;$n')
+ ..add('(')
+ ..addBuffer(
jsAst.prettyPrint(
getReflectionDataParser(this, backend),
compiler, monitor: compiler.dumpInfoTask))
- ..write(')')
- ..write('([$n')
+ ..add(')')
+ ..add('([$n')
..addBuffer(libraryDescriptorBuffer)
- ..write('])$N');
-
+ ..add('])$N');
}
// Set the currentIsolate variable to the current isolate (which is
@@ -2008,33 +2027,33 @@ function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) {
// After we have done the setup it must point to the current Isolate.
// Otherwise all methods/functions accessing isolate variables will
// access the wrong object.
- outputBuffer.write("${namer.currentIsolate}$_=${_}arguments[1]$N");
+ output.add("${namer.currentIsolate}$_=${_}arguments[1]$N");
- emitCompileTimeConstants(outputBuffer, outputUnit);
- emitStaticNonFinalFieldInitializations(outputBuffer, outputUnit);
- outputBuffer.write('}$N');
+ emitCompileTimeConstants(output, outputUnit);
+ emitStaticNonFinalFieldInitializations(output, outputUnit);
+ output.add('}$N');
if (compiler.useContentSecurityPolicy) {
jsAst.FunctionDeclaration precompiledFunctionAst =
buildCspPrecompiledFunctionFor(outputUnit);
- outputBuffer.write(
+ output.addBuffer(
jsAst.prettyPrint(
precompiledFunctionAst, compiler,
monitor: compiler.dumpInfoTask,
- allowVariableMinification: false).getText());
+ allowVariableMinification: false));
}
// Make a unique hash of the code (before the sourcemaps are added)
// This will be used to retrieve the initializing function from the global
// variable.
- String hash = hashOfString(outputBuffer.getText());
+ String hash = hasher.getHash();
- outputBuffer.write('${deferredInitializers}["$hash"]$_=$_'
- '${deferredInitializers}.current$N');
+ output.add('${deferredInitializers}["$hash"]$_=$_'
+ '${deferredInitializers}.current$N');
- String partPrefix = deferredPartFileName(outputUnit, addExtension: false);
if (generateSourceMap) {
+
Uri mapUri, partUri;
Uri sourceMapUri = compiler.sourceMapUri;
Uri outputUri = compiler.outputUri;
@@ -2055,16 +2074,14 @@ function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) {
partUri = compiler.outputUri.replace(pathSegments: partSegments);
}
- outputSourceMap(outputBuffer.getText(), outputBuffer, partName,
- mapUri, partUri);
- outputBuffer.write(generateSourceMapTag(mapUri, partUri));
+ output.add(generateSourceMapTag(mapUri, partUri));
+ output.close();
+ outputSourceMap(output, lineColumnCollector, partName,
+ mapUri, partUri);
+ } else {
+ output.close();
}
- outputBuffers[outputUnit] = outputBuffer;
- compiler.outputProvider(partPrefix, 'part.js')
- ..add(outputBuffer.getText())
- ..close();
-
hunkHashes[outputUnit] = hash;
}
return hunkHashes;
@@ -2076,15 +2093,17 @@ function(originalDescriptor, name, holder, isStatic, globalFunctionsAccess) {
return '// Generated by dart2js, the Dart to JavaScript compiler$suffix.\n';
}
- void outputSourceMap(String code, CodeBuffer buffer, String name,
- [Uri sourceMapUri, Uri fileUri]) {
+ void outputSourceMap(CodeOutput output,
+ LineColumnProvider lineColumnProvider,
+ String name,
+ [Uri sourceMapUri,
+ Uri fileUri]) {
if (!generateSourceMap) return;
// Create a source file for the compilation output. This allows using
// [:getLine:] to transform offsets to line numbers in [SourceMapBuilder].
- SourceFile compiledFile = new StringSourceFile(null, code);
SourceMapBuilder sourceMapBuilder =
- new SourceMapBuilder(sourceMapUri, fileUri, compiledFile);
- buffer.forEachSourceLocation(sourceMapBuilder.addMapping);
+ new SourceMapBuilder(sourceMapUri, fileUri, lineColumnProvider);
+ output.forEachSourceLocation(sourceMapBuilder.addMapping);
String sourceMap = sourceMapBuilder.build();
compiler.outputProvider(name, 'js.map')
..add(sourceMap)
« no previous file with comments | « pkg/compiler/lib/src/js_emitter/js_emitter.dart ('k') | pkg/compiler/lib/src/js_emitter/old_emitter/interceptor_emitter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698