tags:

views:

77

answers:

2
+3  Q: 

'if' block in IL

I think I might be missing something important, but I can't seem to figure out how to construct a conditional statement in IL with dynamic method. I've only dabbled lightly in it before, but I need to extend some code now.

Is there some documentation somewhere that I haven't found (apart from the CLI documentation), or does someone have some sample code? That would be fantastic.

Cheers,

+3  A: 

Depending on your exact code, the various branch instructions are your friend.

Here is

if(memory[pointer] > 0) goto IL_0002;

in IL:

IL_001f:  ldsfld     uint8[] BFHelloWorldCSharp.Program::memory
IL_0024:  ldsfld     int16 BFHelloWorldCSharp.Program::pointer
IL_0029:  ldelem.u1
IL_002a:  ldc.i4.0
IL_002b:  bgt      IL_0002

You basically push the values you want to compare onto the stack and then call bgt to jump where you need to.

You can check the OpCodes Class for a quick overview of IL Commands, for example brtrue/brfalse or beq.

I would also recommend writing the if command in C#, compiling it, and using ILDASM or Reflector to look at the generated IL.

Michael Stum
Thanks for that link to the OpCodes class - I couldn't find a link to that from any of the emit articles... annoying!
Luke Schafer
@Luke If you're interested, I've started a series about writing a .net compiler (i've picked brainf..k as language due to it's simplicity). I'm not using Dynamic Method but I do use Reflection.Emit. The article about actually writing the compiler (Part 6) should come near the weekend: http://www.stum.de/tag/brainfk/
Michael Stum
@Luke Source code for my compiler is here: http://pastie.org/910946 - This is for a while statement though, which behaves similarly. Maybe it helps.
Michael Stum
Thanks, you led me to the answer!
Luke Schafer
+1  A: 

Here's how it goes:

Define a label, e.g.:

var skipProperty = il.DefineLabel();

call your condition:

il.Emit(OpCodes.Brtrue, skipProperty);

in the place where you want it to skip to (e.g. the end of the if):

il.MarkLabel(skipProperty);

So you create a label (you need to do it first so the reference exists, you call 'mark' later to place the label in the actual spot in code you want it). the OpCodes.Brtrue is just one of many conditional operations listed in the link text article (thanks Michael

Luke Schafer