この記事は「AOT技術 Advent Calendar 2017」の9日目です。
というか、今のところこのカテゴリに私しかエントリーしてないので、漏れた日を埋めていこうかな、ぐらいの感じです。
YouTube: Playlist: Making archive IL2C
GitHub: IL2C step-by-step design project
ネタをひねり出すのもアレなので、今まで蓄積したMaking archive IL2Cのダイジェストをやっていこうかと思います。
(イメージをクリックするとYouTubeが開きます)
#6-25
アセンブリ・モジュール・型・メソッド・メソッドボディの関係を説明しました。
で、実装して確認してみると、method tokenからMethodInfo取ってみたら違うメソッドが取れるww 対象のモジュールを間違えていました。method tokenはそれが定義されているモジュールで一意なので、正しいモジュールからResolveする必要があります。
結果として、以下のような出力が得られました:
#include <stdbool.h>
#include <stdint.h>
int32_t IL2C_ConverterTest_CallTestMethod(void)
{
int32_t local0;
int32_t __stack0_int32_t;
int32_t __stack1_int32_t;
__stack0_int32_t = 1;
__stack1_int32_t = 2;
__stack0_int32_t = IL2C_ConverterTest_CallStaticMethodTestType_Test(
__stack0_int32_t, (int16_t)__stack1_int32_t);
local0 = __stack0_int32_t;
goto L_0000;
L_0000:
__stack0_int32_t = local0;
return __stack0_int32_t;
}
第二引数はint16であり、評価スタックが常にint32以上となるので、明示的にキャストを挿入しています。
#6-26
次に、Value type内のスタティックフィールドの変換です。
.NETでのスタティックフィールドとは、一意なインスタンスの格納先となるのですが、C言語に対応するものは「グローバル変数」です。思い出しましたか? えぇ、「グローバル変数」ですよ。そうだっけ?みたいな感じでした :)
C言語でグローバル変数を実現する場合にも、staticキーワードを付けることが出来ます。このキーワードは、シンボルをファイルスコープに制約するもので、(C#構文と似ているのに).NETとは似ても似つかない感じですね。.NETで対応する概念は、アクセス修飾子 ですかね。
この回ではValue typeに対応する定義までを行いました。
#6-27
引き続き、Value typeのスタティックフィールドに対処しました。
スタティックフィールドの初期値を埋めるために、FieldInfo.GetValue()を使いましたが、ここでType initializerの問題に気が付きました。
ここで示した方法は、リフレクションでスタティックフィールドの初期値を取り出していますが、この方法には重大な問題があります。値の取得時に暗黙にType initializerが実行されてしまうということです。これは結構厄介な問題で、現在(#50)の時点ではissueに積んで保留しています。