Merge pull request #5406 from kumpera/fix_12157
[mono.git] / mono / tests / dynamic-method-resurrection.cs
1 using System;
2 using System.Reflection;
3 using System.Reflection.Emit;
4 using System.Runtime.InteropServices;
5 using System.Runtime.CompilerServices;
6 using System.Threading;
7
8 delegate int Getter ();
9
10 class Host {
11
12         static int Field = 42;
13
14         Getter g;
15
16         public Host (Getter g) {
17                 this.g = g;
18         }
19
20         ~Host () {
21                 Console.WriteLine ("got finalizated");
22                 Program.resed = g;
23         }
24 }
25
26
27 class Program {
28                 internal static Getter resed;
29                 static int result;
30                 static void DoStuff ()
31         {
32                         DynamicMethod method = new DynamicMethod ("GetField",
33                         typeof (int), new Type [0], Type.GetType ("Host"));
34
35                         ILGenerator il = method.GetILGenerator ();
36                         il.Emit (OpCodes.Ldsfld, typeof (Host).GetField ("Field", BindingFlags.Static | BindingFlags.NonPublic));
37                         il.Emit (OpCodes.Ret);
38
39                         var g = (Getter)method.CreateDelegate (typeof (Getter));                        
40                         new Host (g);
41         }
42
43                 static bool CheckStuff () {
44                         if (resed == null)
45                                 return false;
46                         Program.result = resed ();
47                         resed = null;
48                         return true;
49                 }
50
51                 public static int Main ()
52         {
53                         int cnt = 5;
54                         var t = new Thread (DoStuff);
55                         t.Start ();
56                         t.Join ();
57                         do {
58                                 if (CheckStuff ())
59                                         break;
60                                 GC.Collect ();
61                                 GC.WaitForPendingFinalizers ();
62                                 Thread.Sleep (10);
63                         } while (cnt-- > 0);
64                         GC.Collect ();
65                         GC.WaitForPendingFinalizers ();
66                         Console.WriteLine ("done with finalizers");
67                         return result == 42 ? 0 : 1;
68                 }
69 }