1

I am writing a special-purpose mini-compiler and I often view disassembled CIL to figure out how to do things. But it's often not obvious how to translate the disassembled code to Reflection.Emit calls. Does a reference manual exist or any other source of information for doing this translation?

Edit: yes, mapping the opcodes to ILGenerator is pretty straightforward; I'm talking about all the other stuff like the .directives and attributes. For instance, how do you find out how to write the Reflection.Emit equivalent of something like Dictionary<TKey,TValue>?

.class public auto ansi serializable beforefieldinit Dictionary<TKey, TValue>
    extends System.Object
    implements System.Collections.Generic.IDictionary`2<!TKey, !TValue>,
    System.Collections.Generic.ICollection`1<valuetype 
        System.Collections.Generic.KeyValuePair`2<!TKey, !TValue>>, 
    ...
{
    .custom instance void System.Diagnostics.DebuggerDisplayAttribute::
        .ctor(string) = { string('Count = {Count}') }

    .method public hidebysig newslot virtual final instance bool TryGetValue
        (!TKey key, [out] !TValue& 'value') cil managed
    {
        .maxstack 3
        .locals init ([0] int32 num)
        ...

Or how about the "param" directive?

// public static void SayHello(string s = "Hello World!")
.method public hidebysig static void SayHello([opt] string s) cil managed
{
    .param [1] = "Hello World!"
Qwertie
  • 16,354
  • 20
  • 105
  • 148
  • Isn't the OpCodes class a one to one mapping? http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.aspx – Brian Rasmussen Jun 13 '10 at 18:23
  • Depending upon what you're doing, it's a lot easier to use expression trees, which you can then compile to CIL: http://msdn.microsoft.com/en-us/library/bb397951.aspx – porges Jun 14 '10 at 21:20
  • Expression trees are concerned mainly with building expressions, not with building the metadata of classes and methods. I asked this question because I want to know how to generate the latter. (I'm not using .NET 4 yet but I heard Expression Trees have been extended somewhat in .NET 4). – Qwertie Apr 12 '11 at 05:14

3 Answers3

4

I would use the EmitHelper component of the BLToolkit for that purpose. It provides a fluent API resembling IL code, wrapping Reflection.Emit. Example extracted from the linked article:

EmitHelper emit = new AssemblyBuilderHelper("HelloWorld.dll")
    .DefineType  ("Hello", typeof(object), typeof(IHello))
    .DefineMethod(typeof(IHello).GetMethod("SayHello"))
    .Emitter;
emit
    // string.Format("Hello, {0}!", toWhom)
    //
    .ldstr   ("Hello, {0}!")
    .ldarg_1
    .call    (typeof(string), "Format", typeof(string), typeof(object))

    // Console.WriteLine("Hello, World!");
    //
    .call    (typeof(Console), "WriteLine", typeof(string))
    .ret();

Type type = emit.Method.Type.Create();
Buu
  • 49,745
  • 5
  • 67
  • 85
1

You are looking at the IL for the System.Collections.Generic.Dictionary<> class. The "Dictionary" class name is the string you pass to ModuleBuilder.DefineType().

The .param attribute is generated in C# version 4 or VB.NET for parameters that have a default value. You set it with the ParameterBuilder you get back from MethodBuilder.DefineParameter(). Use the SetConstant() method.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
1

Since no one could answer the question, I conclude no documentation exists to show the relationship between ilasm syntax and Reflection.Emit calls.

As a side note, I've found that it's usually better to create code at run-time using RunSharp than Reflection.Emit. When I have time I'll try to figure out the new version of Cecil.

Qwertie
  • 16,354
  • 20
  • 105
  • 148
  • +1, good to know about RunSharp. In your exp, how mature it is? Can it generate a full set of objects & CIL for .NET (which version?) There seems to be a lack of ongoing development. – Buu Apr 22 '11 at 11:16
  • I don't think it's actively developed but I was able to talk to the developer. I don't think it's feature-complete enough for use in a compiler, but it can generate types, constructors, fields, methods, events, custom attributes, methods, and expressions. I think I gave the wrong website link; it should be http://code.google.com/p/runsharp/ – Qwertie Apr 26 '11 at 19:16