HLX-001
(0)
- HLXは、a21_txt01やその続編で作ったHLシリーズ(はりぼて言語)をベースに、Kが望む理想の言語を作るプロジェクトです。
- HLX-001はその最初のバージョンです。
(1) 概要
- [1] HL-9a, HL-16b, HL-22bを統合します(ひとつの実行ファイルにします)。これで以下のようなことができるようになります。
- x86版で普通のインタプリタとJITコンパイラの実行速度の比較が簡単にできます。x86用のアセンブラ出力だけではなく、x64用のアセンブラ出力もできます。
- x64版でも同様のことができます。
- x86でもx64でもない環境でも、普通のインタプリタによる実行はでのできますし、x86やx64のアセンブラ出力もできるので、クロス開発環境としても使えます。
- この3つを統合して、どのくらいの行数になるか、どのくらいのサイズになるか(実行ファイルが)、それも確認してみたいと思っています。
- [2] HL-16bやHL-22bのJITコンパイラでは、簡略化のためにJcc命令がすべてnear-jmpになっていました。しかしHLX-001では、距離が短い場合にはshort-jmpを使うようになり、コードがよりコンパクトになります。
- [3] HLシリーズでは簡略化のためにバッファを固定で確保して、それがあふれてしまったら誤動作するようになっていましたが、HLX-001ではバッファは可変長で、大きなソースコードを扱うときはメモリをたくさん使い、小さい時はメモリを少ししか使わない、そういう処理方法になります。
- [4] 対応できる型を増やすとか、構造体をサポートするとか、ローカル変数をサポートするなどの対応は、HLX-002以降でやります。
(2) 内部構造
- プログラムは最初にトークン番号の列に変換された後、中間内部コード列(A)に変換されます。
- (ここまでが上位言語レイヤです。ここまではCPUに依存しません。)
- (以下は下位言語レイヤです。)
- そしてこの中間内部コード(A)から「インタプリタ実行用の中間コード(B)(HL-9aの中間コード相当)」「x86、x64兼用の共通化された仮想的な機械語(C)」のどちらに変換されます。
- x86、x64兼用の仮想機械語(C)は、そこからx86、x64の機械語(D)に変換されるか、もしくはx86用のアセンブラ(E)、x64用のアセンブラ(E)に変換されます。
- (B)はHL-9aの内部コードとほぼ同じです。(D)や(E)はHL-16bやHL-22bが出力していたものとほぼ同じです。
- (A)や(C)が今回新規に導入された中間コードになります。
- [Q] なぜそんなに中間コードを多くしたのか。
- [A] まず中間コードは少ないほうがいいです。そのほうが処理が速くなります。処理もシンプルです。だからHLシリーズでは極力中間層を減らして設計・実装していました。
しかし、HL-9aで使っていた中間コード(B)は高速に実行するために余計な情報を載せる余地がなくて、それだとJITコンパイルするときには不便です。だからそこに1層だけ増やして、上位レイヤは常に1通りの変換をすればいいようにしました。これが(A)を新設した理由です。これで上位レイヤはシンプルになり、CPU別に作り分ける必要がなくなります。
次に、x64の機械語を見ていると、REXプリフィクスの中にレジスタ番号の上位1bitが分離されていて、アセンブル出力するにしても、JITコンパイルのために最適化をするにしても、実にやりにくいです。もっといえば、x86の機械語にしてもmod r/mのバイトの中に3bitだけ命令番号が入っている場合もあります。これだって十分に不便です。これらを解消し、命令体系をシンプルした機械語があれば、おそらく機械語生成はもっと簡単に書けるはずです。そのための中間コードが(C)なのです。