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 void DefineBasicMethod ()
25 MethodBuilder mb = tb.DefineMethod("F",
26 MethodAttributes.Public, typeof(string), null);
27 il_gen = mb.GetILGenerator ();
33 AssemblyName assemblyName = new AssemblyName ();
34 assemblyName.Name = "MonoTests.System.Reflection.Emit.ILGeneratorTest";
36 AssemblyBuilder assembly = Thread.GetDomain ().DefineDynamicAssembly (
37 assemblyName, AssemblyBuilderAccess.Run);
39 ModuleBuilder module = assembly.DefineDynamicModule ("module1");
40 tb = module.DefineType ("T", TypeAttributes.Public);
44 public void DeclareLocal_LocalType_Null ()
49 il_gen.DeclareLocal (null);
51 } catch (ArgumentNullException ex) {
52 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#A2");
53 Assert.IsNull (ex.InnerException, "#A3");
54 Assert.IsNotNull (ex.Message, "#A4");
55 Assert.IsNotNull (ex.ParamName, "#A5");
56 Assert.AreEqual ("localType", ex.ParamName, "#A");
61 il_gen.DeclareLocal (null, false);
63 } catch (ArgumentNullException ex) {
64 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#B2");
65 Assert.IsNull (ex.InnerException, "#B3");
66 Assert.IsNotNull (ex.Message, "#B4");
67 Assert.IsNotNull (ex.ParamName, "#B5");
68 Assert.AreEqual ("localType", ex.ParamName, "#B6");
74 [ExpectedException (typeof (ArgumentException))]
75 public void DefineFilterBodyWithTypeNotNull ()
78 il_gen.BeginExceptionBlock ();
79 il_gen.EmitWriteLine ("in try");
80 il_gen.BeginExceptFilterBlock ();
81 il_gen.EmitWriteLine ("in filter head");
82 il_gen.BeginCatchBlock (typeof (Exception));
83 il_gen.EmitWriteLine ("in filter body");
84 il_gen.EndExceptionBlock ();
88 public void FilterAndCatchBlock ()
91 ILGenerator il = il_gen;
92 il.BeginExceptionBlock ();
93 il.BeginExceptFilterBlock ();
94 il.BeginCatchBlock (null);
95 il.BeginCatchBlock (typeof (SystemException));
99 [ExpectedException (typeof (InvalidOperationException))]
100 public void InvalidFilterBlock1 ()
102 DefineBasicMethod ();
103 ILGenerator il = il_gen;
104 il.BeginExceptionBlock ();
105 il.BeginExceptFilterBlock ();
106 il.EndExceptionBlock ();
110 public void ValidFilterBlock1 ()
112 DefineBasicMethod ();
113 ILGenerator il = il_gen;
114 il.BeginExceptionBlock ();
115 il.BeginExceptFilterBlock ();
116 il.BeginFaultBlock ();
117 il.EndExceptionBlock ();
121 public void ValidFilterBlock2 ()
123 DefineBasicMethod ();
124 ILGenerator il = il_gen;
125 il.BeginExceptionBlock ();
126 il.BeginExceptFilterBlock ();
127 il.BeginFinallyBlock ();
128 il.EndExceptionBlock ();
132 /// Try to emit something like that:
134 /// .method public static bool TestFilter (bool execute_handler)
136 /// .locals init(bool)
138 /// newobj instance void [mscorlib]System.Exception::.ctor()
156 /// It should return true if the handler has been executed
157 /// Otherwise, the exception should not be catched
159 void DefineTestFilterMethod ()
161 MethodBuilder mb = tb.DefineMethod("TestFilter",
162 MethodAttributes.Public | MethodAttributes.Static, typeof(bool), new Type [] { typeof (bool) });
164 ConstructorInfo exCtor = typeof (Exception).GetConstructor (new Type [0]);
166 il_gen = mb.GetILGenerator ();
167 il_gen.DeclareLocal (typeof (bool));
168 Label quit = il_gen.DefineLabel ();
169 il_gen.BeginExceptionBlock ();
170 il_gen.Emit (OpCodes.Newobj, exCtor);
171 il_gen.Emit (OpCodes.Throw);
172 il_gen.BeginExceptFilterBlock ();
173 il_gen.Emit (OpCodes.Pop);
174 il_gen.Emit (OpCodes.Ldarg_0);
175 il_gen.BeginCatchBlock (null);
176 il_gen.Emit (OpCodes.Ldc_I4_1);
177 il_gen.Emit (OpCodes.Stloc_0);
178 il_gen.Emit (OpCodes.Leave, quit);
179 il_gen.EndExceptionBlock ();
180 il_gen.Emit (OpCodes.Ldc_I4_0);
181 il_gen.Emit (OpCodes.Stloc_0);
182 il_gen.MarkLabel (quit);
183 il_gen.Emit (OpCodes.Ldloc_0);
184 il_gen.Emit (OpCodes.Ret);
187 [Test] // Emit (OpCode, ConstructorInfo)
189 [Category ("NotDotNet")] // MS bug: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=304610
191 public void Emit3_Constructor_Null ()
193 DefineBasicMethod ();
195 il_gen.Emit (OpCodes.Newobj, (ConstructorInfo) null);
197 } catch (ArgumentNullException ex) {
198 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
199 Assert.IsNull (ex.InnerException, "#3");
200 Assert.IsNotNull (ex.Message, "#4");
201 Assert.IsNotNull (ex.ParamName, "#5");
206 [Test] // Emit (OpCode, ConstructorInfo)
207 [Category ("NotWorking")] // MS bug: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=304610
208 public void Emit3_Constructor_Null_MS ()
210 DefineBasicMethod ();
212 il_gen.Emit (OpCodes.Newobj, (ConstructorInfo) null);
214 } catch (NullReferenceException) {
219 [Test] // Emit (OpCode, FieldInfo)
220 public void Emit5_Field_Null ()
222 DefineBasicMethod ();
224 il_gen.Emit (OpCodes.Ldsfld, (FieldInfo) null);
226 } catch (ArgumentNullException ex) {
227 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
228 Assert.IsNull (ex.InnerException, "#3");
229 Assert.IsNotNull (ex.Message, "#4");
230 Assert.IsNotNull (ex.ParamName, "#5");
234 [Test] // Emit (OpCode, Label [])
235 [Category ("NotDotNet")] // MS bug: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=304610
236 public void Emit10_Labels_Null ()
238 DefineBasicMethod ();
240 il_gen.Emit (OpCodes.Switch, (Label []) null);
242 } catch (ArgumentNullException ex) {
243 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
244 Assert.IsNull (ex.InnerException, "#3");
245 Assert.IsNotNull (ex.Message, "#4");
246 Assert.IsNotNull (ex.ParamName, "#5");
247 Assert.AreEqual ("labels", ex.ParamName, "#6");
252 [Category ("NotWorking")] // MS bug: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=304610
253 public void Emit10_Labels_Null_MS ()
255 DefineBasicMethod ();
257 il_gen.Emit (OpCodes.Switch, (Label []) null);
259 } catch (NullReferenceException) {
263 [Test] // Emit (OpCode, LocalBuilder)
264 public void Emit11_Local_Null ()
266 DefineBasicMethod ();
268 il_gen.Emit (OpCodes.Switch, (LocalBuilder) null);
270 } catch (ArgumentNullException ex) {
271 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
272 Assert.IsNull (ex.InnerException, "#3");
273 Assert.IsNotNull (ex.Message, "#4");
274 Assert.IsNotNull (ex.ParamName, "#5");
275 Assert.AreEqual ("local", ex.ParamName, "#6");
279 [Test] // Emit (OpCode, MethodInfo)
280 public void Emit12_Method_Null ()
282 DefineBasicMethod ();
284 il_gen.Emit (OpCodes.Switch, (MethodInfo) null);
286 } catch (ArgumentNullException ex) {
287 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
288 Assert.IsNull (ex.InnerException, "#3");
289 Assert.IsNotNull (ex.Message, "#4");
290 Assert.IsNotNull (ex.ParamName, "#5");
291 Assert.AreEqual ("meth", ex.ParamName, "#6");
295 [Test] // Emit (OpCode, SignatureHelper)
296 public void Emit14_Signature_Null ()
298 DefineBasicMethod ();
300 il_gen.Emit (OpCodes.Switch, (SignatureHelper) null);
302 } catch (ArgumentNullException ex) {
303 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
304 Assert.IsNull (ex.InnerException, "#3");
305 Assert.IsNotNull (ex.Message, "#4");
306 Assert.IsNotNull (ex.ParamName, "#5");
310 [Test] // Emit (OpCode, String)
311 public void Emit16_String_Null ()
313 DefineBasicMethod ();
315 il_gen.Emit (OpCodes.Switch, (String) null);
317 } catch (ArgumentNullException ex) {
318 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
319 Assert.IsNull (ex.InnerException, "#3");
320 Assert.IsNotNull (ex.Message, "#4");
324 [Test] // Emit (OpCode, Type)
325 public void Emit16_Type_Null ()
327 DefineBasicMethod ();
329 il_gen.Emit (OpCodes.Switch, (Type) null);
331 } catch (ArgumentNullException ex) {
332 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
333 Assert.IsNull (ex.InnerException, "#3");
334 Assert.IsNotNull (ex.Message, "#4");
335 Assert.IsNotNull (ex.ParamName, "#5");
340 public void EmitCall_MethodInfo_Null ()
342 DefineBasicMethod ();
344 il_gen.EmitCall (OpCodes.Call, (MethodInfo) null, null);
346 } catch (ArgumentNullException ex) {
347 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
348 Assert.IsNull (ex.InnerException, "#3");
349 Assert.IsNotNull (ex.Message, "#4");
350 Assert.IsNotNull (ex.ParamName, "#5");
351 Assert.AreEqual ("methodInfo", ex.ParamName, "#6");
356 public void TestFilterEmittingWithHandlerExecution ()
358 DefineTestFilterMethod ();
359 Type dynt = tb.CreateType ();
361 MethodInfo tf = dynt.GetMethod ("TestFilter");
362 Assert.IsTrue ((bool) tf.Invoke (null, new object [] { true }));
366 [ExpectedException (typeof (Exception))]
367 public void TestFilterEmittingWithoutHandlerExecution ()
369 DefineTestFilterMethod ();
370 Type dynt = tb.CreateType ();
372 MethodInfo tf = dynt.GetMethod ("TestFilter");
374 tf.Invoke (null, new object [] { false });
375 } catch (TargetInvocationException tie) {
376 throw tie.InnerException;