mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 17:15:43 +00:00
dart2js: create constants lazily in the new emitter.
R=zarah@google.com Review URL: https://codereview.chromium.org//952973004 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@44326 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
parent
6e539eab53
commit
028b1d45b7
|
@ -118,8 +118,8 @@ class ModelEmitter {
|
||||||
if (isConstantInlinedOrAlreadyEmitted(value)) {
|
if (isConstantInlinedOrAlreadyEmitted(value)) {
|
||||||
return constantEmitter.generate(value);
|
return constantEmitter.generate(value);
|
||||||
}
|
}
|
||||||
return js.js('#.#', [namer.globalObjectForConstant(value),
|
return js.js('#.#()', [namer.globalObjectForConstant(value),
|
||||||
namer.constantName(value)]);
|
namer.constantName(value)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int emitProgram(Program program) {
|
int emitProgram(Program program) {
|
||||||
|
@ -154,6 +154,11 @@ class ModelEmitter {
|
||||||
js.LiteralString unparse(Compiler compiler, js.Node value) {
|
js.LiteralString unparse(Compiler compiler, js.Node value) {
|
||||||
String text = js.prettyPrint(value, compiler).getText();
|
String text = js.prettyPrint(value, compiler).getText();
|
||||||
if (value is js.Fun) text = '($text)';
|
if (value is js.Fun) text = '($text)';
|
||||||
|
if (value is js.LiteralExpression &&
|
||||||
|
(value.template.startsWith("function ") ||
|
||||||
|
value.template.startsWith("{"))) {
|
||||||
|
text = '($text)';
|
||||||
|
}
|
||||||
return js.js.escapedString(text);
|
return js.js.escapedString(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,6 +173,8 @@ class ModelEmitter {
|
||||||
List<js.Expression> elements = fragment.libraries.map(emitLibrary).toList();
|
List<js.Expression> elements = fragment.libraries.map(emitLibrary).toList();
|
||||||
elements.add(
|
elements.add(
|
||||||
emitLazilyInitializedStatics(fragment.staticLazilyInitializedFields));
|
emitLazilyInitializedStatics(fragment.staticLazilyInitializedFields));
|
||||||
|
elements.add(emitConstants(fragment.constants));
|
||||||
|
|
||||||
|
|
||||||
js.Expression code = new js.ArrayInitializer(elements);
|
js.Expression code = new js.ArrayInitializer(elements);
|
||||||
|
|
||||||
|
@ -185,7 +192,6 @@ class ModelEmitter {
|
||||||
backend.emitter.staticFunctionAccess(backend.getCyclicThrowHelper()),
|
backend.emitter.staticFunctionAccess(backend.getCyclicThrowHelper()),
|
||||||
'outputContainsConstantList': program.outputContainsConstantList,
|
'outputContainsConstantList': program.outputContainsConstantList,
|
||||||
'embeddedGlobals': emitEmbeddedGlobals(program),
|
'embeddedGlobals': emitEmbeddedGlobals(program),
|
||||||
'constants': emitConstants(fragment.constants),
|
|
||||||
'staticNonFinals':
|
'staticNonFinals':
|
||||||
emitStaticNonFinalFields(fragment.staticNonFinalFields),
|
emitStaticNonFinalFields(fragment.staticNonFinalFields),
|
||||||
'operatorIsPrefix': js.string(namer.operatorIsPrefix),
|
'operatorIsPrefix': js.string(namer.operatorIsPrefix),
|
||||||
|
@ -431,16 +437,14 @@ class ModelEmitter {
|
||||||
deferredCode.add(
|
deferredCode.add(
|
||||||
emitLazilyInitializedStatics(fragment.staticLazilyInitializedFields));
|
emitLazilyInitializedStatics(fragment.staticLazilyInitializedFields));
|
||||||
|
|
||||||
|
deferredCode.add(emitConstants(fragment.constants));
|
||||||
|
|
||||||
js.ArrayInitializer deferredArray = new js.ArrayInitializer(deferredCode);
|
js.ArrayInitializer deferredArray = new js.ArrayInitializer(deferredCode);
|
||||||
|
|
||||||
// This is the code that must be evaluated after all deferred classes have
|
// This is the code that must be evaluated after all deferred classes have
|
||||||
// been setup.
|
// been setup.
|
||||||
js.Statement immediateCode = js.js.statement('''{
|
js.Statement immediateCode =
|
||||||
#constants;
|
emitEagerClassInitializations(fragment.libraries);
|
||||||
#eagerClasses;
|
|
||||||
}''',
|
|
||||||
{'constants': emitConstants(fragment.constants),
|
|
||||||
'eagerClasses': emitEagerClassInitializations(fragment.libraries)});
|
|
||||||
|
|
||||||
js.LiteralString immediateString = unparse(compiler, immediateCode);
|
js.LiteralString immediateString = unparse(compiler, immediateCode);
|
||||||
js.ArrayInitializer hunk =
|
js.ArrayInitializer hunk =
|
||||||
|
@ -449,13 +453,25 @@ class ModelEmitter {
|
||||||
return js.js("$deferredInitializersGlobal[$hash] = #", hunk);
|
return js.js("$deferredInitializersGlobal[$hash] = #", hunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
js.Block emitConstants(List<Constant> constants) {
|
// This string should be referenced wherever JavaScript code makes assumptions
|
||||||
Iterable<js.Statement> statements = constants.map((Constant constant) {
|
// on the constants format.
|
||||||
js.Expression code = constantEmitter.generate(constant.value);
|
static final String constantsDescription =
|
||||||
return js.js.statement("#.# = #;",
|
"The constants are encoded as a follows:"
|
||||||
[constant.holder.name, constant.name, code]);
|
" [constantsHolderIndex, name, code, name2, code2, ...]."
|
||||||
});
|
"The array is completely empty if there is no constant at all.";
|
||||||
return new js.Block(statements.toList());
|
|
||||||
|
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) {
|
js.Block emitStaticNonFinalFields(List<StaticField> fields) {
|
||||||
|
@ -824,10 +840,11 @@ function parseFunctionDescriptor(proto, name, descriptor) {
|
||||||
var functionCounter = 0;
|
var functionCounter = 0;
|
||||||
|
|
||||||
function $setupProgramName(program) {
|
function $setupProgramName(program) {
|
||||||
for (var i = 0; i < program.length - 1; i++) {
|
for (var i = 0; i < program.length - 2; i++) {
|
||||||
setupLibrary(program[i]);
|
setupLibrary(program[i]);
|
||||||
}
|
}
|
||||||
setupLazyStatics(program[i]);
|
setupLazyStatics(program[i]);
|
||||||
|
setupConstants(program[i + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupLibrary(library) {
|
function setupLibrary(library) {
|
||||||
|
@ -873,6 +890,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) {
|
function setupStatic(name, holder, descriptor) {
|
||||||
if (typeof descriptor == 'string') {
|
if (typeof descriptor == 'string') {
|
||||||
holder[name] = function() {
|
holder[name] = function() {
|
||||||
|
@ -957,12 +986,26 @@ function parseFunctionDescriptor(proto, name, descriptor) {
|
||||||
// initialization failed.
|
// initialization failed.
|
||||||
holder[name] = null;
|
holder[name] = null;
|
||||||
}
|
}
|
||||||
|
// TODO(floitsch): the function should probably be unique for each
|
||||||
|
// static.
|
||||||
holder[getterName] = function() { return this[name]; };
|
holder[getterName] = function() { return this[name]; };
|
||||||
}
|
}
|
||||||
return result;
|
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) {
|
function setupClass(name, holder, descriptor) {
|
||||||
var patch = function() {
|
var patch = function() {
|
||||||
if (patch.ensureResolved == patch) {
|
if (patch.ensureResolved == patch) {
|
||||||
|
@ -1085,9 +1128,6 @@ function parseFunctionDescriptor(proto, name, descriptor) {
|
||||||
|
|
||||||
$setupProgramName(program);
|
$setupProgramName(program);
|
||||||
|
|
||||||
// Initialize constants.
|
|
||||||
#constants;
|
|
||||||
|
|
||||||
// Initialize globals.
|
// Initialize globals.
|
||||||
#embeddedGlobals;
|
#embeddedGlobals;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue