解释语言(如Ruby)如何运行?

Fra*_*öse 6 ruby compiler-construction interpreter programming-languages

我要学习Ruby.我知道这是一种解释性语言.我知道编译语言最终会被翻译成机器代码,但ruby解释器的作用是什么?我读到解释器是用C语言编写的,但是每一行ruby转换为c,它再次编译成机器代码?我也听说过JIT,但如果这给答案增加了很多复杂性,你就不需要回答这个问题了.我正在寻找的是我的Ruby代码会发生什么.

小智 8

它将Ruby代码转换为某种形式的更简单的"中间"表示(在最近的版本中,它编译为字节码).它还在您的计算机内存中构建一个虚拟机,该虚拟机模拟执行该表示的物理机器.

这台机器镜像物理机器,至少在合理和有用的范围内.它经常有一个用于指令的存储器,一个程序计数器,一个用于存储中间值和返回地址的堆栈等.一些更复杂的机器也有寄存器.有一个固定且相对原始的(与Ruby之类的语言相比,不与实际的CPU指令集相比)指令集.像CPU一样,虚拟机无休止地循环:

  • 读取当前指令(由程序计数器识别).
  • (对它进行解码,虽然这通常比实际CPU中的要简单得多,至少比CISC要简单得多.)
  • 执行它(在过程中可操作堆栈和/或寄存器).
  • 更新程序计数器.

使用解释器,所有这些都通过间接层发生.你的实际物理CPU不知道它在做什么.VM本身就是软件,上面的每个步骤都是委托给CPU的几个(在具有相当高级字节码指令的情况下,可能是几十或几百个)物理CPU周期.每次读取指令时都会发生这种情况.

输入JIT编译.最简单的形式只是将每个字节码指令替换为在解释器遇到它时将执行的代码(稍微优化)的副本.这已经给出了速度胜利,例如可以省略程序计数器操纵.但是甚至还有更聪明的变种.

例如,跟踪JIT以常规解释器开始,并另外观察它们执行的程序.如果他们注意到程序在特定代码段中花费了大量时间(几乎总是,循环或从循环中调用的函数),它会开始记录它在此期间的作用 - 它会生成一个跟踪.当它到达开始记录的点(循环的一次迭代之后)时,它会调用它一天并将跟踪编译为机器代码.但是由于它看到了程序在运行时的实际行为,它可以生成完全符合此行为的代码.以循环添加整数为例.机器代码不包含解释器实际执行的任何类型检查和函数调用.至少,它不会包含大部分内容.这,以确保正确性,补充的是,在何种条件下跟踪记录(例如,所涉及的变量均为整数)仍持有检查.当这样的检查失败时,它会退出并重新开始解释,直到记录另一条跟踪.但在此之前,它可以以与手写C代码相媲美的速度执行一百次迭代.