2005-07-21 Jb Evain <jbevain@gmail.com>
authorJb Evain <jbevain@gmail.com>
Thu, 21 Jul 2005 22:09:14 +0000 (22:09 -0000)
committerJb Evain <jbevain@gmail.com>
Thu, 21 Jul 2005 22:09:14 +0000 (22:09 -0000)
* ILGeneratorTest.cs: Add tests for exception filters (bug #75010).

svn path=/trunk/mcs/; revision=47539

mcs/class/corlib/Test/System.Reflection.Emit/ChangeLog
mcs/class/corlib/Test/System.Reflection.Emit/ILGeneratorTest.cs

index ee9350b6f8260d821ab47f1d3f774696365a9788..a55b6e5bce41fe77151b652835178565f42b3338 100644 (file)
@@ -1,3 +1,7 @@
+2005-07-21  Jb Evain  <jbevain@gmail.com>
+
+       * ILGeneratorTest.cs: Add tests for exception filters (bug #75010).
+
 2005-06-22  Gert Driesen  <drieseng@users.sourceforge.net>
 
        * MethodBuilderTest.cs: Updated existing tests to no longer define
index c80a736f7f84e227c914fcb1be4f6f6de2540e8b..564c2851cf985b5f90341bf22b261ae0a2308b3e 100644 (file)
@@ -17,10 +17,10 @@ namespace MonoTests.System.Reflection.Emit {
        [TestFixture]
        public class ILGeneratorTest {
 
+               TypeBuilder tb;
                ILGenerator il_gen;
 
-               [SetUp]
-               public void SetUp ()
+               static TypeBuilder DefineDynType ()
                {
                        AssemblyName assemblyName = new AssemblyName ();
                        assemblyName.Name = "MonoTests.System.Reflection.Emit.ILGeneratorTest";
@@ -29,19 +29,125 @@ namespace MonoTests.System.Reflection.Emit {
                                assemblyName, AssemblyBuilderAccess.Run);
 
                        ModuleBuilder module = assembly.DefineDynamicModule ("module1");
-                       TypeBuilder _tb = module.DefineType ("GetType", TypeAttributes.Public);
-
-                       MethodBuilder myMethod = _tb.DefineMethod("Function1",
-                               MethodAttributes.Public, typeof(String), null);
+                       return module.DefineType ("T", TypeAttributes.Public);                  
+               }
+               
+               void DefineBasicMethod ()
+               {
+                       MethodBuilder mb = tb.DefineMethod("F",
+                               MethodAttributes.Public, typeof(string), null);
+                       il_gen = mb.GetILGenerator ();
+               }
 
-                       il_gen = myMethod.GetILGenerator();
+               [SetUp]
+               public void SetUp ()
+               {                       
+                       tb = DefineDynType ();
                }
 
                [Test]
                [ExpectedException (typeof (ArgumentNullException))]
                public void DeclareLocal_NULL ()
                {
+                       DefineBasicMethod ();
+
                        il_gen.DeclareLocal (null);
                }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void DefineFilterBodyWithTypeNotNull ()
+               {
+                       DefineBasicMethod ();
+
+                       il_gen.BeginExceptionBlock ();
+                       il_gen.EmitWriteLine ("in try");
+                       il_gen.BeginExceptFilterBlock ();
+                       il_gen.EmitWriteLine ("in filter head");
+                       il_gen.BeginCatchBlock (typeof (Exception));
+                       il_gen.EmitWriteLine ("in filter body");
+                       il_gen.EndExceptionBlock ();
+               }
+               
+               /// <summary>
+               /// Try to emit something like that:
+               ///
+               /// .method public static bool TestFilter (bool execute_handler)
+               /// {
+               ///     .locals init(bool)
+               ///     try {
+               ///             newobj  instance void [mscorlib]System.Exception::.ctor()
+               ///             throw
+               ///     } filter {
+               ///             pop
+               ///             ldarg.0
+               ///             endfilter
+               ///     } {
+               ///             ldc.i4.1
+               ///             stloc.0
+               ///             leave quit
+               ///     }
+               ///     ldc.i4.0
+               ///     stloc.0
+               /// quit:
+               ///     ldloc.0
+               ///     ret
+               /// }
+               ///
+               /// It should return true if the handler has been executed
+               /// Otherwise, the exception should not be catched
+               /// </summary>
+               void DefineTestFilterMethod ()
+               {
+                       MethodBuilder mb = tb.DefineMethod("TestFilter",
+                               MethodAttributes.Public | MethodAttributes.Static, typeof(bool), new Type [] { typeof (bool) });
+
+                       ConstructorInfo exCtor = typeof (Exception).GetConstructor (new Type [0]);
+
+                       il_gen = mb.GetILGenerator ();
+                       il_gen.DeclareLocal (typeof (bool));
+                       Label quit = il_gen.DefineLabel ();
+                       il_gen.BeginExceptionBlock ();
+                       il_gen.Emit (OpCodes.Newobj, exCtor);
+                       il_gen.Emit (OpCodes.Throw);
+                       il_gen.BeginExceptFilterBlock ();
+                       il_gen.Emit (OpCodes.Pop);
+                       il_gen.Emit (OpCodes.Ldarg_0);
+                       il_gen.BeginCatchBlock (null);
+                       il_gen.Emit (OpCodes.Ldc_I4_1);
+                       il_gen.Emit (OpCodes.Stloc_0);
+                       il_gen.Emit (OpCodes.Leave, quit);
+                       il_gen.EndExceptionBlock ();
+                       il_gen.Emit (OpCodes.Ldc_I4_0);
+                       il_gen.Emit (OpCodes.Stloc_0);
+                       il_gen.MarkLabel (quit);
+                       il_gen.Emit (OpCodes.Ldloc_0);
+                       il_gen.Emit (OpCodes.Ret);
+               }
+
+               [Test]
+               public void TestFilterEmittingWithHandlerExecution ()
+               {
+                       DefineTestFilterMethod ();
+                       Type dynt = tb.CreateType ();
+                       
+                       MethodInfo tf = dynt.GetMethod ("TestFilter");
+                       Assert.IsTrue ((bool) tf.Invoke (null, new object [] { true }));
+               }
+
+               [Test]
+               [ExpectedException (typeof (Exception))]
+               public void TestFilterEmittingWithoutHandlerExecution ()
+               {
+                       DefineTestFilterMethod ();
+                       Type dynt = tb.CreateType ();
+                       
+                       MethodInfo tf = dynt.GetMethod ("TestFilter");
+                       try {
+                               tf.Invoke (null, new object [] { false });
+                       } catch (TargetInvocationException tie) {
+                               throw tie.InnerException;
+                       }
+               }
        }
 }