この記事は「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に積んで保留しています。