Index: pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart |
diff --git a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart |
index 9afa419b072f31cddda48e6782879f810e432bb1..5dad7489441018fff63555ce3cdd537ec41e53c2 100644 |
--- a/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart |
+++ b/pkg/compiler/lib/src/js_emitter/new_emitter/model_emitter.dart |
@@ -117,8 +117,8 @@ class ModelEmitter { |
if (isConstantInlinedOrAlreadyEmitted(value)) { |
return constantEmitter.generate(value); |
} |
- return js.js('#.#', [namer.globalObjectForConstant(value), |
- namer.constantName(value)]); |
+ return js.js('#.#()', [namer.globalObjectForConstant(value), |
+ namer.constantName(value)]); |
} |
int emitProgram(Program program) { |
@@ -153,6 +153,11 @@ class ModelEmitter { |
js.LiteralString unparse(Compiler compiler, js.Node value) { |
String text = js.prettyPrint(value, compiler).getText(); |
if (value is js.Fun) text = '($text)'; |
+ if (value is js.LiteralExpression && |
floitsch
2015/03/06 19:30:26
This captures the JS_CONST cases that had a litera
|
+ (value.template.startsWith("function ") || |
+ value.template.startsWith("{"))) { |
+ text = '($text)'; |
+ } |
return js.js.escapedString(text); |
} |
@@ -167,6 +172,8 @@ class ModelEmitter { |
List<js.Expression> elements = fragment.libraries.map(emitLibrary).toList(); |
elements.add( |
emitLazilyInitializedStatics(fragment.staticLazilyInitializedFields)); |
+ elements.add(emitConstants(fragment.constants)); |
+ |
js.Expression code = new js.ArrayInitializer(elements); |
@@ -184,7 +191,6 @@ class ModelEmitter { |
backend.emitter.staticFunctionAccess(backend.getCyclicThrowHelper()), |
'outputContainsConstantList': program.outputContainsConstantList, |
'embeddedGlobals': emitEmbeddedGlobals(program), |
- 'constants': emitConstants(fragment.constants), |
'staticNonFinals': |
emitStaticNonFinalFields(fragment.staticNonFinalFields), |
'operatorIsPrefix': js.string(namer.operatorIsPrefix), |
@@ -421,16 +427,14 @@ class ModelEmitter { |
deferredCode.add( |
emitLazilyInitializedStatics(fragment.staticLazilyInitializedFields)); |
+ deferredCode.add(emitConstants(fragment.constants)); |
floitsch
2015/03/06 19:30:26
This line was missing.
|
+ |
js.ArrayInitializer deferredArray = new js.ArrayInitializer(deferredCode); |
// This is the code that must be evaluated after all deferred classes have |
// been setup. |
- js.Statement immediateCode = js.js.statement('''{ |
- #constants; |
- #eagerClasses; |
- }''', |
- {'constants': emitConstants(fragment.constants), |
- 'eagerClasses': emitEagerClassInitializations(fragment.libraries)}); |
+ js.Statement immediateCode = |
+ emitEagerClassInitializations(fragment.libraries); |
js.LiteralString immediateString = unparse(compiler, immediateCode); |
js.ArrayInitializer hunk = |
@@ -439,13 +443,25 @@ class ModelEmitter { |
return js.js("$deferredInitializersGlobal[$hash] = #", hunk); |
} |
- js.Block emitConstants(List<Constant> constants) { |
- Iterable<js.Statement> statements = constants.map((Constant constant) { |
- js.Expression code = constantEmitter.generate(constant.value); |
- return js.js.statement("#.# = #;", |
- [constant.holder.name, constant.name, code]); |
- }); |
- return new js.Block(statements.toList()); |
+ // This string should be referenced wherever JavaScript code makes assumptions |
+ // on the constants format. |
+ static final String constantsDescription = |
+ "The constants are encoded as a follows:" |
+ " [constantsHolderIndex, name, code, name2, code2, ...]." |
+ "The array is completely empty if there is no constant at all."; |
+ |
+ js.ArrayInitializer emitConstants(List<Constant> constants) { |
+ List<js.Expression> data = <js.Expression>[]; |
+ if (constants.isNotEmpty) { |
+ int holderIndex = constants.first.holder.index; |
+ data.add(js.number(holderIndex)); |
+ data.addAll(constants.expand((Constant constant) { |
+ assert(constant.holder.index == holderIndex); |
+ js.Expression code = constantEmitter.generate(constant.value); |
+ return [js.string(constant.name), unparse(compiler, code)]; |
+ })); |
+ } |
+ return new js.ArrayInitializer(data); |
} |
js.Block emitStaticNonFinalFields(List<StaticField> fields) { |
@@ -814,10 +830,11 @@ function parseFunctionDescriptor(proto, name, descriptor) { |
var functionCounter = 0; |
function $setupProgramName(program) { |
- for (var i = 0; i < program.length - 1; i++) { |
+ for (var i = 0; i < program.length - 2; i++) { |
setupLibrary(program[i]); |
} |
setupLazyStatics(program[i]); |
+ setupConstants(program[i + 1]); |
} |
function setupLibrary(library) { |
@@ -863,6 +880,18 @@ function parseFunctionDescriptor(proto, name, descriptor) { |
} |
} |
+ function setupConstants(constants) { |
+ // $constantsDescription. |
+ if (constants.length == 0) return; |
+ // We assume that all constants are in the same holder. |
+ var holder = holders[constants[0]]; |
+ for (var i = 1; i < constants.length; i += 2) { |
+ var name = constants[i]; |
+ var initializer = constants[i + 1]; |
+ setupConstant(name, holder, initializer); |
+ } |
+ } |
+ |
function setupStatic(name, holder, descriptor) { |
if (typeof descriptor == 'string') { |
holder[name] = function() { |
@@ -935,12 +964,26 @@ function parseFunctionDescriptor(proto, name, descriptor) { |
// initialization failed. |
holder[name] = null; |
} |
+ // TODO(floitsch): the function should probably be unique for each |
+ // static. |
holder[getterName] = function() { return this[name]; }; |
} |
return result; |
}; |
} |
+ function setupConstant(name, holder, descriptor) { |
+ var c; |
+ holder[name] = function() { |
+ if (descriptor !== null) { |
+ c = compile(name, descriptor); |
+ name = null; |
+ descriptor = null; |
+ } |
+ return c; |
+ }; |
+ } |
+ |
function setupClass(name, holder, descriptor) { |
var patch = function() { |
var constructor = compileConstructor(name, descriptor); |
@@ -1051,9 +1094,6 @@ function parseFunctionDescriptor(proto, name, descriptor) { |
$setupProgramName(program); |
- // Initialize constants. |
- #constants; |
- |
// Initialize globals. |
#embeddedGlobals; |