Merge pull request #2247 from ivmai/match-ext-libgc-api
[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                 bool is_null<T> (T t);
1304         }
1305
1306         class ClassBox : IFaceBox {
1307                 public object box<T> (T t) {
1308                         object o = t;
1309                         return o;
1310                 }
1311
1312                 public bool is_null<T> (T t) {
1313                         if (!(default(T) == null))
1314                                 return false;
1315                         return true;
1316                 }
1317         }
1318
1319         public static int test_0_nullable_box () {
1320                 IFaceBox c = new ClassBox ();
1321                 int i = 5;
1322                 object o = c.box<int?> (i);
1323                 if ((int)o != i)
1324                         return 1;
1325                 if (c.box<int?> (null) != null)
1326                         return 2;
1327                 long l = Int64.MaxValue - 1;
1328                 o = c.box<long?> (l);
1329                 if ((long)o != l)
1330                         return 3;
1331                 if (c.box<long?> (null) != null)
1332                         return 4;
1333                 string s = "A";
1334                 if (c.box<string> (s) != (object)s)
1335                         return 5;
1336                 return 0;
1337         }
1338
1339         public static int test_0_nullable_box_brtrue_opt () {
1340                 IFaceBox c = new ClassBox ();
1341
1342                 if (c.is_null<double?> (null))
1343                         return 0;
1344                 else
1345                         return 1;
1346         }
1347
1348         interface IFaceUnbox2 {
1349                 T unbox<T> (object o);
1350         }
1351
1352         class ClassUnbox2 : IFaceUnbox2 {
1353                 public T unbox<T> (object o) {
1354                         return (T)o;
1355                 }
1356         }
1357
1358         public static int test_0_nullable_unbox () {    
1359                 IFaceUnbox2 c = new ClassUnbox2 ();
1360                 int? i = c.unbox<int?> (5);
1361                 if (i != 5)
1362                         return 1;
1363                 int? j = c.unbox<int?> (null);
1364                 if (j != null)
1365                         return 2;
1366                 return 0;
1367         }
1368
1369         interface IConstrained {
1370                 void foo ();
1371                 void foo_ref_arg (string s);
1372         }
1373
1374         interface IConstrained<T3> {
1375                 void foo_gsharedvt_arg (T3 s);
1376                 T3 foo_gsharedvt_ret (T3 s);
1377         }
1378
1379         static object constrained_res;
1380
1381         struct ConsStruct : IConstrained {
1382                 public int i;
1383
1384                 public void foo () {
1385                         constrained_res = i;
1386                 }
1387
1388                 public void foo_ref_arg (string s) {
1389                         constrained_res = s == "A" ? 42 : 0;
1390                 }
1391         }
1392
1393         class ConsClass : IConstrained {
1394                 public int i;
1395
1396                 public void foo () {
1397                         constrained_res = i;
1398                 }
1399
1400                 public void foo_ref_arg (string s) {
1401                         constrained_res = s == "A" ? 43 : 0;
1402                 }
1403         }
1404
1405         struct ConsStruct<T> : IConstrained<T> {
1406                 public void foo_gsharedvt_arg (T s) {
1407                         constrained_res = s;
1408                 }
1409
1410                 public T foo_gsharedvt_ret (T s) {
1411                         return s;
1412                 }
1413         }
1414
1415         struct ConsStructThrow : IConstrained {
1416                 public void foo () {
1417                         throw new Exception ();
1418                 }
1419
1420                 public void foo_ref_arg (string s) {
1421                 }
1422         }
1423
1424         interface IFaceConstrained {
1425                 void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained;
1426                 void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained;
1427                 void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1428                 T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1429                 T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass;
1430         }
1431
1432         class ClassConstrained : IFaceConstrained {
1433                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1434                 public void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained {
1435                         t2.foo ();
1436                 }
1437
1438                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1439                 public void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained {
1440                         t2.foo_ref_arg ("A");
1441                 }
1442
1443                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1444                 public void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1445                         t2.foo_gsharedvt_arg (t);
1446                 }
1447
1448                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1449                 public T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1450                         return t2.foo_gsharedvt_ret (t);
1451                 }
1452
1453                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1454                 public T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass {
1455                         /* This becomes a constrained call even through 't2' is forced to be a reference type by the constraint */
1456                         return (T2)t2.foo (5);
1457                 }
1458         }
1459
1460         class VClass {
1461                 public virtual VClass foo (int i) {
1462                         return this;
1463                 }
1464         }
1465
1466         public static int test_0_constrained_void_iface_call () {
1467                 IFaceConstrained c = new ClassConstrained ();
1468                 var s = new ConsStruct () { i = 42 };
1469                 constrained_res = null;
1470                 c.constrained_void_iface_call<int, ConsStruct> (1, s);
1471                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1472                         return 1;
1473                 constrained_res = null;
1474                 c.constrained_void_iface_call_ref_arg<int, ConsStruct> (1, s);
1475                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1476                         return 2;
1477                 var s2 = new ConsClass () { i = 43 };
1478                 constrained_res = null;
1479                 c.constrained_void_iface_call<int, ConsClass> (1, s2);
1480                 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1481                         return 3;
1482                 constrained_res = null;
1483                 c.constrained_void_iface_call_ref_arg<int, ConsClass> (1, s2);
1484                 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1485                         return 4;
1486                 return 0;
1487         }
1488
1489         public static int test_0_constrained_eh () {
1490                 var s2 = new ConsStructThrow () { };
1491                 try {
1492                         IFaceConstrained c = new ClassConstrained ();
1493                         c.constrained_void_iface_call<int, ConsStructThrow> (1, s2);
1494                         return 1;
1495                 } catch (Exception) {
1496                         return 0;
1497                 }
1498         }
1499
1500         public static int test_0_constrained_void_iface_call_gsharedvt_arg () {
1501                 // This tests constrained calls through interfaces with one gsharedvt arg, like IComparable<T>.CompareTo ()
1502                 IFaceConstrained c = new ClassConstrained ();
1503
1504                 var s = new ConsStruct<int> ();
1505                 constrained_res = null;
1506                 c.constrained_void_iface_call_gsharedvt_arg<int, ConsStruct<int>, int> (42, s, 55);
1507                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1508                         return 1;
1509
1510                 var s2 = new ConsStruct<string> ();
1511                 constrained_res = null;
1512                 c.constrained_void_iface_call_gsharedvt_arg<string, ConsStruct<string>, int> ("A", s2, 55);
1513                 if (!(constrained_res is string) || ((string)constrained_res) != "A")
1514                         return 2;
1515
1516                 return 0;
1517         }
1518
1519         public static int test_0_constrained_iface_call_gsharedvt_ret () {
1520                 IFaceConstrained c = new ClassConstrained ();
1521
1522                 var s = new ConsStruct<int> ();
1523                 int ires = c.constrained_iface_call_gsharedvt_ret<int, ConsStruct<int>, int> (42, s, 55);
1524                 if (ires != 42)
1525                         return 1;
1526
1527                 var s2 = new ConsStruct<string> ();
1528                 string sres = c.constrained_iface_call_gsharedvt_ret<string, ConsStruct<string>, int> ("A", s2, 55);
1529                 if (sres != "A")
1530                         return 2;
1531
1532                 return 0;
1533         }
1534
1535         public static int test_0_constrained_normal_call () {
1536                 IFaceConstrained c = new ClassConstrained ();
1537
1538                 var o = new VClass ();
1539                 var res = c.constrained_normal_call<int, VClass> (1, o);
1540                 return res == o ? 0 : 1;
1541         }
1542
1543         public static async Task<T> FooAsync<T> (int i, int j) {
1544                 Task<int> t = new Task<int> (delegate () { return 42; });
1545                 var response = await t;
1546                 return default(T);
1547         }
1548
1549         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1550         public static void call_async<T> (int i, int j) {
1551                 Task<T> t = FooAsync<T> (1, 2);
1552                 // FIXME: This doesn't work
1553                 //t.RunSynchronously ();
1554         }
1555
1556         // In AOT mode, the async infrastructure depends on gsharedvt methods
1557         public static int test_0_async_call_from_generic () {
1558                 call_async<string> (1, 2);
1559                 return 0;
1560         }
1561
1562         public static int test_0_array_helper_gsharedvt () {
1563                 var arr = new AnEnum [16];
1564                 var c = new ReadOnlyCollection<AnEnum> (arr);
1565                 return c.Contains (AnEnum.Two) == false ? 0 : 1;
1566         }
1567
1568         interface IFaceCallPatching {
1569                 bool caller<T, T2> ();
1570         }
1571
1572         class CallPatching2<T> {
1573                 T t;
1574                 public object o;
1575
1576                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1577                 public bool callee () {
1578                         return (string)o == "ABC";
1579                 }
1580         }
1581
1582         class CallPatching : IFaceCallPatching {
1583                 public bool caller<T, T2> () {
1584                         var c = new CallPatching2<T> ();
1585                         c.o = "ABC";
1586                         return c.callee ();
1587                 }
1588         }
1589
1590         //
1591         // This tests that generic calls made from gsharedvt methods are not patched normally.
1592         // If they are, the first call to 'caller' would patch in the gshared version of
1593         // 'callee', causing the second call to fail because the gshared version of callee
1594         // wouldn't work with CallPatching2<bool> since it has a different object layout.
1595         //
1596         public static int test_0_call_patching () {
1597                 IFaceCallPatching c = new CallPatching ();
1598                 c.caller<object, bool> ();
1599                 if (!c.caller<bool, bool> ())
1600                         return 1;
1601                 return 0;
1602         }
1603
1604         struct EmptyStruct {
1605         }
1606
1607         public struct BStruct {
1608                 public int a, b, c, d;
1609         }
1610
1611         interface IFoo3<T> {
1612                 int Bytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1613                                    byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8);
1614                 int SBytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1615                                         sbyte b1, sbyte b2, sbyte b3, sbyte b4);
1616                 int Shorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1617                                         short b1, short b2, short b3, short b4);
1618                 int UShorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1619                                         ushort b1, ushort b2, ushort b3, ushort b4);
1620                 int Ints (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1621                                   int i1, int i2, int i3, int i4);
1622                 int UInts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1623                                    uint i1, uint i2, uint i3, uint i4);
1624                 int Structs (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1625                                          BStruct s);
1626         }
1627
1628         class Foo3<T> : IFoo3<T> {
1629                 public int Bytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1630                                                   byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8) {
1631                         return b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8;
1632                 }
1633                 public int SBytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1634                                                   sbyte b1, sbyte b2, sbyte b3, sbyte b4) {
1635                         return b1 + b2 + b3 + b4;
1636                 }
1637                 public int Shorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1638                                                    short b1, short b2, short b3, short b4) {
1639                         return b1 + b2 + b3 + b4;
1640                 }
1641                 public int UShorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1642                                                         ushort b1, ushort b2, ushort b3, ushort b4) {
1643                         return b1 + b2 + b3 + b4;
1644                 }
1645                 public int Ints (T t, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8,
1646                                                    int i1, int i2, int i3, int i4) {
1647                         return i1 + i2 + i3 + i4;
1648                 }
1649                 public int UInts (T t, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8,
1650                                                   uint i1, uint i2, uint i3, uint i4) {
1651                         return (int)(i1 + i2 + i3 + i4);
1652                 }
1653                 public int Structs (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1654                                                         BStruct s) {
1655                         return s.a + s.b + s.c + s.d;
1656                 }
1657         }
1658
1659         // Passing small normal arguments on the stack
1660         public static int test_0_arm64_small_stack_args () {
1661                 IFoo3<EmptyStruct> o = (IFoo3<EmptyStruct>)Activator.CreateInstance (typeof (Foo3<>).MakeGenericType (new Type [] { typeof (EmptyStruct) }));
1662                 int res = o.Bytes (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8);
1663                 if (res != 36)
1664                         return 1;
1665                 int res2 = o.SBytes (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1666                 if (res2 != -10)
1667                         return 2;
1668                 int res3 = o.Shorts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1669                 if (res3 != -10)
1670                         return 3;
1671                 int res4 = o.UShorts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
1672                 if (res4 != 10)
1673                         return 4;
1674                 int res5 = o.Ints (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1675                 if (res5 != -10)
1676                         return 5;
1677                 int res6 = o.UInts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
1678                 if (res6 != 10)
1679                         return 6;
1680                 return 0;
1681         }
1682
1683         // Passing vtype normal arguments on the stack
1684         public static int test_0_arm64_vtype_stack_args () {
1685                 IFoo3<EmptyStruct> o = (IFoo3<EmptyStruct>)Activator.CreateInstance (typeof (Foo3<>).MakeGenericType (new Type [] { typeof (EmptyStruct) }));
1686                 int res = o.Structs (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, new BStruct () { a = 1, b = 2, c = 3, d = 4 });
1687                 if (res != 10)
1688                         return 1;
1689                 return 0;
1690         }
1691
1692         interface IFoo4<T> {
1693                 T Get(T[,] arr, T t);
1694         }
1695
1696         class Foo4<T> : IFoo4<T> {
1697                 public T Get(T[,] arr, T t) {
1698                         arr [1, 1] = t;
1699                         return arr [1, 1];
1700                 }
1701         }
1702
1703         struct AStruct {
1704                 public int a, b;
1705         }
1706
1707         public static int test_0_multi_dim_arrays_2 () {
1708                 IFoo4<int> foo = new Foo4<int> ();
1709                 var arr = new int [10, 10];
1710                 int res = foo.Get (arr, 10);
1711                 if (res != 10)
1712                         return 1;
1713
1714                 IFoo4<AStruct> foo2 = new Foo4<AStruct> ();
1715                 var arr2 = new AStruct [10, 10];
1716                 var res2 = foo2.Get (arr2, new AStruct () { a = 1, b = 2 });
1717                 if (res2.a != 1 || res2.b != 2)
1718                         return 2;
1719                 return 0;
1720         }
1721
1722         public interface IFaceTest {
1723                 int iface_method ();
1724         }
1725
1726         public interface IFaceConstrainedIFace {
1727                 int foo<T, T2> (ref T val) where T: IFaceTest;
1728         }
1729
1730         class ConstrainedIFace : IFaceConstrainedIFace {
1731                 public int foo<T, T2> (ref T val) where T: IFaceTest {
1732                         return val.iface_method ();
1733                 }
1734         }
1735
1736         class ClassTest : IFaceTest {
1737                 public int iface_method () {
1738                         return 42;
1739                 }
1740         }
1741
1742         // Test constrained calls on an interface made from gsharedvt methods
1743         public static int test_42_gsharedvt_constrained_iface () {
1744                 IFaceConstrainedIFace obj = new ConstrainedIFace ();
1745                 IFaceTest t = new ClassTest ();
1746                 return obj.foo<IFaceTest, int> (ref t);
1747         }
1748 }
1749
1750 // #13191
1751 public class MobileServiceCollection<TTable, TCol>
1752 {
1753         public async Task<int> LoadMoreItemsAsync(int count = 0) {
1754                 await Task.Delay (1000);
1755                 int results = await ProcessQueryAsync ();
1756                 return results;
1757         }
1758
1759         protected async virtual Task<int> ProcessQueryAsync() {
1760                 await Task.Delay (1000);
1761                 throw new Exception ();
1762         }
1763 }
1764
1765 #if !__MOBILE__
1766 public class GSharedTests : Tests {
1767 }
1768 #endif