千家信息网

Neo的Compiler工作怎么实现

发表于:2024-12-05 作者:千家信息网编辑
千家信息网最后更新 2024年12月05日,这篇文章主要介绍"Neo的Compiler工作怎么实现",在日常操作中,相信很多人在Neo的Compiler工作怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"N
千家信息网最后更新 2024年12月05日Neo的Compiler工作怎么实现

这篇文章主要介绍"Neo的Compiler工作怎么实现",在日常操作中,相信很多人在Neo的Compiler工作怎么实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"Neo的Compiler工作怎么实现"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

Compiler作用
  1. 在Neo区块链系统中,智能合约是一段代码,可以完成一定的逻辑,最后算出合约的结果。现在已经有很多具体的应用了,感兴趣的可以看一下基于Neo做的项目。

  2. 如果对比特币或者智能合约不了解,不知道为什么需要有这些代码,可以看一下比特币的白皮书。这里简单说一下,在比特币系统中,当一个"人"(可以看成一个公钥)需要和另一个"人"产生交易的时候,这段代码用来检查身份,分配比特币。具体的了解可以看一下普林斯顿的公开课

  3. 下面进入到Neo compiler的介绍了,前面所需的基础知识本文不在关注。

Compiler的框架

基本的流程

  1. Neo可以用各种语言写,不过现在主要是C#。

  2. Neo的编译器主要是一个翻译器

  3. C#代码被C#编译器编译成MSIL,对MSIL的理解可以查看Standard ECMA-335 Common Language Infrastructure (CLI)

  4. Neo compiler使用Mono.Cecil读取IL

  5. Neo编译器只关注C#中的static function,所以只是C#语言的一个超级阉割版

  6. Neo的编译器遍历IL,根据语义转成Neo虚拟机的opcode

  7. 至于MSIL向neo.vm的opcode怎么转,需要仔细研究neo.vm的opcode的设计

Compiler工作一个具体事例

先看一段智能合约代码

这段代码没有什么实际的作用,就是返回a+b,但是main可以接受参数。

using Neo.SmartContract.Framework;using Neo.SmartContract.Framework.Services.Neo;public class Sum : SmartContract{    public static int Main(int a, int b)    {        return a + b;    }}
MSIL

main function IL code

IL_0000 NopIL_0001 Ldarg_0IL_0002 Ldarg_1IL_0003 AddIL_0004 Stloc_0IL_0005 Br_SIL_0007 Ldloc_0IL_0008 Ret

这段代码很简单,就是读取参数Ldarg_0,Add,返回。可以看到CLR的虚拟机也是堆栈虚拟机。
关于基于栈的虚拟机和基于寄存器的虚拟机可以看一下这些文章:
栈式虚拟机和寄存器式虚拟机?
另外还有一篇概念讲解的很详细的文章虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩

neo.compiler

为了感性的认识neo编译器做了什么,我们可以看一下上面的只能合约被翻译成了什么

hex:53-C5-6B-6C-76-6B-00-52-7A-C4-6C-76-6B-51-52-7A-C4-61-6C-76-6B-00-C3-6C-76-6B-51-C3-93-6C-76-6B-52-52-7A-C4-62-03-00-6C-76-6B-52-C3-61-6C-75-66

实际上是一串数字了,每个数字对应一个vm的操作码或者是数值,为了更好理解,把汇编代码放出来

PUSH4PUSH3RETPUSH3NEWARRAYTOTALSTACKFROMALSTACKDUPTOALTSTACKPUSH0PUSH2ROLLSETITEMFROMALSTACKDUPTOTALSTACKPUSH1PUSH2ROLLSETITEMNOPFROMALSTACKDUPTOTALSTACKPUSH0PICKITEMFROMALSTACKDUPTOTALSTACKPUSH1PICKITEMADDFROMALSTACKDUPTOTALSTACKPUSH2PUSH2ROLLSETITEMJMPFROMALSTACKDUPTOTALSTACKPUSH2PICKITEMNOPFROMALSTACKDROPret

neo汇编的说明,可以查看这个文档

我们可以发现如下情况:

  1. MSIL的代码很短,Neo.VM的代码很长,这是由于虚拟机的指令和能力不同造成的。我们只需要关注,汇编代码处理了局部变量的存贮获取,参数的传递,程序的退出,还有add指令。

  2. 汇编代码和compiler的生成算法相关,需要我们去同时研究neo的编译器和虚拟机,才能明白具体的细节。

  3. 具体每一行的含义,怎么执行的,可以查看这个文档

  4. 后面还会有一个讲解虚拟机的文章,到那个时候在仔细说明

neo.compiler代码阅读指南

代码阅读还是很头痛的,所以做了两个脑图:

  1. compiler执行脑图

  2. compiler对象关系

对象关系

  1. ILModule是对MSIL的一个映射,包含模块,类型,函数,字段,函数中又包含返回值,参数,函数体,可以点开脑图一层一层查看。

  2. Mono.Cecil是使用来读取MSIL的,他也是对MSIL的一个映射,由于没有文档,只能看代码知道他的类结构了,这一部分在脑图中没有显示,不过没关系,compiler会把感兴趣的代码转成ILModule

  3. ModuleConverter用来遍历ILModule,把里面的MSIL转成Neo.VM的代码,存贮在NeoModule

  4. 具体两边的指令如何对应,真是需要一个一个理解的,非常繁琐,两边都有很多的指令。可以看看这个代码

到此,关于"Neo的Compiler工作怎么实现"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0