all groups > dotnet clr > august 2006 >
You're in the

dotnet clr

group:

DynamicMethod with Exception Clause


DynamicMethod with Exception Clause behnazb NO[at]SPAM gmail.com
8/12/2006 12:57:16 PM
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());
}
}
}
Re: DynamicMethod with Exception Clause Barry Kelly
8/13/2006 12:31:37 AM
[quoted text, click to view]

I've relied more on reusing the existing support, such as ILGenerator,
than trying to roll my own byte-level code generation. That's given me
more success for the things I want to do. To do write your example with
ILGenerator:

---8<---
using System;
using System.Reflection.Emit;

namespace DynamicException
{
class Program
{
delegate void F();

static void Main()
{
DynamicMethod method = new DynamicMethod("f", typeof(void),
null, typeof(Program));

ILGenerator cg = method.GetILGenerator();
cg.BeginExceptionBlock();
cg.Emit(OpCodes.Newobj,
typeof(Exception).GetConstructor(Type.EmptyTypes));
cg.Emit(OpCodes.Throw);
cg.BeginFinallyBlock();
cg.EmitWriteLine("finally");
cg.EndExceptionBlock();
cg.Emit(OpCodes.Ret);

F f = (F) method.CreateDelegate(typeof(F));
try
{
f();
}
catch (Exception ex)
{
Console.WriteLine("Caught: {0}", ex);
}
}
}
}
--->8---

-- Barry

--
AddThis Social Bookmark Button