Здравствуйте, я генерирую класс, используя Reflection.Emit
, и я хочу знать, как вы используете команду brfalse
для conditionals
.
В частности, я не знаю, как мне перевести IL до OPCODES для команды brfalse.s .
Мой метод имеет следующую форму:
object MyMethod()
{
if(isTransaction) //isTransaction is a bool property
return Method1();
else return Method2();
}
Условно
IL_0000: ldarg.0 // this
IL_0001: call instance bool RediusTests.DaemonBase::get_IsTransaction()
IL_0006: brfalse.s IL_0020 //how is this translated within opcodes?
Первая ветвь :
IL_0008:ldarg_0
IL_....... ///INSTRUCTIONS
IL_......
IL_001f:ret
Вторая ветвь :
IL_0020:ldarg_0 //How do i specify with OPCODES to jump here?????
IL_.......
IL_......
IL_001f:ret
Для первого фрагмента, что будет аргументом brfalse.s
?
ilgen.Emit(OpCodes.Ldarg_0);
ilgen.Emit(OpCodes.Call, getIsTransaction);
ilgen.Emit(OpCodes.Brfalse,); //what do i put here in the overload?
Как вы можете видеть в последнем фрагменте, в последней строке, что я должен поставитьв перегрузке ilgen.Emit
?Ничего, 20 или есть какой-то другой код для перевода в IL_0020
?
Кроме того, адрес инструкции, сохраняемый по разному адресу памяти при каждом запуске программы? Не могне изменится ли он с IL0020
на IL00xx
при будущих казнях?
PS После получения исчерпывающих ответов это моя версия:
ILGenerator ilgen = newMethod.GetILGenerator();
Label falseLabel = ilgen.DefineLabel();
Label continueLabel = ilgen.DefineLabel();
ilgen.Emit(OpCodes.Ldarg_0);
ilgen.Emit(OpCodes.Call, getIsTransaction);
ilgen.Emit(OpCodes.Brtrue,continueLabel); //branching
ilgen.MarkLabel(continueLabel); //true branch
----instructions------
ilgen.Emit(OpCodes.Ret);
ilgen.Emit(OpCodes.Br,continueLabel);
ilgen.MarkLabel(falseLabel); //false branch
--instructions----
ilgen.Emit(OpCodes.Ret);