PyPyの翻訳プロセスは、実際には、思ったよりも概念的に再帰的ではありません。
実際には、Python関数/クラス/その他のオブジェクト( Pythonソースコードではない)を処理し、Cコードを出力するPythonプログラムだけです。ただし、もちろん、 Pythonオブジェクトだけを処理するわけではありません。特定のフォームのみを処理できます。これは、変換対象のコードをRPythonで記述した場合に得られるものです。
翻訳ツールチェーンはPythonプログラムであるため、PyPyのPythonインタープリターを含む任意のPythonインタープリター上で実行できます。だからそれは特別なことではありません。
RPythonオブジェクトを変換するため、RPythonで記述されたPyPyのpythonインタープリターを変換するために使用できます。
ただし、 RPythonではない翻訳フレームワーク自体で実行することはできません。PyPyのPythonインタープリター自体だけがRPythonです。
RPythonコードもPythonコード(逆ではない)であり、RPythonがソースファイルに「実際に存在する」ことはなく、他の非RPythonコードを必然的に含む動作中のPythonプロセス内のメモリにのみ存在するため、物事は興味深いものになります。 (たとえば、トランスレータはすでに定義およびインポートされた関数を操作するため、「純粋なRPython」のインポートや関数定義はありません)。
翻訳ツールチェーンは、メモリ内のPythonコードオブジェクトで動作することに注意してください。Pythonの実行モデルは、一部のPythonコードが実行される前にこれらが存在しないことを意味します。非常に単純化すると、翻訳プロセスの開始は次のようになります。
from my_interpreter import main
from pypy import translate
translate(main)
ご存知のとおり、インポートするだけでmain
、他のすべてのモジュールのインポートを含め、多くのPythonコードが実行されますmy_interpreter
。しかし、変換プロセスは関数オブジェクト main
の分析を開始します; を思い付くために実行されたコードが何であれ、それは決して認識せず、気にしませんmain
。
これを考える1つの方法は、「RPythonでのプログラミング」とは、「RPythonプログラムを生成し、それを翻訳プロセスにフィードするPythonプログラムを作成する」ことを意味します。これは比較的理解しやすく、他のコンパイラの数と似ています(たとえば、Cでのプログラミングを考える1つの方法は、Cプログラムを生成するCプリプロセッサプログラムを作成し、それをCコンパイラ)。
3つのコンポーネント(RPythonプログラムを生成するPythonプログラム、RPythonプログラム、および変換プロセス)がすべて同じPythonインタープリターにロードされるため、PyPyの場合は混乱するだけです。つまり、他の引数で呼び出されたときではなく、いくつかの引数で呼び出されたときにRPythonである関数を使用したり、RPythonプログラムの生成の一部として翻訳フレームワークからヘルパー関数を呼び出したり、その他多くの奇妙なことを行うことができます。そのため、状況はかなりぼやけており、ソース行を「翻訳するRPython」、「PythonがRPythonプログラムを生成する」、「RPythonプログラムを翻訳フレームワークに渡す」に必ずしもきれいに分割できるとは限りません。
CPython上で実行されるPyPyインタープリターは、それ自体を部分的に解釈するために実行されます
ここでほのめかしているのは、PyPyが翻訳中にフローオブジェクトスペースを使用して抽象解釈を行うことです。これでさえ、最初に思われるほどクレイジーで気が遠くなるようなものではありません。私はPyPyのこの部分についてあまり知らされていませんが、私が理解しているように:
PyPyは、Pythonインタープリターのすべての操作を、すべての基本的な組み込み操作の実装を含む「オブジェクトスペース」に委任することによって実装します。ただし、さまざまなオブジェクトスペースをプラグインしてさまざまな効果を得ることができ、それらが同じ「オブジェクトスペース」インターフェイスを実装している限り、インタープリターはPythonコードを「実行」できます。
PyPy変換ツールチェーンが処理するRPythonコードオブジェクトは、インタープリターによって実行される可能性のあるPythonコードです。そのため、PyPyは、フローオブジェクトスペースをプラグインすることにより、Pythonインタープリターの一部を翻訳ツールチェーンの一部として再利用します。このオブジェクトスペースを使用してコードを「実行」する場合、インタープリターは実際にはコードの操作を実行せず、代わりにフローグラフを生成します。これは、他の多くのコンパイラーで使用される一種の中間表現に類似しています。これは、コードを機械で操作できる単純な表現であり、さらに処理する必要があります。これは、通常の(R)Pythonコードオブジェクトが残りの翻訳プロセスの入力に変換される方法です。
変換プロセスで変換される通常のものはPyPyのPythonインタープリターであるため、実際にはフローオブジェクトスペースで「それ自体を解釈」します。しかし、実際に意味するのは、処理を実行する関数を含め、Python関数を処理するPythonプログラムがあるということです。それ自体は、デコレータをそれ自体に適用したり、ラッパークラスにそれ自体のインスタンスをラップさせたり(またはクラス自体をラップさせたり)することほど気が遠くなることはありません。
ええと、それは少しぼんやりしました。とにかく、それがお役に立てば幸いです。不正確なことは何も言っていないことを願っています。もしあれば訂正してください。