1. 前端编译器和后端编译器的区别
编译流程粗略分为词法分析、语法分析、类型检查、中间代码生成、代码优化、目标代码生成、目标代码优化。中间代码生成及之前阶段都属于前端编译器的工作,前端和后端相互独立。
2. Flutter 前端编译器(flutter_frontend_server) 源码
github.com/flutter/eng… 入口方法:/bin/starter.dart main函数
3. Flutter 前端编译参数
dart --disable-dart-dev
flutter/bin/cache/artifacts/engine/darwin-x64/frontend_server.dart.snapshot
--sdk-root flutter/bin/cache/artifacts/engine/common/flutter_patched_sdk/
--target=flutter -Ddart.developer.causal_async_stacks=true
-Ddart.vm.profile=false
-Ddart.vm.product=false
--bytecode-options=source-positions,...
--enable-asserts
--track-widget-creation
--no-link-platform
--packages example/.packages
--output-dill example/.dart_tool/flutter_build/046a7caff7f8f88ac9d8ca5634391d78/app.dill
--depfile example/.dart_tool/flutter_build/046a7caff7f8f88ac9d8ca5634391d78/kernel_snapshot.d
package:example/main.dart
4. 源码分析
starter.dart
void main(List<String> args) async {
调用/lib/server.dart文件中的starter方法开始执行前端编译,如果返回码不为0,退出Dart虚拟机,抛出编译错误
final int exitCode = await starter(args);
if (exitCode != 0) {
exit(exitCode);
}
}
server.dart
Future<int> starter(
List<String> args, {
frontend.CompilerInterface compiler,
Stream<List<int>> input,
StringSink output,
frontend.ProgramTransformer transformer,
}) async {
//解析编译参数,解析流程参考: 《ArgParser源码分析》
ArgResults options = frontend.argParser.parse(args);
//创建_FlutterFrontendCompiler对象,用于对Dart代码进行编译
compiler ??= _FlutterFrontendCompiler(...);
//rest[0] = 'example/main.dart',即项目的入口文件
if (options.rest.isNotEmpty) {
//调用_FlutterFrontendCompiler对象的compile方法
return await compiler.compile(options.rest[0], options) ? 0 : 254;
}
}
//_FlutterFrontendCompiler类结构(_FlutterFrontendCompiler只是_FrontendCompiler的代理)
//其中_FrontendCompiler位于:frontend_server包下的frontend_server.dart文件
class _FlutterFrontendCompiler implements frontend.CompilerInterface {
final frontend.CompilerInterface _compiler;
//_FlutterFrontendCompile构造方法创建了一个FrontendCompiler对象
_FlutterFrontendCompiler(): _compiler = frontend.FrontendCompiler(...);
//将CompilerInterface接口中的方法都转发给 _compiler对象处理
@override
Future<bool> compile(String filename, ArgResults options,{IncrementalCompiler generator}) async {
return _compiler.compile(filename, options, generator: generator);
}
...
}
frontend_server.dart#FrontendCompiler
class FrontendCompiler implements CompilerInterface {
@override
Future<bool> compile(String entryPoint,ArgResults options,
{IncrementalCompiler generator}) async {
//从ArgResults中读取参数
_options = options;
...
//获取sdk-root目录
final Uri sdkRoot = _ensureFolderPath(options['sdk-root']);
//平台特性dill文件,里面包含了预编译的framework dart代码,包括类似core、service等库
final String platformKernelDill = options['platform'] ?? 'platform_strong.dill';
//获取.package文件的路径,用来索引三方package位置
final String packagesOption = _options['packages'];
...
//将上面获取到的参数,拼装成一个CompileOptions对象
final CompilerOptions compilerOptions = CompilerOptions()
..sdkRoot = sdkRoot
..fileSystem = _fileSystem
..packagesFileUri =
packagesOption != null ? resolveInputUri(packagesOption) : null
//将平台特性dill文件uri赋值给sdkSummary对象,dart编译器会优化处理, 后面会说明
..sdkSummary = sdkRoot.resolve(platformKernelDill)
..verbose = options['verbose']
..embedSourceText = options['embed-source-text']
..experimentalFlags = parseExperimentalFlags(
parseExperimentalArguments(options['enable-experiment']),
onError: (msg) => errors.add(msg))
..nnbdMode = (nullSafety == true) ? NnbdMode.Strong : NnbdMode.Weak
..onDiagnostic = _onDiagnostic;
...
//处理增量编译
if (options['incremental']) {
...
} else {
...
//调用compileToKernel将dart代码进行编译,生成Dart AST 语法树,
//并保存在Component对象中,下一节着重分析
results = await _runWithPrintRedirection(() => compileToKernel(
_mainSource, compilerOptions,
includePlatform: options['link-platform'],
aot: options['aot'],
useGlobalTypeFlowAnalysis: options['tfa'],
environmentDefines: environmentDefines,
enableAsserts: options['enable-asserts'],
useProtobufTreeShaker: options['protobuf-tree-shaker'],
useProtobufTreeShakerV2: options['protobuf-tree-shaker-v2'],
minimalKernel: options['minimal-kernel'],
treeShakeWriteOnlyFields: options['tree-shake-write-only-fields'],
fromDillFile: options['from-dill']));
}
if (results.component != null) {
//将生成的Component对象保存在app.dill文件中
await writeDillFile(results, _kernelBinaryFilename,
filterExternal: importDill != null || options['minimal-kernel'],
incrementalSerializer: incrementalSerializer);
...
//统计此次编译有哪些文件
final String depfile = options['depfile'];
if (depfile != null) {
await writeDepfile(compilerOptions.fileSystem, results.compiledSources,
_kernelBinaryFilename, depfile);
}
_kernelBinaryFilename = _kernelBinaryFilenameIncremental;
} else {
_outputStream.writeln(boundaryKey);
}
results = null; // Fix leak: Probably variation of http://dartbug.com/36983.
return errors.isEmpty;
}
}
compileToKernel
Future<KernelCompilationResults> compileToKernel(
Uri source, CompilerOptions options,
{bool includePlatform: false,
bool aot: false,
bool useGlobalTypeFlowAnalysis: false,
Map<String, String> environmentDefines,
bool enableAsserts: true,
bool genBytecode: false,
BytecodeOptions bytecodeOptions,
bool dropAST: false,
bool useProtobufTreeShaker: false,
bool useProtobufTreeShakerV2: false,
bool minimalKernel: false,
bool treeShakeWriteOnlyFields: false,
String fromDillFile: null}) async {
...
CompilerResult compilerResult;
if (fromDillFile != null) {
//如果提供了初始化文件,直接读取
//首次编译不走此方法,不分析
compilerResult =
await loadKernel(options.fileSystem, resolveInputUri(fromDillFile));
} else {
//调用kernelForProgram编译Dart代码,生成Component对象,下一节着重分析
compilerResult = await kernelForProgram(source, options);
}
...
if ((aot || minimalKernel) && component != null) {
// 对生成的Component对象,执行Transform处理,类似AGP中的Transform
await runGlobalTransformations(
options.target,
component,
useGlobalTypeFlowAnalysis,
enableAsserts,
useProtobufTreeShaker,
useProtobufTreeShakerV2,
errorDetector,
minimalKernel: minimalKernel,
treeShakeWriteOnlyFields: treeShakeWriteOnlyFields);
...
}
if (genBytecode && !errorDetector.hasCompilationErrors && component != null) {
...
await runWithFrontEndCompilerContext(source, options, component, () {
//根据Component中的AST信息,生成字节码数据,见此代码区域的下一个方法
generateBytecode(component,
libraries: libraries,
hierarchy: compilerResult.classHierarchy,
coreTypes: compilerResult.coreTypes,
options: bytecodeOptions);
});
}
}
//返回结果
return new KernelCompilationResults(
component,
loadedLibraries,
compilerResult?.classHierarchy,
compilerResult?.coreTypes,
compiledSources);
}
void generateBytecode(ast.Component component, {
BytecodeOptions options,
List<Library> libraries,
CoreTypes coreTypes,
ClassHierarchy hierarchy,
}) {
...
//创建BytecodeGenerator对象,处理每一个Library数据(Library: 可以理解为每个dart文件对应一个library对象)
final bytecodeGenerator = new BytecodeGenerator(
component, coreTypes, hierarchy, typeEnvironment, options);
for (library in libraries) {
bytecodeGenerator.visitLibrary(library);
}
});
}
BytecodeGenerator
class BytecodeGenerator extends RecursiveVisitor<Null> {
//开始访问文件
@override
visitLibrary(Library node) {
...
//处理文件中的每个方法
visitList(node.procedures, this);
//处理文件中的每个字段
visitList(node.fields, this);
...
}
@override
visitClass(Class node) {
//处理每个类中构造方法
visitList(node.constructors, this);
//处理每个类中的方法
visitList(node.procedures, this);
//处理每个类中的字段
visitList(node.fields, this);
...
}
@override
defaultMember(Member node) {
...
//asm代表BytecodeAssembler,将对应的Opcode值放入的asm类中的buffer中
asm.emitPushNull();
//把asm.buff数据放入到Component中
end(node, hasCode);
}
}
KernelForProgram
Future<CompilerResult> kernelForProgram(
Uri source, CompilerOptions options) async {
return (await kernelForProgramInternal(source, options));
}
Future<CompilerResult> kernelForProgramInternal(
Uri source, CompilerOptions options,
{bool retainDataForTesting: false, bool requireMain: true}) async {
ProcessedOptions pOptions =
new ProcessedOptions(options: options, inputs: [source]);
return await CompilerContext.runWithOptions(pOptions, (context) async {
//调用 generateKernelInternal方法生成Component对象,下一节分析
CompilerResult result = await generateKernelInternal(
includeHierarchyAndCoreTypes: true,
retainDataForTesting: retainDataForTesting);
Component component = result?.component;
if (component == null) return null;
if (requireMain && component.mainMethod == null) {
context.options.report(
messageMissingMain.withLocation(source, -1, noLength),
Severity.error);
return null;
}
return result;
});
}
generateKernelInternal
Future<CompilerResult> generateKernelInternal(
{bool buildSummary: false,
bool buildComponent: true,
bool truncateSummary: false,
bool includeOffsets: true,
bool retainDataForTesting: false,
bool includeHierarchyAndCoreTypes: false}) async {
return withCrashReporting<CompilerResult>(() async {
//获取UriTranslator对象(UriTranslator包含MapPackages对象),主要用于处理包目录。
UriTranslator uriTranslator = await options.getUriTranslator();
//创建DillTarget对象,用来处理平台特定Dill文件
DillTarget dillTarget =
new DillTarget(options.ticker, uriTranslator, options.target);
//对平台特定文件:platform_strong.dill文件进行解析,生成Component对象:sdkSummary
Component sdkSummary = await options.loadSdkSummary(null);
//剔除sdkSummary中external库,并将剩余Library加入到dillTarget.loader中
CanonicalName nameRoot = sdkSummary?.root ?? new CanonicalName.root();
if (sdkSummary != null) {
Set<Uri> excluded = externalLibs(sdkSummary);
//appendLibraries,见下一节
dillTarget.loader.appendLibraries(sdkSummary,
filter: (uri) => !excluded.contains(uri));
}
//标记dillTarget及Loader.libraries状态,见下一节
await dillTarget.buildOutlines();
//创建KernelTarget,用来解析dart源代码
KernelTarget kernelTarget =
new KernelTarget(fs, false, dillTarget, uriTranslator);
sourceLoader = kernelTarget.loader;
//设置源代码入口文件,如package:example/main.dart,见下一节
kernelTarget.setEntryPoints(options.inputs);
//对源码生成Component对象,构建AST大体结构,见下一节
Component summaryComponent =
await kernelTarget.buildOutlines(nameRoot: nameRoot);
Component component;
if (buildComponent) {
//处理AST细节,比如MethodBody之类的 ,见下一节
component = await kernelTarget.buildComponent(verify: options.verify);
if (options.debugDump) {
printComponentText(component,
libraryFilter: kernelTarget.isSourceLibrary);
}
options.ticker.logMs("Generated component");
}
//将Component对象包装在CompilerResult中,并返回
return new InternalCompilerResult(
summary: summary,
component: component,
classHierarchy:
includeHierarchyAndCoreTypes ? kernelTarget.loader.hierarchy : null,
coreTypes:
includeHierarchyAndCoreTypes ? kernelTarget.loader.coreTypes : null,
deps: new List<Uri>.from(CompilerContext.current.dependencies),
kernelTargetForTesting: retainDataForTesting ? kernelTarget : null);
}, () => sourceLoader?.currentUriForCrashReporting ?? options.inputs.first);
}
此方法重点方法:
- DillTarget.loader.appendLibraries()
- DillTarget.buildOutlines()
- KernelTarget.setEntryPoints()
- KernelTarget.buildOutlines()
- KernelTarget.buildComponent()
DillTarget.loader.appendLibraries()
List<DillLibraryBuilder> appendLibraries(Component component,
{bool filter(Uri uri), int byteCount: 0}) {
List<Library> componentLibraries = component.libraries;
List<Uri> requestedLibraries = <Uri>[];
DillTarget target = this.target;
for (int i = 0; i < componentLibraries.length; i++) {
Library library = componentLibraries[i];
Uri uri = library.importUri;
//找到非external类型的library
if (filter == null || filter(library.importUri)) {
//将library存入到全局变量libraries中
libraries.add(library);
//将library以 library.importUri: DillLibraryBuild(library) 的形式
//存入到DillTarget.libraryBuilders的Map类型变量中
target.addLibrary(library);
//存在临时变量
requestedLibraries.add(uri);
}
}
List<DillLibraryBuilder> result = <DillLibraryBuilder>[];
for (int i = 0; i < requestedLibraries.length; i++) {
//将DillTarget.libraryBuilders的数据,转存到
//Loader.builders和Loader.unParsedLibraries中
//Loader.builder: <Uri,LibraryBuilder>
//Loader.unParsedLibraries: List<LibraryBuilder>
result.add(read(requestedLibraries[i], -1));
}
target.uriToSource.addAll(component.uriToSource);
this.byteCount += byteCount;
return result;
}
DillTarget.buildOutlines()
@override
Future<Null> buildOutlines() async {
if (loader.libraries.isNotEmpty) {
//标记Loader数据状态,如下
await loader.buildOutlines();
loader.finalizeExports();
}
//标记DillTarget状态
isLoaded = true;
}
=========== DillLoader==============
Future<Null> buildOutlines() async {
ensureCoreLibrary();
while (unparsedLibraries.isNotEmpty) {
LibraryBuilder library = unparsedLibraries.removeFirst();
await buildOutline(library);
}
}
Future<Null> buildOutline(DillLibraryBuilder builder) async {
if (builder.library == null) {
unhandled("null", "builder.library", 0, builder.fileUri);
}
builder.markAsReadyToBuild();
}
=========== DillLibraryBuilder ==============
void markAsReadyToBuild() {
isReadyToBuild = true;
}
KernelTarget.setEntryPoints()
List<Uri> setEntryPoints(List<Uri> entryPoints) {
...
//读取入口文件,根据entryPoint创建SourceLibraryBuilder对象
//并存在到loader.builders和loader.unParsedLibraries中
loader.read(entryPoint, -1, accessor: loader.first, fileUri: fileUri);
}
return result;
}
KernelTarget.buildOutlines()
@override
Future<Component> buildOutlines({CanonicalName nameRoot}) async {
if (loader.first == null) return null;
return withCrashReporting<Component>(() async {
loader.createTypeInferenceEngine();
//读取unParsedLibraries数据,构建AST大纲
await loader.buildOutlines();
//完善Library子节点相关数据
loader.coreLibrary.becomeCoreLibrary();
dynamicType.bind(
loader.coreLibrary.lookupLocalMember("dynamic", required: true));
loader.resolveParts();
loader.computeLibraryScopes();
setupTopAndBottomTypes();
loader.resolveTypes();
loader.computeVariances();
loader.computeDefaultTypes(dynamicType, bottomType, objectClassBuilder);
List<SourceClassBuilder> myClasses =
loader.checkSemantics(objectClassBuilder);
loader.finishTypeVariables(objectClassBuilder, dynamicType);
loader.buildComponent();
installDefaultSupertypes();
installSyntheticConstructors(myClasses);
loader.resolveConstructors();
//创建Component对象
component =
link(new List<Library>.from(loader.libraries), nameRoot: nameRoot);
computeCoreTypes();
loader.buildClassHierarchy(myClasses, objectClassBuilder);
loader.computeHierarchy();
loader.performTopLevelInference(myClasses);
loader.checkSupertypes(myClasses);
loader.checkBounds();
loader.checkOverrides(myClasses);
loader.checkAbstractMembers(myClasses);
loader.checkRedirectingFactories(myClasses);
loader.addNoSuchMethodForwarders(myClasses);
loader.checkMixins(myClasses);
loader.buildOutlineExpressions();
installAllComponentProblems(loader.allComponentProblems);
loader.allComponentProblems.clear();
return component;
}, () => loader?.currentUriForCrashReporting);
}
####KernelTarget.buildComponent()
@override
Future<Component> buildComponent({bool verify: false}) async {
if (loader.first == null) return null;
return withCrashReporting<Component>(() async {
//构建AST细节。先构建大纲,然后在构建细节,主要是为了降低内存的使用
await loader.buildBodies();
finishClonedParameters();
loader.finishDeferredLoadTearoffs();
loader.finishNoSuchMethodForwarders();
List<SourceClassBuilder> myClasses = collectMyClasses();
loader.finishNativeMethods();
loader.finishPatchMethods();
finishAllConstructors(myClasses);
//对Component执行转化,比如 trackWidgetCreation Transformer
runBuildTransformations();
if (verify) this.verify();
installAllComponentProblems(loader.allComponentProblems);
return component;
}, () => loader?.currentUriForCrashReporting);
}