Index: sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart |
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart |
index 8b77244cc1358891077732bbda6a8905614a9800..261f4df132a653782637208dc11a1152003164c3 100644 |
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart |
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/code_emitter_task.dart |
@@ -87,9 +87,11 @@ class CodeEmitterTask extends CompilerTask { |
* negatively. So dart2js will emit these functions to a separate file that |
* can be optionally included to support CSP mode or for faster startup. |
*/ |
- List<jsAst.Node> precompiledFunction = <jsAst.Node>[]; |
+ Map<OutputUnit, List<jsAst.Node>> _cspPrecompiledFunctions = |
+ new Map<OutputUnit, List<jsAst.Node>>(); |
- List<jsAst.Expression> precompiledConstructorNames = <jsAst.Expression>[]; |
+ Map<OutputUnit, List<jsAst.Expression>> _cspPrecompiledConstructorNames = |
+ new Map<OutputUnit, List<jsAst.Expression>>(); |
// True if Isolate.makeConstantList is needed. |
bool hasMakeConstantList = false; |
@@ -129,6 +131,26 @@ class CodeEmitterTask extends CompilerTask { |
templateManager.clear(); |
} |
+ List<jsAst.Node> cspPrecompiledFunctionFor(OutputUnit outputUnit) { |
+ return _cspPrecompiledFunctions.putIfAbsent( |
+ outputUnit, |
+ () => new List<jsAst.Node>()); |
+ } |
+ |
+ List<jsAst.Expression> cspPrecompiledConstructorNamesFor( |
+ OutputUnit outputUnit) { |
+ return _cspPrecompiledConstructorNames.putIfAbsent( |
+ outputUnit, |
+ () => new List<jsAst.Expression>()); |
+ } |
+ |
+ /// Erases the precompiled information for csp mode for all output units. |
+ /// Used by the incremental compiler. |
+ void clearCspPrecompiledNodes() { |
+ _cspPrecompiledFunctions.clear(); |
+ _cspPrecompiledConstructorNames.clear(); |
+ } |
+ |
void addComment(String comment, CodeBuffer buffer) { |
buffer.write(jsAst.prettyPrint(js.comment(comment), compiler)); |
} |
@@ -823,16 +845,18 @@ class CodeEmitterTask extends CompilerTask { |
return ':$names'; |
} |
- jsAst.FunctionDeclaration buildPrecompiledFunction() { |
+ jsAst.FunctionDeclaration buildCspPrecompiledFunctionFor( |
+ OutputUnit outputUnit) { |
// TODO(ahe): Compute a hash code. |
return js.statement(''' |
function dart_precompiled(\$collectedClasses) { |
var \$desc; |
#; |
return #; |
- }''', [ |
- precompiledFunction, |
- new jsAst.ArrayInitializer.from(precompiledConstructorNames)]); |
+ }''', |
+ [cspPrecompiledFunctionFor(outputUnit), |
+ new jsAst.ArrayInitializer.from( |
+ cspPrecompiledConstructorNamesFor(outputUnit))]); |
} |
void generateClass(ClassElement classElement, ClassBuilder properties) { |
@@ -1433,13 +1457,14 @@ class CodeEmitterTask extends CompilerTask { |
} |
} |
- void emitPrecompiledConstructor(String constructorName, |
+ void emitPrecompiledConstructor(OutputUnit outputUnit, |
+ String constructorName, |
jsAst.Expression constructorAst) { |
- precompiledFunction.add( |
+ cspPrecompiledFunctionFor(outputUnit).add( |
new jsAst.FunctionDeclaration( |
new jsAst.VariableDeclaration(constructorName), constructorAst)); |
- precompiledFunction.add( |
- js.statement(r'''{ |
+ cspPrecompiledFunctionFor(outputUnit).add( |
+ js.statement(r'''{ |
#.builtin$cls = #; |
if (!"name" in #) |
#.name = #; |
@@ -1454,7 +1479,7 @@ class CodeEmitterTask extends CompilerTask { |
constructorName |
])); |
- precompiledConstructorNames.add(js('#', constructorName)); |
+ cspPrecompiledConstructorNamesFor(outputUnit).add(js('#', constructorName)); |
} |
void assembleProgram() { |
@@ -1621,7 +1646,9 @@ class CodeEmitterTask extends CompilerTask { |
// Also emit a trivial constructor for CSP mode. |
String constructorName = mangledName; |
jsAst.Expression constructorAst = js('function() {}'); |
- emitPrecompiledConstructor(constructorName, constructorAst); |
+ emitPrecompiledConstructor(mainOutputUnit, |
+ constructorName, |
+ constructorAst); |
} |
if (!mangledFieldNames.isEmpty) { |
@@ -1790,7 +1817,7 @@ class CodeEmitterTask extends CompilerTask { |
} |
jsAst.FunctionDeclaration precompiledFunctionAst = |
- buildPrecompiledFunction(); |
+ buildCspPrecompiledFunctionFor(mainOutputUnit); |
emitInitFunction(mainBuffer); |
emitMain(mainBuffer); |
mainBuffer.add('})()\n'); |
@@ -1798,7 +1825,8 @@ class CodeEmitterTask extends CompilerTask { |
if (compiler.useContentSecurityPolicy) { |
mainBuffer.write( |
jsAst.prettyPrint( |
- precompiledFunctionAst, compiler, |
+ precompiledFunctionAst, |
+ compiler, |
monitor: compiler.dumpInfoTask, |
allowVariableMinification: false).getText()); |
} |
@@ -2022,6 +2050,18 @@ class CodeEmitterTask extends CompilerTask { |
emitCompileTimeConstants(outputBuffer, outputUnit); |
outputBuffer.write('}$N'); |
+ |
+ if (compiler.useContentSecurityPolicy) { |
+ jsAst.FunctionDeclaration precompiledFunctionAst = |
+ buildCspPrecompiledFunctionFor(outputUnit); |
+ |
+ outputBuffer.write( |
+ jsAst.prettyPrint( |
+ precompiledFunctionAst, compiler, |
+ monitor: compiler.dumpInfoTask, |
+ allowVariableMinification: false).getText()); |
+ } |
+ |
String code = outputBuffer.getText(); |
// Make a unique hash of the code (before the sourcemaps are added) |
@@ -2033,7 +2073,7 @@ class CodeEmitterTask extends CompilerTask { |
compiler.outputProvider(outputUnit.partFileName(compiler), 'part.js') |
..add(code) |
..add('${deferredInitializers}["$hash"]$_=$_' |
- '${deferredInitializers}.current') |
+ '${deferredInitializers}.current$N') |
..close(); |
hunkHashes[outputUnit] = hash; |