2 // DynamicMethodTest.cs - NUnit Test Cases for the DynamicMethod class
4 // Gert Driesen (drieseng@users.sourceforge.net)
11 using System.Reflection;
12 using System.Reflection.Emit;
14 using NUnit.Framework;
16 namespace MonoTests.System.Reflection.Emit
19 public class DynamicMethodTest
21 private delegate int HelloInvoker (string msg);
24 public void Constructor1_Name_Null ()
27 new DynamicMethod (null,
29 new Type[] { typeof (string) },
30 typeof (DynamicMethodTest).Module);
32 } catch (ArgumentNullException ex) {
33 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
34 Assert.AreEqual ("name", ex.ParamName, "#3");
35 Assert.IsNull (ex.InnerException, "#4");
40 public void Constructor2_Name_Null ()
43 new DynamicMethod (null,
45 new Type[] { typeof (string) },
46 typeof (DynamicMethodTest));
48 } catch (ArgumentNullException ex) {
49 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
50 Assert.AreEqual ("name", ex.ParamName, "#3");
51 Assert.IsNull (ex.InnerException, "#4");
56 public void Constructor3_Name_Null ()
59 new DynamicMethod (null,
61 new Type[] { typeof (string) },
62 typeof (DynamicMethodTest).Module, true);
64 } catch (ArgumentNullException ex) {
65 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
66 Assert.AreEqual ("name", ex.ParamName, "#3");
67 Assert.IsNull (ex.InnerException, "#4");
72 public void Constructor4_Name_Null ()
75 new DynamicMethod (null,
77 new Type[] { typeof (string) },
78 typeof (DynamicMethodTest), true);
80 } catch (ArgumentNullException ex) {
81 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
82 Assert.AreEqual ("name", ex.ParamName, "#3");
83 Assert.IsNull (ex.InnerException, "#4");
88 public void Constructor5_Name_Null ()
91 new DynamicMethod (null,
92 MethodAttributes.Public | MethodAttributes.Static,
93 CallingConventions.Standard,
95 new Type[] { typeof (string) },
96 typeof (DynamicMethodTest).Module, true);
98 } catch (ArgumentNullException ex) {
99 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
100 Assert.AreEqual ("name", ex.ParamName, "#3");
101 Assert.IsNull (ex.InnerException, "#4");
106 public void Constructor6_Name_Null ()
109 new DynamicMethod (null,
110 MethodAttributes.Public | MethodAttributes.Static,
111 CallingConventions.Standard,
113 new Type[] { typeof (string) },
114 typeof (DynamicMethodTest), true);
116 } catch (ArgumentNullException ex) {
117 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
118 Assert.AreEqual ("name", ex.ParamName, "#3");
119 Assert.IsNull (ex.InnerException, "#4");
124 public void DynamicMethodReference ()
126 DynamicMethod hello = new DynamicMethod ("Hello",
128 new Type[] { typeof (string) },
129 typeof (DynamicMethodTest).Module);
130 Assert.IsNull (hello.DeclaringType, "#1");
132 DynamicMethod write = new DynamicMethod ("Write",
134 new Type[] { typeof (string) },
135 typeof (DynamicMethodTest));
136 Assert.IsNull (hello.DeclaringType, "#2");
138 MethodInfo invokeWrite = write.GetBaseDefinition ();
140 ILGenerator helloIL = hello.GetILGenerator ();
141 helloIL.Emit (OpCodes.Ldarg_0);
142 helloIL.EmitCall (OpCodes.Call, invokeWrite, null);
143 helloIL.Emit (OpCodes.Ret);
145 ILGenerator writeIL = write.GetILGenerator ();
146 writeIL.Emit (OpCodes.Ldc_I4_2);
147 writeIL.Emit (OpCodes.Ret);
150 (HelloInvoker) hello.CreateDelegate (typeof (HelloInvoker));
151 int ret = hi ("Hello, World!");
152 Assert.AreEqual (2, ret, "#3");
154 object[] invokeArgs = { "Hello, World!" };
155 object objRet = hello.Invoke (null, invokeArgs);
156 Assert.AreEqual (2, objRet, "#4");
160 public void EmptyMethodBody ()
162 DynamicMethod hello = new DynamicMethod ("Hello",
164 new Type[] { typeof (string) },
165 typeof (DynamicMethodTest).Module);
166 object[] invokeArgs = { "Hello, World!" };
170 hello.Invoke (null, invokeArgs);
172 } catch (InvalidOperationException) {
176 hello.GetILGenerator ();
178 hello.Invoke (null, invokeArgs);
180 } catch (InvalidOperationException) {
184 private delegate string ReturnString (string msg);
185 private delegate void DoNothing (string msg);
187 private static string private_method (string s) {
192 public void SkipVisibility ()
194 DynamicMethod hello = new DynamicMethod ("Hello",
196 new Type[] { typeof (string) },
197 typeof (DynamicMethodTest).Module, true);
199 ILGenerator helloIL = hello.GetILGenerator ();
200 helloIL.Emit (OpCodes.Ldarg_0);
201 helloIL.EmitCall (OpCodes.Call, typeof (DynamicMethodTest).GetMethod ("private_method", BindingFlags.Static|BindingFlags.NonPublic), null);
202 helloIL.Emit (OpCodes.Ret);
205 (ReturnString) hello.CreateDelegate (typeof (ReturnString));
206 Assert.AreEqual ("ABCD", del ("ABCD"));
210 public void ReturnType_Null ()
212 DynamicMethod hello = new DynamicMethod ("Hello",
214 new Type[] { typeof (string) },
215 typeof (DynamicMethodTest).Module, true);
216 Assert.AreEqual (typeof (void), hello.ReturnType, "#1");
218 ILGenerator helloIL = hello.GetILGenerator ();
219 helloIL.Emit (OpCodes.Ret);
221 DoNothing dn = (DoNothing) hello.CreateDelegate (typeof (DoNothing));
224 object[] invokeArgs = { "Hello, World!" };
225 object objRet = hello.Invoke (null, invokeArgs);
226 Assert.IsNull (objRet, "#2");
230 public void Name_Empty ()
232 DynamicMethod hello = new DynamicMethod (string.Empty,
234 new Type[] { typeof (string) },
235 typeof (DynamicMethodTest).Module);
236 Assert.AreEqual (string.Empty, hello.Name, "#1");
238 DynamicMethod write = new DynamicMethod ("Write",
240 new Type[] { typeof (string) },
241 typeof (DynamicMethodTest));
243 MethodInfo invokeWrite = write.GetBaseDefinition ();
245 ILGenerator helloIL = hello.GetILGenerator ();
246 helloIL.Emit (OpCodes.Ldarg_0);
247 helloIL.EmitCall (OpCodes.Call, invokeWrite, null);
248 helloIL.Emit (OpCodes.Ret);
250 ILGenerator writeIL = write.GetILGenerator ();
251 writeIL.Emit (OpCodes.Ldc_I4_2);
252 writeIL.Emit (OpCodes.Ret);
255 (HelloInvoker) hello.CreateDelegate (typeof (HelloInvoker));
256 int ret = hi ("Hello, World!");
257 Assert.AreEqual (2, ret, "#2");
259 object[] invokeArgs = { "Hello, World!" };
260 object objRet = hello.Invoke (null, invokeArgs);
261 Assert.AreEqual (2, objRet, "#3");
265 public void Circular_Refs () {
266 DynamicMethod m1 = new DynamicMethod("f1", typeof(int), new Type[] { typeof (int) },
268 DynamicMethod m2 = new DynamicMethod("f2", typeof(int), new Type[] { typeof (int) },
271 ILGenerator il1 = m1.GetILGenerator();
272 ILGenerator il2 = m2.GetILGenerator();
274 Label l = il1.DefineLabel ();
275 //il1.EmitWriteLine ("f1");
276 il1.Emit (OpCodes.Ldarg_0);
277 il1.Emit (OpCodes.Ldc_I4_0);
278 il1.Emit (OpCodes.Bne_Un, l);
279 il1.Emit (OpCodes.Ldarg_0);
280 il1.Emit (OpCodes.Ret);
282 il1.Emit (OpCodes.Ldarg_0);
283 il1.Emit (OpCodes.Ldc_I4_1);
284 il1.Emit (OpCodes.Sub);
285 il1.Emit (OpCodes.Call, m2);
286 il1.Emit (OpCodes.Ret);
288 //il2.EmitWriteLine("f2");
289 il2.Emit(OpCodes.Ldarg_0);
290 il2.Emit(OpCodes.Call, m1);
291 il2.Emit(OpCodes.Ret);
293 m1.Invoke(null, new object[] { 5 });
297 static string Field = "foo";
301 [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=297416
302 public void TestOwnerMemberAccess ()
304 DynamicMethod method = new DynamicMethod ("GetField",
305 typeof (string), new Type [0], typeof (Host));
307 ILGenerator il = method.GetILGenerator ();
308 il.Emit (OpCodes.Ldsfld, typeof (Host).GetField (
309 "Field", BindingFlags.Static | BindingFlags.NonPublic));
310 il.Emit (OpCodes.Ret);
312 string ret = (string) method.Invoke (null, new object [] {});
313 Assert.AreEqual ("foo", ret, "#1");
317 public void AnonHosted ()
319 DynamicMethod hello = new DynamicMethod ("Hello",
321 new Type[] { typeof (string) });
322 ILGenerator helloIL = hello.GetILGenerator ();
323 helloIL.Emit (OpCodes.Ldc_I4_2);
324 helloIL.Emit (OpCodes.Ret);
327 (HelloInvoker) hello.CreateDelegate (typeof (HelloInvoker));
328 int ret = hi ("Hello, World!");
329 Assert.AreEqual (2, ret);
331 object[] invokeArgs = { "Hello, World!" };
332 object objRet = hello.Invoke (null, invokeArgs);
333 Assert.AreEqual (2, objRet);
336 public delegate int IntInvoker();
338 public class Foo<T> {
339 public virtual int Test () { return 99; }
343 public void ConstrainedPrexixDoesntCrash () //bug #529238
345 Type foo = typeof (Foo<int>);
347 DynamicMethod dm = new DynamicMethod ("Hello", typeof (int), null);
348 ILGenerator ilgen = dm.GetILGenerator ();
349 ilgen.DeclareLocal (foo);
350 ilgen.Emit (OpCodes.Newobj, foo.GetConstructor (new Type [0]));
351 ilgen.Emit (OpCodes.Stloc_0);
352 ilgen.Emit (OpCodes.Ldloca_S, 0);
353 ilgen.Emit (OpCodes.Constrained, foo);
354 ilgen.Emit (OpCodes.Callvirt, foo.GetMethod ("Test"));
355 ilgen.Emit (OpCodes.Ret);
357 IntInvoker hi = (IntInvoker) dm.CreateDelegate (typeof (IntInvoker));
358 Assert.AreEqual (99, hi (), "#1");
363 public void Module_GetMethod () {
364 AssemblyName assemblyName = new AssemblyName ();
365 assemblyName.Name = "foo";
367 AssemblyBuilder assembly =
368 AppDomain.CurrentDomain.DefineDynamicAssembly (
369 assemblyName, AssemblyBuilderAccess.RunAndSave);
371 ModuleBuilder module = assembly.DefineDynamicModule ("foo.dll");
373 var d = new DynamicMethod ("foo", typeof (int), new Type [] { typeof (int[,]) }, module);
374 var ig = d.GetILGenerator ();
375 ig.Emit (OpCodes.Ldarg_0);
376 ig.Emit (OpCodes.Ldc_I4, 1);
377 ig.Emit (OpCodes.Ldc_I4, 1);
378 ig.Emit (OpCodes.Call, module.GetArrayMethod (typeof (int[,]), "Get", CallingConventions.Standard, typeof (int), new Type [] { typeof (int), typeof (int) }));
379 ig.Emit (OpCodes.Ret);
381 var del = (Func<int[,], int>)d.CreateDelegate (typeof (Func<int[,], int>));
382 int[,] arr = new int [10, 10];
384 Assert.AreEqual (5, del (arr));