dotnet clr:
Hi,
I have been working on dynamic method generation. My code has been
working fine for most cases however I don't seem to be able to execute
a dynamic method that contains a try/catch clause.
Specifically, when the call to Invoke() is made the CLR throws a
TargetInvocationException. The exception message is "Common
Language Runtime detected an invalid program.".
Since there is almost no documentation/examples of how to properly
format the buffer to pass to SetExceptions it could be that the
exception record I am creating is invalid. I have tried both the small
and fat Exception Clause formats as described in the CLI ECMA
Spec (Section 25.4.6)
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-335.pdf The code below generates a dynamic method from the IL obtained from the
following C# method source.
void TestFinally()
{
try
{
}
finally
{
}
}
Has anyone successfully created dynamic methods that contain
exception clauses? I have a feeling this has not been tested or is
not supported.
Many thanks
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
using System;
using System.Reflection;
using System.Reflection.Emit;
class Test
{
static void Main()
{
DynamicMethod dm = new DynamicMethod(
"TestFinally",
typeof(void),
Type.EmptyTypes,
typeof(Test),
false);
DynamicILInfo il = dm.GetDynamicILInfo();
SignatureHelper sigHelper = SignatureHelper.GetLocalVarSigHelper();
il.SetLocalSignature(sigHelper.GetSignature());
// Code size 10 (0xa) .maxstack 0
// IL_0000: 00 ;nop
// .try
// {
// IL_0001: 00 ;nop
// IL_0002: 00 ;nop
// IL_0003: DE 03 ; leave.s IL_0008
// }
// finally
// {
// IL_0005: 00 ;nop
// IL_0006: 00 ;nop
// IL_0007: DC ;endfinally
// }
// IL_0008: 00 ;nop
// IL_0009: 2A ;ret
//
// Small: 0200 01 0400 0500 0300 00000000
// Fat: 02000000 01000000 04000000 05000000 03000000 00000000
byte[] code = {
0x00,0x00,0x00,0xDE,0x03,0x00,0x00,0xDC,0x00,0x2a
};
byte[] exceptions = {
02,00,01,04,00,05,00,03,00,00,00,00,00
};
il.SetCode(code, 0);
il.SetExceptions(exceptions);
try
{
dm.Invoke(null, null);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}