Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / tests / bug-389886-2.cs
1 using System;
2 using System.Threading;
3 using System.Reflection;
4 using System.Reflection.Emit;
5
6 /*public delegate void FooDelegate ();*/
7
8 public class EmitTest
9 {
10         static ConstructorBuilder ctor;
11         static MethodBuilder targetMethod;
12         static MethodBuilder testEvents;
13         static Type fooOpenInst;
14         static Type[] genericArgs;
15
16         static void EmitCtor (TypeBuilder genericFoo) {
17                 ConstructorBuilder mb = genericFoo.DefineConstructor (MethodAttributes.Public, CallingConventions.Standard, null);
18                 ILGenerator il = mb.GetILGenerator ();
19                 for (int i = 0; i < 20; ++i)
20                                 il.Emit (OpCodes.Nop);
21
22                 il.Emit (OpCodes.Ldarg_0);
23                 il.Emit (OpCodes.Call, typeof (object).GetConstructors()[0]);
24                 il.Emit (OpCodes.Ret);
25
26                 ctor = mb;
27         }
28
29         static void EmitTestEvents (TypeBuilder genericFoo) {
30                 MethodBuilder mb = genericFoo.DefineMethod ("TestEvents", MethodAttributes.Public, typeof (void), null);
31                 ILGenerator il = mb.GetILGenerator ();
32                 for (int i = 0; i < 20; ++i)
33                                 il.Emit (OpCodes.Nop);
34
35                 il.Emit (OpCodes.Ldarg_0);
36                 il.Emit (OpCodes.Ldnull);
37                 il.Emit (OpCodes.Callvirt, targetMethod);
38
39                 il.Emit (OpCodes.Ret);
40
41                 testEvents = mb;
42         }
43
44
45         static void EmitTargetMethod (TypeBuilder genericFoo) {
46                 MethodBuilder mb = genericFoo.DefineMethod ("TargetMethod", MethodAttributes.Public, typeof (void), new Type[] {typeof (object) });
47                 ILGenerator il = mb.GetILGenerator ();
48
49                 for (int i = 0; i < 20; ++i)
50                                 il.Emit (OpCodes.Nop);
51
52                 il.Emit (OpCodes.Ldtoken, genericArgs [0]);
53                 il.Emit (OpCodes.Call, typeof (Type).GetMethod ("GetTypeFromHandle"));
54                 il.Emit (OpCodes.Call, typeof (Console).GetMethod ("WriteLine", new Type[] { typeof (object) }));
55                 il.Emit (OpCodes.Ret);
56
57                 targetMethod = mb;
58         }
59
60         public static int Main () {
61                 AssemblyName assemblyName = new AssemblyName();
62                 assemblyName.Name = "customMod";
63                 assemblyName.Version = new Version (1, 2, 3, 4);
64
65                 AssemblyBuilder assembly 
66                         = Thread.GetDomain().DefineDynamicAssembly(
67                                   assemblyName, AssemblyBuilderAccess.RunAndSave);
68
69                 ModuleBuilder module = assembly.DefineDynamicModule("res.exe", "res.exe");
70
71                 TypeBuilder genericFoo = module.DefineType ("GenericFoo", TypeAttributes.Public, typeof (object));
72                 genericArgs = genericFoo.DefineGenericParameters ("T");
73                 fooOpenInst = genericFoo.MakeGenericType (genericArgs);
74
75                 EmitCtor (genericFoo);
76                 EmitTargetMethod (genericFoo);
77                 EmitTestEvents (genericFoo);
78
79                 TypeBuilder moduletype = module.DefineType ("ModuleType", TypeAttributes.Public, typeof (object));
80                 MethodBuilder main = moduletype.DefineMethod ("Main", MethodAttributes.Public | MethodAttributes.Static, typeof (void), null);
81                 ILGenerator il = main.GetILGenerator ();
82
83                 Type strInst = genericFoo.MakeGenericType (typeof (string));
84                 il.Emit (OpCodes.Newobj, TypeBuilder.GetConstructor (strInst, ctor));
85                 il.Emit (OpCodes.Callvirt, TypeBuilder.GetMethod (strInst, testEvents));
86                 il.Emit (OpCodes.Ret);
87
88                 genericFoo.CreateType ();
89                 Type res = moduletype.CreateType ();
90         
91                 res.GetMethod ("Main").Invoke (null, null);
92                 return 0;
93         }
94
95 }
96