Add unit test for AggregateException.GetBaseException that works on .net but is broke...
[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         public static int test_0_unbox_any_enum () {
216                 IFaceUnbox iface = new ClassUnbox ();
217                 AnEnum res = iface.Unbox<AnEnum, int> (AnEnum.One, 0, 1);
218                 if (res != AnEnum.Two)
219                         return 1;
220                 res = iface.Unbox<AnEnum, int> (AnEnum.One, 0, AnEnum.Two);
221                 if (res != AnEnum.Two)
222                         return 2;
223                 return 0;
224         }
225
226         [MethodImplAttribute (MethodImplOptions.NoInlining)]
227         static void ldfld_nongeneric<T> (GFoo<T>[] foo, int[] arr) {
228                 arr [0] = foo [0].i;
229         }
230
231         [MethodImplAttribute (MethodImplOptions.NoInlining)]
232         static void ldfld<T> (GFoo<T>[] foo, T[] arr) {
233                 arr [0] = foo [0].t;
234         }
235
236         [MethodImplAttribute (MethodImplOptions.NoInlining)]
237         static void stfld_nongeneric<T> (GFoo<T>[] foo, int[] arr) {
238                 foo [0].i = arr [0];
239         }
240
241         [MethodImplAttribute (MethodImplOptions.NoInlining)]
242         static void stfld<T> (GFoo<T>[] foo, T[] arr) {
243                 foo [0].t = arr [0];
244         }
245
246         [MethodImplAttribute (MethodImplOptions.NoInlining)]
247         static void ldflda<T> (GFoo<T>[] foo, int[] arr) {
248                 arr [0] = foo [0].f.i;
249         }
250
251         public static int test_0_vt_ldfld_stfld () {
252                 var foo = new GFoo<Foo> () { t = new Foo () { i = 1, j = 2 }, i = 5, f = new Foo () { i = 5, j = 6 } };
253                 var farr = new GFoo<Foo>[] { foo };
254
255                 /* Normal fields with a variable offset */
256                 var iarr = new int [10];
257                 ldfld_nongeneric<Foo> (farr, iarr);
258                 if (iarr [0] != 5)
259                         return 1;
260                 iarr [0] = 16;
261                 stfld_nongeneric<Foo> (farr, iarr);
262                 if (farr [0].i != 16)
263                         return 2;
264
265                 /* Variable type field with a variable offset */
266                 var arr = new Foo [10];
267                 ldfld<Foo> (farr, arr);
268                 if (arr [0].i != 1 || arr [0].j != 2)
269                         return 3;
270                 arr [0] = new Foo () { i = 3, j = 4 };
271                 stfld<Foo> (farr, arr);
272                 if (farr [0].t.i != 3 || farr [0].t.j != 4)
273                         return 4;
274
275                 ldflda<Foo> (farr, iarr);
276                 if (iarr [0] != 5)
277                         return 5;
278
279                 return 0;
280         }
281
282         [MethodImplAttribute (MethodImplOptions.NoInlining)]
283         static void stsfld<T> (T[] arr) {
284                 GFoo<T>.static_t = arr [0];
285         }
286
287         [MethodImplAttribute (MethodImplOptions.NoInlining)]
288         static void ldsfld<T> (T[] arr) {
289                 arr [0] = GFoo<T>.static_t;
290         }
291
292         [MethodImplAttribute (MethodImplOptions.NoInlining)]
293         static void ldsflda<T> (int[] iarr) {
294                 iarr [0] = GFoo<T>.static_f.i;
295         }
296         
297         public static int test_0_stsfld () {
298                 Foo[] farr = new Foo [] { new Foo () { i = 1, j = 2 } };
299                 stsfld<Foo> (farr);
300
301                 if (GFoo<Foo>.static_t.i != 1 || GFoo<Foo>.static_t.j != 2)
302                         return 1;
303
304                 Foo[] farr2 = new Foo [1];
305                 ldsfld<Foo> (farr2);
306                 if (farr2 [0].i != 1 || farr2 [0].j != 2)
307                         return 2;
308
309                 var iarr = new int [10];
310                 GFoo<Foo>.static_f = new Foo () { i = 5, j = 6 };
311                 ldsflda<Foo> (iarr);
312                 if (iarr [0] != 5)
313                         return 3;
314
315                 return 0;
316         }
317
318         [MethodImplAttribute (MethodImplOptions.NoInlining)]
319         static object newarr<T> () {
320                 object o = new T[10];
321                 return o;
322         }
323
324         public static int test_0_vt_newarr () {
325                 object o = newarr<Foo> ();
326                 if (!(o is Foo[]))
327                         return 1;
328                 return 0;
329         }
330
331         [MethodImplAttribute (MethodImplOptions.NoInlining)]
332         static Type ldtoken<T> () {
333                 return typeof (GFoo<T>);
334         }
335
336         public static int test_0_vt_ldtoken () {
337                 Type t = ldtoken<Foo> ();
338                 if (t != typeof (GFoo<Foo>))
339                         return 1;
340                 t = ldtoken<int> ();
341                 if (t != typeof (GFoo<int>))
342                         return 2;
343
344                 return 0;
345         }
346
347         public static int test_0_vtype_list () {
348                 List<int> l = new List<int> ();
349
350                 l.Add (5);
351                 if (l.Count != 1)
352                         return 1;
353                 return 0;
354         }
355
356         [MethodImplAttribute (MethodImplOptions.NoInlining)]
357         static int args_simple<T> (T t, int i) {
358                 return i;
359         }
360
361         [MethodImplAttribute (MethodImplOptions.NoInlining)]
362         static int args_simple<T> (T t, int i, T t2) {
363                 return i;
364         }
365
366         [MethodImplAttribute (MethodImplOptions.NoInlining)]
367         static Type args_rgctx<T> (T t, int i) {
368                 return typeof (T);
369         }
370
371         [MethodImplAttribute (MethodImplOptions.NoInlining)]
372         static Type eh_in<T> (T t, int i) {
373                 throw new OverflowException ();
374         }
375
376         [MethodImplAttribute (MethodImplOptions.NoInlining)]
377         static T return_t<T> (T t) {
378                 return t;
379         }
380
381         [MethodImplAttribute (MethodImplOptions.NoInlining)]
382         T return_this_t<T> (T t) {
383                 return t;
384         }
385
386         public static int test_0_gsharedvt_in () {
387                 // Check that the non-generic argument is passed at the correct stack position
388                 int r = args_simple<bool> (true, 42);
389                 if (r != 42)
390                         return 1;
391                 r = args_simple<Foo> (new Foo (), 43);
392                 if (r != 43)
393                         return 2;
394                 // Check that the proper rgctx is passed to the method
395                 Type t = args_rgctx<int> (5, 42);
396                 if (t != typeof (int))
397                         return 3;
398                 var v = args_simple<GFoo2<int>> (new GFoo2<int> () { t = 11, t2 = 12 }, 44, new GFoo2<int> () { t = 11, t2 = 12 });
399                 if (v != 44)
400                         return 4;
401                 // Check that EH works properly
402                 try {
403                         eh_in<int> (1, 2);
404                 } catch (OverflowException) {
405                 }
406                 return 0;
407         }
408
409         public static int test_0_gsharedvt_in_ret () {
410                 int i = return_t<int> (42);
411                 if (i != 42)
412                         return 1;
413                 long l = return_t<long> (Int64.MaxValue);
414                 if (l != Int64.MaxValue)
415                         return 2;
416                 double d = return_t<double> (3.0);
417                 if (d != 3.0)
418                         return 3;
419                 float f = return_t<float> (3.0f);
420                 if (f != 3.0f)
421                         return 4;
422                 short s = return_t<short> (16);
423                 if (s != 16)
424                         return 5;
425                 var v = new GFoo2<int> () { t = 55, t2 = 32 };
426                 var v2 = return_t<GFoo2<int>> (v);
427                 if (v2.t != 55 || v2.t2 != 32)
428                         return 6;
429                 i = new GSharedTests ().return_this_t<int> (42);
430                 if (i != 42)
431                         return 7;
432                 return 0;
433         }
434
435         public static int test_0_gsharedvt_in_delegates () {
436                 Func<int, int> f = new Func<int, int> (return_t<int>);
437                 if (f (42) != 42)
438                         return 1;
439                 return 0;
440         }
441
442         [MethodImplAttribute (MethodImplOptions.NoInlining)]
443         static T return2_t<T> (T t) {
444                 return return_t (t);
445         }
446
447         public static int test_0_gsharedvt_calls () {
448                 if (return2_t (2) != 2)
449                         return 1;
450                 if (return2_t ("A") != "A")
451                         return 2;
452                 if (return2_t (2.0) != 2.0)
453                         return 3;
454                 return 0;
455         }
456
457         static GFoo3<T> newobj<T> (T t1, T t2) {
458                 return new GFoo3<T> (t1, t2);
459         }
460         
461         public static int test_0_gshared_new () {
462                 var g1 = newobj (1, 2);
463                 if (g1.t != 1 || g1.t2 != 2)
464                         return 1;
465                 var g2 = newobj (1.0, 2.0);
466                 if (g1.t != 1.0 || g1.t2 != 2.0)
467                         return 2;
468
469                 return 0;
470         }
471
472         [MethodImplAttribute (MethodImplOptions.NoInlining)]
473         static GFoo2<T> newobj_vt<T> (T t1, T t2) {
474                 return new GFoo2<T> () { t = t1, t2 = t2 };
475         }
476
477         public static int test_0_gshared_new_vt () {
478                 GFoo2<int> v1 = newobj_vt (1, 2);
479                 if (v1.t != 1 || v1.t2 != 2)
480                         return 1;
481                 GFoo2<double> v2 = newobj_vt (1.0, 2.0);
482                 if (v2.t != 1.0 || v2.t2 != 2.0)
483                         return 2;
484                 return 0;
485         }
486
487         //
488         // Tests for transitioning out of gsharedvt code
489         //
490
491         // T1=Nullable<..> is not currently supported by gsharedvt
492
493         [MethodImplAttribute (MethodImplOptions.NoInlining)]
494         static T return_t_nogshared<T,T1> (T t) {
495                 object o = t;
496                 T t2 = (T)o;
497                 //Console.WriteLine ("X: " + t);
498                 return t;
499         }
500
501         [MethodImplAttribute (MethodImplOptions.NoInlining)]
502         static int return_int_nogshared<T,T1> (T t) {
503                 object o = t;
504                 T t2 = (T)o;
505                 return 2;
506         }
507
508         [MethodImplAttribute (MethodImplOptions.NoInlining)]
509         static A return_vtype_nogshared<T,T1> (T t) {
510                 object o = t;
511                 T t2 = (T)o;
512                 return new A () { a = 1, b = 2, c = 3 };
513         }
514
515         [MethodImplAttribute (MethodImplOptions.NoInlining)]
516         static T return2_t_out<T> (T t) {
517                 return return_t_nogshared<T, int?> (t);
518         }
519
520         [MethodImplAttribute (MethodImplOptions.NoInlining)]
521         static int return2_int_out<T> (T t) {
522                 return return_int_nogshared<T, int?> (t);
523         }
524
525         [MethodImplAttribute (MethodImplOptions.NoInlining)]
526         static A return2_vtype_out<T> (T t) {
527                 return return_vtype_nogshared<T, int?> (t);
528         }
529
530         struct A {
531                 public int a, b, c;
532         }
533
534         [Category ("!FULLAOT")]
535         public static int test_0_gsharedvt_out () {
536                 if (return2_t_out (2) != 2)
537                         return 1;
538                 if (return2_t_out ("A") != "A")
539                         return 2;
540                 if (return2_t_out (2.0) != 2.0)
541                         return 3;
542                 if (return2_t_out (2.0f) != 2.0f)
543                         return 4;
544                 A a = new A () { a = 1, b = 2, c = 3 };
545                 A a2 = return2_t_out (a);
546                 if (a2.a != 1 || a2.b != 2 || a2.c != 3)
547                         return 5;
548                 // Calls with non gsharedvt return types
549                 if (return2_int_out (1) != 2)
550                         return 6;
551                 A c = return2_vtype_out (a);
552                 if (a2.a != 1 || a2.b != 2 || a2.c != 3)
553                         return 7;
554                 return 0;
555         }
556
557         public class GenericClass<T> {
558                 public static T Z (IList<T> x, int index)
559                 {
560                         return x [index];
561                 }
562         }
563
564         public static int test_0_generic_array_helpers () {
565                 int[] x = new int[] {100, 200};
566
567                 // Generic array helpers should be treated as gsharedvt-out
568                 if (GenericClass<int>.Z (x, 0) != 100)
569                         return 1;
570
571                 return 0;
572         }
573
574         internal class IntComparer : IComparer<int>
575         {
576                 public int Compare (int ix, int iy)
577                 {
578                         if (ix == iy)
579                                 return 0;
580
581                         if (((uint) ix) < ((uint) iy))
582                                 return -1;
583                         return 1;
584                 }
585         }
586
587         [MethodImplAttribute (MethodImplOptions.NoInlining)]
588         static int gshared_out_iface<T> (T t1, T t2, IComparer<T> comp) {
589                 return comp.Compare (t1, t2);
590         }
591
592         public static int test_0_gshared_out_iface () {
593                 // Call out from gshared to a nongeneric method through a generic interface method
594                 if (gshared_out_iface (2, 2, new IntComparer ()) != 0)
595                         return 1;
596                 return 0;
597         }
598
599         struct Foo1 {
600                 public int i1, i2, i3;
601         }
602
603         struct Foo2<T> {
604                 int i1, i2, i3, i4, i5;
605                 public T foo;
606         }
607
608         [MethodImplAttribute (MethodImplOptions.NoInlining)]    
609         public static void locals<T> (T t) {
610                 Foo2<T> t2 = new Foo2<T> ();
611                 object o = t2;
612         }
613
614         public static int test_0_locals () {
615                 // Test that instantiations of type parameters are allocated the proper local type
616                 int i = 1;
617                 for (int j = 0; j < 10; ++j)
618                         i ++;
619                 locals<Foo1> (new Foo1 () { i1 = 1, i2 = 2, i3 = 3 });
620                 return 0;
621         }
622
623         public interface IFace<T> {
624                 T return_t_iface (T t);
625         }
626
627         public class Parent<T> {
628                 public virtual T return_t_vcall (T t) {
629                         throw new Exception ();
630                         return t;
631                 }
632         }
633
634         public class Child<T> : Parent<T>, IFace<T> {
635                 public override T return_t_vcall (T t) {
636                         return t;
637                 }
638                 public T return_t_iface (T t) {
639                         return t;
640                 }
641         }
642
643         [MethodImplAttribute (MethodImplOptions.NoInlining)]
644         static T return_t_vcall<T> (Parent<T> r, T t) {
645                 return r.return_t_vcall (t);
646         }
647
648         public static int test_0_vcalls () {
649                 if (return_t_vcall (new Child<int> (), 2) != 2)
650                         return 1;
651                 // Patching
652                 for (int i = 0; i < 10; ++i) {
653                         if (return_t_vcall (new Child<int> (), 2) != 2)
654                                 return 2;
655                 }
656                 if (return_t_vcall (new Child<double> (), 2.0) != 2.0)
657                         return 3;
658                 return 0;
659         }
660
661         [MethodImplAttribute (MethodImplOptions.NoInlining)]
662         static T return_t_iface<T> (IFace<T> r, T t) {
663                 return r.return_t_iface (t);
664         }
665
666         public static int test_0_iface_calls () {
667                 if (return_t_iface (new Child<int> (), 2) != 2)
668                         return 1;
669                 if (return_t_iface (new Child<double> (), 2.0) != 2.0)
670                         return 3;
671                 return 0;
672         }
673
674         interface IFaceKVP {
675                 T do_kvp<T> (T a);
676         }
677
678         static KeyValuePair<T1, T2> make_kvp<T1, T2> (T1 t1, T2 t2) {
679                 return new KeyValuePair<T1, T2> (t1, t2);
680         }
681
682         static T2 use_kvp<T1, T2> (KeyValuePair<T1, T2> kvp) {
683                 return kvp.Value;
684         }
685
686         class ClassKVP : IFaceKVP {
687                 public T do_kvp<T> (T a) {
688                         var t = make_kvp (a, a);
689                         // argument is an instance of a vtype instantiated with gsharedvt type arguments
690                         return use_kvp (t);
691                 }
692         }
693
694         public static int test_0_gsharedvt_ginstvt_constructed_arg () {
695                 IFaceKVP c = new ClassKVP ();
696                 if (c.do_kvp<long> (1) != 1)
697                         return 1;
698                 return 0;
699         }
700
701         interface IGetter
702         {
703                 T Get<T>();
704         }
705
706         class Getter : IGetter
707         {
708                 public T Get<T>() { return default(T); }
709         }
710
711         abstract class Session
712         {
713                 public abstract IGetter Getter { get; }
714         }
715
716         class IosSession : Session
717         {
718                 private IGetter getter = new Getter();
719                 public override IGetter Getter { get { return getter; } }
720         }
721
722         enum ENUM_TYPE {
723         }
724
725         public static int test_0_regress_5156 () {
726                 new IosSession().Getter.Get<ENUM_TYPE>();
727                 return 0;
728         }
729
730         public struct VT
731         {
732                 public Action a;
733         }
734
735         public class D
736         {
737         }
738
739         public class A3
740         {
741                 public void OuterMethod<TArg1>(TArg1 value)
742                 {
743                         this.InnerMethod<TArg1, long>(value, 0);
744                 }
745
746                 private void InnerMethod<TArg1, TArg2>(TArg1 v1, TArg2 v2)
747                 {
748                         //Console.WriteLine("{0} {1}",v1,v2);
749                 }
750         }
751
752         public static int test_0_regress_2096 () {
753                 var a = new A3();
754
755                 // The following work:
756                 a.OuterMethod<int>(1);
757                 a.OuterMethod<DateTime>(DateTime.Now);
758
759                 var v = new VT();
760                 a.OuterMethod<VT>(v);
761
762                 var x = new D();
763                 // Next line will crash with Attempting to JIT compile method on device
764                 //  Attempting to JIT compile method
765                 a.OuterMethod<D>(x);
766                 return 0;
767         }
768
769         public class B
770         {
771                 public void Test<T>()
772                 {
773                         //System.Console.WriteLine(typeof(T));
774                 }
775         }
776
777         public class A<T>
778         {
779                 public void Test()
780                 {
781                         new B().Test<System.Collections.Generic.KeyValuePair<T, T>>();
782                 }
783         }
784
785     public static int test_0_regress_6040 () {
786         //new B().Test<System.Collections.Generic.KeyValuePair<string, string>>();
787         new A<int>().Test();
788         new A<object>().Test();
789         new A<string>().Test();
790                 return 0;
791     }
792
793         class ArrayContainer<T> {
794                 private T[,] container = new T[1,1];
795
796                 public T Prop {
797                         [MethodImplAttribute (MethodImplOptions.NoInlining)]
798                         get {
799                                 return container [0, 0];
800                         }
801                         [MethodImplAttribute (MethodImplOptions.NoInlining)]
802                         set {
803                                 container [0, 0] = value;
804                         }
805                 }
806         }
807
808         [MethodImplAttribute (MethodImplOptions.NoInlining)]
809         public static int test_0_multi_dim_arrays () {
810                 var c = new ArrayContainer<int> ();
811                 c.Prop = 5;
812                 return c.Prop == 5 ? 0 : 1;
813         }
814
815         [MethodImplAttribute (MethodImplOptions.NoInlining)]
816         static T2 rgctx_in_call_innner_inner<T1, T2> (T1 t1, T2 t2) {
817                 return t2;
818         }
819
820         [MethodImplAttribute (MethodImplOptions.NoInlining)]
821         static GFoo3<T> rgctx_in_call_inner<T> (T t) {
822                 return rgctx_in_call_innner_inner (1, new GFoo3<T> ());
823         }
824
825     public static int test_0_rgctx_in_call () {
826                 // The call is made through the rgctx call, and it needs an IN trampoline
827                 var t = rgctx_in_call_inner (1);
828                 if (t is GFoo3<int>)
829                         return 0;
830                 return 1;
831         }
832
833         [MethodImplAttribute (MethodImplOptions.NoInlining)]
834         static void arm_params1<T> (T t1, T t2, T t3, T t4, T t5, T t6) {
835         }
836
837         [MethodImplAttribute (MethodImplOptions.NoInlining)]
838         static void arm_params2<T> (T t1, T t2, T t3, long t4, T t5, T t6) {
839         }
840
841         public static int test_0_arm_param_passing () {
842                 arm_params1<int> (1, 2, 3, 4, 5, 6);
843                 arm_params1<int> (1, 2, 3, 4, 5, 6);
844                 return 0;
845         }
846
847         sealed class ScheduledItem<TAbsolute, TValue> {
848                 private readonly object _scheduler;
849                 private readonly TValue _state;
850                 private readonly object _action;
851
852                 public ScheduledItem(object o, TValue state, object action, TAbsolute dueTime) {
853                         _state = state;
854                 }
855         }
856
857     abstract class VirtualTimeSchedulerBase<TAbsolute, TRelative> {
858         public abstract void ScheduleAbsolute<TState>(TState state, TAbsolute dueTime);
859         }
860
861         class VirtualTimeScheduler<TAbsolute, TRelative> : VirtualTimeSchedulerBase<TAbsolute, TRelative> {
862                 public override void ScheduleAbsolute<TState>(TState state, TAbsolute dueTime) {
863                         var si = new ScheduledItem<TAbsolute, TState>(this, state, null, dueTime);
864                 }
865         }
866
867         public static int test_0_rx_mixed_regress () {
868                 var v = new VirtualTimeScheduler<long, long> ();
869                 v.ScheduleAbsolute<Action> (null, 22);
870                 return 0;
871         }
872
873         public class Base {
874                 public virtual T foo<T> (T t) {
875                         return t;
876                 }
877         }
878
879         class Class1 : Base {
880                 public object o;
881
882                 public override T foo<T> (T t) {
883                         o = t;
884                         return t;
885                 }
886         }
887
888         class Class2 : Base {
889                 public object o;
890
891                 public override T foo<T> (T t) {
892                         o = t;
893                         return t;
894                 }
895         }
896
897         [MethodImplAttribute (MethodImplOptions.NoInlining)]
898         public static void bar<T> (Base b, T t) {
899                 b.foo (t);
900         }
901
902         public static int test_0_virtual_generic () {
903                 Class1 c1 = new Class1 ();
904                 Class2 c2 = new Class2 ();
905                 bar (c1, 5);
906                 if (!(c1.o is int) || ((int)c1.o != 5))
907                         return 1;
908                 bar (c1, 6.0);
909                 if (!(c1.o is double) || ((double)c1.o != 6.0))
910                         return 2;
911                 bar (c1, 7.0f);
912                 if (!(c1.o is float) || ((float)c1.o != 7.0f))
913                         return 3;
914                 bar (c2, 5);
915                 if (!(c2.o is int) || ((int)c2.o != 5))
916                         return 4;
917                 bar (c2, 6.0);
918                 bar (c2, 7.0f);
919                 return 0;
920         }
921
922         [MethodImplAttribute (MethodImplOptions.NoInlining)]
923         static string to_string<T, T2>(T t, T2 t2) {
924                 return t.ToString ();
925         }
926
927         enum AnEnum {
928                 One,
929                 Two
930         };
931
932         public static int test_0_constrained_tostring () {
933                 if (to_string<int, int> (1, 1) != "1")
934                         return 1;
935                 if (to_string<AnEnum, int> (AnEnum.One, 1) != "One")
936                         return 2;
937                 if (to_string<string, int> ("A", 1) != "A")
938                         return 3;
939                 return 0;
940         }
941
942         [MethodImplAttribute (MethodImplOptions.NoInlining)]
943         static int get_hash<T, T2>(T t, T2 t2) {
944                 return t.GetHashCode ();
945         }
946
947         public static int test_0_constrained_get_hash () {
948                 if (get_hash<int, int> (1, 1) != 1.GetHashCode ())
949                         return 1;
950                 if (get_hash<double, int> (1.0, 1) != 1.0.GetHashCode ())
951                         return 2;
952                 if (get_hash<AnEnum, int> (AnEnum.One, 1) != AnEnum.One.GetHashCode ())
953                         return 3;
954                 if (get_hash<string, int> ("A", 1) != "A".GetHashCode ())
955                         return 4;
956                 return 0;
957         }
958
959         [MethodImplAttribute (MethodImplOptions.NoInlining)]
960         static bool equals<T, T2>(T t, T2 t2) {
961                 return t.Equals (t);
962         }
963
964         public static int test_0_constrained_equals () {
965                 if (equals<int, int> (1, 1) != true)
966                         return 1;
967                 if (equals<double, int> (1.0, 1) != true)
968                         return 2;
969                 if (equals<AnEnum, int> (AnEnum.One, 1) != true)
970                         return 3;
971                 if (equals<string, int> ("A", 1) != true)
972                         return 4;
973                 return 0;
974         }
975
976         interface IGetType {
977                 Type gettype<T, T2>(T t, T2 t2);
978         }
979
980         public class CGetType : IGetType {
981                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
982                 public Type gettype<T, T2>(T t, T2 t2) {
983                         return t.GetType ();
984                 }
985         }
986
987         public static int test_0_constrained_gettype () {
988                 IGetType c = new CGetType ();
989                 if (c.gettype<int, int> (1, 1) != typeof (int))
990                         return 1;
991                 if (c.gettype<string, int> ("A", 1) != typeof (string))
992                         return 2;
993                 return 0;
994         }
995
996         struct Pair<T1, T2> {
997                 public T1 First;
998                 public T2 Second;
999         }
1000
1001         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1002         public static TState call_del<TState>(TState state, Func<object, TState, TState> action) {
1003                 return action(null, state);
1004         }
1005
1006         public static int test_0_delegate_wrappers () {
1007                 Func<object, Pair<int, int>, Pair<int, int>> del1 = delegate (object o, Pair<int, int> p) { return p; };
1008                 Func<object, Pair<int, int>, Pair<int, int>> del2 = delegate (object o, Pair<int, int> p) { return p; };
1009                 Func<object, Pair<double, int>, Pair<double, int>> del3 = delegate (object o, Pair<double, int> p) { return p; };
1010                 var r1 = call_del<Pair<int, int>> (new Pair<int, int> { First = 1, Second = 2}, del1);
1011                 if (r1.First != 1 || r1.Second != 2)
1012                         return 1;
1013                 var r2 = call_del<Pair<int, int>> (new Pair<int, int> { First = 3, Second = 4}, del2);
1014                 if (r2.First != 3 || r2.Second != 4)
1015                         return 2;
1016                 var r3 = call_del<Pair<double, int>> (new Pair<double, int> { First = 1.0, Second = 2}, del3);
1017                 if (r3.First != 1.0 || r3.Second != 2)
1018                         return 3;
1019                 return 0;
1020         }
1021
1022         class Base<T> {
1023                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1024                 public object foo<T1> (T1 t1, T t, object o) {
1025                         return o;
1026                 }
1027         }
1028
1029         class AClass : Base<long> {
1030
1031                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1032                 public object bar<T> (T t, long time, object o) {
1033                         return foo (t, time, o);
1034                 }
1035         }
1036
1037         public static int test_0_out_in_wrappers () {
1038                 var a = new AClass ();
1039                 object o1 = "A";
1040                 object o2 = a.bar<long> (1024, 0, o1);
1041                 if (o1 != o2)
1042                         return 1;
1043                 return 0;               
1044         }
1045
1046                 interface BIFace {
1047                         object AMethod ();
1048                 }
1049
1050                 class Base<TAbsolute, T2> : BIFace {
1051
1052                         public TAbsolute Clock { get; set; }
1053
1054                         public virtual object AMethod () {
1055                                 return Clock;
1056                         }
1057                 }
1058
1059                 class BClass : Base<long, long> {
1060                 }
1061
1062         public static int test_0_regress_1 () {
1063                 BIFace c = new BClass ();
1064                 object o = c.AMethod ();
1065                 if (!(o is long) || ((long)o != 0))
1066                         return 1;
1067                 return 0;
1068         }
1069
1070         interface IFace3 {
1071                 T unbox_any<T> (object o);
1072         }
1073
1074         class Class3 : IFace3 {
1075                 public virtual T unbox_any<T> (object o) {
1076                         return (T)o;
1077                 }
1078         }
1079
1080         public static int test_0_unbox_any () {
1081                 IFace3 o = new Class3 ();
1082                 if (o.unbox_any<int> (16) != 16)
1083                         return 1;
1084                 if (o.unbox_any<long> ((long)32) != 32)
1085                         return 2;
1086                 if (o.unbox_any<double> (2.0) != 2.0)
1087                         return 3;
1088                 try {
1089                         o.unbox_any<int> (2.0);
1090                         return 4;
1091                 } catch (Exception) {
1092                 }
1093                 return 0;
1094         }
1095
1096         interface IFace4 {
1097                 TSource Catch<TSource, TException>(TSource t)  where TException : Exception;
1098         }
1099
1100         class Class4 : IFace4 {
1101                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1102                         public TSource Catch<TSource, TException>(TSource t)  where TException : Exception {
1103                         return t;
1104                 }
1105         }
1106
1107         // Check that mixed instantiations are correctly created/found in AOT
1108         public static int test_0_constraints () {
1109                 IFace4 o = new Class4 ();
1110                 o.Catch<int, Exception> (1);
1111                 return 0;
1112         }
1113
1114         internal static Type Process<TSource, TElement> (TSource[] arr, Action<TElement, TElement> call) {
1115                 arr [0] = default (TSource);
1116                 return typeof (TSource);
1117         }
1118
1119         interface IFace5 {
1120                 Type foo<T> ();
1121         }
1122
1123         class Class5 : IFace5 {
1124                 public Type foo<T> () {
1125                         return Process<KeyValuePair<long, T>, T> (new KeyValuePair<long, T> [10], null);
1126                 }
1127         }
1128
1129         public static int test_0_rgctx_call_from_gshared_code () {
1130                 var c = new Class5 ();
1131                 if (c.foo<string> () != typeof (KeyValuePair<long, string>))
1132                         return 1;
1133                 return 0;
1134         }
1135
1136         public class Enumbers<T> {
1137                 public object Enumerate (List<KeyValuePair<T, string>> alist)
1138                 {
1139                         return alist.ToArray ();
1140                 }
1141         }
1142
1143         public static int test_0_checkthis_gshared_call () {
1144                 Enumbers<string> e = new Enumbers<string> ();
1145                 try {
1146                         e.Enumerate (null);
1147                         return 1;
1148                 }
1149                 catch (NullReferenceException) {
1150                 }
1151                 return 0;
1152         }
1153
1154         interface IFace6 {
1155                 T[] Del<T> (T t);
1156         }
1157
1158         class Class6 : IFace6 {
1159                 public T[] Del<T> (T t) {
1160                         var res = new T [5];
1161                         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; };
1162                         var v = func.BeginInvoke(t, t, t, t, null, null);
1163                         res [4] = func.EndInvoke (v);
1164                         return res;
1165                 }
1166         }
1167
1168         // FIXME: The runtime-invoke wrapper used by BeginInvoke is not found
1169         [Category ("!FULLAOT")]
1170         public static int test_0_begin_end_invoke () {
1171                 IFace6 o = new Class6 ();
1172                 var arr1 = o.Del (1);
1173                 if (arr1 [0] != 1 || arr1 [1] != 1 || arr1 [2] != 1 || arr1 [3] != 1 || arr1 [4] != 1)
1174                         return 1;
1175                 var arr2 = o.Del (2.0);
1176                 if (arr2 [0] != 2.0 || arr2 [1] != 2.0 || arr2 [2] != 2.0 || arr2 [3] != 2.0 || arr2 [4] != 2.0)
1177                         return 2;
1178                 return 0;
1179         }
1180
1181         public class TAbstractTableItem<TC> {
1182                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1183                 public static void SetProperty<TV> () {    }
1184
1185                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1186                 public static void Test () {
1187                         SetProperty<bool> ();
1188                 }
1189         }
1190
1191         public static int test_0_gsharedvt_method_on_shared_class () {
1192        TAbstractTableItem<object>.Test ();
1193            return 0;
1194         }
1195
1196         interface IFaceBox {
1197                 object box<T> (T t);
1198         }
1199
1200         class ClassBox : IFaceBox {
1201                 public object box<T> (T t) {
1202                         object o = t;
1203                         return o;
1204                 }
1205         }
1206
1207         public static int test_0_nullable_box () {
1208                 IFaceBox c = new ClassBox ();
1209                 int i = 5;
1210                 object o = c.box<int?> (i);
1211                 if ((int)o != i)
1212                         return 1;
1213                 if (c.box<int?> (null) != null)
1214                         return 2;
1215                 long l = Int64.MaxValue - 1;
1216                 o = c.box<long?> (l);
1217                 if ((long)o != l)
1218                         return 3;
1219                 if (c.box<long?> (null) != null)
1220                         return 4;
1221                 string s = "A";
1222                 if (c.box<string> (s) != (object)s)
1223                         return 5;
1224                 return 0;
1225         }
1226
1227         interface IFaceUnbox2 {
1228                 T unbox<T> (object o);
1229         }
1230
1231         class ClassUnbox2 : IFaceUnbox2 {
1232                 public T unbox<T> (object o) {
1233                         return (T)o;
1234                 }
1235         }
1236
1237         public static int test_0_nullable_unbox () {    
1238                 IFaceUnbox2 c = new ClassUnbox2 ();
1239                 int? i = c.unbox<int?> (5);
1240                 if (i != 5)
1241                         return 1;
1242                 int? j = c.unbox<int?> (null);
1243                 if (j != null)
1244                         return 2;
1245                 return 0;
1246         }
1247
1248         interface IConstrained {
1249                 void foo ();
1250                 void foo_ref_arg (string s);
1251         }
1252
1253         interface IConstrained<T3> {
1254                 void foo_gsharedvt_arg (T3 s);
1255                 T3 foo_gsharedvt_ret (T3 s);
1256         }
1257
1258         static object constrained_res;
1259
1260         struct ConsStruct : IConstrained {
1261                 public int i;
1262
1263                 public void foo () {
1264                         constrained_res = i;
1265                 }
1266
1267                 public void foo_ref_arg (string s) {
1268                         constrained_res = s == "A" ? 42 : 0;
1269                 }
1270         }
1271
1272         class ConsClass : IConstrained {
1273                 public int i;
1274
1275                 public void foo () {
1276                         constrained_res = i;
1277                 }
1278
1279                 public void foo_ref_arg (string s) {
1280                         constrained_res = s == "A" ? 43 : 0;
1281                 }
1282         }
1283
1284         struct ConsStruct<T> : IConstrained<T> {
1285                 public void foo_gsharedvt_arg (T s) {
1286                         constrained_res = s;
1287                 }
1288
1289                 public T foo_gsharedvt_ret (T s) {
1290                         return s;
1291                 }
1292         }
1293
1294         interface IFaceConstrained {
1295                 void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained;
1296                 void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained;
1297                 void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1298                 T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1299                 T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass;
1300         }
1301
1302         class ClassConstrained : IFaceConstrained {
1303                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1304                 public void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained {
1305                         t2.foo ();
1306                 }
1307
1308                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1309                 public void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained {
1310                         t2.foo_ref_arg ("A");
1311                 }
1312
1313                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1314                 public void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1315                         t2.foo_gsharedvt_arg (t);
1316                 }
1317
1318                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1319                 public T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1320                         return t2.foo_gsharedvt_ret (t);
1321                 }
1322
1323                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1324                 public T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass {
1325                         /* This becomes a constrained call even through 't2' is forced to be a reference type by the constraint */
1326                         return (T2)t2.foo (5);
1327                 }
1328         }
1329
1330         class VClass {
1331                 public virtual VClass foo (int i) {
1332                         return this;
1333                 }
1334         }
1335
1336         public static int test_0_constrained_void_iface_call () {
1337                 IFaceConstrained c = new ClassConstrained ();
1338                 var s = new ConsStruct () { i = 42 };
1339                 constrained_res = null;
1340                 c.constrained_void_iface_call<int, ConsStruct> (1, s);
1341                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1342                         return 1;
1343                 constrained_res = null;
1344                 c.constrained_void_iface_call_ref_arg<int, ConsStruct> (1, s);
1345                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1346                         return 2;
1347                 var s2 = new ConsClass () { i = 43 };
1348                 constrained_res = null;
1349                 c.constrained_void_iface_call<int, ConsClass> (1, s2);
1350                 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1351                         return 3;
1352                 constrained_res = null;
1353                 c.constrained_void_iface_call_ref_arg<int, ConsClass> (1, s2);
1354                 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1355                         return 4;
1356                 return 0;
1357         }
1358
1359         public static int test_0_constrained_void_iface_call_gsharedvt_arg () {
1360                 // This tests constrained calls through interfaces with one gsharedvt arg, like IComparable<T>.CompareTo ()
1361                 IFaceConstrained c = new ClassConstrained ();
1362
1363                 var s = new ConsStruct<int> ();
1364                 constrained_res = null;
1365                 c.constrained_void_iface_call_gsharedvt_arg<int, ConsStruct<int>, int> (42, s, 55);
1366                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1367                         return 1;
1368
1369                 var s2 = new ConsStruct<string> ();
1370                 constrained_res = null;
1371                 c.constrained_void_iface_call_gsharedvt_arg<string, ConsStruct<string>, int> ("A", s2, 55);
1372                 if (!(constrained_res is string) || ((string)constrained_res) != "A")
1373                         return 2;
1374
1375                 return 0;
1376         }
1377
1378         public static int test_0_constrained_iface_call_gsharedvt_ret () {
1379                 IFaceConstrained c = new ClassConstrained ();
1380
1381                 var s = new ConsStruct<int> ();
1382                 int ires = c.constrained_iface_call_gsharedvt_ret<int, ConsStruct<int>, int> (42, s, 55);
1383                 if (ires != 42)
1384                         return 1;
1385
1386                 var s2 = new ConsStruct<string> ();
1387                 string sres = c.constrained_iface_call_gsharedvt_ret<string, ConsStruct<string>, int> ("A", s2, 55);
1388                 if (sres != "A")
1389                         return 2;
1390
1391                 return 0;
1392         }
1393
1394         public static int test_0_constrained_normal_call () {
1395                 IFaceConstrained c = new ClassConstrained ();
1396
1397                 var o = new VClass ();
1398                 var res = c.constrained_normal_call<int, VClass> (1, o);
1399                 return res == o ? 0 : 1;
1400         }
1401
1402         public static async Task<T> FooAsync<T> (int i, int j) {
1403                 Task<int> t = new Task<int> (delegate () { return 42; });
1404                 var response = await t;
1405                 return default(T);
1406         }
1407
1408         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1409         public static void call_async<T> (int i, int j) {
1410                 Task<T> t = FooAsync<T> (1, 2);
1411                 t.RunSynchronously ();
1412         }
1413
1414         // In AOT mode, the async infrastructure depends on gsharedvt methods
1415         public static int test_0_async_call_from_generic () {
1416                 call_async<string> (1, 2);
1417                 return 0;
1418         }
1419 }
1420
1421 // #13191
1422 public class MobileServiceCollection<TTable, TCol>
1423 {
1424         public async Task<int> LoadMoreItemsAsync(int count = 0) {
1425                 await Task.Delay (1000);
1426                 int results = await ProcessQueryAsync ();
1427                 return results;
1428         }
1429
1430         protected async virtual Task<int> ProcessQueryAsync() {
1431                 await Task.Delay (1000);
1432                 throw new Exception ();
1433         }
1434 }
1435
1436 #if !MOBILE
1437 public class GSharedTests : Tests {
1438 }
1439 #endif