关于断言“你的ruby代码从未被翻译成机器语言”

时间:2016-07-10 18:49:23

标签: ruby compilation low-level

我正在阅读显微镜下的Ruby书,我不理解第二章中的引用部分:

根据我的理解,运行ruby程序的过程大致如下

  • 阅读文件并将其标记为

  • 使用语法规则,将这些标记转换为抽象语法树中的指令。

  • 遍历节点,将它们转换为YARV字节码(此步骤称为编译?)。

最后一个是困扰我的那个

  • “Ruby从不编译Ruby代码一直到机器语言。 [...] Ruby解释字节码指令。“

我的问题是,为了理解和执行那些字节码指令,我不应该在之前将它们转换为汇编/机器代码吗?如果没有,机器如何理解它们?

2 个答案:

答案 0 :(得分:1)

不,你陷入困境的声明只能说明问题。 Ruby字节代码解释器代表字节代码执行评估,并将结果(在大多数情况下)传递给下一个要评估的字节代码集。

它比这更复杂,但把它想象成Ruby字节代码和本机之间的处理层。

答案 1 :(得分:1)

  

“Ruby从不编译你的Ruby代码一直到机器语言。[...] Ruby解释字节码指令。”

这句话是 - 如果不是完全错误 - 非常误导。

首先,Ruby是一种编程语言。编程语言不编译或解释任何东西。编译器和口译员这样做。编程语言只是一组抽象的数学规则和限制。

其次,Ruby有许多不同的实现:RubiniusJRubyIronRubyMacRubyMRubyTopaz,{ {3}},CardinalOpalMagLev,......而且它们的工作方式完全不同。例如,Rubinius将Ruby编译为Rubinius字节码,然后在解释该字节码时收集一些统计信息,然后使用这些统计信息将字节码编译为高效,高性能的本机机器码。 JRuby解释JRuby AST并同时收集统计信息,然后将JRuby AST编译为JRuby编译器IR,使用统计信息对其进行优化,然后将其进一步编译为JVM字节码。然后JVM对该字节码执行的操作取决于特定的JVM实现,但大多数JVM最终会将JVM字节码编译为高效,高性能的本机机器代码。 Opal将Ruby代码编译为ECMAScript代码,大多数ECMAScript实现最终将ECMAScript源代码编译为高效,高性能的本机代码。

第三,“机器语言”甚至意味着什么? YARV字节码是YARV机器的机器语言,不是吗?有些CPU可以直接执行JVM字节码,这是否意味着JVM字节码是机器语言?有YARV,这是否意味着x86对象代码不是机器语言?如果我在ARM机器上的.NET之上运行interpreters running on the JVM that can interpret x86 object code之上的x86解释器怎么办?什么是机器语言?

所以,回顾一下:

  • Ruby是一种语言,而不是一种实现,声明甚至没有意义。
  • 大多数Ruby实现(Rubinius,Topaz,MacRuby,MagLev)或至少可以(JRuby,IronRuby,Opal,Cardinal)最终使用本机机器代码。
  • 无论如何,术语“机器语言”都是不明确的。
  

我的问题是,为了理解和执行那些字节码指令,我不应该在之前将它们转换为汇编/机器代码吗?

不,翻译员理解并执行它们。如果它将它们翻译成其他东西,它将是一个编译器,而不是一个解释器。

编译器会进行转换,但不会运行。解释器运行,但不翻译。你需要一个解释器某处,你不能只用编译器运行一个程序。编译器只是将程序从一种语言翻译成另一种语言。期。如果你想实际运行该程序,你需要一个解释器。该解释器可以用硬件实现,在这种情况下我们称之为“CPU”,但它仍然只是一个解释器。

另请参阅Programmers.SE上的IKVM (a JVM running on top of .NET)

  

如果没有,机器如何理解它们?

没有。口译员理解他们。它以与编译器理解它们相同的方式理解它们,除了生成与输入程序的语义相对应的代码,它运行代码对应于输入程序的语义。

另请参阅Programmers.SE上的Understanding the differences: traditional interpreter, JIT compiler, JIT interpreter and AOT compilerDoes an interpreter produce machine code?