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;
15 using NUnit.Framework;
17 namespace MonoTests.System.Reflection.Emit
20 public class DynamicMethodTest
22 private delegate int HelloInvoker (string msg);
25 public void Constructor1_Name_Null ()
28 new DynamicMethod (null,
30 new Type[] { typeof (string) },
31 typeof (DynamicMethodTest).Module);
33 } catch (ArgumentNullException ex) {
34 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
35 Assert.AreEqual ("name", ex.ParamName, "#3");
36 Assert.IsNull (ex.InnerException, "#4");
41 public void Constructor2_Name_Null ()
44 new DynamicMethod (null,
46 new Type[] { typeof (string) },
47 typeof (DynamicMethodTest));
49 } catch (ArgumentNullException ex) {
50 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
51 Assert.AreEqual ("name", ex.ParamName, "#3");
52 Assert.IsNull (ex.InnerException, "#4");
57 public void Constructor3_Name_Null ()
60 new DynamicMethod (null,
62 new Type[] { typeof (string) },
63 typeof (DynamicMethodTest).Module, true);
65 } catch (ArgumentNullException ex) {
66 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
67 Assert.AreEqual ("name", ex.ParamName, "#3");
68 Assert.IsNull (ex.InnerException, "#4");
73 public void Constructor4_Name_Null ()
76 new DynamicMethod (null,
78 new Type[] { typeof (string) },
79 typeof (DynamicMethodTest), true);
81 } catch (ArgumentNullException ex) {
82 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
83 Assert.AreEqual ("name", ex.ParamName, "#3");
84 Assert.IsNull (ex.InnerException, "#4");
89 public void Constructor5_Name_Null ()
92 new DynamicMethod (null,
93 MethodAttributes.Public | MethodAttributes.Static,
94 CallingConventions.Standard,
96 new Type[] { typeof (string) },
97 typeof (DynamicMethodTest).Module, true);
99 } catch (ArgumentNullException ex) {
100 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
101 Assert.AreEqual ("name", ex.ParamName, "#3");
102 Assert.IsNull (ex.InnerException, "#4");
107 public void Constructor6_Name_Null ()
110 new DynamicMethod (null,
111 MethodAttributes.Public | MethodAttributes.Static,
112 CallingConventions.Standard,
114 new Type[] { typeof (string) },
115 typeof (DynamicMethodTest), true);
117 } catch (ArgumentNullException ex) {
118 Assert.AreEqual (typeof (ArgumentNullException), ex.GetType (), "#2");
119 Assert.AreEqual ("name", ex.ParamName, "#3");
120 Assert.IsNull (ex.InnerException, "#4");
125 public void DynamicMethodReference ()
127 DynamicMethod hello = new DynamicMethod ("Hello",
129 new Type[] { typeof (string) },
130 typeof (DynamicMethodTest).Module);
131 Assert.IsNull (hello.DeclaringType, "#1");
133 DynamicMethod write = new DynamicMethod ("Write",
135 new Type[] { typeof (string) },
136 typeof (DynamicMethodTest));
137 Assert.IsNull (hello.DeclaringType, "#2");
139 MethodInfo invokeWrite = write.GetBaseDefinition ();
141 ILGenerator helloIL = hello.GetILGenerator ();
142 helloIL.Emit (OpCodes.Ldarg_0);
143 helloIL.EmitCall (OpCodes.Call, invokeWrite, null);
144 helloIL.Emit (OpCodes.Ret);
146 ILGenerator writeIL = write.GetILGenerator ();
147 writeIL.Emit (OpCodes.Ldc_I4_2);
148 writeIL.Emit (OpCodes.Ret);
151 (HelloInvoker) hello.CreateDelegate (typeof (HelloInvoker));
152 int ret = hi ("Hello, World!");
153 Assert.AreEqual (2, ret, "#3");
155 object[] invokeArgs = { "Hello, World!" };
156 object objRet = hello.Invoke (null, invokeArgs);
157 Assert.AreEqual (2, objRet, "#4");
161 public void EmptyMethodBody ()
163 DynamicMethod hello = new DynamicMethod ("Hello",
165 new Type[] { typeof (string) },
166 typeof (DynamicMethodTest).Module);
167 object[] invokeArgs = { "Hello, World!" };
171 hello.Invoke (null, invokeArgs);
173 } catch (InvalidOperationException) {
177 hello.GetILGenerator ();
179 hello.Invoke (null, invokeArgs);
181 } catch (InvalidOperationException) {
185 private delegate string ReturnString (string msg);
186 private delegate void DoNothing (string msg);
188 private static string private_method (string s) {
193 public void SkipVisibility ()
195 DynamicMethod hello = new DynamicMethod ("Hello",
197 new Type[] { typeof (string) },
198 typeof (DynamicMethodTest).Module, true);
200 ILGenerator helloIL = hello.GetILGenerator ();
201 helloIL.Emit (OpCodes.Ldarg_0);
202 helloIL.EmitCall (OpCodes.Call, typeof (DynamicMethodTest).GetMethod ("private_method", BindingFlags.Static|BindingFlags.NonPublic), null);
203 helloIL.Emit (OpCodes.Ret);
206 (ReturnString) hello.CreateDelegate (typeof (ReturnString));
207 Assert.AreEqual ("ABCD", del ("ABCD"));
211 public void ReturnType_Null ()
213 DynamicMethod hello = new DynamicMethod ("Hello",
215 new Type[] { typeof (string) },
216 typeof (DynamicMethodTest).Module, true);
217 Assert.AreEqual (typeof (void), hello.ReturnType, "#1");
219 ILGenerator helloIL = hello.GetILGenerator ();
220 helloIL.Emit (OpCodes.Ret);
222 DoNothing dn = (DoNothing) hello.CreateDelegate (typeof (DoNothing));
225 object[] invokeArgs = { "Hello, World!" };
226 object objRet = hello.Invoke (null, invokeArgs);
227 Assert.IsNull (objRet, "#2");
231 public void Name_Empty ()
233 DynamicMethod hello = new DynamicMethod (string.Empty,
235 new Type[] { typeof (string) },
236 typeof (DynamicMethodTest).Module);
237 Assert.AreEqual (string.Empty, hello.Name, "#1");
239 DynamicMethod write = new DynamicMethod ("Write",
241 new Type[] { typeof (string) },
242 typeof (DynamicMethodTest));
244 MethodInfo invokeWrite = write.GetBaseDefinition ();
246 ILGenerator helloIL = hello.GetILGenerator ();
247 helloIL.Emit (OpCodes.Ldarg_0);
248 helloIL.EmitCall (OpCodes.Call, invokeWrite, null);
249 helloIL.Emit (OpCodes.Ret);
251 ILGenerator writeIL = write.GetILGenerator ();
252 writeIL.Emit (OpCodes.Ldc_I4_2);
253 writeIL.Emit (OpCodes.Ret);
256 (HelloInvoker) hello.CreateDelegate (typeof (HelloInvoker));
257 int ret = hi ("Hello, World!");
258 Assert.AreEqual (2, ret, "#2");
260 object[] invokeArgs = { "Hello, World!" };
261 object objRet = hello.Invoke (null, invokeArgs);
262 Assert.AreEqual (2, objRet, "#3");
266 public void Circular_Refs () {
267 DynamicMethod m1 = new DynamicMethod("f1", typeof(int), new Type[] { typeof (int) },
269 DynamicMethod m2 = new DynamicMethod("f2", typeof(int), new Type[] { typeof (int) },
272 ILGenerator il1 = m1.GetILGenerator();
273 ILGenerator il2 = m2.GetILGenerator();
275 Label l = il1.DefineLabel ();
276 //il1.EmitWriteLine ("f1");
277 il1.Emit (OpCodes.Ldarg_0);
278 il1.Emit (OpCodes.Ldc_I4_0);
279 il1.Emit (OpCodes.Bne_Un, l);
280 il1.Emit (OpCodes.Ldarg_0);
281 il1.Emit (OpCodes.Ret);
283 il1.Emit (OpCodes.Ldarg_0);
284 il1.Emit (OpCodes.Ldc_I4_1);
285 il1.Emit (OpCodes.Sub);
286 il1.Emit (OpCodes.Call, m2);
287 il1.Emit (OpCodes.Ret);
289 //il2.EmitWriteLine("f2");
290 il2.Emit(OpCodes.Ldarg_0);
291 il2.Emit(OpCodes.Call, m1);
292 il2.Emit(OpCodes.Ret);
294 m1.Invoke(null, new object[] { 5 });
298 static string Field = "foo";
302 [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=297416
303 public void TestOwnerMemberAccess ()
305 DynamicMethod method = new DynamicMethod ("GetField",
306 typeof (string), new Type [0], typeof (Host));
308 ILGenerator il = method.GetILGenerator ();
309 il.Emit (OpCodes.Ldsfld, typeof (Host).GetField (
310 "Field", BindingFlags.Static | BindingFlags.NonPublic));
311 il.Emit (OpCodes.Ret);
313 string ret = (string) method.Invoke (null, new object [] {});
314 Assert.AreEqual ("foo", ret, "#1");
318 public void AnonHosted ()
320 DynamicMethod hello = new DynamicMethod ("Hello",
322 new Type[] { typeof (string) });
323 ILGenerator helloIL = hello.GetILGenerator ();
324 helloIL.Emit (OpCodes.Ldc_I4_2);
325 helloIL.Emit (OpCodes.Ret);
328 (HelloInvoker) hello.CreateDelegate (typeof (HelloInvoker));
329 int ret = hi ("Hello, World!");
330 Assert.AreEqual (2, ret);
332 object[] invokeArgs = { "Hello, World!" };
333 object objRet = hello.Invoke (null, invokeArgs);
334 Assert.AreEqual (2, objRet);
337 public delegate int IntInvoker();
339 public class Foo<T> {
340 public virtual int Test () { return 99; }
344 public void ConstrainedPrexixDoesntCrash () //bug #529238
346 Type foo = typeof (Foo<int>);
348 DynamicMethod dm = new DynamicMethod ("Hello", typeof (int), null);
349 ILGenerator ilgen = dm.GetILGenerator ();
350 ilgen.DeclareLocal (foo);
351 ilgen.Emit (OpCodes.Newobj, foo.GetConstructor (new Type [0]));
352 ilgen.Emit (OpCodes.Stloc_0);
353 ilgen.Emit (OpCodes.Ldloca_S, 0);
354 ilgen.Emit (OpCodes.Constrained, foo);
355 ilgen.Emit (OpCodes.Callvirt, foo.GetMethod ("Test"));
356 ilgen.Emit (OpCodes.Ret);
358 IntInvoker hi = (IntInvoker) dm.CreateDelegate (typeof (IntInvoker));
359 Assert.AreEqual (99, hi (), "#1");
364 public void Module_GetMethod () {
365 AssemblyName assemblyName = new AssemblyName ();
366 assemblyName.Name = "foo";
368 AssemblyBuilder assembly =
369 AppDomain.CurrentDomain.DefineDynamicAssembly (
370 assemblyName, AssemblyBuilderAccess.RunAndSave);
372 ModuleBuilder module = assembly.DefineDynamicModule ("foo.dll");
374 var d = new DynamicMethod ("foo", typeof (int), new Type [] { typeof (int[,]) }, module);
375 var ig = d.GetILGenerator ();
376 ig.Emit (OpCodes.Ldarg_0);
377 ig.Emit (OpCodes.Ldc_I4, 1);
378 ig.Emit (OpCodes.Ldc_I4, 1);
379 ig.Emit (OpCodes.Call, module.GetArrayMethod (typeof (int[,]), "Get", CallingConventions.Standard, typeof (int), new Type [] { typeof (int), typeof (int) }));
380 ig.Emit (OpCodes.Ret);
382 var del = (Func<int[,], int>)d.CreateDelegate (typeof (Func<int[,], int>));
383 int[,] arr = new int [10, 10];
385 Assert.AreEqual (5, del (arr));
389 [Category ("NotWorking")]
390 public void InvalidUnicodeName ()
392 var name = new StringBuilder ().Append ('\udf45').Append ('\ud808');
393 var method = new DynamicMethod (name.ToString (), typeof (bool), new Type [0]);
394 var il = method.GetILGenerator ();
395 il.Emit (OpCodes.Ldc_I4_1);
396 il.Emit (OpCodes.Ret);
398 var function = (Func<bool>) method.CreateDelegate (typeof (Func<bool>));
400 Assert.IsTrue (function ());