Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
解释语言(如Ruby)是如何运行的?_Ruby_Compiler Construction_Programming Languages_Interpreter - Fatal编程技术网

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

解释语言(如Ruby)是如何运行的?,ruby,compiler-construction,programming-languages,interpreter,Ruby,Compiler Construction,Programming Languages,Interpreter,我要学红宝石。我知道这是一种解释性语言。我知道编译后的语言最终会被翻译成机器代码,但是ruby解释器做什么呢?我读到解释器是用C编写的,但是ruby的每一行是否都会转换成C,然后再编译成机器代码?我也听说过JIT,但是如果这增加了答案的复杂性,你就不需要回答这个问题了。我要寻找的是我的Ruby代码发生了什么。它将Ruby代码转换为某种形式的更简单的“中间”表示(在最近的版本中,它编译成字节码)。它还在计算机内存中构建一个虚拟机,模拟执行该表示的物理机 这台机器反映了物理机器,至少在合理和有用的范

我要学红宝石。我知道这是一种解释性语言。我知道编译后的语言最终会被翻译成机器代码,但是ruby解释器做什么呢?我读到解释器是用C编写的,但是ruby的每一行是否都会转换成C,然后再编译成机器代码?我也听说过JIT,但是如果这增加了答案的复杂性,你就不需要回答这个问题了。我要寻找的是我的Ruby代码发生了什么。

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

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

  • 读取当前指令(由程序计数器标识)
  • (对其进行解码,尽管这通常比实际CPU要简单得多,至少比CISC CPU要简单得多。)
  • 执行它(可能在进程中操作堆栈和/或寄存器)
  • 更新程序计数器
有了解释器,所有这些都是通过一层间接寻址实现的。您的实际物理CPU不知道它在做什么。虚拟机本身就是软件,上面的每一步都是在几个物理CPU周期内(在具有相当高级别字节码指令的情况下,可能是几十个或几百个)委托给CPU的。每次读取指令时都会发生这种情况

进入JIT编译。最简单的形式只是将每个字节码指令替换为解释器遇到时将执行的代码副本(稍微优化)。这已经带来了速度优势,例如,可以忽略程序计数器操作。但还有更聪明的变种

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