Ruby MRI是什么样的解释器?

4

它是一种语言解释器吗?还是一个字节码解释器/即时编译器?除了浏览源代码外,我在哪里可以了解更多有关实现的信息?

3个回答

9
注意:“MRI”这个术语很令人困惑。它代表“Matz's Ruby/Reference Implementation/Interpreter(Matz的Ruby / 参考实现 / 解释器)”。但是,MRI已经被废弃了,不再开发或维护。
MRI是一个纯AST解释器,没有涉及任何编译。
让人困惑的是:Matz编写了一种新的实现,但那个叫做MRuby,而不是MRI。现在称为MRI的实现并非由Matz编写。因此,最好根本不使用该术语,并明确你正在谈论哪个实现。
人们现在称为MRI的实现名称实际上是YARV(Yet Another Ruby VM的缩写),由Koichi Sasada编写。它由一个Ahead-Of-Time编译器和一个解释器组成,编译Ruby源代码为YARV字节码,然后解释该字节码。因此,它是一个完全典型的字节码虚拟机,就像Python的CPython,PHP的Zend Engine,Lua VM,旧版本的Rubinius,ECMAScript的旧版本的SpiderMonkey等一样。
有关在YARV 3中向YARV字节码添加JIT编译器以将其编译为本机机器代码的讨论,这将使VM成为混合模式执行引擎。
Matz的当前实现MRuby也是一个字节码虚拟机。
为了完整起见,这里有一些其他的Ruby实现,首先是目前已准备好使用的实现,然后是一些历史上有趣的实现:
Rubinius:将Ruby源代码编译为Rubinius字节码,然后将其传递给一个由字节码解释器和基于LLVM的JIT编译器组成的混合模式执行引擎;他们最近引入或正在引入一个单独的Intermediate Representation(IR)用于JIT编译器,因此解释器从Rubinius字节码中工作,但JIT编译器从Compiler IR中工作。 Rubinius也属于“历史上有趣”的类别,因为它是第一个重要部分用Ruby实现的成功的Ruby实现;之前还有其他项目,但Rubinius是第一个准备就绪的项目。
JRuby:主要模式是由AST解释器和JIT编译器组成的混合模式执行引擎,它首先将AST转换为IR,然后进一步编译为JVM字节码。另一种模式是AOT编译器,其在运行之前将Ruby源代码编译为JVM字节码。
Opal:一个Ahead-Of-Time编译器,将Ruby源代码编译为ECMAScript源代码。
MagLev:基于GemStone / S Smalltalk VM的实现。不幸的是,我对它不太了解,我认为它将Ruby源代码编译为GemStone / S字节码,然后GemStone / S VM是一个标准的混合模式VM,具有字节码解释器和JIT编译器。
一些历史上有趣但不再维护的实现:
  • Topaz:使用RPython/PyPy VM框架实现的解释器;PyPy框架很有趣,因为它包含一个跟踪JIT编译器,与其他JIT编译器不同的是,它并不是在解释器旁边工作,而是在解释用户程序时编译解释器。这基本上意味着JIT只需要由PyPy开发人员编写一次,而每个使用PyPy框架的语言实现者只需要编写一个简单的字节码解释器就可以免费获得优化的本地JIT编译器。
  • XRuby:针对JVM实现的Ruby第一个静态AOT编译器。
  • IronRuby:最初是一个纯JIT编译器,没有解释器,但后来添加了一个解释器,因为事实证明这实际上提高了性能(这与流行的“解释器很慢”的神话相反)。
  • unholy:一个将YARV字节码编译成CPython字节码的概念证明AOT编译器;当Google App Engine首次推出并且仅支持Python时,_why the lucky stiff就实现了它,其想法是您可以使用YARV将Ruby源代码编译为YARV字节码,使用unholy将YARV字节码编译为CPython字节码,使用decompyle将CPython字节码编译为Python源代码,然后上传Python源代码到GAE运行您的全新的Ruby应用程序。
  • 荣誉提名:tinyrb、metaruby、Ruby.NET、Red Sun、HotRuby、BlueRuby、SmallRuby

一些有趣的当前研究项目包括:

  • JRuby+Truffle:该项目正在使用来自Oracle Labs的Truffle AST解释器框架重新实现JRuby的内部;在启用了Graal的JVM上运行时,此版本能够获得类似于Java的性能,有时甚至达到(并超过)C。
  • Ruby+OMR:IBM已经将其J9 JVM拆分为可以独立重复使用的、语言无关的构建块,并在Eclipse伞下以开源许可证发布为Eclipse Open Managed Runtime。这不是一个学术项目:IBM J9的Java 8版本实际上是使用OMR实现的。 Ruby+OMR项目是OMR开发人员的概念证明,将YARV的垃圾回收器替换为OMR的,并将OMR的JIT编译器、分析器和调试器添加到YARV中。令人印象深刻的是,所有东西都非常独立于语言,整个补丁不到10000行,这不仅是粘合代码,它实际上包括所有所需的OMR组件(还有一个相当Python+OMR项目,但这仍然是不公开的)。
最后,你可能会听到“Rite”的名字。在过去的十年中,“Rite”被用作MRI的完全重写的代号。Matz说当他编写MRI时,他实际上对语言实现一无所知,因此他想第二次做得“正确”(明白吗?)。同时,也有很多关于Ruby 2.0的讨论,希望解决语言中存在已久的设计缺陷。这两者被合并在一起,因此Rite被称为Ruby 2.0的新实现。但是,YARV出现了,它非常优秀,以至于Matz决定他不需要自己编写VM,他基本上认为“YARV就是Rite”。

但现在,他仍然编写了自己的VM,这就是为什么有时候你会听到MRuby(或其VM组件)被称为“Rite”的原因。


4

这是一个名为YARV的字节码解释器,由Sasada Koichi编写。

以下是一个示例:

puts RubyVM::InstructionSequence.compile("1+1").disasm
== disasm: #<ISeq:<compiled>@<compiled>>================================
0000 trace            1                                               (   1)
0002 putobject_OP_INT2FIX_O_1_C_
0003 putobject_OP_INT2FIX_O_1_C_
0004 opt_plus         <callinfo!mid:+, argc:1, ARGS_SIMPLE>, <callcache>
0007 leave

更多阅读:

虽然MRI目前还没有JIT,但有Ruby+OMR项目正在尝试基于Eclipse OMR添加JIT编译器:


哇!真有趣!我不知道它可以从语言内部获得。 - user6245072
我刚刚为您添加了更多信息 :-) - Michael Kohl
我仍然不理解字节码解释器和JIT编译器之间的区别。在软件工程中提出了一个问题。感谢您的回答! - user6245072
2
@user6245072:关键区别就是:解释器执行程序,编译器将程序从一种语言翻译成另一种语言。AOT vs. JIT 指的是编译发生的时间:ahead-of-time 是在运行时之前,just-in-time 是在运行时。 - Jörg W Mittag

1

Ruby现在拥有一个由VM生成的JIT编译器!

自从2.6.0-preview1分支合并后,Ruby现在拥有一个基本的JIT编译器,称为“MJIT”(YARV MRI Jit)。它受到了Vladimir Makarov的作品的启发,他提出了一种基于RTL(寄存器传输语言)的指令集,而不是基于堆栈的指令集。由于并非所有指令路径都由MJIT处理,因此速度提升尚不明显,但该分支包含了未来工作的基础。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接