dart2js: add FragmentEmitter for startup-emitter.

R=sigmund@google.com

Review URL: https://codereview.chromium.org//1229913002 .
This commit is contained in:
Florian Loitsch 2015-07-14 11:23:51 +02:00
parent 562825e161
commit 9c2195e814
2 changed files with 93 additions and 2 deletions

View file

@ -0,0 +1,41 @@
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of dart2js.js_emitter.startup_emitter.model_emitter;
/**
* This class builds a JavaScript tree for a given fragment.
*
* A fragment is generally written into a separate file so that it can be
* loaded dynamically when a deferred library is loaded.
*
* This class is stateless and can be reused for different fragments.
*/
class FragmentEmitter {
final Compiler compiler;
final Namer namer;
final JavaScriptBackend backend;
final ConstantEmitter constantEmitter;
final ModelEmitter modelEmitter;
FragmentEmitter(this.compiler, this.namer, this.backend, this.constantEmitter,
this.modelEmitter);
js.Expression generateEmbeddedGlobalAccess(String global) =>
modelEmitter.generateEmbeddedGlobalAccess(global);
js.Expression generateConstantReference(ConstantValue value) =>
modelEmitter.generateConstantReference(value);
js.Statement emitMainFragment(Program program) {
MainFragment fragment = program.fragments.first;
throw new UnimplementedError('emitMain');
}
js.Statement emitDeferredFragment(DeferredFragment fragment,
js.Expression deferredTypes,
List<Holder> holders) {
throw new UnimplementedError('emitDeferred');
}
}

View file

@ -35,6 +35,8 @@ import 'package:js_runtime/shared/embedded_names.dart' show
import '../js_emitter.dart' show NativeGenerator, buildTearOffCode;
import '../model.dart';
part 'fragment_emitter.dart';
class ModelEmitter {
final Compiler compiler;
final Namer namer;
@ -124,7 +126,55 @@ class ModelEmitter {
}
int emitProgram(Program program) {
// TODO(floitsch): implement.
throw new UnimplementedError("startup-emitter.emitProgram");
List<Fragment> fragments = program.fragments;
MainFragment mainFragment = fragments.first;
int totalSize = 0;
FragmentEmitter fragmentEmitter =
new FragmentEmitter(compiler, namer, backend, constantEmitter, this);
// We have to emit the deferred fragments first, since we need their
// deferred hash (which depends on the output) when emitting the main
// fragment.
List<js.Expression> fragmentsCode = fragments.skip(1).map(
(DeferredFragment deferredFragment) {
js.Expression types =
program.metadataTypesForOutputUnit(deferredFragment.outputUnit);
return fragmentEmitter.emitDeferredFragment(
deferredFragment, types, program.holders);
}).toList();
js.Statement mainAst = fragmentEmitter.emitMainFragment(program);
js.TokenCounter counter = new js.TokenCounter();
fragmentsCode.forEach(counter.countTokens);
counter.countTokens(mainAst);
program.finalizers.forEach((js.TokenFinalizer f) => f.finalizeTokens());
for (int i = 0; i < fragmentsCode.length; ++i) {
String code = js.prettyPrint(fragmentsCode[i], compiler).getText();
totalSize += code.length;
compiler.outputProvider(fragments[i+1].outputFileName, deferredExtension)
..add(code)
..close();
}
String mainCode = js.prettyPrint(mainAst, compiler).getText();
compiler.outputProvider(mainFragment.outputFileName, 'js')
..add(buildGeneratedBy(compiler))
..add(mainCode)
..close();
totalSize += mainCode.length;
return totalSize;
}
String buildGeneratedBy(compiler) {
var suffix = '';
if (compiler.hasBuildId) suffix = ' version: ${compiler.buildId}';
return '// Generated by dart2js (fast startup), '
'the Dart to JavaScript compiler$suffix.\n';
}
}