diff --git a/language/documentation/spec/vm.md b/language/documentation/spec/vm.md index fea24adb6b..97847859ae 100644 --- a/language/documentation/spec/vm.md +++ b/language/documentation/spec/vm.md @@ -495,7 +495,7 @@ Signature tokens examples: * `u8, u128, A` where A is a struct -> `0x3 0x2 0x4 0x8 0x10` - size(`0x3`), U8(`0x2`), u128(`0x4`), Struct::A (`0x8 0x10` assuming the struct is in the `STRUCT_HANDLES` table at position `0x10`) -* `vector
, &A` where A is a struct -> `0x2 0xA 0x5 0x8 0x10` - size(`0x2`), +* `vector, &A` where A is a struct -> `0x2 0xA 0x5 0x6 0x8 0x10` - size(`0x2`), vector(`0xA 0x5`), &Struct::A (`0x6 0x8 0x10` assuming the struct is in the `STRUCT_HANDLES` table at position `0x10`) * `vector, &A` where A and B are a struct -> diff --git a/language/documentation/spec/vm_cn.md b/language/documentation/spec/vm_cn.md new file mode 100644 index 0000000000..061818460a --- /dev/null +++ b/language/documentation/spec/vm_cn.md @@ -0,0 +1,404 @@ +# MoveVM Specification + +**Move VM** 的实例化其实就是初始化一个 *Loader* 实例,而初始化的 *Loader* 实际上就是一小组空白的 `Tables`(其背后是通过 `Mutex` 保护的少量几个 `HashMap` 和 `Vec`)。因此,**VM** 的初始化相当便宜。*Loader* 本质上就是一个 `Code Cacher`,其拥有 **VM** 等长的生命周期。当 `functions` 和 `scripts` 执行的时候,代码首先会在 *runtime* 中得以加载。一旦加载之后,`modules` 和 `scripts` 就会做好立即执行的准备,且可以以加载的形式重新使用。加载代码是昂贵的,且 **VM** 执行急迫(`Eager`)加载。当执行开始后,就不会再加载了。也就是说,所有(可能通过任意控制流)的代码都会在加载阶段就缓存好以备执行。也许更重要的是,该 `Eager`模型确保了在运行时不会有链接错误,并且给定的调用是不会因为代码路径的不同而出现加载或链接错误的。该调用的一致性在执行之前就得以保证。很明显,运行时错误是仍然可能且可“预期的”。 + +上述模型非常适合典型的区块链需求: + +* 仅仅使用有限的几个在创世时就发布的函数,就足以验证。一旦加载,代码就总是可以从缓存中取出并立即可用; +* 执行是在给定数据视图的上下文中进行的,该数据视图稳定且不可变。由于这些代码也是稳定的,因此优化上述加载的过程是很重要的。此外,交易的结构也是相当类似的,且代码的重用也可以显著的提升性能和稳定性; + +**Move VM**有一个数据缓存的内部实现以减轻客户端的重任(数据缓存一致性)。该抽象位于 *Session* 之后,`Session`是和 *Runtime* 交流的唯一方式。 + +*Session* 的目标是创建和管理一组对 **VM** 中的调用的数据缓存。它还旨在以适合适配器的格式返回副作用。*Session* 将调用转发到 *Runtime* ,*Runtime* 是 **VM** 逻辑和实现所存在和启动的地方。 + +### Code Cache + +当首次加载 *Module* 时,**VM** 会在数据存储中查询该 *Module*。其二进制数据被 *Loader* 反序列化,验证,加载,缓存。一旦加载后,该 *Module* 在该 **VM** 实例的生命周期内便永远不会再请求。在该系统中,代码是不可变资源。 + +`加载` 过程可以被概括为以下步骤: + +1. 从数据存储中取得以序列化形式表示的二进制 *Module*(`Vec