[xbuild] Actually delete common files (CopyLocal) during Clean.
[mono.git] / mono / mini / gshared.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Runtime.CompilerServices;
4
5 struct Foo {
6         public int i, j;
7 }
8
9 struct GFoo<T> {
10         public T dummy;
11         public T t;
12         public int i;
13         public Foo f;
14         public static T static_dummy;
15         public static T static_t;
16         public static Foo static_f;
17 }
18
19 struct GFoo2<T> {
20         public T t, t2;
21 }
22
23 class GFoo3<T> {
24         public T t, t2;
25
26         public GFoo3 () {
27         }
28
29         [MethodImplAttribute (MethodImplOptions.NoInlining)]
30         public GFoo3 (T i1, T i2) {
31                 t = i1;
32                 t2 = i2;
33         }
34 }
35
36 //
37 // Tests for generic sharing of vtypes.
38 // The tests use arrays to pass/receive values to keep the calling convention of the methods stable, which is a current limitation of the runtime support for gsharedvt.
39 //
40
41 // FIXME: Add mixed ref/noref tests, i.e. Dictionary<string, int>
42
43 public class Tests
44 {
45         public static int Main (String[] args) {
46                 return TestDriver.RunTests (typeof (Tests), args);
47         }
48
49         [MethodImplAttribute (MethodImplOptions.NoInlining)]
50         static void gshared<T> (T [] array, int i, int j) {
51                 T tmp = array [i];
52                 array [i] = array [j];
53                 array [j] = tmp;
54         }
55
56         // Test that the gshared and gsharedvt versions don't mix
57         public static int test_0_vt_gshared () {
58                 string[] sarr = new string [2] { "A", "B" };
59
60                 gshared<string> (sarr, 0, 1);
61
62                 Foo[] arr = new Foo [2];
63                 arr [0] = new Foo () { i = 1, j = 2 };
64                 arr [1] = new Foo () { i = 3, j = 4 };
65
66                 gshared<Foo> (arr, 0, 1);
67                 if (arr [0].i != 3 || arr [0].j != 4)
68                         return 1;
69                 if (arr [1].i != 1 || arr [1].j != 2)
70                         return 2;
71
72                 return 0;
73         }
74
75         static void ldelem_stelem<T> (T [] array, int i, int j) {
76                 T tmp = array [i];
77                 array [i] = array [j];
78                 array [j] = tmp;
79         }
80
81         public static int test_0_vt_ldelem_stelem () {
82                 Foo[] arr = new Foo [2];
83                 arr [0] = new Foo () { i = 1, j = 2 };
84                 arr [1] = new Foo () { i = 3, j = 4 };
85
86                 ldelem_stelem<Foo> (arr, 0, 1);
87                 if (arr [0].i != 3 || arr [0].j != 4)
88                         return 1;
89                 if (arr [1].i != 1 || arr [1].j != 2)
90                         return 2;
91
92                 int[] arr2 = new int [2] { 1, 2 };
93                 ldelem_stelem<int> (arr2, 0, 1);
94                 if (arr2 [0] !=2 || arr2 [1] != 1)
95                         return 3;
96
97                 return 0;
98         }
99
100         [MethodImplAttribute (MethodImplOptions.NoInlining)]
101         private static void initobj<T> (T [] array, int i, int j) {
102                 T x = default(T);
103                 array [i] = x;
104         }
105
106         public static int test_0_vt_initobj () {
107                 Foo[] arr = new Foo [2];
108                 arr [0] = new Foo () { i = 1, j = 2 };
109                 arr [1] = new Foo () { i = 3, j = 4 };
110
111                 initobj<Foo> (arr, 0, 1);
112                 if (arr [0].i != 0 || arr [0].j != 0)
113                         return 1;
114                 if (arr [1].i != 3 || arr [1].j != 4)
115                         return 2;
116                 return 0;
117         }
118
119         [MethodImplAttribute (MethodImplOptions.NoInlining)]
120         static T ldobj_stobj<T> (ref T t1, ref T t2) {
121                 t1 = t2;
122                 T t = t2;
123                 t2 = default(T);
124                 return t;
125         }
126
127         public static int test_0_vt_ldobj_stobj () {
128                 int i = 5;
129                 int j = 6;
130                 if (ldobj_stobj (ref i, ref j) != 6)
131                         return 1;
132                 if (i != 6 || j != 0)
133                         return 2;
134                 double d1 = 1.0;
135                 double d2 = 2.0;
136                 if (ldobj_stobj (ref d1, ref d2) != 2.0)
137                         return 3;
138                 if (d1 != 2.0 || d2 != 0.0)
139                         return 4;               
140                 return 0;
141         }
142
143         [MethodImplAttribute (MethodImplOptions.NoInlining)]
144         private static void box<T1, T> (T [] array, object[] arr) {
145                 object x = array [0];
146                 arr [0] = x;
147         }
148
149         public static int test_0_vt_box () {
150                 Foo[] arr = new Foo [2];
151                 arr [0] = new Foo () { i = 1, j = 2 };
152
153                 object[] arr2 = new object [16];
154                 box<int, Foo> (arr, arr2);
155                 if (arr2 [0].GetType () != typeof (Foo))
156                         return 1;
157                 Foo f = (Foo)arr2 [0];
158                 if (f.i != 1 || f.j != 2)
159                         return 2;
160                 string[] arr3 = new string [16];
161                 object[] arr4 = new object [16];
162                 arr3 [0] = "OK";
163                 box<int, string> (arr3, arr4);
164                 if (arr4 [0] != (object)arr3 [0])
165                         return 3;
166                 return 0;
167         }
168
169         [MethodImplAttribute (MethodImplOptions.NoInlining)]
170         private static void unbox_any<T> (T [] array, object[] arr) {
171                 T t = (T)arr [0];
172                 array [0] = t;
173         }
174
175         public static int test_0_vt_unbox_any () {
176                 Foo[] arr = new Foo [2];
177
178                 object[] arr2 = new object [16];
179                 arr2 [0] = new Foo () { i = 1, j = 2 };
180                 unbox_any<Foo> (arr, arr2);
181                 if (arr [0].i != 1 || arr [0].j != 2)
182                         return 2;
183                 return 0;
184         }
185
186         interface IFaceUnbox {
187                 T Unbox<T, T2> (T t, T2 t2, object o);
188         }
189
190         class ClassUnbox : IFaceUnbox {
191                 public T Unbox<T, T2> (T t, T2 t2, object o) {
192                         return (T)o;
193                 }
194         }
195
196         // unbox.any on a ref type in a gsharedvt method
197         public static int test_0_ref_gsharedvt_aot_unbox_any () {
198                 IFaceUnbox iface = new ClassUnbox ();
199                 string s = iface.Unbox<string, int> ("A", 2, "A");
200                 if (s != "A")
201                         return 1;
202                 return 0;
203         }
204
205         [MethodImplAttribute (MethodImplOptions.NoInlining)]
206         static void ldfld_nongeneric<T> (GFoo<T>[] foo, int[] arr) {
207                 arr [0] = foo [0].i;
208         }
209
210         [MethodImplAttribute (MethodImplOptions.NoInlining)]
211         static void ldfld<T> (GFoo<T>[] foo, T[] arr) {
212                 arr [0] = foo [0].t;
213         }
214
215         [MethodImplAttribute (MethodImplOptions.NoInlining)]
216         static void stfld_nongeneric<T> (GFoo<T>[] foo, int[] arr) {
217                 foo [0].i = arr [0];
218         }
219
220         [MethodImplAttribute (MethodImplOptions.NoInlining)]
221         static void stfld<T> (GFoo<T>[] foo, T[] arr) {
222                 foo [0].t = arr [0];
223         }
224
225         [MethodImplAttribute (MethodImplOptions.NoInlining)]
226         static void ldflda<T> (GFoo<T>[] foo, int[] arr) {
227                 arr [0] = foo [0].f.i;
228         }
229
230         public static int test_0_vt_ldfld_stfld () {
231                 var foo = new GFoo<Foo> () { t = new Foo () { i = 1, j = 2 }, i = 5, f = new Foo () { i = 5, j = 6 } };
232                 var farr = new GFoo<Foo>[] { foo };
233
234                 /* Normal fields with a variable offset */
235                 var iarr = new int [10];
236                 ldfld_nongeneric<Foo> (farr, iarr);
237                 if (iarr [0] != 5)
238                         return 1;
239                 iarr [0] = 16;
240                 stfld_nongeneric<Foo> (farr, iarr);
241                 if (farr [0].i != 16)
242                         return 2;
243
244                 /* Variable type field with a variable offset */
245                 var arr = new Foo [10];
246                 ldfld<Foo> (farr, arr);
247                 if (arr [0].i != 1 || arr [0].j != 2)
248                         return 3;
249                 arr [0] = new Foo () { i = 3, j = 4 };
250                 stfld<Foo> (farr, arr);
251                 if (farr [0].t.i != 3 || farr [0].t.j != 4)
252                         return 4;
253
254                 ldflda<Foo> (farr, iarr);
255                 if (iarr [0] != 5)
256                         return 5;
257
258                 return 0;
259         }
260
261         [MethodImplAttribute (MethodImplOptions.NoInlining)]
262         static void stsfld<T> (T[] arr) {
263                 GFoo<T>.static_t = arr [0];
264         }
265
266         [MethodImplAttribute (MethodImplOptions.NoInlining)]
267         static void ldsfld<T> (T[] arr) {
268                 arr [0] = GFoo<T>.static_t;
269         }
270
271         [MethodImplAttribute (MethodImplOptions.NoInlining)]
272         static void ldsflda<T> (int[] iarr) {
273                 iarr [0] = GFoo<T>.static_f.i;
274         }
275         
276         public static int test_0_stsfld () {
277                 Foo[] farr = new Foo [] { new Foo () { i = 1, j = 2 } };
278                 stsfld<Foo> (farr);
279
280                 if (GFoo<Foo>.static_t.i != 1 || GFoo<Foo>.static_t.j != 2)
281                         return 1;
282
283                 Foo[] farr2 = new Foo [1];
284                 ldsfld<Foo> (farr2);
285                 if (farr2 [0].i != 1 || farr2 [0].j != 2)
286                         return 2;
287
288                 var iarr = new int [10];
289                 GFoo<Foo>.static_f = new Foo () { i = 5, j = 6 };
290                 ldsflda<Foo> (iarr);
291                 if (iarr [0] != 5)
292                         return 3;
293
294                 return 0;
295         }
296
297         [MethodImplAttribute (MethodImplOptions.NoInlining)]
298         static object newarr<T> () {
299                 object o = new T[10];
300                 return o;
301         }
302
303         public static int test_0_vt_newarr () {
304                 object o = newarr<Foo> ();
305                 if (!(o is Foo[]))
306                         return 1;
307                 return 0;
308         }
309
310         [MethodImplAttribute (MethodImplOptions.NoInlining)]
311         static Type ldtoken<T> () {
312                 return typeof (GFoo<T>);
313         }
314
315         public static int test_0_vt_ldtoken () {
316                 Type t = ldtoken<Foo> ();
317                 if (t != typeof (GFoo<Foo>))
318                         return 1;
319                 t = ldtoken<int> ();
320                 if (t != typeof (GFoo<int>))
321                         return 2;
322
323                 return 0;
324         }
325
326         public static int test_0_vtype_list () {
327                 List<int> l = new List<int> ();
328
329                 l.Add (5);
330                 if (l.Count != 1)
331                         return 1;
332                 return 0;
333         }
334
335         [MethodImplAttribute (MethodImplOptions.NoInlining)]
336         static int args_simple<T> (T t, int i) {
337                 return i;
338         }
339
340         [MethodImplAttribute (MethodImplOptions.NoInlining)]
341         static int args_simple<T> (T t, int i, T t2) {
342                 return i;
343         }
344
345         [MethodImplAttribute (MethodImplOptions.NoInlining)]
346         static Type args_rgctx<T> (T t, int i) {
347                 return typeof (T);
348         }
349
350         [MethodImplAttribute (MethodImplOptions.NoInlining)]
351         static Type eh_in<T> (T t, int i) {
352                 throw new OverflowException ();
353         }
354
355         [MethodImplAttribute (MethodImplOptions.NoInlining)]
356         static T return_t<T> (T t) {
357                 return t;
358         }
359
360         [MethodImplAttribute (MethodImplOptions.NoInlining)]
361         T return_this_t<T> (T t) {
362                 return t;
363         }
364
365         public static int test_0_gsharedvt_in () {
366                 // Check that the non-generic argument is passed at the correct stack position
367                 int r = args_simple<bool> (true, 42);
368                 if (r != 42)
369                         return 1;
370                 r = args_simple<Foo> (new Foo (), 43);
371                 if (r != 43)
372                         return 2;
373                 // Check that the proper rgctx is passed to the method
374                 Type t = args_rgctx<int> (5, 42);
375                 if (t != typeof (int))
376                         return 3;
377                 var v = args_simple<GFoo2<int>> (new GFoo2<int> () { t = 11, t2 = 12 }, 44, new GFoo2<int> () { t = 11, t2 = 12 });
378                 if (v != 44)
379                         return 4;
380                 // Check that EH works properly
381                 try {
382                         eh_in<int> (1, 2);
383                 } catch (OverflowException) {
384                 }
385                 return 0;
386         }
387
388         public static int test_0_gsharedvt_in_ret () {
389                 int i = return_t<int> (42);
390                 if (i != 42)
391                         return 1;
392                 long l = return_t<long> (Int64.MaxValue);
393                 if (l != Int64.MaxValue)
394                         return 2;
395                 double d = return_t<double> (3.0);
396                 if (d != 3.0)
397                         return 3;
398                 float f = return_t<float> (3.0f);
399                 if (f != 3.0f)
400                         return 4;
401                 short s = return_t<short> (16);
402                 if (s != 16)
403                         return 5;
404                 var v = new GFoo2<int> () { t = 55, t2 = 32 };
405                 var v2 = return_t<GFoo2<int>> (v);
406                 if (v2.t != 55 || v2.t2 != 32)
407                         return 6;
408                 i = new Tests ().return_this_t<int> (42);
409                 if (i != 42)
410                         return 7;
411                 return 0;
412         }
413
414         public static int test_0_gsharedvt_in_delegates () {
415                 Func<int, int> f = new Func<int, int> (return_t<int>);
416                 if (f (42) != 42)
417                         return 1;
418                 return 0;
419         }
420
421         [MethodImplAttribute (MethodImplOptions.NoInlining)]
422         static T return2_t<T> (T t) {
423                 return return_t (t);
424         }
425
426         public static int test_0_gsharedvt_calls () {
427                 if (return2_t (2) != 2)
428                         return 1;
429                 if (return2_t ("A") != "A")
430                         return 2;
431                 if (return2_t (2.0) != 2.0)
432                         return 3;
433                 return 0;
434         }
435
436         static GFoo3<T> newobj<T> (T t1, T t2) {
437                 return new GFoo3<T> (t1, t2);
438         }
439         
440         public static int test_0_gshared_new () {
441                 var g1 = newobj (1, 2);
442                 if (g1.t != 1 || g1.t2 != 2)
443                         return 1;
444                 var g2 = newobj (1.0, 2.0);
445                 if (g1.t != 1.0 || g1.t2 != 2.0)
446                         return 2;
447
448                 return 0;
449         }
450
451         [MethodImplAttribute (MethodImplOptions.NoInlining)]
452         static GFoo2<T> newobj_vt<T> (T t1, T t2) {
453                 return new GFoo2<T> () { t = t1, t2 = t2 };
454         }
455
456         public static int test_0_gshared_new_vt () {
457                 GFoo2<int> v1 = newobj_vt (1, 2);
458                 if (v1.t != 1 || v1.t2 != 2)
459                         return 1;
460                 GFoo2<double> v2 = newobj_vt (1.0, 2.0);
461                 if (v2.t != 1.0 || v2.t2 != 2.0)
462                         return 2;
463                 return 0;
464         }
465
466         //
467         // Tests for transitioning out of gsharedvt code
468         //
469
470         // T1=Nullable<..> is not currently supported by gsharedvt
471
472         [MethodImplAttribute (MethodImplOptions.NoInlining)]
473         static T return_t_nogshared<T,T1> (T t) {
474                 object o = t;
475                 T t2 = (T)o;
476                 //Console.WriteLine ("X: " + t);
477                 return t;
478         }
479
480         [MethodImplAttribute (MethodImplOptions.NoInlining)]
481         static int return_int_nogshared<T,T1> (T t) {
482                 object o = t;
483                 T t2 = (T)o;
484                 return 2;
485         }
486
487         [MethodImplAttribute (MethodImplOptions.NoInlining)]
488         static A return_vtype_nogshared<T,T1> (T t) {
489                 object o = t;
490                 T t2 = (T)o;
491                 return new A () { a = 1, b = 2, c = 3 };
492         }
493
494         [MethodImplAttribute (MethodImplOptions.NoInlining)]
495         static T return2_t_out<T> (T t) {
496                 return return_t_nogshared<T, int?> (t);
497         }
498
499         [MethodImplAttribute (MethodImplOptions.NoInlining)]
500         static int return2_int_out<T> (T t) {
501                 return return_int_nogshared<T, int?> (t);
502         }
503
504         [MethodImplAttribute (MethodImplOptions.NoInlining)]
505         static A return2_vtype_out<T> (T t) {
506                 return return_vtype_nogshared<T, int?> (t);
507         }
508
509         struct A {
510                 public int a, b, c;
511         }
512
513         [Category ("!FULLAOT")]
514         public static int test_0_gsharedvt_out () {
515                 if (return2_t_out (2) != 2)
516                         return 1;
517                 if (return2_t_out ("A") != "A")
518                         return 2;
519                 if (return2_t_out (2.0) != 2.0)
520                         return 3;
521                 if (return2_t_out (2.0f) != 2.0f)
522                         return 4;
523                 A a = new A () { a = 1, b = 2, c = 3 };
524                 A a2 = return2_t_out (a);
525                 if (a2.a != 1 || a2.b != 2 || a2.c != 3)
526                         return 5;
527                 // Calls with non gsharedvt return types
528                 if (return2_int_out (1) != 2)
529                         return 6;
530                 A c = return2_vtype_out (a);
531                 if (a2.a != 1 || a2.b != 2 || a2.c != 3)
532                         return 7;
533                 return 0;
534         }
535
536         public class GenericClass<T> {
537                 public static T Z (IList<T> x, int index)
538                 {
539                         return x [index];
540                 }
541         }
542
543         public static int test_0_generic_array_helpers () {
544                 int[] x = new int[] {100, 200};
545
546                 // Generic array helpers should be treated as gsharedvt-out
547                 if (GenericClass<int>.Z (x, 0) != 100)
548                         return 1;
549
550                 return 0;
551         }
552
553         internal class IntComparer : IComparer<int>
554         {
555                 public int Compare (int ix, int iy)
556                 {
557                         if (ix == iy)
558                                 return 0;
559
560                         if (((uint) ix) < ((uint) iy))
561                                 return -1;
562                         return 1;
563                 }
564         }
565
566         [MethodImplAttribute (MethodImplOptions.NoInlining)]
567         static int gshared_out_iface<T> (T t1, T t2, IComparer<T> comp) {
568                 return comp.Compare (t1, t2);
569         }
570
571         public static int test_0_gshared_out_iface () {
572                 // Call out from gshared to a nongeneric method through a generic interface method
573                 if (gshared_out_iface (2, 2, new IntComparer ()) != 0)
574                         return 1;
575                 return 0;
576         }
577
578         struct Foo1 {
579                 public int i1, i2, i3;
580         }
581
582         struct Foo2<T> {
583                 int i1, i2, i3, i4, i5;
584                 public T foo;
585         }
586
587         [MethodImplAttribute (MethodImplOptions.NoInlining)]    
588         public static void locals<T> (T t) {
589                 Foo2<T> t2 = new Foo2<T> ();
590                 object o = t2;
591         }
592
593         public static int test_0_locals () {
594                 // Test that instantiations of type parameters are allocated the proper local type
595                 int i = 1;
596                 for (int j = 0; j < 10; ++j)
597                         i ++;
598                 locals<Foo1> (new Foo1 () { i1 = 1, i2 = 2, i3 = 3 });
599                 return 0;
600         }
601
602         public interface IFace<T> {
603                 T return_t_iface (T t);
604         }
605
606         public class Parent<T> {
607                 public virtual T return_t_vcall (T t) {
608                         throw new Exception ();
609                         return t;
610                 }
611         }
612
613         public class Child<T> : Parent<T>, IFace<T> {
614                 public override T return_t_vcall (T t) {
615                         return t;
616                 }
617                 public T return_t_iface (T t) {
618                         return t;
619                 }
620         }
621
622         [MethodImplAttribute (MethodImplOptions.NoInlining)]
623         static T return_t_vcall<T> (Parent<T> r, T t) {
624                 return r.return_t_vcall (t);
625         }
626
627         public static int test_0_vcalls () {
628                 if (return_t_vcall (new Child<int> (), 2) != 2)
629                         return 1;
630                 // Patching
631                 for (int i = 0; i < 10; ++i) {
632                         if (return_t_vcall (new Child<int> (), 2) != 2)
633                                 return 2;
634                 }
635                 if (return_t_vcall (new Child<double> (), 2.0) != 2.0)
636                         return 3;
637                 return 0;
638         }
639
640         [MethodImplAttribute (MethodImplOptions.NoInlining)]
641         static T return_t_iface<T> (IFace<T> r, T t) {
642                 return r.return_t_iface (t);
643         }
644
645         public static int test_0_iface_calls () {
646                 if (return_t_iface (new Child<int> (), 2) != 2)
647                         return 1;
648                 if (return_t_iface (new Child<double> (), 2.0) != 2.0)
649                         return 3;
650                 return 0;
651         }
652
653         static KeyValuePair<T1, T2> make_kvp<T1, T2> (T1 t1, T2 t2) {
654                 return new KeyValuePair<T1, T2> (t1, t2);
655         }
656
657         static T2 use_kvp<T1, T2> (KeyValuePair<T1, T2> kvp) {
658                 return kvp.Value;
659         }
660                 
661         [MethodImplAttribute (MethodImplOptions.NoInlining)]
662         static T do_kvp<T> (T a) {
663                 var t = make_kvp (a, a);
664                 // argument is an instance of a vtype instantiated with gsharedvt type arguments
665                 return use_kvp (t);
666         }
667
668         public static int test_0_gsharedvt_ginstvt_constructed_arg () {
669                 if (do_kvp<long> (1) != 1)
670                         return 1;
671                 return 0;
672         }
673
674         interface IGetter
675         {
676                 T Get<T>();
677         }
678
679         class Getter : IGetter
680         {
681                 public T Get<T>() { return default(T); }
682         }
683
684         abstract class Session
685         {
686                 public abstract IGetter Getter { get; }
687         }
688
689         class IosSession : Session
690         {
691                 private IGetter getter = new Getter();
692                 public override IGetter Getter { get { return getter; } }
693         }
694
695         enum ENUM_TYPE {
696         }
697
698         public static int test_0_regress_5156 () {
699                 new IosSession().Getter.Get<ENUM_TYPE>();
700                 return 0;
701         }
702
703         public struct VT
704         {
705                 public Action a;
706         }
707
708         public class D
709         {
710         }
711
712         public class A3
713         {
714                 public void OuterMethod<TArg1>(TArg1 value)
715                 {
716                         this.InnerMethod<TArg1, long>(value, 0);
717                 }
718
719                 private void InnerMethod<TArg1, TArg2>(TArg1 v1, TArg2 v2)
720                 {
721                         //Console.WriteLine("{0} {1}",v1,v2);
722                 }
723         }
724
725         public static int test_0_regress_2096 () {
726                 var a = new A3();
727
728                 // The following work:
729                 a.OuterMethod<int>(1);
730                 a.OuterMethod<DateTime>(DateTime.Now);
731
732                 var v = new VT();
733                 a.OuterMethod<VT>(v);
734
735                 var x = new D();
736                 // Next line will crash with Attempting to JIT compile method on device
737                 //  Attempting to JIT compile method
738                 a.OuterMethod<D>(x);
739                 return 0;
740         }
741
742         public class B
743         {
744                 public void Test<T>()
745                 {
746                         //System.Console.WriteLine(typeof(T));
747                 }
748         }
749
750         public class A<T>
751         {
752                 public void Test()
753                 {
754                         new B().Test<System.Collections.Generic.KeyValuePair<T, T>>();
755                 }
756         }
757
758     public static int test_0_regress_6040 () {
759         //new B().Test<System.Collections.Generic.KeyValuePair<string, string>>();
760         new A<int>().Test();
761         new A<object>().Test();
762         new A<string>().Test();
763                 return 0;
764     }
765
766         class ArrayContainer<T> {
767                 private T[,] container = new T[1,1];
768
769                 public T Prop {
770                         [MethodImplAttribute (MethodImplOptions.NoInlining)]
771                         get {
772                                 return container [0, 0];
773                         }
774                         [MethodImplAttribute (MethodImplOptions.NoInlining)]
775                         set {
776                                 container [0, 0] = value;
777                         }
778                 }
779         }
780
781         [MethodImplAttribute (MethodImplOptions.NoInlining)]
782         public static int test_0_multi_dim_arrays () {
783                 var c = new ArrayContainer<int> ();
784                 c.Prop = 5;
785                 return c.Prop == 5 ? 0 : 1;
786         }
787
788         [MethodImplAttribute (MethodImplOptions.NoInlining)]
789         static T2 rgctx_in_call_innner_inner<T1, T2> (T1 t1, T2 t2) {
790                 return t2;
791         }
792
793         [MethodImplAttribute (MethodImplOptions.NoInlining)]
794         static GFoo3<T> rgctx_in_call_inner<T> (T t) {
795                 return rgctx_in_call_innner_inner (1, new GFoo3<T> ());
796         }
797
798     public static int test_0_rgctx_in_call () {
799                 // The call is made through the rgctx call, and it needs an IN trampoline
800                 var t = rgctx_in_call_inner (1);
801                 if (t is GFoo3<int>)
802                         return 0;
803                 return 1;
804         }
805
806         [MethodImplAttribute (MethodImplOptions.NoInlining)]
807         static void arm_params1<T> (T t1, T t2, T t3, T t4, T t5, T t6) {
808         }
809
810         [MethodImplAttribute (MethodImplOptions.NoInlining)]
811         static void arm_params2<T> (T t1, T t2, T t3, long t4, T t5, T t6) {
812         }
813
814         public static int test_0_arm_param_passing () {
815                 arm_params1<int> (1, 2, 3, 4, 5, 6);
816                 arm_params1<int> (1, 2, 3, 4, 5, 6);
817                 return 0;
818         }
819
820         sealed class ScheduledItem<TAbsolute, TValue> {
821                 private readonly object _scheduler;
822                 private readonly TValue _state;
823                 private readonly object _action;
824
825                 public ScheduledItem(object o, TValue state, object action, TAbsolute dueTime) {
826                         _state = state;
827                 }
828         }
829
830     abstract class VirtualTimeSchedulerBase<TAbsolute, TRelative> {
831         public abstract void ScheduleAbsolute<TState>(TState state, TAbsolute dueTime);
832         }
833
834         class VirtualTimeScheduler<TAbsolute, TRelative> : VirtualTimeSchedulerBase<TAbsolute, TRelative> {
835                 public override void ScheduleAbsolute<TState>(TState state, TAbsolute dueTime) {
836                         var si = new ScheduledItem<TAbsolute, TState>(this, state, null, dueTime);
837                 }
838         }
839
840         public static int test_0_rx_mixed_regress () {
841                 var v = new VirtualTimeScheduler<long, long> ();
842                 v.ScheduleAbsolute<Action> (null, 22);
843                 return 0;
844         }
845
846         public class Base {
847                 public virtual T foo<T> (T t) {
848                         return t;
849                 }
850         }
851
852         class Class1 : Base {
853                 public object o;
854
855                 public override T foo<T> (T t) {
856                         o = t;
857                         return t;
858                 }
859         }
860
861         class Class2 : Base {
862                 public object o;
863
864                 public override T foo<T> (T t) {
865                         o = t;
866                         return t;
867                 }
868         }
869
870         [MethodImplAttribute (MethodImplOptions.NoInlining)]
871         public static void bar<T> (Base b, T t) {
872                 b.foo (t);
873         }
874
875         public static int test_0_virtual_generic () {
876                 Class1 c1 = new Class1 ();
877                 Class2 c2 = new Class2 ();
878                 bar (c1, 5);
879                 if (!(c1.o is int) || ((int)c1.o != 5))
880                         return 1;
881                 bar (c1, 6.0);
882                 if (!(c1.o is double) || ((double)c1.o != 6.0))
883                         return 2;
884                 bar (c1, 7.0f);
885                 if (!(c1.o is float) || ((float)c1.o != 7.0f))
886                         return 3;
887                 bar (c2, 5);
888                 if (!(c2.o is int) || ((int)c2.o != 5))
889                         return 4;
890                 bar (c2, 6.0);
891                 bar (c2, 7.0f);
892                 return 0;
893         }
894
895         [MethodImplAttribute (MethodImplOptions.NoInlining)]
896         static string to_string<T, T2>(T t, T2 t2) {
897                 return t.ToString ();
898         }
899
900         public static int test_0_constrained_tostring () {
901                 if (to_string<int, int> (1, 1) != "1")
902                         return 1;
903                 if (to_string<string, int> ("A", 1) != "A")
904                         return 2;
905                 return 0;
906         }
907
908         [MethodImplAttribute (MethodImplOptions.NoInlining)]
909         static int get_hash<T, T2>(T t, T2 t2) {
910                 return t.GetHashCode ();
911         }
912
913         public static int test_0_constrained_get_hash () {
914                 if (get_hash<int, int> (1, 1) != 1.GetHashCode ())
915                         return 1;
916                 if (get_hash<double, int> (1.0, 1) != 1.0.GetHashCode ())
917                         return 2;
918                 if (get_hash<string, int> ("A", 1) != "A".GetHashCode ())
919                         return 3;
920                 return 0;
921         }
922
923         struct Pair<T1, T2> {
924                 public T1 First;
925                 public T2 Second;
926         }
927
928         [MethodImplAttribute (MethodImplOptions.NoInlining)]
929         public static TState call_del<TState>(TState state, Func<object, TState, TState> action) {
930                 return action(null, state);
931         }
932
933         public static int test_0_delegate_wrappers () {
934                 Func<object, Pair<int, int>, Pair<int, int>> del1 = delegate (object o, Pair<int, int> p) { return p; };
935                 Func<object, Pair<int, int>, Pair<int, int>> del2 = delegate (object o, Pair<int, int> p) { return p; };
936                 Func<object, Pair<double, int>, Pair<double, int>> del3 = delegate (object o, Pair<double, int> p) { return p; };
937                 var r1 = call_del<Pair<int, int>> (new Pair<int, int> { First = 1, Second = 2}, del1);
938                 if (r1.First != 1 || r1.Second != 2)
939                         return 1;
940                 var r2 = call_del<Pair<int, int>> (new Pair<int, int> { First = 3, Second = 4}, del2);
941                 if (r2.First != 3 || r2.Second != 4)
942                         return 2;
943                 var r3 = call_del<Pair<double, int>> (new Pair<double, int> { First = 1.0, Second = 2}, del3);
944                 if (r3.First != 1.0 || r3.Second != 2)
945                         return 3;
946                 return 0;
947         }
948
949         class Base<T> {
950                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
951                 public object foo<T1> (T1 t1, T t, object o) {
952                         return o;
953                 }
954         }
955
956         class AClass : Base<long> {
957
958                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
959                 public object bar<T> (T t, long time, object o) {
960                         return foo (t, time, o);
961                 }
962         }
963
964         public static int test_0_out_in_wrappers () {
965                 var a = new AClass ();
966                 object o1 = "A";
967                 object o2 = a.bar<long> (1024, 0, o1);
968                 if (o1 != o2)
969                         return 1;
970                 return 0;               
971         }
972
973                 interface BIFace {
974                         object AMethod ();
975                 }
976
977                 class Base<TAbsolute, T2> : BIFace {
978
979                         public TAbsolute Clock { get; set; }
980
981                         public virtual object AMethod () {
982                                 return Clock;
983                         }
984                 }
985
986                 class BClass : Base<long, long> {
987                 }
988
989         public static int test_0_regress_1 () {
990                 BIFace c = new BClass ();
991                 object o = c.AMethod ();
992                 if (!(o is long) || ((long)o != 0))
993                         return 1;
994                 return 0;
995         }
996
997         interface IFace3 {
998                 T unbox_any<T> (object o);
999         }
1000
1001         class Class3 : IFace3 {
1002                 public virtual T unbox_any<T> (object o) {
1003                         return (T)o;
1004                 }
1005         }
1006
1007         public static int test_0_unbox_any () {
1008                 IFace3 o = new Class3 ();
1009                 if (o.unbox_any<int> (16) != 16)
1010                         return 1;
1011                 if (o.unbox_any<long> ((long)32) != 32)
1012                         return 2;
1013                 if (o.unbox_any<double> (2.0) != 2.0)
1014                         return 3;
1015                 try {
1016                         o.unbox_any<int> (2.0);
1017                         return 4;
1018                 } catch (Exception) {
1019                 }
1020                 return 0;
1021         }
1022
1023         interface IFace4 {
1024                 TSource Catch<TSource, TException>(TSource t)  where TException : Exception;
1025         }
1026
1027         class Class4 : IFace4 {
1028                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1029                         public TSource Catch<TSource, TException>(TSource t)  where TException : Exception {
1030                         return t;
1031                 }
1032         }
1033
1034         // Check that mixed instantiations are correctly created/found in AOT
1035         public static int test_0_constraints () {
1036                 IFace4 o = new Class4 ();
1037                 o.Catch<int, Exception> (1);
1038                 return 0;
1039         }
1040
1041         internal static Type Process<TSource, TElement> (TSource[] arr, Action<TElement, TElement> call) {
1042                 arr [0] = default (TSource);
1043                 return typeof (TSource);
1044         }
1045
1046         interface IFace5 {
1047                 Type foo<T> ();
1048         }
1049
1050         class Class5 : IFace5 {
1051                 public Type foo<T> () {
1052                         return Process<KeyValuePair<long, T>, T> (new KeyValuePair<long, T> [10], null);
1053                 }
1054         }
1055
1056         public static int test_0_rgctx_call_from_gshared_code () {
1057                 var c = new Class5 ();
1058                 if (c.foo<string> () != typeof (KeyValuePair<long, string>))
1059                         return 1;
1060                 return 0;
1061         }
1062
1063         public class Enumbers<T> {
1064                 public object Enumerate (List<KeyValuePair<T, string>> alist)
1065                 {
1066                         return alist.ToArray ();
1067                 }
1068         }
1069
1070         public static int test_0_checkthis_gshared_call () {
1071                 Enumbers<string> e = new Enumbers<string> ();
1072                 try {
1073                         e.Enumerate (null);
1074                         return 1;
1075                 }
1076                 catch (NullReferenceException) {
1077                 }
1078                 return 0;
1079         }
1080
1081         interface IFace6 {
1082                 T[] Del<T> (T t);
1083         }
1084
1085         class Class6 : IFace6 {
1086                 public T[] Del<T> (T t) {
1087                         var res = new T [5];
1088                         Func<T, T, T, T, T> func = delegate(T t1, T t2, T t3, T t4) { res [0] = t1; res [1] = t2; res [2] = t3; res [3] = t4; return t1; };
1089                         var v = func.BeginInvoke(t, t, t, t, null, null);
1090                         res [4] = func.EndInvoke (v);
1091                         return res;
1092                 }
1093         }
1094
1095         // FIXME: The runtime-invoke wrapper used by BeginInvoke is not found
1096         [Category ("!FULLAOT")]
1097         public static int test_0_begin_end_invoke () {
1098                 IFace6 o = new Class6 ();
1099                 var arr1 = o.Del (1);
1100                 if (arr1 [0] != 1 || arr1 [1] != 1 || arr1 [2] != 1 || arr1 [3] != 1 || arr1 [4] != 1)
1101                         return 1;
1102                 var arr2 = o.Del (2.0);
1103                 if (arr2 [0] != 2.0 || arr2 [1] != 2.0 || arr2 [2] != 2.0 || arr2 [3] != 2.0 || arr2 [4] != 2.0)
1104                         return 2;
1105                 return 0;
1106         }
1107
1108         public class TAbstractTableItem<TC> {
1109                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1110                 public static void SetProperty<TV> () {    }
1111
1112                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1113                 public static void Test () {
1114                         SetProperty<bool> ();
1115                 }
1116         }
1117
1118         public static int test_0_gsharedvt_method_on_shared_class () {
1119        TAbstractTableItem<object>.Test ();
1120            return 0;
1121         }
1122 }