写在前面
Dart VM 在运行时会对 .dart 文件编译成 .dill 文件,有时候我们可以通过查看 .dill 文件来从更深一层的角度来理解代码。本篇主要是 .dill 文件的编译和查看,后续补充一些实际的例子。
内容
准备
由于在 Dart 打包出来的 SDK 和 Flutter 下的 SDK 都是有经过筛选的,像在这里我们需要用到一个 dump_kernel.dart 文件,这个在打包出来的 SDK 里是没有的。
所以首先我们去 GitHub 上 clone 完整的 dart-sdk。
假如我们电脑里没有 Flutter,那我们直接把 clone 下的 dart-sdk 配置到环境变量,然后就可以直接使用。
如果有 Flutter,那么此时的 dart 命令应该就是 Flutter 的,那么我们要确保当前 Flutter 的 dart-sdk 跟我们 clone 下的 dart-sdk 的版本一致。
举个例子,通过dart --version
命令查看 Flutter 下的 dart-sdk 版本:
➜ dart --version
Dart SDK version: 2.14.0-188.5.beta (beta) (Thu Jun 24 15:29:20 2021 +0200) on “macos_x64”
这里是 2.14.0-188.5.beta,然后我们可以将我们 clone 下的 dart-sdk 切换到相应的 tag,这样两边就一致了。
➜ git checkout 2.14.0-188.5.beta
Note: checking out ‘2.14.0-188.5.beta’.
编译
假设我们现在写了一个 main.dart 文件,想要查看其编译代码文件,我们先执行dart compile kernel main.dart
,这样就生成了 main.dill 文件。
接着通过dart .../pkg/vm/bin/dump_kernel.dart main.dill main.txt
就会将编译代码输出到 main.txt 里,这样我们就可以查看编译代码了。
dump_kernel.dart 文件就是在我们 clone 下的 dart-sdk 的 pkg 目录里,上面的路径要根据自己的情况补全。
由于我们前面将 Flutter 的 dart-sdk 和 clone 下的 dart-sdk 做到了版本一致,所以我们的命令就可以正常进行。否则会出现类似以下的错误:
Unhandled exception:
Unexpected Kernel Format Version 60 (expected 65)
#0 BinaryBuilder.readComponent. (package:kernel/binary/ast_from_binary.dart:601:9)
#1 Timeline.timeSync (dart:developer/timeline.dart:163:22)
#2 BinaryBuilder.readComponent (package:kernel/binary/ast_from_binary.dart:588:21)
#3 main (file:///…/dart_sdk/sdk/pkg/vm/bin/dump_kernel.dart:54:40)
#4 _delayEntrypointInvocation. (dart:isolate-patch/isolate_patch.dart:281:32)
#5 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)