Search code examples
c#reflection.emit

Creating object using Reflection.Emit in a simple compiler


To create instance of a class using Reflection.Emit I need to issue OpCodes.Newobj, however it requires a constructor of created class. So if I write my own compiler, how do I generate code for a method which creates instance of another class which is defined in a source code (not in a runtime library)?

I do code generation in 2 passes, first I create TypeBuilder for each class I have and I add method stubs to them so that they can be referenced during second pass. However I can't call TypeBuilder.CreateType for those stubs because I will get an exception, Reflection.Emit requires all methods to be defined and have body. But at the same time I can't finish code generation for a method which needs to create an instance of a class which was defined in a source code.

So, how do I create code for this:

class Foo
{
}

class Bar
{
    Foo DoSomething()
    {
        return new Foo();
    }
}

and this:

class Foo
{
    public Foo Create()
    {
         return new Foo();
    }
}

Solution

  • You need three passes:

    1. create a TypeBuilder for each class
    2. for each class, create a MethodBuilder for each member method including constructors
    3. for each class, generate method bodies using ILGenerator. As you finish iterating methods on each class, call CreateType()

    When you emit newobj, you can pass a ConstructorBuilder representing the constructor, which means the class and constructor don't have to be frozen yet.