MrLoose.Assembler manual


Table of Contents

Introduction
C# IL look and feel
ILGenerator C# syntax sample
ILBlock C# syntax sample
IL opcodes syntax checking
IL block manipulation
Block insertion
Code generation with DynamicILMethod

Introduction

This dot net library was built with the following goals in mind:

  • Nice looking IL code when coding in C#

  • Type checked opcodes parameters

  • IL blocks manipulation

  • Easier IL mainpulation than Reflection.Emit

The use of this library is a matter of taste. It does not follow the standard C# naming for the IL opcodes related method and i think it allows a clean IL code representation in the C# sources. This library is a simple wrapper for the Reflection.Emit stuff and it was not desinged to be anything more.

C# IL look and feel

The IL generation is made through ILBlock objects. The C# code can be formatted to look like a msil code fragment. The ILBlock syntax is shorter and (imho) is more readable.

ILGenerator C# syntax sample

Sample from msdn:

          il.Emit(OpCodes.Ldarg_0);
          il.EmitCall(OpCodes.Call, writeString, null);
          il.Emit(OpCodes.Ldarg_1);
          il.Emit(OpCodes.Ret);
        

ILBlock C# syntax sample

          il
              .ldarg0   ()
              .call     (writeString)
              .ldarg1   ()
              .ret      ();
      

IL opcodes syntax checking

This is no big deal but it offers some IL correctness. Where one can easily use:

        il.Emit(OpCodes.Ldarg,0);
      

that doesn't produce the expected IL as the parameter should be a short, the ILBlock provides the correct IL method (possibly overloaded with an int parameter that will be checked and cast):

        il.ldarg(0);
      

The example provided simply illustrate the type checking. The Ldarg_0 opcode might have been used in this particular case and as it has no arg the example would be pointless. Still one might have made some typo such as

        il.Emit(OpCodes.Ldarg_0,0);
      

and this is not possible using and ILBLock as ldarg_0 does not take any parameter.

IL block manipulation

One can create blocks and then insert them into antoher block.

Block insertion

          ILBlock add3block = new ILBlock()
              .ldc_i3 ()
              .add    ();
          ILBLock block = new ILBlock()
              .ldarg_0  ()
              ._insert  (add3block)
              ._insert  (add3block)
              .starg    (0);
        

Code generation with DynamicILMethod

We illustrate the code generation using DynamicMethod and DynamicILMethod, the DynamicMethod code sample is taken from the msdn. The DynamicILMethod is a bit shorter and cleaner (imho).

          
          Type[] helloArgs = {typeof(string), typeof(int)};
          DynamicMethod hello = new DynamicMethod("Hello", typeof(int), helloArgs, typeof(string).Module);

          ILGenerator il = hello.GetILGenerator(256);
          il.Emit(OpCodes.Ldarg_0);
          il.EmitCall(OpCodes.Call, writeString, null);
          il.Emit(OpCodes.Ldarg_1);
          il.Emit(OpCodes.Ret);

          HelloDelegate hi = (HelloDelegate) hello.CreateDelegate(typeof(HelloDelegate));
          
      

Using DynamicILMethod:

         
          DynamicILMethod<HelloDelegate> hello = new DynamicILMethod<HelloDelegate>();

          hello.Body
            .ldarg_0  ()
            .call     (writeString)
            .ldarg_1  ()
            .ret      ();

          HelloDelegate hi = hello.CreateDelegate();