Merge pull request #1936 from esdrubal/DotNetRelativeOrAbsolute
[mono.git] / mcs / class / corlib / Test / System.Reflection.Emit / MethodBuilderTestIL.cs
1         //
2         // MethodBuilderTestIL.cs - NUnit Test Cases for MethodBuilder.CreateMethodBody and MethodBuilder.SetMethodBody
3         //
4         // Marcos Henrich (marcos.henrich@xamarin.com)
5         //
6         // (C) Xamarin, Inc.
7
8         using System;
9         using System.Linq;
10         using System.Reflection;
11         using System.Reflection.Emit;
12         using System.Threading;
13
14         using NUnit.Framework;
15         using System.IO;
16
17         namespace MonoTests.System.Reflection.Emit
18         {
19                 public abstract class MethodBuilderTestIL
20                 {
21                         protected abstract void SetIL (MethodBuilder methodBuilder, MemoryStream ilStream);
22
23                         public static ModuleBuilder CreateModuleBuilder ()
24                         {
25                                 AppDomain currentDom = Thread.GetDomain ();
26
27                                 AssemblyBuilder assemblyBuilder = currentDom.DefineDynamicAssembly (
28                                         new AssemblyName ("NewDynamicAssembly"),
29                                         AssemblyBuilderAccess.Run);
30
31                                 return assemblyBuilder.DefineDynamicModule ("NewModule");
32                         }
33
34                         public static object Invoke (Type type, MethodBuilder methodBuilder, params object[] parameters)
35                         {
36                                 var method = type.GetMethods ().First (m => {
37                                         if (m.Name != methodBuilder.Name)
38                                                 return false;
39                                         var params1 = m.GetParameters ();
40                                         var params2 = methodBuilder.GetParameters ();
41                                         if (params1.Length != params2.Length)
42                                                 return false;
43                                         for (var i = 0; i < params1.Length; i++)
44                                                 if (params1 [i].ParameterType.FullName != params2 [i].ParameterType.FullName)
45                                                         return false;
46
47                                         return true;
48                                 });
49
50                                 object inst = Activator.CreateInstance (type, new object [0]);
51
52                                 return method.Invoke (inst, parameters);
53                         }
54
55                         [Test]
56                         public void CallMethodRef ()
57                         {
58                                 var expected = "value";
59
60                                 var moduleBuilder = CreateModuleBuilder ();
61                                 var typeBuilder = moduleBuilder.DefineType ("NewType");
62
63                                 var methodBuilder1 = typeBuilder.DefineMethod ("NewMethod1",
64                                         MethodAttributes.Public | MethodAttributes.Static,
65                                         typeof (string),
66                                         Type.EmptyTypes);
67
68                                 var gen1 = methodBuilder1.GetILGenerator ();
69                                 gen1.Emit (OpCodes.Ldstr, expected);
70                                 gen1.Emit (OpCodes.Ret);
71
72                                 var methodBuilder2 = typeBuilder.DefineMethod ("NewMethod2",
73                                 MethodAttributes.Public | MethodAttributes.Static,
74                                         typeof (string),
75                                         Type.EmptyTypes);
76
77                                 var ilStream = new MemoryStream ();
78                                 var ilWriter = new BinaryWriter (ilStream);
79                                 ilWriter.Write ((byte) 0x28); // call
80                                 ilWriter.Write ((int)  moduleBuilder.GetMethodToken (methodBuilder1).Token);
81                                 ilWriter.Write ((byte) 0x2A); // ret
82
83                                 SetIL (methodBuilder2, ilStream);
84
85                                 var type = typeBuilder.CreateType ();
86
87                                 Assert.AreEqual (expected, Invoke (type, methodBuilder2));
88                         }
89
90                         [Test]
91                         public void CallMethodDef ()
92                         {
93                                 var expected = "value";
94
95                                 var moduleBuilder1 = CreateModuleBuilder ();
96                                 var typeBuilder1 = moduleBuilder1.DefineType ("NewType1", TypeAttributes.Public);
97
98                                 var methodBuilder1 = typeBuilder1.DefineMethod ("NewMethod1",
99                                  MethodAttributes.Public | MethodAttributes.Static,
100                                         typeof (string),
101                                         Type.EmptyTypes);
102
103                                 var gen1 = methodBuilder1.GetILGenerator ();
104                                 gen1.Emit (OpCodes.Ldstr, expected);
105                                 gen1.Emit (OpCodes.Ret);
106
107                                 typeBuilder1.CreateType ();
108
109                                 var moduleBuilder2 = CreateModuleBuilder ();
110                                 var typeBuilder2 = moduleBuilder2.DefineType ("NewType2");
111
112                                 var methodBuilder2 = typeBuilder2.DefineMethod ("NewMethod2",
113                                         MethodAttributes.Public | MethodAttributes.Static,
114                                         typeof (string),
115                                         Type.EmptyTypes);
116
117                                 var ilStream = new MemoryStream ();
118                                 var ilWriter = new BinaryWriter (ilStream);
119                                 ilWriter.Write ((byte) 0x28); // call
120                                 ilWriter.Write ((int) moduleBuilder2.GetMethodToken (methodBuilder1).Token);
121                                 ilWriter.Write ((byte) 0x2A); // ret
122
123                                 SetIL (methodBuilder2, ilStream);
124
125                                 var type = typeBuilder2.CreateType ();
126
127                                 Assert.AreEqual (expected, Invoke (type, methodBuilder2));
128                         }
129                 }
130
131                 /*
132                  * Tests MethodBuilder.CreateMethodBody
133                  */
134                 [TestFixture]
135                 public class MethodBuilderTestIL_CreateMethodBody : MethodBuilderTestIL
136                 {
137                         protected override void SetIL (MethodBuilder methodBuilder, MemoryStream ilStream)
138                         {
139                                 methodBuilder.CreateMethodBody (ilStream.ToArray (), (int) ilStream.Length);
140                         }
141                 }
142
143                 /*
144                  * Tests MethodBuilder.SetMethodBody
145                  */
146                 [TestFixture]
147                 public class MethodBuilderTestIL_SetMethodBody : MethodBuilderTestIL
148                 {
149                         protected override void SetIL (MethodBuilder methodBuilder, MemoryStream ilStream)
150                         {
151                                 methodBuilder.SetMethodBody (ilStream.ToArray (), 999, null, null, null);
152                         }
153                 }
154         }