mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 19:40:29 +00:00
Emit constants during expression compilation to js
Closes: https://github.com/dart-lang/sdk/issues/43963 Change-Id: Ic8af046b2cf1506984b84ea66b2676b3cc0f1771 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/169580 Commit-Queue: Anna Gringauze <annagrin@google.com> Reviewed-by: Nicholas Shahan <nshahan@google.com>
This commit is contained in:
parent
3eb34ef646
commit
42dc617ee8
|
@ -3002,12 +3002,49 @@ class ProgramCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
|
|||
// size on expression evaluation is better.
|
||||
// Issue: https://github.com/dart-lang/sdk/issues/43288
|
||||
var fun = _emitFunction(functionNode, name);
|
||||
var items = _typeTable?.discharge();
|
||||
var body = js_ast.Block([...?items, ...fun.body.statements]);
|
||||
|
||||
var types = _typeTable.discharge();
|
||||
var constants = _dischargeConstTable();
|
||||
|
||||
var body = js_ast.Block([...?types, ...?constants, ...fun.body.statements]);
|
||||
return js_ast.Fun(fun.params, body);
|
||||
}
|
||||
|
||||
/// Emit all collected const symbols
|
||||
///
|
||||
/// This is similar to how constants are emitted during
|
||||
/// initial compilation in emitModule
|
||||
///
|
||||
/// TODO: unify the code with emitModule.
|
||||
List<js_ast.Statement> _dischargeConstTable() {
|
||||
var items = <js_ast.Statement>[];
|
||||
|
||||
if (_constLazyAccessors.isNotEmpty) {
|
||||
var constTableBody = runtimeStatement(
|
||||
'defineLazy(#, { # }, false)', [_constTable, _constLazyAccessors]);
|
||||
items.add(constTableBody);
|
||||
_constLazyAccessors.clear();
|
||||
}
|
||||
|
||||
_copyAndFlattenBlocks(items, moduleItems);
|
||||
moduleItems.clear();
|
||||
return items;
|
||||
}
|
||||
|
||||
/// Flattens blocks in [items] to a single list.
|
||||
///
|
||||
/// This will not flatten blocks that are marked as being scopes.
|
||||
void _copyAndFlattenBlocks(
|
||||
List<js_ast.Statement> result, Iterable<js_ast.ModuleItem> items) {
|
||||
for (var item in items) {
|
||||
if (item is js_ast.Block && !item.isScope) {
|
||||
_copyAndFlattenBlocks(result, item.statements);
|
||||
} else {
|
||||
result.add(item as js_ast.Statement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
js_ast.Fun _emitFunction(FunctionNode f, String name) {
|
||||
// normal function (sync), vs (sync*, async, async*)
|
||||
var isSync = f.asyncMarker == AsyncMarker.Sync;
|
||||
|
|
|
@ -409,6 +409,28 @@ void main() {
|
|||
))
|
||||
''');
|
||||
});
|
||||
|
||||
test('function', () async {
|
||||
await driver.check(
|
||||
scope: <String, String>{'x': '1', 'y': '2', 'z': '3'},
|
||||
expression: 'main',
|
||||
expectedResult: '''
|
||||
(function(x, y, z) {
|
||||
var VoidTodynamic = () => (VoidTodynamic = dart.constFn(dart.fnType(dart.dynamic, [])))();
|
||||
dart.defineLazy(CT, {
|
||||
get C0() {
|
||||
return C0 = dart.fn(foo.main, VoidTodynamic());
|
||||
}
|
||||
}, false);
|
||||
var C0;
|
||||
return C0 || CT.C0;
|
||||
}(
|
||||
1,
|
||||
2,
|
||||
3
|
||||
))
|
||||
''');
|
||||
});
|
||||
});
|
||||
|
||||
group('Expression compiler tests in method:', () {
|
||||
|
@ -1313,7 +1335,16 @@ void main() {
|
|||
expression: 'const MyClass(1)',
|
||||
expectedResult: '''
|
||||
(function(p) {
|
||||
return C0 || CT.C0;
|
||||
dart.defineLazy(CT, {
|
||||
get C0() {
|
||||
return C0 = dart.const({
|
||||
__proto__: foo.MyClass.prototype,
|
||||
[_t]: 1
|
||||
});
|
||||
}
|
||||
}, false);
|
||||
var C0;
|
||||
return C0 || CT.C0;
|
||||
}(
|
||||
1
|
||||
))
|
||||
|
@ -1353,6 +1384,15 @@ void main() {
|
|||
expression: "const Key('t')",
|
||||
expectedResult: '''
|
||||
(function(p) {
|
||||
dart.defineLazy(CT, {
|
||||
get C0() {
|
||||
return C0 = dart.const({
|
||||
__proto__: foo.ValueKey.prototype,
|
||||
[value]: "t"
|
||||
});
|
||||
}
|
||||
}, false);
|
||||
var C0;
|
||||
return C0 || CT.C0;
|
||||
}(
|
||||
1
|
||||
|
|
Loading…
Reference in a new issue