Return a value from the inside of a try and catch with an ILGenerator

264 Views Asked by At

I am currently trying to generate a method which would return a result right inside the try block. The equivalent C# code would look something like this:

public int Foo()
{
    try
    {
        return 1;
    }
    catch(Exception ex)
    {
        Console.WriteLine(ex);
        return -1;
    }
}

And I do know, that this will obviously never throw an error, however this is just shortened thing of what I am trying to do and I could nail the issue down to the try/catch.

Here is what I got so far:

var method = new DynamicMethod("Foo", typeof(int), null);
var methodIL = method.GetILGenerator();

var exBlock = methodIL.BeginExceptionBlock();

methodIL.Emit(OpCodes.Ldc_I4_1);
methodIL.Emit(OpCodes.Stloc_0);
methodIL.Emit(OpCodes.Leave_S, exBlock);

methodIL.BeginCatchBlock(typeof(Exception));

methodIL.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new[] { typeof(string) }));

methodIL.Emit(OpCodes.Ldc_I4_M1);
methodIL.Emit(OpCodes.Stloc_0);
methodIL.Emit(OpCodes.Leave_S, exBlock);

methodIL.EndExceptionBlock();

methodIL.Emit(OpCodes.Ldloc_0);
methodIL.Emit(OpCodes.Ret);

var foo = (Func<int>)method.CreateDelegate(typeof(Func<int>));

Console.WriteLine(foo.Invoke());

I took the IL more or less straight from sharplab.io.

However this method throws an Exception at me:

System.InvalidProgramException: 'Common Language Runtime detected an invalid program.'

Which to my knowledge, indicates that I somehow messed the IL up.

1

There are 1 best solutions below

2
thehennyy On BEST ANSWER

You have to call the IlGenerator.DeclareLocal() Method to declare the local variable that you are going to use withh OpCodes.Ldloc_0 and OpCodes.Stloc_0.

Just add: methodIL.DeclareLocal(typeof(int));