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