メソッドを生成するためにILの解析を試しています。私は各文字列がIL命令である文字列[]でメソッドのILコードを取得しました。私は再現する必要がILている。ここBr_S OpCodeを使用してReflection.Emit.Labelを使用して次の命令を指す
foreach (string ins in instructions) //string representations of IL
{
string opCode = ins.Split(':').ElementAt(1);
// other conditions omitted
if (opCode.Contains("br.s"))
{
Label targetInstruction = ilGenerator.DefineLabel();
ilGenerator.MarkLabel(targetInstruction);
ilGenerator.Emit(OpCodes.Br_S, targetInstruction);
}
:
:Source IL:
IL_0000: nop
IL_0001: ldstr "Hello, World!"
IL_0006: stloc.0
IL_0007: br.s IL_0009
IL_0009: ldloc.0
IL_000a: ret
そして、ここでは、私は出力として取得しています何である私は、この配列をループしてILGeneratorを使用してオペコードを追加してい
Target IL:
IL_0000: nop
IL_0001: ldstr "Hello, World!"
IL_0006: stloc.0
IL_0007: br.s IL_0007 // this is wrong -- needs to point to IL_0009
IL_0009: ldloc.0
IL_000a: ret
br.s呼び出しが無限ループを引き起こしていることを指摘しています。どのようにしてソースのように次の指示を指すようにするのですか?これはReflection.Emit.Labelの使用と関係がありますが、どのように動作するのか分かりません。 ILは、上で見ところで
EDITは、この単純な方法で、あなたがにをジャンプしたいオペコードを発する直前ilGenerator.MarkLabel()
呼び出しを配置する必要があり
public string HelloWorld()
{
return "Hello, World!";
}
私はここで見ていないよ何か...あなたは次の命令に分岐したくない理由がなければなりませんか?それは少し高価なノーオペレーションではありませんか?また、ブランチ命令をターゲットにしたくない場合は、ブランチ命令をラベルターゲットとしてマークするのはなぜですか? –
Emit()呼び出しの後にMarkLabel()呼び出しを移動します。あるいはブランチを完全に省略すると、何もしません。 –
@Seanあなたはあなたが頭の中にいることを間もなく分かっていると思います。完全なILアセンブラの実装を計画している場合は、分岐命令のために "string.Contains"よりもはるかに優れている必要があります。基本的にはラベルを作成し、それに適切な場所を見つける必要があります。すべてのブランチが「次の行のため」ではない。 –