Merge pull request #1570 from mono/fix27010
[mono.git] / mono / mini / gshared.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Collections.ObjectModel;
4 using System.Runtime.CompilerServices;
5 using System.Threading.Tasks;
6
7 struct Foo {
8         public int i, j, k, l, m, n;
9 }
10
11 struct GFoo<T> {
12         public T dummy;
13         public T t;
14         public int i;
15         public Foo f;
16         public static T static_dummy;
17         public static T static_t;
18         public static Foo static_f;
19 }
20
21 struct GFoo2<T> {
22         public T t, t2, t3;
23 }
24
25 class GFoo3<T> {
26         public T t, t2;
27
28         public GFoo3 () {
29         }
30
31         [MethodImplAttribute (MethodImplOptions.NoInlining)]
32         public GFoo3 (T i1, T i2) {
33                 t = i1;
34                 t2 = i2;
35         }
36 }
37
38 //
39 // Tests for generic sharing of vtypes.
40 // 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.
41 //
42
43 //
44 // Interfaces are used to prevent the AOT compiler from discovering instantiations, thus forcing the usage of the gsharedvt
45 // versions of methods. Unused vtype type arguments are used to test gsharedvt methods with ref type arguments, i.e.
46 // when calling foo<T,T2> as foo<object,bool>, the gsharedvt version is used, but with a ref type argument.
47 //
48
49 // FIXME: Add mixed ref/noref tests, i.e. Dictionary<string, int>
50
51 #if MOBILE
52 public class GSharedTests
53 #else
54 public class Tests
55 #endif
56 {
57 #if !MOBILE
58         public static int Main (String[] args) {
59                 return TestDriver.RunTests (typeof (Tests), args);
60         }
61 #endif
62
63         [MethodImplAttribute (MethodImplOptions.NoInlining)]
64         static void gshared<T> (T [] array, int i, int j) {
65                 T tmp = array [i];
66                 array [i] = array [j];
67                 array [j] = tmp;
68         }
69
70         // Test that the gshared and gsharedvt versions don't mix
71         public static int test_0_vt_gshared () {
72                 string[] sarr = new string [2] { "A", "B" };
73
74                 gshared<string> (sarr, 0, 1);
75
76                 Foo[] arr = new Foo [2];
77                 arr [0] = new Foo () { i = 1, j = 2 };
78                 arr [1] = new Foo () { i = 3, j = 4 };
79
80                 gshared<Foo> (arr, 0, 1);
81                 if (arr [0].i != 3 || arr [0].j != 4)
82                         return 1;
83                 if (arr [1].i != 1 || arr [1].j != 2)
84                         return 2;
85
86                 return 0;
87         }
88
89         static void ldelem_stelem<T> (T [] array, int i, int j) {
90                 T tmp = array [i];
91                 array [i] = array [j];
92                 array [j] = tmp;
93         }
94
95         public static int test_0_vt_ldelem_stelem () {
96                 Foo[] arr = new Foo [2];
97                 arr [0] = new Foo () { i = 1, j = 2 };
98                 arr [1] = new Foo () { i = 3, j = 4 };
99
100                 ldelem_stelem<Foo> (arr, 0, 1);
101                 if (arr [0].i != 3 || arr [0].j != 4)
102                         return 1;
103                 if (arr [1].i != 1 || arr [1].j != 2)
104                         return 2;
105
106                 int[] arr2 = new int [2] { 1, 2 };
107                 ldelem_stelem<int> (arr2, 0, 1);
108                 if (arr2 [0] !=2 || arr2 [1] != 1)
109                         return 3;
110
111                 return 0;
112         }
113
114         [MethodImplAttribute (MethodImplOptions.NoInlining)]
115         private static void initobj<T> (T [] array, int i, int j) {
116                 T x = default(T);
117                 array [i] = x;
118         }
119
120         public static int test_0_vt_initobj () {
121                 Foo[] arr = new Foo [2];
122                 arr [0] = new Foo () { i = 1, j = 2 };
123                 arr [1] = new Foo () { i = 3, j = 4 };
124
125                 initobj<Foo> (arr, 0, 1);
126                 if (arr [0].i != 0 || arr [0].j != 0)
127                         return 1;
128                 if (arr [1].i != 3 || arr [1].j != 4)
129                         return 2;
130                 return 0;
131         }
132
133         [MethodImplAttribute (MethodImplOptions.NoInlining)]
134         static T ldobj_stobj<T> (ref T t1, ref T t2) {
135                 t1 = t2;
136                 T t = t2;
137                 t2 = default(T);
138                 return t;
139         }
140
141         public static int test_0_vt_ldobj_stobj () {
142                 int i = 5;
143                 int j = 6;
144                 if (ldobj_stobj (ref i, ref j) != 6)
145                         return 1;
146                 if (i != 6 || j != 0)
147                         return 2;
148                 double d1 = 1.0;
149                 double d2 = 2.0;
150                 if (ldobj_stobj (ref d1, ref d2) != 2.0)
151                         return 3;
152                 if (d1 != 2.0 || d2 != 0.0)
153                         return 4;               
154                 return 0;
155         }
156
157         [MethodImplAttribute (MethodImplOptions.NoInlining)]
158         private static void box<T1, T> (T [] array, object[] arr) {
159                 object x = array [0];
160                 arr [0] = x;
161         }
162
163         public static int test_0_vt_box () {
164                 Foo[] arr = new Foo [2];
165                 arr [0] = new Foo () { i = 1, j = 2 };
166
167                 object[] arr2 = new object [16];
168                 box<int, Foo> (arr, arr2);
169                 if (arr2 [0].GetType () != typeof (Foo))
170                         return 1;
171                 Foo f = (Foo)arr2 [0];
172                 if (f.i != 1 || f.j != 2)
173                         return 2;
174                 string[] arr3 = new string [16];
175                 object[] arr4 = new object [16];
176                 arr3 [0] = "OK";
177                 box<int, string> (arr3, arr4);
178                 if (arr4 [0] != (object)arr3 [0])
179                         return 3;
180                 return 0;
181         }
182
183         [MethodImplAttribute (MethodImplOptions.NoInlining)]
184         private static void unbox_any<T> (T [] array, object[] arr) {
185                 T t = (T)arr [0];
186                 array [0] = t;
187         }
188
189         public static int test_0_vt_unbox_any () {
190                 int[] iarr = new int [16];
191                 unbox_any<int> (iarr, new object [] { 12 });
192
193                 Foo[] arr = new Foo [2];
194
195                 object[] arr2 = new object [16];
196                 arr2 [0] = new Foo () { i = 1, j = 2 };
197                 unbox_any<Foo> (arr, arr2);
198                 if (arr [0].i != 1 || arr [0].j != 2)
199                         return 2;
200                 return 0;
201         }
202
203         interface IFaceUnbox {
204                 T Unbox<T, T2> (T t, T2 t2, object o);
205         }
206
207         class ClassUnbox : IFaceUnbox {
208                 public T Unbox<T, T2> (T t, T2 t2, object o) {
209                         return (T)o;
210                 }
211         }
212
213         // unbox.any on a ref type in a gsharedvt method
214         public static int test_0_ref_gsharedvt_aot_unbox_any () {
215                 IFaceUnbox iface = new ClassUnbox ();
216                 string s = iface.Unbox<string, int> ("A", 2, "A");
217                 if (s != "A")
218                         return 1;
219                 return 0;
220         }
221
222         public static int test_0_unbox_any_enum () {
223                 IFaceUnbox iface = new ClassUnbox ();
224                 AnEnum res = iface.Unbox<AnEnum, int> (AnEnum.One, 0, 1);
225                 if (res != AnEnum.Two)
226                         return 1;
227                 res = iface.Unbox<AnEnum, int> (AnEnum.One, 0, AnEnum.Two);
228                 if (res != AnEnum.Two)
229                         return 2;
230                 int res2 = iface.Unbox<int, AnEnum> (0, AnEnum.One, AnEnum.Two);
231                 if (res2 != 1)
232                         return 3;
233                 return 0;
234         }
235
236         [MethodImplAttribute (MethodImplOptions.NoInlining)]
237         static void ldfld_nongeneric<T> (GFoo<T>[] foo, int[] arr) {
238                 arr [0] = foo [0].i;
239         }
240
241         [MethodImplAttribute (MethodImplOptions.NoInlining)]
242         static void ldfld<T> (GFoo<T>[] foo, T[] arr) {
243                 arr [0] = foo [0].t;
244         }
245
246         [MethodImplAttribute (MethodImplOptions.NoInlining)]
247         static void stfld_nongeneric<T> (GFoo<T>[] foo, int[] arr) {
248                 foo [0].i = arr [0];
249         }
250
251         [MethodImplAttribute (MethodImplOptions.NoInlining)]
252         static void stfld<T> (GFoo<T>[] foo, T[] arr) {
253                 foo [0].t = arr [0];
254         }
255
256         [MethodImplAttribute (MethodImplOptions.NoInlining)]
257         static void ldflda<T> (GFoo<T>[] foo, int[] arr) {
258                 arr [0] = foo [0].f.i;
259         }
260
261         public static int test_0_vt_ldfld_stfld () {
262                 var foo = new GFoo<Foo> () { t = new Foo () { i = 1, j = 2 }, i = 5, f = new Foo () { i = 5, j = 6 } };
263                 var farr = new GFoo<Foo>[] { foo };
264
265                 /* Normal fields with a variable offset */
266                 var iarr = new int [10];
267                 ldfld_nongeneric<Foo> (farr, iarr);
268                 if (iarr [0] != 5)
269                         return 1;
270                 iarr [0] = 16;
271                 stfld_nongeneric<Foo> (farr, iarr);
272                 if (farr [0].i != 16)
273                         return 2;
274
275                 /* Variable type field with a variable offset */
276                 var arr = new Foo [10];
277                 ldfld<Foo> (farr, arr);
278                 if (arr [0].i != 1 || arr [0].j != 2)
279                         return 3;
280                 arr [0] = new Foo () { i = 3, j = 4 };
281                 stfld<Foo> (farr, arr);
282                 if (farr [0].t.i != 3 || farr [0].t.j != 4)
283                         return 4;
284
285                 ldflda<Foo> (farr, iarr);
286                 if (iarr [0] != 5)
287                         return 5;
288
289                 return 0;
290         }
291
292         [MethodImplAttribute (MethodImplOptions.NoInlining)]
293         static void stsfld<T> (T[] arr) {
294                 GFoo<T>.static_t = arr [0];
295         }
296
297         [MethodImplAttribute (MethodImplOptions.NoInlining)]
298         static void ldsfld<T> (T[] arr) {
299                 arr [0] = GFoo<T>.static_t;
300         }
301
302         [MethodImplAttribute (MethodImplOptions.NoInlining)]
303         static void ldsflda<T> (int[] iarr) {
304                 iarr [0] = GFoo<T>.static_f.i;
305         }
306         
307         public static int test_0_stsfld () {
308                 Foo[] farr = new Foo [] { new Foo () { i = 1, j = 2 } };
309                 stsfld<Foo> (farr);
310
311                 if (GFoo<Foo>.static_t.i != 1 || GFoo<Foo>.static_t.j != 2)
312                         return 1;
313
314                 Foo[] farr2 = new Foo [1];
315                 ldsfld<Foo> (farr2);
316                 if (farr2 [0].i != 1 || farr2 [0].j != 2)
317                         return 2;
318
319                 var iarr = new int [10];
320                 GFoo<Foo>.static_f = new Foo () { i = 5, j = 6 };
321                 ldsflda<Foo> (iarr);
322                 if (iarr [0] != 5)
323                         return 3;
324
325                 return 0;
326         }
327
328         [MethodImplAttribute (MethodImplOptions.NoInlining)]
329         static object newarr<T> () {
330                 object o = new T[10];
331                 return o;
332         }
333
334         public static int test_0_vt_newarr () {
335                 object o = newarr<Foo> ();
336                 if (!(o is Foo[]))
337                         return 1;
338                 return 0;
339         }
340
341         [MethodImplAttribute (MethodImplOptions.NoInlining)]
342         static Type ldtoken<T> () {
343                 return typeof (GFoo<T>);
344         }
345
346         public static int test_0_vt_ldtoken () {
347                 Type t = ldtoken<Foo> ();
348                 if (t != typeof (GFoo<Foo>))
349                         return 1;
350                 t = ldtoken<int> ();
351                 if (t != typeof (GFoo<int>))
352                         return 2;
353
354                 return 0;
355         }
356
357         public static int test_0_vtype_list () {
358                 List<int> l = new List<int> ();
359
360                 l.Add (5);
361                 if (l.Count != 1)
362                         return 1;
363                 return 0;
364         }
365
366         [MethodImplAttribute (MethodImplOptions.NoInlining)]
367         static int args_simple<T> (T t, int i) {
368                 return i;
369         }
370
371         [MethodImplAttribute (MethodImplOptions.NoInlining)]
372         static int args_simple<T> (T t, int i, T t2) {
373                 return i;
374         }
375
376         [MethodImplAttribute (MethodImplOptions.NoInlining)]
377         static Type args_rgctx<T> (T t, int i) {
378                 return typeof (T);
379         }
380
381         [MethodImplAttribute (MethodImplOptions.NoInlining)]
382         static Type eh_in<T> (T t, int i) {
383                 throw new OverflowException ();
384         }
385
386         [MethodImplAttribute (MethodImplOptions.NoInlining)]
387         static T return_t<T> (T t) {
388                 return t;
389         }
390
391         [MethodImplAttribute (MethodImplOptions.NoInlining)]
392         T return_this_t<T> (T t) {
393                 return t;
394         }
395
396         interface IFaceGSharedVtIn {
397                 T return_t<T> (T t);
398         }
399
400         class ClassGSharedVtIn : IFaceGSharedVtIn {
401                 public T return_t<T> (T t) {
402                         return t;
403                 }
404         }
405
406         public static int test_0_gsharedvt_in () {
407                 // Check that the non-generic argument is passed at the correct stack position
408                 int r = args_simple<bool> (true, 42);
409                 if (r != 42)
410                         return 1;
411                 r = args_simple<Foo> (new Foo (), 43);
412                 if (r != 43)
413                         return 2;
414                 // Check that the proper rgctx is passed to the method
415                 Type t = args_rgctx<int> (5, 42);
416                 if (t != typeof (int))
417                         return 3;
418                 var v = args_simple<GFoo2<int>> (new GFoo2<int> () { t = 11, t2 = 12 }, 44, new GFoo2<int> () { t = 11, t2 = 12 });
419                 if (v != 44)
420                         return 4;
421                 // Check that EH works properly
422                 try {
423                         eh_in<int> (1, 2);
424                 } catch (OverflowException) {
425                 }
426                 return 0;
427         }
428
429         public static int test_0_gsharedvt_in_ret () {
430                 int i = return_t<int> (42);
431                 if (i != 42)
432                         return 1;
433                 long l = return_t<long> (Int64.MaxValue);
434                 if (l != Int64.MaxValue)
435                         return 2;
436                 double d = return_t<double> (3.0);
437                 if (d != 3.0)
438                         return 3;
439                 float f = return_t<float> (3.0f);
440                 if (f != 3.0f)
441                         return 4;
442                 short s = return_t<short> (16);
443                 if (s != 16)
444                         return 5;
445                 var v = new GFoo2<int> () { t = 55, t2 = 32 };
446                 var v2 = return_t<GFoo2<int>> (v);
447                 if (v2.t != 55 || v2.t2 != 32)
448                         return 6;
449                 IFaceGSharedVtIn o = new ClassGSharedVtIn ();
450                 var v3 = new GFoo2<long> () { t = 55, t2 = 32 };
451                 var v4 = o.return_t<GFoo2<long>> (v3);
452                 if (v4.t != 55 || v4.t2 != 32)
453                         return 7;
454                 i = new GSharedTests ().return_this_t<int> (42);
455                 if (i != 42)
456                         return 8;
457                 return 0;
458         }
459
460         public static int test_0_gsharedvt_in_delegates () {
461                 Func<int, int> f = new Func<int, int> (return_t<int>);
462                 if (f (42) != 42)
463                         return 1;
464                 return 0;
465         }
466
467         [MethodImplAttribute (MethodImplOptions.NoInlining)]
468         static T return2_t<T> (T t) {
469                 return return_t (t);
470         }
471
472         public static int test_0_gsharedvt_calls () {
473                 if (return2_t (2) != 2)
474                         return 1;
475                 if (return2_t ("A") != "A")
476                         return 2;
477                 if (return2_t (2.0) != 2.0)
478                         return 3;
479                 return 0;
480         }
481
482         static GFoo3<T> newobj<T> (T t1, T t2) {
483                 return new GFoo3<T> (t1, t2);
484         }
485         
486         public static int test_0_gshared_new () {
487                 var g1 = newobj (1, 2);
488                 if (g1.t != 1 || g1.t2 != 2)
489                         return 1;
490                 var g2 = newobj (1.0, 2.0);
491                 if (g1.t != 1.0 || g1.t2 != 2.0)
492                         return 2;
493
494                 return 0;
495         }
496
497         [MethodImplAttribute (MethodImplOptions.NoInlining)]
498         static GFoo2<T> newobj_vt<T> (T t1, T t2) {
499                 return new GFoo2<T> () { t = t1, t2 = t2 };
500         }
501
502         public static int test_0_gshared_new_vt () {
503                 GFoo2<int> v1 = newobj_vt (1, 2);
504                 if (v1.t != 1 || v1.t2 != 2)
505                         return 1;
506                 GFoo2<double> v2 = newobj_vt (1.0, 2.0);
507                 if (v2.t != 1.0 || v2.t2 != 2.0)
508                         return 2;
509                 return 0;
510         }
511
512         //
513         // Tests for transitioning out of gsharedvt code
514         //
515
516         // T1=Nullable<..> is not currently supported by gsharedvt
517
518         [MethodImplAttribute (MethodImplOptions.NoInlining)]
519         static T return_t_nogshared<T,T1> (T t) {
520                 object o = t;
521                 T t2 = (T)o;
522                 //Console.WriteLine ("X: " + t);
523                 return t;
524         }
525
526         [MethodImplAttribute (MethodImplOptions.NoInlining)]
527         static int return_int_nogshared<T,T1> (T t) {
528                 object o = t;
529                 T t2 = (T)o;
530                 return 2;
531         }
532
533         [MethodImplAttribute (MethodImplOptions.NoInlining)]
534         static A return_vtype_nogshared<T,T1> (T t) {
535                 object o = t;
536                 T t2 = (T)o;
537                 return new A () { a = 1, b = 2, c = 3 };
538         }
539
540         [MethodImplAttribute (MethodImplOptions.NoInlining)]
541         static T return2_t_out<T> (T t) {
542                 return return_t_nogshared<T, int?> (t);
543         }
544
545         [MethodImplAttribute (MethodImplOptions.NoInlining)]
546         static int return2_int_out<T> (T t) {
547                 return return_int_nogshared<T, int?> (t);
548         }
549
550         [MethodImplAttribute (MethodImplOptions.NoInlining)]
551         static A return2_vtype_out<T> (T t) {
552                 return return_vtype_nogshared<T, int?> (t);
553         }
554
555         struct A {
556                 public int a, b, c;
557         }
558
559         [Category ("!FULLAOT")]
560         public static int test_0_gsharedvt_out () {
561                 if (return2_t_out (2) != 2)
562                         return 1;
563                 if (return2_t_out ("A") != "A")
564                         return 2;
565                 if (return2_t_out (2.0) != 2.0)
566                         return 3;
567                 if (return2_t_out (2.0f) != 2.0f)
568                         return 4;
569                 A a = new A () { a = 1, b = 2, c = 3 };
570                 A a2 = return2_t_out (a);
571                 if (a2.a != 1 || a2.b != 2 || a2.c != 3)
572                         return 5;
573                 // Calls with non gsharedvt return types
574                 if (return2_int_out (1) != 2)
575                         return 6;
576                 A c = return2_vtype_out (a);
577                 if (a2.a != 1 || a2.b != 2 || a2.c != 3)
578                         return 7;
579                 return 0;
580         }
581
582         public class GenericClass<T> {
583                 public static T Z (IList<T> x, int index)
584                 {
585                         return x [index];
586                 }
587         }
588
589         public static int test_0_generic_array_helpers () {
590                 int[] x = new int[] {100, 200};
591
592                 // Generic array helpers should be treated as gsharedvt-out
593                 if (GenericClass<int>.Z (x, 0) != 100)
594                         return 1;
595
596                 return 0;
597         }
598
599         internal class IntComparer : IComparer<int>
600         {
601                 public int Compare (int ix, int iy)
602                 {
603                         if (ix == iy)
604                                 return 0;
605
606                         if (((uint) ix) < ((uint) iy))
607                                 return -1;
608                         return 1;
609                 }
610         }
611
612         [MethodImplAttribute (MethodImplOptions.NoInlining)]
613         static int gshared_out_iface<T> (T t1, T t2, IComparer<T> comp) {
614                 return comp.Compare (t1, t2);
615         }
616
617         public static int test_0_gshared_out_iface () {
618                 // Call out from gshared to a nongeneric method through a generic interface method
619                 if (gshared_out_iface (2, 2, new IntComparer ()) != 0)
620                         return 1;
621                 return 0;
622         }
623
624         struct Foo1 {
625                 public int i1, i2, i3;
626         }
627
628         struct Foo2<T> {
629                 int i1, i2, i3, i4, i5;
630                 public T foo;
631         }
632
633         [MethodImplAttribute (MethodImplOptions.NoInlining)]    
634         public static void locals<T> (T t) {
635                 Foo2<T> t2 = new Foo2<T> ();
636                 object o = t2;
637         }
638
639         public static int test_0_locals () {
640                 // Test that instantiations of type parameters are allocated the proper local type
641                 int i = 1;
642                 for (int j = 0; j < 10; ++j)
643                         i ++;
644                 locals<Foo1> (new Foo1 () { i1 = 1, i2 = 2, i3 = 3 });
645                 return 0;
646         }
647
648         public interface IFace<T> {
649                 T return_t_iface (T t);
650         }
651
652         public class Parent<T> {
653                 public virtual T return_t_vcall (T t) {
654                         throw new Exception ();
655                         return t;
656                 }
657         }
658
659         public class Child<T> : Parent<T>, IFace<T> {
660                 public override T return_t_vcall (T t) {
661                         return t;
662                 }
663                 public T return_t_iface (T t) {
664                         return t;
665                 }
666         }
667
668         [MethodImplAttribute (MethodImplOptions.NoInlining)]
669         static T return_t_vcall<T> (Parent<T> r, T t) {
670                 return r.return_t_vcall (t);
671         }
672
673         public static int test_0_vcalls () {
674                 if (return_t_vcall (new Child<int> (), 2) != 2)
675                         return 1;
676                 // Patching
677                 for (int i = 0; i < 10; ++i) {
678                         if (return_t_vcall (new Child<int> (), 2) != 2)
679                                 return 2;
680                 }
681                 if (return_t_vcall (new Child<double> (), 2.0) != 2.0)
682                         return 3;
683                 return 0;
684         }
685
686         [MethodImplAttribute (MethodImplOptions.NoInlining)]
687         static T return_t_iface<T> (IFace<T> r, T t) {
688                 return r.return_t_iface (t);
689         }
690
691         public static int test_0_iface_calls () {
692                 if (return_t_iface (new Child<int> (), 2) != 2)
693                         return 1;
694                 if (return_t_iface (new Child<double> (), 2.0) != 2.0)
695                         return 3;
696                 return 0;
697         }
698
699         interface IFaceKVP {
700                 T do_kvp<T> (T a);
701         }
702
703         static KeyValuePair<T1, T2> make_kvp<T1, T2> (T1 t1, T2 t2) {
704                 return new KeyValuePair<T1, T2> (t1, t2);
705         }
706
707         static T2 use_kvp<T1, T2> (KeyValuePair<T1, T2> kvp) {
708                 return kvp.Value;
709         }
710
711         class ClassKVP : IFaceKVP {
712                 public T do_kvp<T> (T a) {
713                         var t = make_kvp (a, a);
714                         // argument is an instance of a vtype instantiated with gsharedvt type arguments
715                         return use_kvp (t);
716                 }
717         }
718
719         public static int test_0_gsharedvt_ginstvt_constructed_arg () {
720                 IFaceKVP c = new ClassKVP ();
721                 if (c.do_kvp<long> (1) != 1)
722                         return 1;
723                 return 0;
724         }
725
726         interface IGetter
727         {
728                 T Get<T>();
729         }
730
731         class Getter : IGetter
732         {
733                 public T Get<T>() { return default(T); }
734         }
735
736         abstract class Session
737         {
738                 public abstract IGetter Getter { get; }
739         }
740
741         class IosSession : Session
742         {
743                 private IGetter getter = new Getter();
744                 public override IGetter Getter { get { return getter; } }
745         }
746
747         enum ENUM_TYPE {
748         }
749
750         public static int test_0_regress_5156 () {
751                 new IosSession().Getter.Get<ENUM_TYPE>();
752                 return 0;
753         }
754
755         public struct VT
756         {
757                 public Action a;
758         }
759
760         public class D
761         {
762         }
763
764         public class A3
765         {
766                 public void OuterMethod<TArg1>(TArg1 value)
767                 {
768                         this.InnerMethod<TArg1, long>(value, 0);
769                 }
770
771                 private void InnerMethod<TArg1, TArg2>(TArg1 v1, TArg2 v2)
772                 {
773                         //Console.WriteLine("{0} {1}",v1,v2);
774                 }
775         }
776
777         public static int test_0_regress_2096 () {
778                 var a = new A3();
779
780                 // The following work:
781                 a.OuterMethod<int>(1);
782                 a.OuterMethod<DateTime>(DateTime.Now);
783
784                 var v = new VT();
785                 a.OuterMethod<VT>(v);
786
787                 var x = new D();
788                 // Next line will crash with Attempting to JIT compile method on device
789                 //  Attempting to JIT compile method
790                 a.OuterMethod<D>(x);
791                 return 0;
792         }
793
794         public class B
795         {
796                 public void Test<T>()
797                 {
798                         //System.Console.WriteLine(typeof(T));
799                 }
800         }
801
802         public class A<T>
803         {
804                 public void Test()
805                 {
806                         new B().Test<System.Collections.Generic.KeyValuePair<T, T>>();
807                 }
808         }
809
810     public static int test_0_regress_6040 () {
811         //new B().Test<System.Collections.Generic.KeyValuePair<string, string>>();
812         new A<int>().Test();
813         new A<object>().Test();
814         new A<string>().Test();
815                 return 0;
816     }
817
818         class ArrayContainer<T> {
819                 private T[,] container = new T[1,1];
820
821                 public T Prop {
822                         [MethodImplAttribute (MethodImplOptions.NoInlining)]
823                         get {
824                                 return container [0, 0];
825                         }
826                         [MethodImplAttribute (MethodImplOptions.NoInlining)]
827                         set {
828                                 container [0, 0] = value;
829                         }
830                 }
831         }
832
833         [MethodImplAttribute (MethodImplOptions.NoInlining)]
834         public static int test_0_multi_dim_arrays () {
835                 var c = new ArrayContainer<int> ();
836                 c.Prop = 5;
837                 return c.Prop == 5 ? 0 : 1;
838         }
839
840         [MethodImplAttribute (MethodImplOptions.NoInlining)]
841         static T2 rgctx_in_call_innner_inner<T1, T2> (T1 t1, T2 t2) {
842                 return t2;
843         }
844
845         [MethodImplAttribute (MethodImplOptions.NoInlining)]
846         static GFoo3<T> rgctx_in_call_inner<T> (T t) {
847                 return rgctx_in_call_innner_inner (1, new GFoo3<T> ());
848         }
849
850     public static int test_0_rgctx_in_call () {
851                 // The call is made through the rgctx call, and it needs an IN trampoline
852                 var t = rgctx_in_call_inner (1);
853                 if (t is GFoo3<int>)
854                         return 0;
855                 return 1;
856         }
857
858         [MethodImplAttribute (MethodImplOptions.NoInlining)]
859         static void arm_params1<T> (T t1, T t2, T t3, T t4, T t5, T t6) {
860         }
861
862         [MethodImplAttribute (MethodImplOptions.NoInlining)]
863         static void arm_params2<T> (T t1, T t2, T t3, long t4, T t5, T t6) {
864         }
865
866         public static int test_0_arm_param_passing () {
867                 arm_params1<int> (1, 2, 3, 4, 5, 6);
868                 arm_params1<int> (1, 2, 3, 4, 5, 6);
869                 return 0;
870         }
871
872         sealed class ScheduledItem<TAbsolute, TValue> {
873                 private readonly object _scheduler;
874                 private readonly TValue _state;
875                 private readonly object _action;
876
877                 public ScheduledItem(object o, TValue state, object action, TAbsolute dueTime) {
878                         _state = state;
879                 }
880         }
881
882     abstract class VirtualTimeSchedulerBase<TAbsolute, TRelative> {
883         public abstract void ScheduleAbsolute<TState>(TState state, TAbsolute dueTime);
884         }
885
886         class VirtualTimeScheduler<TAbsolute, TRelative> : VirtualTimeSchedulerBase<TAbsolute, TRelative> {
887                 public override void ScheduleAbsolute<TState>(TState state, TAbsolute dueTime) {
888                         var si = new ScheduledItem<TAbsolute, TState>(this, state, null, dueTime);
889                 }
890         }
891
892         public static int test_0_rx_mixed_regress () {
893                 var v = new VirtualTimeScheduler<long, long> ();
894                 v.ScheduleAbsolute<Action> (null, 22);
895                 return 0;
896         }
897
898         public class Base {
899                 public virtual T foo<T> (T t) {
900                         return t;
901                 }
902         }
903
904         class Class1 : Base {
905                 public object o;
906
907                 public override T foo<T> (T t) {
908                         o = t;
909                         return t;
910                 }
911         }
912
913         class Class2 : Base {
914                 public object o;
915
916                 public override T foo<T> (T t) {
917                         o = t;
918                         return t;
919                 }
920         }
921
922         [MethodImplAttribute (MethodImplOptions.NoInlining)]
923         public static void bar<T> (Base b, T t) {
924                 b.foo (t);
925         }
926
927         public static int test_0_virtual_generic () {
928                 Class1 c1 = new Class1 ();
929                 Class2 c2 = new Class2 ();
930                 bar (c1, 5);
931                 if (!(c1.o is int) || ((int)c1.o != 5))
932                         return 1;
933                 bar (c1, 6.0);
934                 if (!(c1.o is double) || ((double)c1.o != 6.0))
935                         return 2;
936                 bar (c1, 7.0f);
937                 if (!(c1.o is float) || ((float)c1.o != 7.0f))
938                         return 3;
939                 bar (c2, 5);
940                 if (!(c2.o is int) || ((int)c2.o != 5))
941                         return 4;
942                 bar (c2, 6.0);
943                 bar (c2, 7.0f);
944                 return 0;
945         }
946
947         public interface IFace1<T> {
948                 void m1 ();
949                 void m2 ();
950                 void m3 ();
951                 void m4 ();
952                 void m5 ();
953         }
954
955         public class ClassIFace<T> : IFace1<T> {
956                 public void m1 () {
957                 }
958                 public void m2 () {
959                 }
960                 public void m3 () {
961                 }
962                 public void m4 () {
963                 }
964                 public void m5 () {
965                 }
966         }
967
968         interface IFaceIFaceCall {
969                 void call<T, T2> (IFace1<object> iface);
970         }
971
972         class MakeIFaceCall : IFaceIFaceCall {
973                 public void call<T, T2> (IFace1<object> iface) {
974                         iface.m1 ();
975                 }
976         }
977
978         // Check normal interface calls from gsharedvt call to fully instantiated methods
979         public static int test_0_instatiated_iface_call () {
980                 ClassIFace<object> c1 = new ClassIFace<object> ();
981
982                 IFaceIFaceCall c = new MakeIFaceCall ();
983
984                 c.call<object, int> (c1);
985                 return 0;
986         }
987
988         [MethodImplAttribute (MethodImplOptions.NoInlining)]
989         static string to_string<T, T2>(T t, T2 t2) {
990                 return t.ToString ();
991         }
992
993         enum AnEnum {
994                 One,
995                 Two
996         };
997
998         public static int test_0_constrained_tostring () {
999                 if (to_string<int, int> (1, 1) != "1")
1000                         return 1;
1001                 if (to_string<AnEnum, int> (AnEnum.One, 1) != "One")
1002                         return 2;
1003                 if (to_string<string, int> ("A", 1) != "A")
1004                         return 3;
1005                 return 0;
1006         }
1007
1008         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1009         static int get_hash<T, T2>(T t, T2 t2) {
1010                 return t.GetHashCode ();
1011         }
1012
1013         public static int test_0_constrained_get_hash () {
1014                 if (get_hash<int, int> (1, 1) != 1.GetHashCode ())
1015                         return 1;
1016                 if (get_hash<double, int> (1.0, 1) != 1.0.GetHashCode ())
1017                         return 2;
1018                 if (get_hash<AnEnum, int> (AnEnum.One, 1) != AnEnum.One.GetHashCode ())
1019                         return 3;
1020                 if (get_hash<string, int> ("A", 1) != "A".GetHashCode ())
1021                         return 4;
1022                 return 0;
1023         }
1024
1025         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1026         static bool equals<T, T2>(T t, T2 t2) {
1027                 return t.Equals (t);
1028         }
1029
1030         public static int test_0_constrained_equals () {
1031                 if (equals<int, int> (1, 1) != true)
1032                         return 1;
1033                 if (equals<double, int> (1.0, 1) != true)
1034                         return 2;
1035                 if (equals<AnEnum, int> (AnEnum.One, 1) != true)
1036                         return 3;
1037                 if (equals<string, int> ("A", 1) != true)
1038                         return 4;
1039                 return 0;
1040         }
1041
1042         interface IGetType {
1043                 Type gettype<T, T2>(T t, T2 t2);
1044         }
1045
1046         public class CGetType : IGetType {
1047                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1048                 public Type gettype<T, T2>(T t, T2 t2) {
1049                         return t.GetType ();
1050                 }
1051         }
1052
1053         public static int test_0_constrained_gettype () {
1054                 IGetType c = new CGetType ();
1055                 if (c.gettype<int, int> (1, 1) != typeof (int))
1056                         return 1;
1057                 if (c.gettype<string, int> ("A", 1) != typeof (string))
1058                         return 2;
1059                 return 0;
1060         }
1061
1062         interface IConstrainedCalls {
1063                 Pair<int, int> vtype_ret<T, T2>(T t, T2 t2) where T: IReturnVType;
1064         }
1065
1066         public interface IReturnVType {
1067                 Pair<int, int> return_vtype ();
1068         }
1069
1070         public class CConstrainedCalls : IConstrainedCalls {
1071                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1072                 public Pair<int, int> vtype_ret<T, T2>(T t, T2 t2) where T : IReturnVType {
1073                         return t.return_vtype ();
1074                 }
1075         }
1076
1077         class ReturnVType : IReturnVType {
1078                 public Pair<int, int> return_vtype () {
1079                         return new Pair<int, int> () { First = 1, Second = 2 };
1080                 }
1081         }
1082
1083         public static int test_0_constrained_vtype_ret () {
1084                 IConstrainedCalls c = new CConstrainedCalls ();
1085                 var r = c.vtype_ret<ReturnVType, int> (new ReturnVType (), 1);
1086                 if (r.First != 1 || r.Second != 2)
1087                         return 1;
1088                 return 0;
1089         }
1090
1091         public struct Pair<T1, T2> {
1092                 public T1 First;
1093                 public T2 Second;
1094         }
1095
1096         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1097         public static TState call_del<TState>(TState state, Func<object, TState, TState> action) {
1098                 return action(null, state);
1099         }
1100
1101         [Category ("!FULLAOT")]
1102         public static int test_0_delegate_wrappers () {
1103                 Func<object, Pair<int, int>, Pair<int, int>> del1 = delegate (object o, Pair<int, int> p) { return p; };
1104                 Func<object, Pair<int, int>, Pair<int, int>> del2 = delegate (object o, Pair<int, int> p) { return p; };
1105                 Func<object, Pair<double, int>, Pair<double, int>> del3 = delegate (object o, Pair<double, int> p) { return p; };
1106                 var r1 = call_del<Pair<int, int>> (new Pair<int, int> { First = 1, Second = 2}, del1);
1107                 if (r1.First != 1 || r1.Second != 2)
1108                         return 1;
1109                 var r2 = call_del<Pair<int, int>> (new Pair<int, int> { First = 3, Second = 4}, del2);
1110                 if (r2.First != 3 || r2.Second != 4)
1111                         return 2;
1112                 var r3 = call_del<Pair<double, int>> (new Pair<double, int> { First = 1.0, Second = 2}, del3);
1113                 if (r3.First != 1.0 || r3.Second != 2)
1114                         return 3;
1115                 return 0;
1116         }
1117
1118         class Base<T> {
1119                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1120                 public object foo<T1> (T1 t1, T t, object o) {
1121                         return o;
1122                 }
1123         }
1124
1125         class AClass : Base<long> {
1126
1127                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1128                 public object bar<T> (T t, long time, object o) {
1129                         return foo (t, time, o);
1130                 }
1131         }
1132
1133         public static int test_0_out_in_wrappers () {
1134                 var a = new AClass ();
1135                 object o1 = "A";
1136                 object o2 = a.bar<long> (1024, 0, o1);
1137                 if (o1 != o2)
1138                         return 1;
1139                 return 0;               
1140         }
1141
1142                 interface BIFace {
1143                         object AMethod ();
1144                 }
1145
1146                 class Base<TAbsolute, T2> : BIFace {
1147
1148                         public TAbsolute Clock { get; set; }
1149
1150                         public virtual object AMethod () {
1151                                 return Clock;
1152                         }
1153                 }
1154
1155                 class BClass : Base<long, long> {
1156                 }
1157
1158         public static int test_0_regress_1 () {
1159                 BIFace c = new BClass ();
1160                 object o = c.AMethod ();
1161                 if (!(o is long) || ((long)o != 0))
1162                         return 1;
1163                 return 0;
1164         }
1165
1166         interface IFace3 {
1167                 T unbox_any<T> (object o);
1168         }
1169
1170         class Class3 : IFace3 {
1171                 public virtual T unbox_any<T> (object o) {
1172                         return (T)o;
1173                 }
1174         }
1175
1176         public static int test_0_unbox_any () {
1177                 IFace3 o = new Class3 ();
1178                 if (o.unbox_any<int> (16) != 16)
1179                         return 1;
1180                 if (o.unbox_any<long> ((long)32) != 32)
1181                         return 2;
1182                 if (o.unbox_any<double> (2.0) != 2.0)
1183                         return 3;
1184                 try {
1185                         o.unbox_any<int> (2.0);
1186                         return 4;
1187                 } catch (Exception) {
1188                 }
1189                 return 0;
1190         }
1191
1192         interface IFace4 {
1193                 TSource Catch<TSource, TException>(TSource t)  where TException : Exception;
1194         }
1195
1196         class Class4 : IFace4 {
1197                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1198                         public TSource Catch<TSource, TException>(TSource t)  where TException : Exception {
1199                         return t;
1200                 }
1201         }
1202
1203         // Check that mixed instantiations are correctly created/found in AOT
1204         public static int test_0_constraints () {
1205                 IFace4 o = new Class4 ();
1206                 o.Catch<int, Exception> (1);
1207                 return 0;
1208         }
1209
1210         internal static Type Process<TSource, TElement> (TSource[] arr, Action<TElement, TElement> call) {
1211                 arr [0] = default (TSource);
1212                 return typeof (TSource);
1213         }
1214
1215         interface IFace5 {
1216                 Type foo<T> ();
1217         }
1218
1219         class Class5 : IFace5 {
1220                 public Type foo<T> () {
1221                         return Process<KeyValuePair<long, T>, T> (new KeyValuePair<long, T> [10], null);
1222                 }
1223         }
1224
1225         public static int test_0_rgctx_call_from_gshared_code () {
1226                 var c = new Class5 ();
1227                 if (c.foo<string> () != typeof (KeyValuePair<long, string>))
1228                         return 1;
1229                 return 0;
1230         }
1231
1232         public class Enumbers<T> {
1233                 public object Enumerate (List<KeyValuePair<T, string>> alist)
1234                 {
1235                         return alist.ToArray ();
1236                 }
1237         }
1238
1239         public static int test_0_checkthis_gshared_call () {
1240                 Enumbers<string> e = new Enumbers<string> ();
1241                 try {
1242                         e.Enumerate (null);
1243                         return 1;
1244                 }
1245                 catch (NullReferenceException) {
1246                 }
1247                 return 0;
1248         }
1249
1250         interface IFace6 {
1251                 T[] Del<T> (T t);
1252         }
1253
1254         class Class6 : IFace6 {
1255                 public T[] Del<T> (T t) {
1256                         var res = new T [5];
1257                         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; };
1258                         var v = func.BeginInvoke(t, t, t, t, null, null);
1259                         res [4] = func.EndInvoke (v);
1260                         return res;
1261                 }
1262         }
1263
1264         // FIXME: The runtime-invoke wrapper used by BeginInvoke is not found
1265         [Category ("!FULLAOT")]
1266         public static int test_0_begin_end_invoke () {
1267                 IFace6 o = new Class6 ();
1268                 var arr1 = o.Del (1);
1269                 if (arr1 [0] != 1 || arr1 [1] != 1 || arr1 [2] != 1 || arr1 [3] != 1 || arr1 [4] != 1)
1270                         return 1;
1271                 var arr2 = o.Del (2.0);
1272                 if (arr2 [0] != 2.0 || arr2 [1] != 2.0 || arr2 [2] != 2.0 || arr2 [3] != 2.0 || arr2 [4] != 2.0)
1273                         return 2;
1274                 return 0;
1275         }
1276
1277         public class TAbstractTableItem<TC> {
1278                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1279                 public static void SetProperty<TV> () {    }
1280
1281                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1282                 public static void Test () {
1283                         SetProperty<bool> ();
1284                 }
1285         }
1286
1287         public static int test_0_gsharedvt_method_on_shared_class () {
1288        TAbstractTableItem<object>.Test ();
1289            return 0;
1290         }
1291
1292         interface IFaceBox {
1293                 object box<T> (T t);
1294         }
1295
1296         class ClassBox : IFaceBox {
1297                 public object box<T> (T t) {
1298                         object o = t;
1299                         return o;
1300                 }
1301         }
1302
1303         public static int test_0_nullable_box () {
1304                 IFaceBox c = new ClassBox ();
1305                 int i = 5;
1306                 object o = c.box<int?> (i);
1307                 if ((int)o != i)
1308                         return 1;
1309                 if (c.box<int?> (null) != null)
1310                         return 2;
1311                 long l = Int64.MaxValue - 1;
1312                 o = c.box<long?> (l);
1313                 if ((long)o != l)
1314                         return 3;
1315                 if (c.box<long?> (null) != null)
1316                         return 4;
1317                 string s = "A";
1318                 if (c.box<string> (s) != (object)s)
1319                         return 5;
1320                 return 0;
1321         }
1322
1323         interface IFaceUnbox2 {
1324                 T unbox<T> (object o);
1325         }
1326
1327         class ClassUnbox2 : IFaceUnbox2 {
1328                 public T unbox<T> (object o) {
1329                         return (T)o;
1330                 }
1331         }
1332
1333         public static int test_0_nullable_unbox () {    
1334                 IFaceUnbox2 c = new ClassUnbox2 ();
1335                 int? i = c.unbox<int?> (5);
1336                 if (i != 5)
1337                         return 1;
1338                 int? j = c.unbox<int?> (null);
1339                 if (j != null)
1340                         return 2;
1341                 return 0;
1342         }
1343
1344         interface IConstrained {
1345                 void foo ();
1346                 void foo_ref_arg (string s);
1347         }
1348
1349         interface IConstrained<T3> {
1350                 void foo_gsharedvt_arg (T3 s);
1351                 T3 foo_gsharedvt_ret (T3 s);
1352         }
1353
1354         static object constrained_res;
1355
1356         struct ConsStruct : IConstrained {
1357                 public int i;
1358
1359                 public void foo () {
1360                         constrained_res = i;
1361                 }
1362
1363                 public void foo_ref_arg (string s) {
1364                         constrained_res = s == "A" ? 42 : 0;
1365                 }
1366         }
1367
1368         class ConsClass : IConstrained {
1369                 public int i;
1370
1371                 public void foo () {
1372                         constrained_res = i;
1373                 }
1374
1375                 public void foo_ref_arg (string s) {
1376                         constrained_res = s == "A" ? 43 : 0;
1377                 }
1378         }
1379
1380         struct ConsStruct<T> : IConstrained<T> {
1381                 public void foo_gsharedvt_arg (T s) {
1382                         constrained_res = s;
1383                 }
1384
1385                 public T foo_gsharedvt_ret (T s) {
1386                         return s;
1387                 }
1388         }
1389
1390         struct ConsStructThrow : IConstrained {
1391                 public void foo () {
1392                         throw new Exception ();
1393                 }
1394
1395                 public void foo_ref_arg (string s) {
1396                 }
1397         }
1398
1399         interface IFaceConstrained {
1400                 void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained;
1401                 void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained;
1402                 void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1403                 T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1404                 T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass;
1405         }
1406
1407         class ClassConstrained : IFaceConstrained {
1408                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1409                 public void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained {
1410                         t2.foo ();
1411                 }
1412
1413                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1414                 public void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained {
1415                         t2.foo_ref_arg ("A");
1416                 }
1417
1418                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1419                 public void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1420                         t2.foo_gsharedvt_arg (t);
1421                 }
1422
1423                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1424                 public T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1425                         return t2.foo_gsharedvt_ret (t);
1426                 }
1427
1428                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1429                 public T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass {
1430                         /* This becomes a constrained call even through 't2' is forced to be a reference type by the constraint */
1431                         return (T2)t2.foo (5);
1432                 }
1433         }
1434
1435         class VClass {
1436                 public virtual VClass foo (int i) {
1437                         return this;
1438                 }
1439         }
1440
1441         public static int test_0_constrained_void_iface_call () {
1442                 IFaceConstrained c = new ClassConstrained ();
1443                 var s = new ConsStruct () { i = 42 };
1444                 constrained_res = null;
1445                 c.constrained_void_iface_call<int, ConsStruct> (1, s);
1446                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1447                         return 1;
1448                 constrained_res = null;
1449                 c.constrained_void_iface_call_ref_arg<int, ConsStruct> (1, s);
1450                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1451                         return 2;
1452                 var s2 = new ConsClass () { i = 43 };
1453                 constrained_res = null;
1454                 c.constrained_void_iface_call<int, ConsClass> (1, s2);
1455                 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1456                         return 3;
1457                 constrained_res = null;
1458                 c.constrained_void_iface_call_ref_arg<int, ConsClass> (1, s2);
1459                 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1460                         return 4;
1461                 return 0;
1462         }
1463
1464         public static int test_0_constrained_eh () {
1465                 var s2 = new ConsStructThrow () { };
1466                 try {
1467                         IFaceConstrained c = new ClassConstrained ();
1468                         c.constrained_void_iface_call<int, ConsStructThrow> (1, s2);
1469                         return 1;
1470                 } catch (Exception) {
1471                         return 0;
1472                 }
1473         }
1474
1475         public static int test_0_constrained_void_iface_call_gsharedvt_arg () {
1476                 // This tests constrained calls through interfaces with one gsharedvt arg, like IComparable<T>.CompareTo ()
1477                 IFaceConstrained c = new ClassConstrained ();
1478
1479                 var s = new ConsStruct<int> ();
1480                 constrained_res = null;
1481                 c.constrained_void_iface_call_gsharedvt_arg<int, ConsStruct<int>, int> (42, s, 55);
1482                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1483                         return 1;
1484
1485                 var s2 = new ConsStruct<string> ();
1486                 constrained_res = null;
1487                 c.constrained_void_iface_call_gsharedvt_arg<string, ConsStruct<string>, int> ("A", s2, 55);
1488                 if (!(constrained_res is string) || ((string)constrained_res) != "A")
1489                         return 2;
1490
1491                 return 0;
1492         }
1493
1494         public static int test_0_constrained_iface_call_gsharedvt_ret () {
1495                 IFaceConstrained c = new ClassConstrained ();
1496
1497                 var s = new ConsStruct<int> ();
1498                 int ires = c.constrained_iface_call_gsharedvt_ret<int, ConsStruct<int>, int> (42, s, 55);
1499                 if (ires != 42)
1500                         return 1;
1501
1502                 var s2 = new ConsStruct<string> ();
1503                 string sres = c.constrained_iface_call_gsharedvt_ret<string, ConsStruct<string>, int> ("A", s2, 55);
1504                 if (sres != "A")
1505                         return 2;
1506
1507                 return 0;
1508         }
1509
1510         public static int test_0_constrained_normal_call () {
1511                 IFaceConstrained c = new ClassConstrained ();
1512
1513                 var o = new VClass ();
1514                 var res = c.constrained_normal_call<int, VClass> (1, o);
1515                 return res == o ? 0 : 1;
1516         }
1517
1518         public static async Task<T> FooAsync<T> (int i, int j) {
1519                 Task<int> t = new Task<int> (delegate () { return 42; });
1520                 var response = await t;
1521                 return default(T);
1522         }
1523
1524         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1525         public static void call_async<T> (int i, int j) {
1526                 Task<T> t = FooAsync<T> (1, 2);
1527                 // FIXME: This doesn't work
1528                 //t.RunSynchronously ();
1529         }
1530
1531         // In AOT mode, the async infrastructure depends on gsharedvt methods
1532         public static int test_0_async_call_from_generic () {
1533                 call_async<string> (1, 2);
1534                 return 0;
1535         }
1536
1537         public static int test_0_array_helper_gsharedvt () {
1538                 var arr = new AnEnum [16];
1539                 var c = new ReadOnlyCollection<AnEnum> (arr);
1540                 return c.Contains (AnEnum.Two) == false ? 0 : 1;
1541         }
1542
1543         interface IFaceCallPatching {
1544                 bool caller<T, T2> ();
1545         }
1546
1547         class CallPatching2<T> {
1548                 T t;
1549                 public object o;
1550
1551                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1552                 public bool callee () {
1553                         return (string)o == "ABC";
1554                 }
1555         }
1556
1557         class CallPatching : IFaceCallPatching {
1558                 public bool caller<T, T2> () {
1559                         var c = new CallPatching2<T> ();
1560                         c.o = "ABC";
1561                         return c.callee ();
1562                 }
1563         }
1564
1565         //
1566         // This tests that generic calls made from gsharedvt methods are not patched normally.
1567         // If they are, the first call to 'caller' would patch in the gshared version of
1568         // 'callee', causing the second call to fail because the gshared version of callee
1569         // wouldn't work with CallPatching2<bool> since it has a different object layout.
1570         //
1571         public static int test_0_call_patching () {
1572                 IFaceCallPatching c = new CallPatching ();
1573                 c.caller<object, bool> ();
1574                 if (!c.caller<bool, bool> ())
1575                         return 1;
1576                 return 0;
1577         }
1578
1579         struct EmptyStruct {
1580         }
1581
1582         public struct BStruct {
1583                 public int a, b, c, d;
1584         }
1585
1586         interface IFoo3<T> {
1587                 int Bytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1588                                    byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8);
1589                 int SBytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1590                                         sbyte b1, sbyte b2, sbyte b3, sbyte b4);
1591                 int Shorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1592                                         short b1, short b2, short b3, short b4);
1593                 int UShorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1594                                         ushort b1, ushort b2, ushort b3, ushort b4);
1595                 int Ints (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1596                                   int i1, int i2, int i3, int i4);
1597                 int UInts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1598                                    uint i1, uint i2, uint i3, uint i4);
1599                 int Structs (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1600                                          BStruct s);
1601         }
1602
1603         class Foo3<T> : IFoo3<T> {
1604                 public int Bytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1605                                                   byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8) {
1606                         return b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8;
1607                 }
1608                 public int SBytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1609                                                   sbyte b1, sbyte b2, sbyte b3, sbyte b4) {
1610                         return b1 + b2 + b3 + b4;
1611                 }
1612                 public int Shorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1613                                                    short b1, short b2, short b3, short b4) {
1614                         return b1 + b2 + b3 + b4;
1615                 }
1616                 public int UShorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1617                                                         ushort b1, ushort b2, ushort b3, ushort b4) {
1618                         return b1 + b2 + b3 + b4;
1619                 }
1620                 public int Ints (T t, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8,
1621                                                    int i1, int i2, int i3, int i4) {
1622                         return i1 + i2 + i3 + i4;
1623                 }
1624                 public int UInts (T t, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8,
1625                                                   uint i1, uint i2, uint i3, uint i4) {
1626                         return (int)(i1 + i2 + i3 + i4);
1627                 }
1628                 public int Structs (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1629                                                         BStruct s) {
1630                         return s.a + s.b + s.c + s.d;
1631                 }
1632         }
1633
1634         // Passing small normal arguments on the stack
1635         public static int test_0_arm64_small_stack_args () {
1636                 IFoo3<EmptyStruct> o = (IFoo3<EmptyStruct>)Activator.CreateInstance (typeof (Foo3<>).MakeGenericType (new Type [] { typeof (EmptyStruct) }));
1637                 int res = o.Bytes (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8);
1638                 if (res != 36)
1639                         return 1;
1640                 int res2 = o.SBytes (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1641                 if (res2 != -10)
1642                         return 2;
1643                 int res3 = o.Shorts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1644                 if (res3 != -10)
1645                         return 3;
1646                 int res4 = o.UShorts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
1647                 if (res4 != 10)
1648                         return 4;
1649                 int res5 = o.Ints (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1650                 if (res5 != -10)
1651                         return 5;
1652                 int res6 = o.UInts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
1653                 if (res6 != 10)
1654                         return 6;
1655                 return 0;
1656         }
1657
1658         // Passing vtype normal arguments on the stack
1659         public static int test_0_arm64_vtype_stack_args () {
1660                 IFoo3<EmptyStruct> o = (IFoo3<EmptyStruct>)Activator.CreateInstance (typeof (Foo3<>).MakeGenericType (new Type [] { typeof (EmptyStruct) }));
1661                 int res = o.Structs (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, new BStruct () { a = 1, b = 2, c = 3, d = 4 });
1662                 if (res != 10)
1663                         return 1;
1664                 return 0;
1665         }
1666
1667         interface IFoo4<T> {
1668                 T Get(T[,] arr, T t);
1669         }
1670
1671         class Foo4<T> : IFoo4<T> {
1672                 public T Get(T[,] arr, T t) {
1673                         arr [1, 1] = t;
1674                         return arr [1, 1];
1675                 }
1676         }
1677
1678         struct AStruct {
1679                 public int a, b;
1680         }
1681
1682         public static int test_0_multi_dim_arrays_2 () {
1683                 IFoo4<int> foo = new Foo4<int> ();
1684                 var arr = new int [10, 10];
1685                 int res = foo.Get (arr, 10);
1686                 if (res != 10)
1687                         return 1;
1688
1689                 IFoo4<AStruct> foo2 = new Foo4<AStruct> ();
1690                 var arr2 = new AStruct [10, 10];
1691                 var res2 = foo2.Get (arr2, new AStruct () { a = 1, b = 2 });
1692                 if (res2.a != 1 || res2.b != 2)
1693                         return 2;
1694                 return 0;
1695         }
1696 }
1697
1698 // #13191
1699 public class MobileServiceCollection<TTable, TCol>
1700 {
1701         public async Task<int> LoadMoreItemsAsync(int count = 0) {
1702                 await Task.Delay (1000);
1703                 int results = await ProcessQueryAsync ();
1704                 return results;
1705         }
1706
1707         protected async virtual Task<int> ProcessQueryAsync() {
1708                 await Task.Delay (1000);
1709                 throw new Exception ();
1710         }
1711 }
1712
1713 #if !MOBILE
1714 public class GSharedTests : Tests {
1715 }
1716 #endif