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 ();
74 public void FilterAndCatchBlock ()
77 ILGenerator il = il_gen;
78 il.BeginExceptionBlock ();
79 il.BeginExceptFilterBlock ();
80 il.BeginCatchBlock (null);
81 il.BeginCatchBlock (typeof (SystemException));
85 [ExpectedException (typeof (InvalidOperationException))]
86 public void InvalidFilterBlock1 ()
89 ILGenerator il = il_gen;
90 il.BeginExceptionBlock ();
91 il.BeginExceptFilterBlock ();
92 il.EndExceptionBlock ();
96 public void ValidFilterBlock1 ()
99 ILGenerator il = il_gen;
100 il.BeginExceptionBlock ();
101 il.BeginExceptFilterBlock ();
102 il.BeginFaultBlock ();
103 il.EndExceptionBlock ();
107 public void ValidFilterBlock2 ()
109 DefineBasicMethod ();
110 ILGenerator il = il_gen;
111 il.BeginExceptionBlock ();
112 il.BeginExceptFilterBlock ();
113 il.BeginFinallyBlock ();
114 il.EndExceptionBlock ();
118 /// Try to emit something like that:
120 /// .method public static bool TestFilter (bool execute_handler)
122 /// .locals init(bool)
124 /// newobj instance void [mscorlib]System.Exception::.ctor()
142 /// It should return true if the handler has been executed
143 /// Otherwise, the exception should not be catched
145 void DefineTestFilterMethod ()
147 MethodBuilder mb = tb.DefineMethod("TestFilter",
148 MethodAttributes.Public | MethodAttributes.Static, typeof(bool), new Type [] { typeof (bool) });
150 ConstructorInfo exCtor = typeof (Exception).GetConstructor (new Type [0]);
152 il_gen = mb.GetILGenerator ();
153 il_gen.DeclareLocal (typeof (bool));
154 Label quit = il_gen.DefineLabel ();
155 il_gen.BeginExceptionBlock ();
156 il_gen.Emit (OpCodes.Newobj, exCtor);
157 il_gen.Emit (OpCodes.Throw);
158 il_gen.BeginExceptFilterBlock ();
159 il_gen.Emit (OpCodes.Pop);
160 il_gen.Emit (OpCodes.Ldarg_0);
161 il_gen.BeginCatchBlock (null);
162 il_gen.Emit (OpCodes.Ldc_I4_1);
163 il_gen.Emit (OpCodes.Stloc_0);
164 il_gen.Emit (OpCodes.Leave, quit);
165 il_gen.EndExceptionBlock ();
166 il_gen.Emit (OpCodes.Ldc_I4_0);
167 il_gen.Emit (OpCodes.Stloc_0);
168 il_gen.MarkLabel (quit);
169 il_gen.Emit (OpCodes.Ldloc_0);
170 il_gen.Emit (OpCodes.Ret);
174 public void TestFilterEmittingWithHandlerExecution ()
176 DefineTestFilterMethod ();
177 Type dynt = tb.CreateType ();
179 MethodInfo tf = dynt.GetMethod ("TestFilter");
180 Assert.IsTrue ((bool) tf.Invoke (null, new object [] { true }));
184 [ExpectedException (typeof (Exception))]
185 public void TestFilterEmittingWithoutHandlerExecution ()
187 DefineTestFilterMethod ();
188 Type dynt = tb.CreateType ();
190 MethodInfo tf = dynt.GetMethod ("TestFilter");
192 tf.Invoke (null, new object [] { false });
193 } catch (TargetInvocationException tie) {
194 throw tie.InnerException;