JSConf JP

Oseo:SBCLスタイルのJavaScript/TypeScript AOTコンパイラ

SessionTrack CJapanese

Common LispのSBCLやSchemeのChez Schemeは動的型付き言語でありながら、プログラム全体を事前にネイティブコードへコンパイルし、何十年もプロダクションで使われてきました。一方JavaScriptは今なお、速く動くにはインタプリタと複数段のJIT、その上に載るデオプティマイゼーション機構が要る言語だと見なされています。この違いはどこから来るのか。この問いから始まったプロジェクトがOseoです。

Oseoはすべての関数を二重にコンパイルします。言語のフルセマンティクスを実装するジェネリックパスが一つあり、値の種類や形状に対して安価なランタイムガードを掛けられる箇所には、その隣に特殊化されたパスを並べます。ガードが失敗すれば、バイナリの中にすでにコンパイルされているジェネリックパスへ分岐するだけです。インタプリタへ落ちることも、デオプティマイズすることもありません。TypeScriptの型表記やJSDocはこの特殊化パスを選ぶヒントとして使われますが、決して鵜呑みにされることはありません。anyや型アサーション、素のJavaScriptとの相互運用のせいで: numberという表記はいつでも誤りうるので、Oseoはその可能性をガードで防ぎます。

この発表では、このアイデアが実際にどう動くのかをコードとバイナリで直接お見せします。Node.jsもDenoも使わず、V8が一切リンクされていない純粋なネイティブ実行ファイルがどう作られるか。--dump-mirと--emit-cで覗いた生成コードの中で、一つのガードが実際にどんな比較と分岐にコンパイルされるか。型ヒントが実行結果を変えてはならないという原則も、同じ領域にある別プロジェクトとの具体的な比較を通じて見ていきます。

Oseoはまだ完成したプロジェクトではありません。この発表は、これまでに証明できたことと、まだ残っている道のりを一緒にお見せする場でもあります。ネイティブI/O、ガベージコレクタ、セルフホスティングまで、システムプログラミングに関心がある方なら貢献できる余地がまだたくさんあります。