2 // ILGeneratorTest.cs - NUnit Test Cases for the ILGenerator class
4 // Marek Safar (marek.safar@seznam.cz)
6 // (C) Novell, Inc. http://www.novell.com
9 using System.Reflection;
10 using System.Reflection.Emit;
11 using System.Threading;
13 using NUnit.Framework;
15 namespace MonoTests.System.Reflection.Emit {
18 public class ILGeneratorTest {
23 static TypeBuilder DefineDynType ()
25 AssemblyName assemblyName = new AssemblyName ();
26 assemblyName.Name = "MonoTests.System.Reflection.Emit.ILGeneratorTest";
28 AssemblyBuilder assembly = Thread.GetDomain ().DefineDynamicAssembly (
29 assemblyName, AssemblyBuilderAccess.Run);
31 ModuleBuilder module = assembly.DefineDynamicModule ("module1");
32 return module.DefineType ("T", TypeAttributes.Public);
35 void DefineBasicMethod ()
37 MethodBuilder mb = tb.DefineMethod("F",
38 MethodAttributes.Public, typeof(string), null);
39 il_gen = mb.GetILGenerator ();
45 tb = DefineDynType ();
49 [ExpectedException (typeof (ArgumentNullException))]
50 public void DeclareLocal_NULL ()
54 il_gen.DeclareLocal (null);
58 [ExpectedException (typeof (ArgumentException))]
59 public void DefineFilterBodyWithTypeNotNull ()
63 il_gen.BeginExceptionBlock ();
64 il_gen.EmitWriteLine ("in try");
65 il_gen.BeginExceptFilterBlock ();
66 il_gen.EmitWriteLine ("in filter head");
67 il_gen.BeginCatchBlock (typeof (Exception));
68 il_gen.EmitWriteLine ("in filter body");
69 il_gen.EndExceptionBlock ();
73 /// Try to emit something like that:
75 /// .method public static bool TestFilter (bool execute_handler)
77 /// .locals init(bool)
79 /// newobj instance void [mscorlib]System.Exception::.ctor()
97 /// It should return true if the handler has been executed
98 /// Otherwise, the exception should not be catched
100 void DefineTestFilterMethod ()
102 MethodBuilder mb = tb.DefineMethod("TestFilter",
103 MethodAttributes.Public | MethodAttributes.Static, typeof(bool), new Type [] { typeof (bool) });
105 ConstructorInfo exCtor = typeof (Exception).GetConstructor (new Type [0]);
107 il_gen = mb.GetILGenerator ();
108 il_gen.DeclareLocal (typeof (bool));
109 Label quit = il_gen.DefineLabel ();
110 il_gen.BeginExceptionBlock ();
111 il_gen.Emit (OpCodes.Newobj, exCtor);
112 il_gen.Emit (OpCodes.Throw);
113 il_gen.BeginExceptFilterBlock ();
114 il_gen.Emit (OpCodes.Pop);
115 il_gen.Emit (OpCodes.Ldarg_0);
116 il_gen.BeginCatchBlock (null);
117 il_gen.Emit (OpCodes.Ldc_I4_1);
118 il_gen.Emit (OpCodes.Stloc_0);
119 il_gen.Emit (OpCodes.Leave, quit);
120 il_gen.EndExceptionBlock ();
121 il_gen.Emit (OpCodes.Ldc_I4_0);
122 il_gen.Emit (OpCodes.Stloc_0);
123 il_gen.MarkLabel (quit);
124 il_gen.Emit (OpCodes.Ldloc_0);
125 il_gen.Emit (OpCodes.Ret);
129 public void TestFilterEmittingWithHandlerExecution ()
131 DefineTestFilterMethod ();
132 Type dynt = tb.CreateType ();
134 MethodInfo tf = dynt.GetMethod ("TestFilter");
135 Assert.IsTrue ((bool) tf.Invoke (null, new object [] { true }));
139 [ExpectedException (typeof (Exception))]
140 public void TestFilterEmittingWithoutHandlerExecution ()
142 DefineTestFilterMethod ();
143 Type dynt = tb.CreateType ();
145 MethodInfo tf = dynt.GetMethod ("TestFilter");
147 tf.Invoke (null, new object [] { false });
148 } catch (TargetInvocationException tie) {
149 throw tie.InnerException;