Merge pull request #1870 from saper/langinfo_h
[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                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1053                 public Type gettype2<T>(T t) {
1054                         return t.GetType ();
1055                 }
1056         }
1057
1058         public static int test_0_constrained_gettype () {
1059                 IGetType c = new CGetType ();
1060                 if (c.gettype<int, int> (1, 1) != typeof (int))
1061                         return 1;
1062                 if (c.gettype<string, int> ("A", 1) != typeof (string))
1063                         return 2;
1064                 /* Partial sharing */
1065                 var c2 = new CGetType ();
1066                 if (c2.gettype2<long> (1) != typeof (long))
1067                         return 3;
1068                 return 0;
1069         }
1070
1071         interface IConstrainedCalls {
1072                 Pair<int, int> vtype_ret<T, T2>(T t, T2 t2) where T: IReturnVType;
1073         }
1074
1075         public interface IReturnVType {
1076                 Pair<int, int> return_vtype ();
1077         }
1078
1079         public class CConstrainedCalls : IConstrainedCalls {
1080                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1081                 public Pair<int, int> vtype_ret<T, T2>(T t, T2 t2) where T : IReturnVType {
1082                         return t.return_vtype ();
1083                 }
1084         }
1085
1086         class ReturnVType : IReturnVType {
1087                 public Pair<int, int> return_vtype () {
1088                         return new Pair<int, int> () { First = 1, Second = 2 };
1089                 }
1090         }
1091
1092         public static int test_0_constrained_vtype_ret () {
1093                 IConstrainedCalls c = new CConstrainedCalls ();
1094                 var r = c.vtype_ret<ReturnVType, int> (new ReturnVType (), 1);
1095                 if (r.First != 1 || r.Second != 2)
1096                         return 1;
1097                 return 0;
1098         }
1099
1100         public struct Pair<T1, T2> {
1101                 public T1 First;
1102                 public T2 Second;
1103         }
1104
1105         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1106         public static TState call_del<TState>(TState state, Func<object, TState, TState> action) {
1107                 return action(null, state);
1108         }
1109
1110         [Category ("!FULLAOT")]
1111         public static int test_0_delegate_wrappers () {
1112                 Func<object, Pair<int, int>, Pair<int, int>> del1 = delegate (object o, Pair<int, int> p) { return p; };
1113                 Func<object, Pair<int, int>, Pair<int, int>> del2 = delegate (object o, Pair<int, int> p) { return p; };
1114                 Func<object, Pair<double, int>, Pair<double, int>> del3 = delegate (object o, Pair<double, int> p) { return p; };
1115                 var r1 = call_del<Pair<int, int>> (new Pair<int, int> { First = 1, Second = 2}, del1);
1116                 if (r1.First != 1 || r1.Second != 2)
1117                         return 1;
1118                 var r2 = call_del<Pair<int, int>> (new Pair<int, int> { First = 3, Second = 4}, del2);
1119                 if (r2.First != 3 || r2.Second != 4)
1120                         return 2;
1121                 var r3 = call_del<Pair<double, int>> (new Pair<double, int> { First = 1.0, Second = 2}, del3);
1122                 if (r3.First != 1.0 || r3.Second != 2)
1123                         return 3;
1124                 return 0;
1125         }
1126
1127         class Base<T> {
1128                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1129                 public object foo<T1> (T1 t1, T t, object o) {
1130                         return o;
1131                 }
1132         }
1133
1134         class AClass : Base<long> {
1135
1136                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1137                 public object bar<T> (T t, long time, object o) {
1138                         return foo (t, time, o);
1139                 }
1140         }
1141
1142         public static int test_0_out_in_wrappers () {
1143                 var a = new AClass ();
1144                 object o1 = "A";
1145                 object o2 = a.bar<long> (1024, 0, o1);
1146                 if (o1 != o2)
1147                         return 1;
1148                 return 0;               
1149         }
1150
1151                 interface BIFace {
1152                         object AMethod ();
1153                 }
1154
1155                 class Base<TAbsolute, T2> : BIFace {
1156
1157                         public TAbsolute Clock { get; set; }
1158
1159                         public virtual object AMethod () {
1160                                 return Clock;
1161                         }
1162                 }
1163
1164                 class BClass : Base<long, long> {
1165                 }
1166
1167         public static int test_0_regress_1 () {
1168                 BIFace c = new BClass ();
1169                 object o = c.AMethod ();
1170                 if (!(o is long) || ((long)o != 0))
1171                         return 1;
1172                 return 0;
1173         }
1174
1175         interface IFace3 {
1176                 T unbox_any<T> (object o);
1177         }
1178
1179         class Class3 : IFace3 {
1180                 public virtual T unbox_any<T> (object o) {
1181                         return (T)o;
1182                 }
1183         }
1184
1185         public static int test_0_unbox_any () {
1186                 IFace3 o = new Class3 ();
1187                 if (o.unbox_any<int> (16) != 16)
1188                         return 1;
1189                 if (o.unbox_any<long> ((long)32) != 32)
1190                         return 2;
1191                 if (o.unbox_any<double> (2.0) != 2.0)
1192                         return 3;
1193                 try {
1194                         o.unbox_any<int> (2.0);
1195                         return 4;
1196                 } catch (Exception) {
1197                 }
1198                 return 0;
1199         }
1200
1201         interface IFace4 {
1202                 TSource Catch<TSource, TException>(TSource t)  where TException : Exception;
1203         }
1204
1205         class Class4 : IFace4 {
1206                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1207                         public TSource Catch<TSource, TException>(TSource t)  where TException : Exception {
1208                         return t;
1209                 }
1210         }
1211
1212         // Check that mixed instantiations are correctly created/found in AOT
1213         public static int test_0_constraints () {
1214                 IFace4 o = new Class4 ();
1215                 o.Catch<int, Exception> (1);
1216                 return 0;
1217         }
1218
1219         internal static Type Process<TSource, TElement> (TSource[] arr, Action<TElement, TElement> call) {
1220                 arr [0] = default (TSource);
1221                 return typeof (TSource);
1222         }
1223
1224         interface IFace5 {
1225                 Type foo<T> ();
1226         }
1227
1228         class Class5 : IFace5 {
1229                 public Type foo<T> () {
1230                         return Process<KeyValuePair<long, T>, T> (new KeyValuePair<long, T> [10], null);
1231                 }
1232         }
1233
1234         public static int test_0_rgctx_call_from_gshared_code () {
1235                 var c = new Class5 ();
1236                 if (c.foo<string> () != typeof (KeyValuePair<long, string>))
1237                         return 1;
1238                 return 0;
1239         }
1240
1241         public class Enumbers<T> {
1242                 public object Enumerate (List<KeyValuePair<T, string>> alist)
1243                 {
1244                         return alist.ToArray ();
1245                 }
1246         }
1247
1248         public static int test_0_checkthis_gshared_call () {
1249                 Enumbers<string> e = new Enumbers<string> ();
1250                 try {
1251                         e.Enumerate (null);
1252                         return 1;
1253                 }
1254                 catch (NullReferenceException) {
1255                 }
1256                 return 0;
1257         }
1258
1259         interface IFace6 {
1260                 T[] Del<T> (T t);
1261         }
1262
1263         class Class6 : IFace6 {
1264                 public T[] Del<T> (T t) {
1265                         var res = new T [5];
1266                         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; };
1267                         var v = func.BeginInvoke(t, t, t, t, null, null);
1268                         res [4] = func.EndInvoke (v);
1269                         return res;
1270                 }
1271         }
1272
1273         // FIXME: The runtime-invoke wrapper used by BeginInvoke is not found
1274         [Category ("!FULLAOT")]
1275         public static int test_0_begin_end_invoke () {
1276                 IFace6 o = new Class6 ();
1277                 var arr1 = o.Del (1);
1278                 if (arr1 [0] != 1 || arr1 [1] != 1 || arr1 [2] != 1 || arr1 [3] != 1 || arr1 [4] != 1)
1279                         return 1;
1280                 var arr2 = o.Del (2.0);
1281                 if (arr2 [0] != 2.0 || arr2 [1] != 2.0 || arr2 [2] != 2.0 || arr2 [3] != 2.0 || arr2 [4] != 2.0)
1282                         return 2;
1283                 return 0;
1284         }
1285
1286         public class TAbstractTableItem<TC> {
1287                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1288                 public static void SetProperty<TV> () {    }
1289
1290                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1291                 public static void Test () {
1292                         SetProperty<bool> ();
1293                 }
1294         }
1295
1296         public static int test_0_gsharedvt_method_on_shared_class () {
1297        TAbstractTableItem<object>.Test ();
1298            return 0;
1299         }
1300
1301         interface IFaceBox {
1302                 object box<T> (T t);
1303         }
1304
1305         class ClassBox : IFaceBox {
1306                 public object box<T> (T t) {
1307                         object o = t;
1308                         return o;
1309                 }
1310         }
1311
1312         public static int test_0_nullable_box () {
1313                 IFaceBox c = new ClassBox ();
1314                 int i = 5;
1315                 object o = c.box<int?> (i);
1316                 if ((int)o != i)
1317                         return 1;
1318                 if (c.box<int?> (null) != null)
1319                         return 2;
1320                 long l = Int64.MaxValue - 1;
1321                 o = c.box<long?> (l);
1322                 if ((long)o != l)
1323                         return 3;
1324                 if (c.box<long?> (null) != null)
1325                         return 4;
1326                 string s = "A";
1327                 if (c.box<string> (s) != (object)s)
1328                         return 5;
1329                 return 0;
1330         }
1331
1332         interface IFaceUnbox2 {
1333                 T unbox<T> (object o);
1334         }
1335
1336         class ClassUnbox2 : IFaceUnbox2 {
1337                 public T unbox<T> (object o) {
1338                         return (T)o;
1339                 }
1340         }
1341
1342         public static int test_0_nullable_unbox () {    
1343                 IFaceUnbox2 c = new ClassUnbox2 ();
1344                 int? i = c.unbox<int?> (5);
1345                 if (i != 5)
1346                         return 1;
1347                 int? j = c.unbox<int?> (null);
1348                 if (j != null)
1349                         return 2;
1350                 return 0;
1351         }
1352
1353         interface IConstrained {
1354                 void foo ();
1355                 void foo_ref_arg (string s);
1356         }
1357
1358         interface IConstrained<T3> {
1359                 void foo_gsharedvt_arg (T3 s);
1360                 T3 foo_gsharedvt_ret (T3 s);
1361         }
1362
1363         static object constrained_res;
1364
1365         struct ConsStruct : IConstrained {
1366                 public int i;
1367
1368                 public void foo () {
1369                         constrained_res = i;
1370                 }
1371
1372                 public void foo_ref_arg (string s) {
1373                         constrained_res = s == "A" ? 42 : 0;
1374                 }
1375         }
1376
1377         class ConsClass : IConstrained {
1378                 public int i;
1379
1380                 public void foo () {
1381                         constrained_res = i;
1382                 }
1383
1384                 public void foo_ref_arg (string s) {
1385                         constrained_res = s == "A" ? 43 : 0;
1386                 }
1387         }
1388
1389         struct ConsStruct<T> : IConstrained<T> {
1390                 public void foo_gsharedvt_arg (T s) {
1391                         constrained_res = s;
1392                 }
1393
1394                 public T foo_gsharedvt_ret (T s) {
1395                         return s;
1396                 }
1397         }
1398
1399         struct ConsStructThrow : IConstrained {
1400                 public void foo () {
1401                         throw new Exception ();
1402                 }
1403
1404                 public void foo_ref_arg (string s) {
1405                 }
1406         }
1407
1408         interface IFaceConstrained {
1409                 void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained;
1410                 void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained;
1411                 void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1412                 T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1413                 T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass;
1414         }
1415
1416         class ClassConstrained : IFaceConstrained {
1417                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1418                 public void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained {
1419                         t2.foo ();
1420                 }
1421
1422                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1423                 public void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained {
1424                         t2.foo_ref_arg ("A");
1425                 }
1426
1427                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1428                 public void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1429                         t2.foo_gsharedvt_arg (t);
1430                 }
1431
1432                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1433                 public T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1434                         return t2.foo_gsharedvt_ret (t);
1435                 }
1436
1437                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1438                 public T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass {
1439                         /* This becomes a constrained call even through 't2' is forced to be a reference type by the constraint */
1440                         return (T2)t2.foo (5);
1441                 }
1442         }
1443
1444         class VClass {
1445                 public virtual VClass foo (int i) {
1446                         return this;
1447                 }
1448         }
1449
1450         public static int test_0_constrained_void_iface_call () {
1451                 IFaceConstrained c = new ClassConstrained ();
1452                 var s = new ConsStruct () { i = 42 };
1453                 constrained_res = null;
1454                 c.constrained_void_iface_call<int, ConsStruct> (1, s);
1455                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1456                         return 1;
1457                 constrained_res = null;
1458                 c.constrained_void_iface_call_ref_arg<int, ConsStruct> (1, s);
1459                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1460                         return 2;
1461                 var s2 = new ConsClass () { i = 43 };
1462                 constrained_res = null;
1463                 c.constrained_void_iface_call<int, ConsClass> (1, s2);
1464                 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1465                         return 3;
1466                 constrained_res = null;
1467                 c.constrained_void_iface_call_ref_arg<int, ConsClass> (1, s2);
1468                 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1469                         return 4;
1470                 return 0;
1471         }
1472
1473         public static int test_0_constrained_eh () {
1474                 var s2 = new ConsStructThrow () { };
1475                 try {
1476                         IFaceConstrained c = new ClassConstrained ();
1477                         c.constrained_void_iface_call<int, ConsStructThrow> (1, s2);
1478                         return 1;
1479                 } catch (Exception) {
1480                         return 0;
1481                 }
1482         }
1483
1484         public static int test_0_constrained_void_iface_call_gsharedvt_arg () {
1485                 // This tests constrained calls through interfaces with one gsharedvt arg, like IComparable<T>.CompareTo ()
1486                 IFaceConstrained c = new ClassConstrained ();
1487
1488                 var s = new ConsStruct<int> ();
1489                 constrained_res = null;
1490                 c.constrained_void_iface_call_gsharedvt_arg<int, ConsStruct<int>, int> (42, s, 55);
1491                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1492                         return 1;
1493
1494                 var s2 = new ConsStruct<string> ();
1495                 constrained_res = null;
1496                 c.constrained_void_iface_call_gsharedvt_arg<string, ConsStruct<string>, int> ("A", s2, 55);
1497                 if (!(constrained_res is string) || ((string)constrained_res) != "A")
1498                         return 2;
1499
1500                 return 0;
1501         }
1502
1503         public static int test_0_constrained_iface_call_gsharedvt_ret () {
1504                 IFaceConstrained c = new ClassConstrained ();
1505
1506                 var s = new ConsStruct<int> ();
1507                 int ires = c.constrained_iface_call_gsharedvt_ret<int, ConsStruct<int>, int> (42, s, 55);
1508                 if (ires != 42)
1509                         return 1;
1510
1511                 var s2 = new ConsStruct<string> ();
1512                 string sres = c.constrained_iface_call_gsharedvt_ret<string, ConsStruct<string>, int> ("A", s2, 55);
1513                 if (sres != "A")
1514                         return 2;
1515
1516                 return 0;
1517         }
1518
1519         public static int test_0_constrained_normal_call () {
1520                 IFaceConstrained c = new ClassConstrained ();
1521
1522                 var o = new VClass ();
1523                 var res = c.constrained_normal_call<int, VClass> (1, o);
1524                 return res == o ? 0 : 1;
1525         }
1526
1527         public static async Task<T> FooAsync<T> (int i, int j) {
1528                 Task<int> t = new Task<int> (delegate () { return 42; });
1529                 var response = await t;
1530                 return default(T);
1531         }
1532
1533         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1534         public static void call_async<T> (int i, int j) {
1535                 Task<T> t = FooAsync<T> (1, 2);
1536                 // FIXME: This doesn't work
1537                 //t.RunSynchronously ();
1538         }
1539
1540         // In AOT mode, the async infrastructure depends on gsharedvt methods
1541         public static int test_0_async_call_from_generic () {
1542                 call_async<string> (1, 2);
1543                 return 0;
1544         }
1545
1546         public static int test_0_array_helper_gsharedvt () {
1547                 var arr = new AnEnum [16];
1548                 var c = new ReadOnlyCollection<AnEnum> (arr);
1549                 return c.Contains (AnEnum.Two) == false ? 0 : 1;
1550         }
1551
1552         interface IFaceCallPatching {
1553                 bool caller<T, T2> ();
1554         }
1555
1556         class CallPatching2<T> {
1557                 T t;
1558                 public object o;
1559
1560                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1561                 public bool callee () {
1562                         return (string)o == "ABC";
1563                 }
1564         }
1565
1566         class CallPatching : IFaceCallPatching {
1567                 public bool caller<T, T2> () {
1568                         var c = new CallPatching2<T> ();
1569                         c.o = "ABC";
1570                         return c.callee ();
1571                 }
1572         }
1573
1574         //
1575         // This tests that generic calls made from gsharedvt methods are not patched normally.
1576         // If they are, the first call to 'caller' would patch in the gshared version of
1577         // 'callee', causing the second call to fail because the gshared version of callee
1578         // wouldn't work with CallPatching2<bool> since it has a different object layout.
1579         //
1580         public static int test_0_call_patching () {
1581                 IFaceCallPatching c = new CallPatching ();
1582                 c.caller<object, bool> ();
1583                 if (!c.caller<bool, bool> ())
1584                         return 1;
1585                 return 0;
1586         }
1587
1588         struct EmptyStruct {
1589         }
1590
1591         public struct BStruct {
1592                 public int a, b, c, d;
1593         }
1594
1595         interface IFoo3<T> {
1596                 int Bytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1597                                    byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8);
1598                 int SBytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1599                                         sbyte b1, sbyte b2, sbyte b3, sbyte b4);
1600                 int Shorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1601                                         short b1, short b2, short b3, short b4);
1602                 int UShorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1603                                         ushort b1, ushort b2, ushort b3, ushort b4);
1604                 int Ints (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1605                                   int i1, int i2, int i3, int i4);
1606                 int UInts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1607                                    uint i1, uint i2, uint i3, uint i4);
1608                 int Structs (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1609                                          BStruct s);
1610         }
1611
1612         class Foo3<T> : IFoo3<T> {
1613                 public int Bytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1614                                                   byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8) {
1615                         return b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8;
1616                 }
1617                 public int SBytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1618                                                   sbyte b1, sbyte b2, sbyte b3, sbyte b4) {
1619                         return b1 + b2 + b3 + b4;
1620                 }
1621                 public int Shorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1622                                                    short b1, short b2, short b3, short b4) {
1623                         return b1 + b2 + b3 + b4;
1624                 }
1625                 public int UShorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1626                                                         ushort b1, ushort b2, ushort b3, ushort b4) {
1627                         return b1 + b2 + b3 + b4;
1628                 }
1629                 public int Ints (T t, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8,
1630                                                    int i1, int i2, int i3, int i4) {
1631                         return i1 + i2 + i3 + i4;
1632                 }
1633                 public int UInts (T t, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8,
1634                                                   uint i1, uint i2, uint i3, uint i4) {
1635                         return (int)(i1 + i2 + i3 + i4);
1636                 }
1637                 public int Structs (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1638                                                         BStruct s) {
1639                         return s.a + s.b + s.c + s.d;
1640                 }
1641         }
1642
1643         // Passing small normal arguments on the stack
1644         public static int test_0_arm64_small_stack_args () {
1645                 IFoo3<EmptyStruct> o = (IFoo3<EmptyStruct>)Activator.CreateInstance (typeof (Foo3<>).MakeGenericType (new Type [] { typeof (EmptyStruct) }));
1646                 int res = o.Bytes (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8);
1647                 if (res != 36)
1648                         return 1;
1649                 int res2 = o.SBytes (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1650                 if (res2 != -10)
1651                         return 2;
1652                 int res3 = o.Shorts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1653                 if (res3 != -10)
1654                         return 3;
1655                 int res4 = o.UShorts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
1656                 if (res4 != 10)
1657                         return 4;
1658                 int res5 = o.Ints (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1659                 if (res5 != -10)
1660                         return 5;
1661                 int res6 = o.UInts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
1662                 if (res6 != 10)
1663                         return 6;
1664                 return 0;
1665         }
1666
1667         // Passing vtype normal arguments on the stack
1668         public static int test_0_arm64_vtype_stack_args () {
1669                 IFoo3<EmptyStruct> o = (IFoo3<EmptyStruct>)Activator.CreateInstance (typeof (Foo3<>).MakeGenericType (new Type [] { typeof (EmptyStruct) }));
1670                 int res = o.Structs (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, new BStruct () { a = 1, b = 2, c = 3, d = 4 });
1671                 if (res != 10)
1672                         return 1;
1673                 return 0;
1674         }
1675
1676         interface IFoo4<T> {
1677                 T Get(T[,] arr, T t);
1678         }
1679
1680         class Foo4<T> : IFoo4<T> {
1681                 public T Get(T[,] arr, T t) {
1682                         arr [1, 1] = t;
1683                         return arr [1, 1];
1684                 }
1685         }
1686
1687         struct AStruct {
1688                 public int a, b;
1689         }
1690
1691         public static int test_0_multi_dim_arrays_2 () {
1692                 IFoo4<int> foo = new Foo4<int> ();
1693                 var arr = new int [10, 10];
1694                 int res = foo.Get (arr, 10);
1695                 if (res != 10)
1696                         return 1;
1697
1698                 IFoo4<AStruct> foo2 = new Foo4<AStruct> ();
1699                 var arr2 = new AStruct [10, 10];
1700                 var res2 = foo2.Get (arr2, new AStruct () { a = 1, b = 2 });
1701                 if (res2.a != 1 || res2.b != 2)
1702                         return 2;
1703                 return 0;
1704         }
1705 }
1706
1707 // #13191
1708 public class MobileServiceCollection<TTable, TCol>
1709 {
1710         public async Task<int> LoadMoreItemsAsync(int count = 0) {
1711                 await Task.Delay (1000);
1712                 int results = await ProcessQueryAsync ();
1713                 return results;
1714         }
1715
1716         protected async virtual Task<int> ProcessQueryAsync() {
1717                 await Task.Delay (1000);
1718                 throw new Exception ();
1719         }
1720 }
1721
1722 #if !MOBILE
1723 public class GSharedTests : Tests {
1724 }
1725 #endif