我正在阅读显微镜下的Ruby书,我不理解第二章中的引用部分:
根据我的理解,运行ruby程序的过程大致如下
阅读文件并将其标记为
使用语法规则,将这些标记转换为抽象语法树中的指令。
遍历节点,将它们转换为YARV字节码(此步骤称为编译?)。
最后一个是困扰我的那个
我的问题是,为了理解和执行那些字节码指令,我不应该在之前将它们转换为汇编/机器代码吗?如果没有,机器如何理解它们?
答案 0 :(得分:1)
不,你陷入困境的声明只能说明问题。 Ruby字节代码解释器代表字节代码执行评估,并将结果(在大多数情况下)传递给下一个要评估的字节代码集。
它比这更复杂,但把它想象成Ruby字节代码和本机之间的处理层。
答案 1 :(得分:1)
“Ruby从不编译你的Ruby代码一直到机器语言。[...] Ruby解释字节码指令。”
这句话是 - 如果不是完全错误 - 非常误导。
首先,Ruby是一种编程语言。编程语言不编译或解释任何东西。编译器和口译员这样做。编程语言只是一组抽象的数学规则和限制。
其次,Ruby有许多不同的实现:Rubinius,JRuby,IronRuby,MacRuby,MRuby,Topaz,{ {3}},Cardinal,Opal,MagLev,......而且它们的工作方式完全不同。例如,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解释器怎么办?什么是机器语言?
所以,回顾一下:
我的问题是,为了理解和执行那些字节码指令,我不应该在之前将它们转换为汇编/机器代码吗?
不,翻译员理解并执行它们。如果它将它们翻译成其他东西,它将是一个编译器,而不是一个解释器。
编译器会进行转换,但不会运行。解释器运行,但不翻译。你需要一个解释器某处,你不能只用编译器运行一个程序。编译器只是将程序从一种语言翻译成另一种语言。期。如果你想实际运行该程序,你需要一个解释器。该解释器可以用硬件实现,在这种情况下我们称之为“CPU”,但它仍然只是一个解释器。
另请参阅Programmers.SE上的IKVM (a JVM running on top of .NET)。
如果没有,机器如何理解它们?
没有。口译员理解他们。它以与编译器理解它们相同的方式理解它们,除了生成与输入程序的语义相对应的代码,它运行代码对应于输入程序的语义。
另请参阅Programmers.SE上的Understanding the differences: traditional interpreter, JIT compiler, JIT interpreter and AOT compiler和Does an interpreter produce machine code?。