Chromium プロジェクトが Rust の利用をサポート
このブログ投稿では、現時点(元記事公開当時)でサードパーティ製 Rust ライブラリをサポートしつつも、Chromium で Rust を幅広く使うことはしないという決断に至った経緯について説明します。
C++ と Rust は、cxx、autocxx、bindgen、cbindgen、diplomat、(試験運用版の)crubit などのツールを使ってうまく連携できることがわかっています。ただし、制限事項もあります。やがて新しいツールや改良されたツールによって、こういった制限事項の状況は変わるものと期待できますが、今回の決断や説明は現在のテクノロジーの状況に基づいています。
Chrome セキュリティ チームは、どのように Rust と C++ のコードの併用にアプローチすべきか、時間をかけて調査してきました。Google のソフトウェア スタックでも、C++ ではなく Rust を記述する時間が増えていることの意味を理解し、安全かつシンプルで信頼性の高い相互利用の制限とはどのようなものかを把握するためです。
この調査に基づき、Chromium の方向性について 2 つの結論を出しました。
- 現時点では、C++ から Rust への一方通行の利用のみをサポートします。Chromium は C++ で書かれており、main() から exit() までのスタック フレームの大半は C++ コードです。前述の方向を選んだ理由はここにあります。利用を一方向に限定することで、依存関係ツリーの形を制御します。Rust は C++ に依存することはできないので、依存関係の注入を除けば、Rust が C++ の型や関数を知ることはできません。こうすることで、Rust は任意の C++ コードではなく、C++ から API を通して渡された関数だけを実行できるようになります。
- 現時点では、サードパーティ製ライブラリのみをサポートします。サードパーティ製ライブラリはスタンドアロン コンポーネントとして書かれたもので、Chromium の実装についての暗黙的な知識は持ち合わせていません。つまり、シンプルで 1 つのタスクに特化した API を提供しています。言い換えれば、通常はインターフェースが狭く、複雑なポインタグラフや共有所有権は存在しません。C++ で使用するライブラリのレビューし、期待を満たすものであることを確認します。
- 1 つの関数から同じ可変ポインタを 2 回返し、1 つを保持できるようにする。
- 重複する複数のポインタの片方は可変として Rust に渡し、参照として同時に保持できるようにする。
- 共有または可変の参照を通して、Rust から状態の変化が見えるようにする。
概念的にまとめると、別の相互利用ツールのサポートがない段階では、次のようになります。
- 言語間でのポインタ渡しや参照渡しにはリスクがある。
- 現実的に正しいコードを書けるようにするには、言語間の狭いインターフェースが重要である。
Chromium のようなセキュリティを重視したオープンソース プロジェクトにとって、Rust エコシステムはとりわけ重要な存在です。このエコシステムは巨大で(crates.io には 96,000 以上のクレートがあります)、Google を含むシステム開発業界からの大規模な投資を受けて成長を続けています。Chrome はサードパーティ製コードを多用しているので、サードパーティへの投資が行われている場所を把握する必要があります。私たちにとって重要なのは、Rust を Chromium プロジェクトに組み込む対応です。