Dart 代码的组件集合Dart VM3

简介: 这是我参与8月更文挑战的第 8 天,活动详情查看:8月更文挑战。为应掘金的八月更文挑战,通过 JIT 运行源代码本节将介绍当从命令行执行 Dart 时会发生什么:

这是我参与8月更文挑战的第 8 天,活动详情查看:8月更文挑战。为应掘金的八月更文挑战

通过 JIT 运行源代码

本节将介绍当从命令行执行 Dart 时会发生什么:

// hello.dart
main() => print('Hello, World!');
$ dart hello.dart
Hello, World!
复制代码

「Dart 2 VM 开始不再具有从原始代码直接执行 Dart 的能力,相反 VM 希望获得包含序列化内核 AST 的内核二进制文件(也称为 dill 文件)」。将 Dart 源代码翻译成 Kernel AST 的任务是由通用前端 (CFE)处理的,CFE 是用 Dart 编写并在不同 Dart 工具上共享(例如 VM、dart2js、Dart Dev Compiler)。

网络异常,图片无法展示
|

为了保持直接从源代码执行 Dart ,这里托管一个名为 kernel service 的辅助 isolate,它处理将 Dart 源代码编译到内核中,然后 VM 运行生成的内核二进制文件。

网络异常,图片无法展示
|

然而这种设置并不是 CFE 和 VM 运行 Dart 代码的唯一方法,例如 「Flutter 是将编译到 Kernel 的过程和从 Kernel 执行的过程完全分离」,并将它们放在不同的设备上实现:编译发生在开发者机器(主机)上,执行在目标移动设备上处理,目标移动设备接收由 flutter 工具发送给它的内核二进制文件。

网络异常,图片无法展示
|

这里需要注意,该 Flutter 工具不处理 Dart 本身的解析, 相反它会生成另一个持久进程 frontend_server,它本质上是围绕 CFE 和一些 Flutter 特定的 Kernel-to-Kernel 转换的封装。

frontend_server 将 Dart 源代码编译为内核文件, 然后 flutter 将其发送到设备, 当开发人员请求热重载时 frontend_server 开始发挥作用:在这种情况下 frontend_server 可以重用先前编译中的 CFE 状态,并重新编译实际更改的库。

「一旦内核二进制文件加载到 VM 中,它就会被解析以创建代表各种程序实体的对象,然而这个过程是惰性完成的」:首先只加载关于库和类的基本信息,源自内核二进制文件的每个实体都保留一个指向二进制文件的指针,以便以后可以根据需要加载更多信息。

网络异常,图片无法展示
|

每当我们引用 VM 内部分配的对象时,我们都会使用 Untagged 前缀,因为这遵循了 VM 自己的命名约定:内部 VM 对象的布局由 C++ 类定义,名称以 Untagged头文件 runtime/vm/raw_object.h 开头。例如 dart::UntaggedClass 是描述一个 Dart 类 VM 对象, dart::UntaggedField 是一个 VM 对象

「只有在运行时需要它时(例如查找类成员、分配实例等),有关类的信息才会完全反序列化」,在这个阶段,类成员会从内核二进制文件中读取,然而在此阶段不会反序列化完整的函数体,只会反序列化它们的签名。

网络异常,图片无法展示
|

此时 methods 在运行时可以被成功解析和调用,因为已经从内核二进制文件加载了足够的信息,例如它可以解析和调用 main 库中的函数。

package:kernel/ast.dart 定义了描述内核 AST 的类; package:front_end处理解析 Dart 源代码并从中构建内核 AST。dart::kernel::KernelLoader::LoadEntireProgram是 将内核 AST 反序列化为相应 VM 对象的入口点;pkg/vm/bin/kernel_service.dart 实现了内核服务隔离,runtime/vm/kernel_isolate.cc 将 Dart 实现粘合到 VM 的其余部分; package:vm 承载大多数基于内核的 VM 特定功能,例如各种内核到内核的转换;由于历史原因一些特定于 VM 的转换仍然存在于 package:kernel 中。

最初所有的函数都会有一个占位符,而不是它们的主体的实际可执行代码:它们指向 LazyCompileStub,它只是要求运行时系统为当前函数生成可执行代码,然后 tail-calls 这个新生成的代码。

网络异常,图片无法展示
|

第一次编译函数时,是通过未优化编译器完成的。

网络异常,图片无法展示
|



相关文章
|
9月前
|
前端开发 JavaScript Android开发
React Native 和 Flutter对比,包含代码实例
@[TOC](目录) React Native 和 Flutter 都是流行的跨平台移动应用开发框架。虽然它们在很多方面都有相似之处,但它们也有一些不同之处。在本文中,我们将详细比较这两个框架,讨论它们的优缺点、应用场景、性能以及包含的代码。 # 1. 框架概述 React Native 是由 Facebook 开发的一个开源框架,它允许开发者使用 JavaScript 和 React 来创建原生移动应用。React Native 可以用于开发 iOS、Android 和 Web 应用。它使用 JavaScript 的生态系统和工具,如 Babel、ESLint 和 React 工具链,使得开
106 0
|
10月前
|
存储 Dart JavaScript
《深入浅出Dart》Dart库的使用和创建
Dart库的使用和创建 引言 在Dart中,代码重用和模块化可以通过库(libraries)和包(packages)实现。一个库就是一组代码,被一起打包为了实现一种或多种特定功能。一个包则是一种发布和分享Dart库的方式。在这一章,我们将详细介绍如何使用和创建Dart库和包,以及如何实现一个具有大数相加功能的库。 Dart库的使用
90 0
|
12月前
|
Dart 程序员 C++
Flutter 基础 | Dart 语法 mixin
Flutter 基础 | Dart 语法 mixin
99 0
|
12月前
|
Dart 编译器 索引
Flutter 基础 | Dart 语法
Flutter 基础 | Dart 语法
131 0
|
Dart 开发者
【Flutter】Dart 面向对象 ( get 方法 | set 方法 | 静态方法
【Flutter】Dart 面向对象 ( get 方法 | set 方法 | 静态方法
845 0
|
Dart 开发者
【Flutter】Dart 面向对象 ( mixins 特性 )
【Flutter】Dart 面向对象 ( mixins 特性 )
107 0
|
Dart
dart 类型提升
dart 类型提升
92 0
|
Dart IDE 开发工具
Flutter工程解析(如何运行写初始化一个Dart文件)
解析 — Flutter工程解析(如何运行写初始化一个Dart文件) 这是一节小白必看的解析哦~,如果你了解过一点Flutter的写法可以跳过这节.
Flutter工程解析(如何运行写初始化一个Dart文件)
|
Dart
Dart 之 接口
Dart 之 接口
65 0
Dart 之 接口
|
Dart
Dart之 方法定义
Dart之 方法定义
83 0
Dart之 方法定义