🔎

【Unity】BCLソースコードの歩き方

2024/11/26に公開

Unityでシステム寄りの実装をやっていると「このAPIの実装ってどうなってるんだっけ?」とか「これってパフォーマンス的にどのくらい気軽に呼んでいいんだろう?」などと疑問に感じることがしばしばあります。今回はそうした場合の実装の掘り方についてです。

Unityのエンジンソースコードは基本的に非公開ですが、System名前空間をはじめとする.NETのBCL (Base Class Library) に含まれるAPIについてはMonoの実装を利用しており、その実装を読むことができます。ただ、ディレクトリの構成などがちょっと特殊で調査にコツがいるので、今回はそれを紹介します。

こちらがUnityに組み込まれているMonoのリポジトリです。

https://github.com/Unity-Technologies/mono

このリポジトリにはCによるランタイム実装とC#によるBCL (Base Class Library) 実装が含まれています。今回は後者の話です。

.NET BCL 実装

.NET BCL 実装は Mono リポジトリの mcs/class 以下にあります。

このディレクトリにはアセンブリごとにサブディレクトリがあり、それぞれにC# ソースファイルが含まれています。まずは目的のクラスを検索してみましょう。

ここで重要なのが、クラス名そのままではなくクラス名.csという文字列で検索をかけることです。すると*.sourcesという拡張子をもったファイルが見つかります。例えばFileStream.csで検索すると次のようなものがヒットします:

この *.sources ファイルにはコンパイルの対象とするソースファイルの一覧が含まれています。大抵は アセンブリ名.sources の形式をとりますが、今回のように mscorlib.dll は Mono では corlib という名前がついていたりと例外があります(理由はよくわからない)。

今回はFileStream.csを探してみて、System.IO/FileStream.csが実装の本体であることがわかりました。ただ、corlib.sources のほかの行を見てみると、../../../external/corefx で始まるソースファイルを参照しているのが見えます。

../../../externalはsubmoduleへのパスです。クラスによっては実装が Mono リポジトリ本体のものではなく、CoreCLR の実装を参照している場合があるのです。Mono 自体にも実装があるのにそれが使われていないこともあるので注意が必要です!

externalはMonoリポジトリのルートにあるので、そこからsubmoduleを辿れます。

以上です!

Discussion