PyPy自己翻译吗?

2024-03-28 20:50:32 发布

您现在位置:Python中文网/ 问答频道 /正文


Tags: python
2条回答

PyPy的翻译过程实际上在概念上的递归性比听起来要差得多。

实际上,它只是一个Python程序,处理Python函数/类/其他对象(不是Python源代码)并输出C代码。当然,它不会处理任何Python对象;它只能处理特定的表单,如果您用RPython编写要翻译的代码,就会得到这些表单。

由于翻译工具链是一个Python程序,您可以在任何Python解释器之上运行它,很明显,它包括PyPy的Python解释器。所以没什么特别的。

因为它转换了RPython对象,所以您可以使用它来转换pypyy的python解释器,它是用RPython编写的。

但是您不能在翻译框架本身上运行它,它是而不是RPython。只有PyPy的python解释器本身是RPython。

事情之所以有趣,是因为RPython代码也是Python代码(但不是相反),而且RPython在源文件中并不“真正存在”,而是只存在于工作Python进程中的内存中,该进程必须包含其他非RPython代码(例如,没有“纯RPython”导入或函数定义,因为翻译器操作已经定义并导入了的函数。

请记住,转换工具链对内存中的Python代码对象进行操作。Python的执行模型意味着这些在一些Python代码运行之前不存在。如果高度简化,可以想象开始翻译过程有点像这样:

from my_interpreter import main
from pypy import translate

translate(main)

众所周知,只导入main将运行大量Python代码,包括所有其他模块my_interpreter导入。但是转换过程开始分析函数对象main;它从不看到,也不关心执行什么代码来产生main

一种方法是,“用RPython编程”意味着“编写一个Python程序,生成一个RPython程序,然后将其提供给翻译过程”。这是相对容易理解的,并且有点类似于其他编译器的工作方式(例如,用C语言编程的一种方法是,你实际上是在编写一个生成C程序的C预处理器程序,然后将其输入C编译器)。

在PyPy的情况下,事情只会变得混乱,因为所有3个组件(生成RPython程序的Python程序、RPython程序和转换过程)都加载到同一个Python解释器中。这意味着当用一些参数调用而不是用其他参数调用时,很可能有一些函数是RPython,从翻译框架中调用helper函数作为生成RPython程序的一部分,以及许多其他奇怪的事情。因此,这种情况在边缘变得相当模糊,您不必将源代码行清晰地划分为“要翻译的RPython”、“Python生成我的RPython程序”和“将RPython程序移交给翻译框架”。


The PyPy interpreter, running on top of CPython, executes to partially interpret itself

我想你在这里指的是PyPy在翻译过程中使用the flow object space来做抽象解释。即使这样也不像一开始看起来那么疯狂和心不在焉。我对PyPy的这一部分知之甚少,但据我所知:

PyPy通过将Python解释器的所有操作委托给“对象空间”来实现,对象空间包含所有基本内置操作的实现。但是您可以插入不同的对象空间来获得不同的效果,只要它们实现相同的“对象空间”接口,解释器就仍然能够“执行”Python代码。

PyPy翻译工具链处理的RPython代码对象是可以由解释器执行的Python代码. 因此,PyPy通过插入流对象空间,将其Python解释器的一部分重新用作翻译工具链的一部分。当使用这个对象空间“执行”代码时,解释器实际上并不执行代码的操作,而是生成流图,类似于许多其他编译器使用的中间表示;它只是代码的一个简单的机器可操作表示,有待进一步处理。这就是如何将常规(R)Python代码对象转换为翻译过程其余部分的输入。

由于翻译过程中通常要翻译的是PyPy的Python解释器,因此它确实使用流对象空间“解释自己”。但真正的意思是,有一个Python程序正在处理Python函数,包括那些正在处理的函数。它本身并不比将decorator应用于自己,或者让包装类包装自己的实例(或者包装类本身)更令人费解。


嗯,有点乱。不管怎样,我希望这会有帮助,我希望我没有说任何不准确的话;如果我说了,请纠正我。

Disclaimer: I'm not an expert on PyPy - in particular, I don't understand the details of the RPython translation, I'm only citing stuff that I've read before. For a more specific post on how RPython translation may work, check out this answer.

答案是,是的,它可以(但只有在它第一次使用CPython编译之后)。

更长的描述:

一开始,它看起来非常令人费解和矛盾,但一旦你理解了它,就很容易了。在Wikipedia上签出答案。

Bootstrapping in program development began during the 1950s when each program was constructed on paper in decimal code or in binary code, bit by bit (1s and 0s), because there was no high-level computer language, no compiler, no assembler, and no linker. A tiny assembler program was hand-coded for a new computer (for example the IBM 650) which converted a few instructions into binary or decimal code: A1. This simple assembler program was then rewritten in its just-defined assembly language but with extensions that would enable the use of some additional mnemonics for more complex operation codes.

这个过程称为软件引导。基本上,你用一种已经被(已经从一个点必须从二进制编码的)的语言来构建一个工具,比如C++编译器,比如ASM。既然你有C++,现在可以在C++中编译一个C++编译器,然后使用ASM C++编译器编译你的新编译器。编译完新编译器后,现在可以使用它编译自己了。

所以基本上,第一个电脑工具是手工编码的,用那个解释器来做另一个稍微好一点的,用那个来做一个更好的。。。最终你会得到今天所有复杂的软件!:)

另一个有趣的例子是CoffeeScript语言,它是用。。。咖啡脚本。(尽管这个用例仍然需要使用外部解释器,即Node.js)

运行在CPython之上的PyPy解释器执行部分解释器本身,此时它将控制权交给执行翻译的RPython一半?

可以使用已经编译过的PyPy解释器编译pypypy,也可以使用CPython来编译它。但是,由于PyPy现在有一个JIT,使用它自己而不是CPython来编译PyPy会更快。(PyPy is now faster than CPython在大多数情况下)

相关问题 更多 >