Merge pull request #2476 from ludovic-henry/fix-process-readbuffer-nullref
[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         class DelClass {
468                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
469                 public static T return_t<T> (T t) {
470                         return t;
471                 }
472         }
473
474         public static int test_0_gsharedvt_in_delegates_reflection () {
475                 var m = typeof(DelClass).GetMethod ("return_t").MakeGenericMethod (new Type [] { typeof (int) });
476                 Func<int, int> f = (Func<int, int>)Delegate.CreateDelegate (typeof (Func<int,int>), null, m, false);
477                 if (f (42) != 42)
478                         return 1;
479                 return 0;
480         }
481
482         [MethodImplAttribute (MethodImplOptions.NoInlining)]
483         static T return2_t<T> (T t) {
484                 return return_t (t);
485         }
486
487         public static int test_0_gsharedvt_calls () {
488                 if (return2_t (2) != 2)
489                         return 1;
490                 if (return2_t ("A") != "A")
491                         return 2;
492                 if (return2_t (2.0) != 2.0)
493                         return 3;
494                 return 0;
495         }
496
497         static GFoo3<T> newobj<T> (T t1, T t2) {
498                 return new GFoo3<T> (t1, t2);
499         }
500         
501         public static int test_0_gshared_new () {
502                 var g1 = newobj (1, 2);
503                 if (g1.t != 1 || g1.t2 != 2)
504                         return 1;
505                 var g2 = newobj (1.0, 2.0);
506                 if (g1.t != 1.0 || g1.t2 != 2.0)
507                         return 2;
508
509                 return 0;
510         }
511
512         [MethodImplAttribute (MethodImplOptions.NoInlining)]
513         static GFoo2<T> newobj_vt<T> (T t1, T t2) {
514                 return new GFoo2<T> () { t = t1, t2 = t2 };
515         }
516
517         public static int test_0_gshared_new_vt () {
518                 GFoo2<int> v1 = newobj_vt (1, 2);
519                 if (v1.t != 1 || v1.t2 != 2)
520                         return 1;
521                 GFoo2<double> v2 = newobj_vt (1.0, 2.0);
522                 if (v2.t != 1.0 || v2.t2 != 2.0)
523                         return 2;
524                 return 0;
525         }
526
527         //
528         // Tests for transitioning out of gsharedvt code
529         //
530
531         // T1=Nullable<..> is not currently supported by gsharedvt
532
533         [MethodImplAttribute (MethodImplOptions.NoInlining)]
534         static T return_t_nogshared<T,T1> (T t) {
535                 object o = t;
536                 T t2 = (T)o;
537                 //Console.WriteLine ("X: " + t);
538                 return t;
539         }
540
541         [MethodImplAttribute (MethodImplOptions.NoInlining)]
542         static int return_int_nogshared<T,T1> (T t) {
543                 object o = t;
544                 T t2 = (T)o;
545                 return 2;
546         }
547
548         [MethodImplAttribute (MethodImplOptions.NoInlining)]
549         static A return_vtype_nogshared<T,T1> (T t) {
550                 object o = t;
551                 T t2 = (T)o;
552                 return new A () { a = 1, b = 2, c = 3 };
553         }
554
555         [MethodImplAttribute (MethodImplOptions.NoInlining)]
556         static T return2_t_out<T> (T t) {
557                 return return_t_nogshared<T, int?> (t);
558         }
559
560         [MethodImplAttribute (MethodImplOptions.NoInlining)]
561         static int return2_int_out<T> (T t) {
562                 return return_int_nogshared<T, int?> (t);
563         }
564
565         [MethodImplAttribute (MethodImplOptions.NoInlining)]
566         static A return2_vtype_out<T> (T t) {
567                 return return_vtype_nogshared<T, int?> (t);
568         }
569
570         struct A {
571                 public int a, b, c;
572         }
573
574         [Category ("!FULLAOT")]
575         public static int test_0_gsharedvt_out () {
576                 if (return2_t_out (2) != 2)
577                         return 1;
578                 if (return2_t_out ("A") != "A")
579                         return 2;
580                 if (return2_t_out (2.0) != 2.0)
581                         return 3;
582                 if (return2_t_out (2.0f) != 2.0f)
583                         return 4;
584                 A a = new A () { a = 1, b = 2, c = 3 };
585                 A a2 = return2_t_out (a);
586                 if (a2.a != 1 || a2.b != 2 || a2.c != 3)
587                         return 5;
588                 // Calls with non gsharedvt return types
589                 if (return2_int_out (1) != 2)
590                         return 6;
591                 A c = return2_vtype_out (a);
592                 if (a2.a != 1 || a2.b != 2 || a2.c != 3)
593                         return 7;
594                 return 0;
595         }
596
597         public class GenericClass<T> {
598                 public static T Z (IList<T> x, int index)
599                 {
600                         return x [index];
601                 }
602         }
603
604         public static int test_0_generic_array_helpers () {
605                 int[] x = new int[] {100, 200};
606
607                 // Generic array helpers should be treated as gsharedvt-out
608                 if (GenericClass<int>.Z (x, 0) != 100)
609                         return 1;
610
611                 return 0;
612         }
613
614         internal class IntComparer : IComparer<int>
615         {
616                 public int Compare (int ix, int iy)
617                 {
618                         if (ix == iy)
619                                 return 0;
620
621                         if (((uint) ix) < ((uint) iy))
622                                 return -1;
623                         return 1;
624                 }
625         }
626
627         [MethodImplAttribute (MethodImplOptions.NoInlining)]
628         static int gshared_out_iface<T> (T t1, T t2, IComparer<T> comp) {
629                 return comp.Compare (t1, t2);
630         }
631
632         public static int test_0_gshared_out_iface () {
633                 // Call out from gshared to a nongeneric method through a generic interface method
634                 if (gshared_out_iface (2, 2, new IntComparer ()) != 0)
635                         return 1;
636                 return 0;
637         }
638
639         struct Foo1 {
640                 public int i1, i2, i3;
641         }
642
643         struct Foo2<T> {
644                 int i1, i2, i3, i4, i5;
645                 public T foo;
646         }
647
648         [MethodImplAttribute (MethodImplOptions.NoInlining)]    
649         public static void locals<T> (T t) {
650                 Foo2<T> t2 = new Foo2<T> ();
651                 object o = t2;
652         }
653
654         public static int test_0_locals () {
655                 // Test that instantiations of type parameters are allocated the proper local type
656                 int i = 1;
657                 for (int j = 0; j < 10; ++j)
658                         i ++;
659                 locals<Foo1> (new Foo1 () { i1 = 1, i2 = 2, i3 = 3 });
660                 return 0;
661         }
662
663         public interface IFace<T> {
664                 T return_t_iface (T t);
665         }
666
667         public class Parent<T> {
668                 public virtual T return_t_vcall (T t) {
669                         throw new Exception ();
670                         return t;
671                 }
672         }
673
674         public class Child<T> : Parent<T>, IFace<T> {
675                 public override T return_t_vcall (T t) {
676                         return t;
677                 }
678                 public T return_t_iface (T t) {
679                         return t;
680                 }
681         }
682
683         [MethodImplAttribute (MethodImplOptions.NoInlining)]
684         static T return_t_vcall<T> (Parent<T> r, T t) {
685                 return r.return_t_vcall (t);
686         }
687
688         public static int test_0_vcalls () {
689                 if (return_t_vcall (new Child<int> (), 2) != 2)
690                         return 1;
691                 // Patching
692                 for (int i = 0; i < 10; ++i) {
693                         if (return_t_vcall (new Child<int> (), 2) != 2)
694                                 return 2;
695                 }
696                 if (return_t_vcall (new Child<double> (), 2.0) != 2.0)
697                         return 3;
698                 return 0;
699         }
700
701         [MethodImplAttribute (MethodImplOptions.NoInlining)]
702         static T return_t_iface<T> (IFace<T> r, T t) {
703                 return r.return_t_iface (t);
704         }
705
706         public static int test_0_iface_calls () {
707                 if (return_t_iface (new Child<int> (), 2) != 2)
708                         return 1;
709                 if (return_t_iface (new Child<double> (), 2.0) != 2.0)
710                         return 3;
711                 return 0;
712         }
713
714         interface IFaceKVP {
715                 T do_kvp<T> (T a);
716         }
717
718         static KeyValuePair<T1, T2> make_kvp<T1, T2> (T1 t1, T2 t2) {
719                 return new KeyValuePair<T1, T2> (t1, t2);
720         }
721
722         static T2 use_kvp<T1, T2> (KeyValuePair<T1, T2> kvp) {
723                 return kvp.Value;
724         }
725
726         class ClassKVP : IFaceKVP {
727                 public T do_kvp<T> (T a) {
728                         var t = make_kvp (a, a);
729                         // argument is an instance of a vtype instantiated with gsharedvt type arguments
730                         return use_kvp (t);
731                 }
732         }
733
734         public static int test_0_gsharedvt_ginstvt_constructed_arg () {
735                 IFaceKVP c = new ClassKVP ();
736                 if (c.do_kvp<long> (1) != 1)
737                         return 1;
738                 return 0;
739         }
740
741         interface IGetter
742         {
743                 T Get<T>();
744         }
745
746         class Getter : IGetter
747         {
748                 public T Get<T>() { return default(T); }
749         }
750
751         abstract class Session
752         {
753                 public abstract IGetter Getter { get; }
754         }
755
756         class IosSession : Session
757         {
758                 private IGetter getter = new Getter();
759                 public override IGetter Getter { get { return getter; } }
760         }
761
762         enum ENUM_TYPE {
763         }
764
765         public static int test_0_regress_5156 () {
766                 new IosSession().Getter.Get<ENUM_TYPE>();
767                 return 0;
768         }
769
770         public struct VT
771         {
772                 public Action a;
773         }
774
775         public class D
776         {
777         }
778
779         public class A3
780         {
781                 public void OuterMethod<TArg1>(TArg1 value)
782                 {
783                         this.InnerMethod<TArg1, long>(value, 0);
784                 }
785
786                 private void InnerMethod<TArg1, TArg2>(TArg1 v1, TArg2 v2)
787                 {
788                         //Console.WriteLine("{0} {1}",v1,v2);
789                 }
790         }
791
792         public static int test_0_regress_2096 () {
793                 var a = new A3();
794
795                 // The following work:
796                 a.OuterMethod<int>(1);
797                 a.OuterMethod<DateTime>(DateTime.Now);
798
799                 var v = new VT();
800                 a.OuterMethod<VT>(v);
801
802                 var x = new D();
803                 // Next line will crash with Attempting to JIT compile method on device
804                 //  Attempting to JIT compile method
805                 a.OuterMethod<D>(x);
806                 return 0;
807         }
808
809         public class B
810         {
811                 public void Test<T>()
812                 {
813                         //System.Console.WriteLine(typeof(T));
814                 }
815         }
816
817         public class A<T>
818         {
819                 public void Test()
820                 {
821                         new B().Test<System.Collections.Generic.KeyValuePair<T, T>>();
822                 }
823         }
824
825     public static int test_0_regress_6040 () {
826         //new B().Test<System.Collections.Generic.KeyValuePair<string, string>>();
827         new A<int>().Test();
828         new A<object>().Test();
829         new A<string>().Test();
830                 return 0;
831     }
832
833         class ArrayContainer<T> {
834                 private T[,] container = new T[1,1];
835
836                 public T Prop {
837                         [MethodImplAttribute (MethodImplOptions.NoInlining)]
838                         get {
839                                 return container [0, 0];
840                         }
841                         [MethodImplAttribute (MethodImplOptions.NoInlining)]
842                         set {
843                                 container [0, 0] = value;
844                         }
845                 }
846         }
847
848         [MethodImplAttribute (MethodImplOptions.NoInlining)]
849         public static int test_0_multi_dim_arrays () {
850                 var c = new ArrayContainer<int> ();
851                 c.Prop = 5;
852                 return c.Prop == 5 ? 0 : 1;
853         }
854
855         [MethodImplAttribute (MethodImplOptions.NoInlining)]
856         static T2 rgctx_in_call_innner_inner<T1, T2> (T1 t1, T2 t2) {
857                 return t2;
858         }
859
860         [MethodImplAttribute (MethodImplOptions.NoInlining)]
861         static GFoo3<T> rgctx_in_call_inner<T> (T t) {
862                 return rgctx_in_call_innner_inner (1, new GFoo3<T> ());
863         }
864
865     public static int test_0_rgctx_in_call () {
866                 // The call is made through the rgctx call, and it needs an IN trampoline
867                 var t = rgctx_in_call_inner (1);
868                 if (t is GFoo3<int>)
869                         return 0;
870                 return 1;
871         }
872
873         [MethodImplAttribute (MethodImplOptions.NoInlining)]
874         static void arm_params1<T> (T t1, T t2, T t3, T t4, T t5, T t6) {
875         }
876
877         [MethodImplAttribute (MethodImplOptions.NoInlining)]
878         static void arm_params2<T> (T t1, T t2, T t3, long t4, T t5, T t6) {
879         }
880
881         public static int test_0_arm_param_passing () {
882                 arm_params1<int> (1, 2, 3, 4, 5, 6);
883                 arm_params1<int> (1, 2, 3, 4, 5, 6);
884                 return 0;
885         }
886
887         sealed class ScheduledItem<TAbsolute, TValue> {
888                 private readonly object _scheduler;
889                 private readonly TValue _state;
890                 private readonly object _action;
891
892                 public ScheduledItem(object o, TValue state, object action, TAbsolute dueTime) {
893                         _state = state;
894                 }
895         }
896
897     abstract class VirtualTimeSchedulerBase<TAbsolute, TRelative> {
898         public abstract void ScheduleAbsolute<TState>(TState state, TAbsolute dueTime);
899         }
900
901         class VirtualTimeScheduler<TAbsolute, TRelative> : VirtualTimeSchedulerBase<TAbsolute, TRelative> {
902                 public override void ScheduleAbsolute<TState>(TState state, TAbsolute dueTime) {
903                         var si = new ScheduledItem<TAbsolute, TState>(this, state, null, dueTime);
904                 }
905         }
906
907         public static int test_0_rx_mixed_regress () {
908                 var v = new VirtualTimeScheduler<long, long> ();
909                 v.ScheduleAbsolute<Action> (null, 22);
910                 return 0;
911         }
912
913         public class Base {
914                 public virtual T foo<T> (T t) {
915                         return t;
916                 }
917         }
918
919         class Class1 : Base {
920                 public object o;
921
922                 public override T foo<T> (T t) {
923                         o = t;
924                         return t;
925                 }
926         }
927
928         class Class2 : Base {
929                 public object o;
930
931                 public override T foo<T> (T t) {
932                         o = t;
933                         return t;
934                 }
935         }
936
937         [MethodImplAttribute (MethodImplOptions.NoInlining)]
938         public static void bar<T> (Base b, T t) {
939                 b.foo (t);
940         }
941
942         public static int test_0_virtual_generic () {
943                 Class1 c1 = new Class1 ();
944                 Class2 c2 = new Class2 ();
945                 bar (c1, 5);
946                 if (!(c1.o is int) || ((int)c1.o != 5))
947                         return 1;
948                 bar (c1, 6.0);
949                 if (!(c1.o is double) || ((double)c1.o != 6.0))
950                         return 2;
951                 bar (c1, 7.0f);
952                 if (!(c1.o is float) || ((float)c1.o != 7.0f))
953                         return 3;
954                 bar (c2, 5);
955                 if (!(c2.o is int) || ((int)c2.o != 5))
956                         return 4;
957                 bar (c2, 6.0);
958                 bar (c2, 7.0f);
959                 return 0;
960         }
961
962         public interface IFace1<T> {
963                 void m1 ();
964                 void m2 ();
965                 void m3 ();
966                 void m4 ();
967                 void m5 ();
968         }
969
970         public class ClassIFace<T> : IFace1<T> {
971                 public void m1 () {
972                 }
973                 public void m2 () {
974                 }
975                 public void m3 () {
976                 }
977                 public void m4 () {
978                 }
979                 public void m5 () {
980                 }
981         }
982
983         interface IFaceIFaceCall {
984                 void call<T, T2> (IFace1<object> iface);
985         }
986
987         class MakeIFaceCall : IFaceIFaceCall {
988                 public void call<T, T2> (IFace1<object> iface) {
989                         iface.m1 ();
990                 }
991         }
992
993         // Check normal interface calls from gsharedvt call to fully instantiated methods
994         public static int test_0_instatiated_iface_call () {
995                 ClassIFace<object> c1 = new ClassIFace<object> ();
996
997                 IFaceIFaceCall c = new MakeIFaceCall ();
998
999                 c.call<object, int> (c1);
1000                 return 0;
1001         }
1002
1003         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1004         static string to_string<T, T2>(T t, T2 t2) {
1005                 return t.ToString ();
1006         }
1007
1008         enum AnEnum {
1009                 One,
1010                 Two
1011         };
1012
1013         public static int test_0_constrained_tostring () {
1014                 if (to_string<int, int> (1, 1) != "1")
1015                         return 1;
1016                 if (to_string<AnEnum, int> (AnEnum.One, 1) != "One")
1017                         return 2;
1018                 if (to_string<string, int> ("A", 1) != "A")
1019                         return 3;
1020                 return 0;
1021         }
1022
1023         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1024         static int get_hash<T, T2>(T t, T2 t2) {
1025                 return t.GetHashCode ();
1026         }
1027
1028         public static int test_0_constrained_get_hash () {
1029                 if (get_hash<int, int> (1, 1) != 1.GetHashCode ())
1030                         return 1;
1031                 if (get_hash<double, int> (1.0, 1) != 1.0.GetHashCode ())
1032                         return 2;
1033                 if (get_hash<AnEnum, int> (AnEnum.One, 1) != AnEnum.One.GetHashCode ())
1034                         return 3;
1035                 if (get_hash<string, int> ("A", 1) != "A".GetHashCode ())
1036                         return 4;
1037                 return 0;
1038         }
1039
1040         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1041         static bool equals<T, T2>(T t, T2 t2) {
1042                 return t.Equals (t);
1043         }
1044
1045         public static int test_0_constrained_equals () {
1046                 if (equals<int, int> (1, 1) != true)
1047                         return 1;
1048                 if (equals<double, int> (1.0, 1) != true)
1049                         return 2;
1050                 if (equals<AnEnum, int> (AnEnum.One, 1) != true)
1051                         return 3;
1052                 if (equals<string, int> ("A", 1) != true)
1053                         return 4;
1054                 return 0;
1055         }
1056
1057         interface IGetType {
1058                 Type gettype<T, T2>(T t, T2 t2);
1059         }
1060
1061         public class CGetType : IGetType {
1062                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1063                 public Type gettype<T, T2>(T t, T2 t2) {
1064                         return t.GetType ();
1065                 }
1066
1067                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1068                 public Type gettype2<T>(T t) {
1069                         return t.GetType ();
1070                 }
1071         }
1072
1073         public static int test_0_constrained_gettype () {
1074                 IGetType c = new CGetType ();
1075                 if (c.gettype<int, int> (1, 1) != typeof (int))
1076                         return 1;
1077                 if (c.gettype<string, int> ("A", 1) != typeof (string))
1078                         return 2;
1079                 /* Partial sharing */
1080                 var c2 = new CGetType ();
1081                 if (c2.gettype2<long> (1) != typeof (long))
1082                         return 3;
1083                 return 0;
1084         }
1085
1086         interface IConstrainedCalls {
1087                 Pair<int, int> vtype_ret<T, T2>(T t, T2 t2) where T: IReturnVType;
1088         }
1089
1090         public interface IReturnVType {
1091                 Pair<int, int> return_vtype ();
1092         }
1093
1094         public class CConstrainedCalls : IConstrainedCalls {
1095                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1096                 public Pair<int, int> vtype_ret<T, T2>(T t, T2 t2) where T : IReturnVType {
1097                         return t.return_vtype ();
1098                 }
1099         }
1100
1101         class ReturnVType : IReturnVType {
1102                 public Pair<int, int> return_vtype () {
1103                         return new Pair<int, int> () { First = 1, Second = 2 };
1104                 }
1105         }
1106
1107         public static int test_0_constrained_vtype_ret () {
1108                 IConstrainedCalls c = new CConstrainedCalls ();
1109                 var r = c.vtype_ret<ReturnVType, int> (new ReturnVType (), 1);
1110                 if (r.First != 1 || r.Second != 2)
1111                         return 1;
1112                 return 0;
1113         }
1114
1115         public struct Pair<T1, T2> {
1116                 public T1 First;
1117                 public T2 Second;
1118         }
1119
1120         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1121         public static TState call_del<TState>(TState state, Func<object, TState, TState> action) {
1122                 return action(null, state);
1123         }
1124
1125         [Category ("!FULLAOT")]
1126         public static int test_0_delegate_wrappers () {
1127                 Func<object, Pair<int, int>, Pair<int, int>> del1 = delegate (object o, Pair<int, int> p) { return p; };
1128                 Func<object, Pair<int, int>, Pair<int, int>> del2 = delegate (object o, Pair<int, int> p) { return p; };
1129                 Func<object, Pair<double, int>, Pair<double, int>> del3 = delegate (object o, Pair<double, int> p) { return p; };
1130                 var r1 = call_del<Pair<int, int>> (new Pair<int, int> { First = 1, Second = 2}, del1);
1131                 if (r1.First != 1 || r1.Second != 2)
1132                         return 1;
1133                 var r2 = call_del<Pair<int, int>> (new Pair<int, int> { First = 3, Second = 4}, del2);
1134                 if (r2.First != 3 || r2.Second != 4)
1135                         return 2;
1136                 var r3 = call_del<Pair<double, int>> (new Pair<double, int> { First = 1.0, Second = 2}, del3);
1137                 if (r3.First != 1.0 || r3.Second != 2)
1138                         return 3;
1139                 return 0;
1140         }
1141
1142         class Base<T> {
1143                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1144                 public object foo<T1> (T1 t1, T t, object o) {
1145                         return o;
1146                 }
1147         }
1148
1149         class AClass : Base<long> {
1150
1151                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1152                 public object bar<T> (T t, long time, object o) {
1153                         return foo (t, time, o);
1154                 }
1155         }
1156
1157         public static int test_0_out_in_wrappers () {
1158                 var a = new AClass ();
1159                 object o1 = "A";
1160                 object o2 = a.bar<long> (1024, 0, o1);
1161                 if (o1 != o2)
1162                         return 1;
1163                 return 0;               
1164         }
1165
1166                 interface BIFace {
1167                         object AMethod ();
1168                 }
1169
1170                 class Base<TAbsolute, T2> : BIFace {
1171
1172                         public TAbsolute Clock { get; set; }
1173
1174                         public virtual object AMethod () {
1175                                 return Clock;
1176                         }
1177                 }
1178
1179                 class BClass : Base<long, long> {
1180                 }
1181
1182         public static int test_0_regress_1 () {
1183                 BIFace c = new BClass ();
1184                 object o = c.AMethod ();
1185                 if (!(o is long) || ((long)o != 0))
1186                         return 1;
1187                 return 0;
1188         }
1189
1190         interface IFace3 {
1191                 T unbox_any<T> (object o);
1192         }
1193
1194         class Class3 : IFace3 {
1195                 public virtual T unbox_any<T> (object o) {
1196                         return (T)o;
1197                 }
1198         }
1199
1200         public static int test_0_unbox_any () {
1201                 IFace3 o = new Class3 ();
1202                 if (o.unbox_any<int> (16) != 16)
1203                         return 1;
1204                 if (o.unbox_any<long> ((long)32) != 32)
1205                         return 2;
1206                 if (o.unbox_any<double> (2.0) != 2.0)
1207                         return 3;
1208                 try {
1209                         o.unbox_any<int> (2.0);
1210                         return 4;
1211                 } catch (Exception) {
1212                 }
1213                 return 0;
1214         }
1215
1216         interface IFace4 {
1217                 TSource Catch<TSource, TException>(TSource t)  where TException : Exception;
1218         }
1219
1220         class Class4 : IFace4 {
1221                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1222                         public TSource Catch<TSource, TException>(TSource t)  where TException : Exception {
1223                         return t;
1224                 }
1225         }
1226
1227         // Check that mixed instantiations are correctly created/found in AOT
1228         public static int test_0_constraints () {
1229                 IFace4 o = new Class4 ();
1230                 o.Catch<int, Exception> (1);
1231                 return 0;
1232         }
1233
1234         internal static Type Process<TSource, TElement> (TSource[] arr, Action<TElement, TElement> call) {
1235                 arr [0] = default (TSource);
1236                 return typeof (TSource);
1237         }
1238
1239         interface IFace5 {
1240                 Type foo<T> ();
1241         }
1242
1243         class Class5 : IFace5 {
1244                 public Type foo<T> () {
1245                         return Process<KeyValuePair<long, T>, T> (new KeyValuePair<long, T> [10], null);
1246                 }
1247         }
1248
1249         public static int test_0_rgctx_call_from_gshared_code () {
1250                 var c = new Class5 ();
1251                 if (c.foo<string> () != typeof (KeyValuePair<long, string>))
1252                         return 1;
1253                 return 0;
1254         }
1255
1256         public class Enumbers<T> {
1257                 public object Enumerate (List<KeyValuePair<T, string>> alist)
1258                 {
1259                         return alist.ToArray ();
1260                 }
1261         }
1262
1263         public static int test_0_checkthis_gshared_call () {
1264                 Enumbers<string> e = new Enumbers<string> ();
1265                 try {
1266                         e.Enumerate (null);
1267                         return 1;
1268                 }
1269                 catch (NullReferenceException) {
1270                 }
1271                 return 0;
1272         }
1273
1274         interface IFace6 {
1275                 T[] Del<T> (T t);
1276         }
1277
1278         class Class6 : IFace6 {
1279                 public T[] Del<T> (T t) {
1280                         var res = new T [5];
1281                         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; };
1282                         var v = func.BeginInvoke(t, t, t, t, null, null);
1283                         res [4] = func.EndInvoke (v);
1284                         return res;
1285                 }
1286         }
1287
1288         // FIXME: The runtime-invoke wrapper used by BeginInvoke is not found
1289         [Category ("!FULLAOT")]
1290         public static int test_0_begin_end_invoke () {
1291                 IFace6 o = new Class6 ();
1292                 var arr1 = o.Del (1);
1293                 if (arr1 [0] != 1 || arr1 [1] != 1 || arr1 [2] != 1 || arr1 [3] != 1 || arr1 [4] != 1)
1294                         return 1;
1295                 var arr2 = o.Del (2.0);
1296                 if (arr2 [0] != 2.0 || arr2 [1] != 2.0 || arr2 [2] != 2.0 || arr2 [3] != 2.0 || arr2 [4] != 2.0)
1297                         return 2;
1298                 return 0;
1299         }
1300
1301         public class TAbstractTableItem<TC> {
1302                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1303                 public static void SetProperty<TV> () {    }
1304
1305                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1306                 public static void Test () {
1307                         SetProperty<bool> ();
1308                 }
1309         }
1310
1311         public static int test_0_gsharedvt_method_on_shared_class () {
1312        TAbstractTableItem<object>.Test ();
1313            return 0;
1314         }
1315
1316         interface IFaceBox {
1317                 object box<T> (T t);
1318                 bool is_null<T> (T t);
1319         }
1320
1321         class ClassBox : IFaceBox {
1322                 public object box<T> (T t) {
1323                         object o = t;
1324                         return o;
1325                 }
1326
1327                 public bool is_null<T> (T t) {
1328                         if (!(default(T) == null))
1329                                 return false;
1330                         return true;
1331                 }
1332         }
1333
1334         public static int test_0_nullable_box () {
1335                 IFaceBox c = new ClassBox ();
1336                 int i = 5;
1337                 object o = c.box<int?> (i);
1338                 if ((int)o != i)
1339                         return 1;
1340                 if (c.box<int?> (null) != null)
1341                         return 2;
1342                 long l = Int64.MaxValue - 1;
1343                 o = c.box<long?> (l);
1344                 if ((long)o != l)
1345                         return 3;
1346                 if (c.box<long?> (null) != null)
1347                         return 4;
1348                 string s = "A";
1349                 if (c.box<string> (s) != (object)s)
1350                         return 5;
1351                 return 0;
1352         }
1353
1354         public static int test_0_nullable_box_brtrue_opt () {
1355                 IFaceBox c = new ClassBox ();
1356
1357                 if (c.is_null<double?> (null))
1358                         return 0;
1359                 else
1360                         return 1;
1361         }
1362
1363         interface IFaceUnbox2 {
1364                 T unbox<T> (object o);
1365         }
1366
1367         class ClassUnbox2 : IFaceUnbox2 {
1368                 public T unbox<T> (object o) {
1369                         return (T)o;
1370                 }
1371         }
1372
1373         public static int test_0_nullable_unbox () {    
1374                 IFaceUnbox2 c = new ClassUnbox2 ();
1375                 int? i = c.unbox<int?> (5);
1376                 if (i != 5)
1377                         return 1;
1378                 int? j = c.unbox<int?> (null);
1379                 if (j != null)
1380                         return 2;
1381                 return 0;
1382         }
1383
1384         interface IConstrained {
1385                 void foo ();
1386                 void foo_ref_arg (string s);
1387         }
1388
1389         interface IConstrained<T3> {
1390                 void foo_gsharedvt_arg (T3 s);
1391                 T3 foo_gsharedvt_ret (T3 s);
1392         }
1393
1394         static object constrained_res;
1395
1396         struct ConsStruct : IConstrained {
1397                 public int i;
1398
1399                 public void foo () {
1400                         constrained_res = i;
1401                 }
1402
1403                 public void foo_ref_arg (string s) {
1404                         constrained_res = s == "A" ? 42 : 0;
1405                 }
1406         }
1407
1408         class ConsClass : IConstrained {
1409                 public int i;
1410
1411                 public void foo () {
1412                         constrained_res = i;
1413                 }
1414
1415                 public void foo_ref_arg (string s) {
1416                         constrained_res = s == "A" ? 43 : 0;
1417                 }
1418         }
1419
1420         struct ConsStruct<T> : IConstrained<T> {
1421                 public void foo_gsharedvt_arg (T s) {
1422                         constrained_res = s;
1423                 }
1424
1425                 public T foo_gsharedvt_ret (T s) {
1426                         return s;
1427                 }
1428         }
1429
1430         struct ConsStructThrow : IConstrained {
1431                 public void foo () {
1432                         throw new Exception ();
1433                 }
1434
1435                 public void foo_ref_arg (string s) {
1436                 }
1437         }
1438
1439         interface IFaceConstrained {
1440                 void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained;
1441                 void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained;
1442                 void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1443                 T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1444                 T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass;
1445         }
1446
1447         class ClassConstrained : IFaceConstrained {
1448                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1449                 public void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained {
1450                         t2.foo ();
1451                 }
1452
1453                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1454                 public void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained {
1455                         t2.foo_ref_arg ("A");
1456                 }
1457
1458                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1459                 public void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1460                         t2.foo_gsharedvt_arg (t);
1461                 }
1462
1463                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1464                 public T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1465                         return t2.foo_gsharedvt_ret (t);
1466                 }
1467
1468                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1469                 public T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass {
1470                         /* This becomes a constrained call even through 't2' is forced to be a reference type by the constraint */
1471                         return (T2)t2.foo (5);
1472                 }
1473         }
1474
1475         class VClass {
1476                 public virtual VClass foo (int i) {
1477                         return this;
1478                 }
1479         }
1480
1481         public static int test_0_constrained_void_iface_call () {
1482                 IFaceConstrained c = new ClassConstrained ();
1483                 var s = new ConsStruct () { i = 42 };
1484                 constrained_res = null;
1485                 c.constrained_void_iface_call<int, ConsStruct> (1, s);
1486                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1487                         return 1;
1488                 constrained_res = null;
1489                 c.constrained_void_iface_call_ref_arg<int, ConsStruct> (1, s);
1490                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1491                         return 2;
1492                 var s2 = new ConsClass () { i = 43 };
1493                 constrained_res = null;
1494                 c.constrained_void_iface_call<int, ConsClass> (1, s2);
1495                 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1496                         return 3;
1497                 constrained_res = null;
1498                 c.constrained_void_iface_call_ref_arg<int, ConsClass> (1, s2);
1499                 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1500                         return 4;
1501                 return 0;
1502         }
1503
1504         public static int test_0_constrained_eh () {
1505                 var s2 = new ConsStructThrow () { };
1506                 try {
1507                         IFaceConstrained c = new ClassConstrained ();
1508                         c.constrained_void_iface_call<int, ConsStructThrow> (1, s2);
1509                         return 1;
1510                 } catch (Exception) {
1511                         return 0;
1512                 }
1513         }
1514
1515         public static int test_0_constrained_void_iface_call_gsharedvt_arg () {
1516                 // This tests constrained calls through interfaces with one gsharedvt arg, like IComparable<T>.CompareTo ()
1517                 IFaceConstrained c = new ClassConstrained ();
1518
1519                 var s = new ConsStruct<int> ();
1520                 constrained_res = null;
1521                 c.constrained_void_iface_call_gsharedvt_arg<int, ConsStruct<int>, int> (42, s, 55);
1522                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1523                         return 1;
1524
1525                 var s2 = new ConsStruct<string> ();
1526                 constrained_res = null;
1527                 c.constrained_void_iface_call_gsharedvt_arg<string, ConsStruct<string>, int> ("A", s2, 55);
1528                 if (!(constrained_res is string) || ((string)constrained_res) != "A")
1529                         return 2;
1530
1531                 return 0;
1532         }
1533
1534         public static int test_0_constrained_iface_call_gsharedvt_ret () {
1535                 IFaceConstrained c = new ClassConstrained ();
1536
1537                 var s = new ConsStruct<int> ();
1538                 int ires = c.constrained_iface_call_gsharedvt_ret<int, ConsStruct<int>, int> (42, s, 55);
1539                 if (ires != 42)
1540                         return 1;
1541
1542                 var s2 = new ConsStruct<string> ();
1543                 string sres = c.constrained_iface_call_gsharedvt_ret<string, ConsStruct<string>, int> ("A", s2, 55);
1544                 if (sres != "A")
1545                         return 2;
1546
1547                 return 0;
1548         }
1549
1550         public static int test_0_constrained_normal_call () {
1551                 IFaceConstrained c = new ClassConstrained ();
1552
1553                 var o = new VClass ();
1554                 var res = c.constrained_normal_call<int, VClass> (1, o);
1555                 return res == o ? 0 : 1;
1556         }
1557
1558         public static async Task<T> FooAsync<T> (int i, int j) {
1559                 Task<int> t = new Task<int> (delegate () { return 42; });
1560                 var response = await t;
1561                 return default(T);
1562         }
1563
1564         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1565         public static void call_async<T> (int i, int j) {
1566                 Task<T> t = FooAsync<T> (1, 2);
1567                 // FIXME: This doesn't work
1568                 //t.RunSynchronously ();
1569         }
1570
1571         // In AOT mode, the async infrastructure depends on gsharedvt methods
1572         public static int test_0_async_call_from_generic () {
1573                 call_async<string> (1, 2);
1574                 return 0;
1575         }
1576
1577         public static int test_0_array_helper_gsharedvt () {
1578                 var arr = new AnEnum [16];
1579                 var c = new ReadOnlyCollection<AnEnum> (arr);
1580                 return c.Contains (AnEnum.Two) == false ? 0 : 1;
1581         }
1582
1583         interface IFaceCallPatching {
1584                 bool caller<T, T2> ();
1585         }
1586
1587         class CallPatching2<T> {
1588                 T t;
1589                 public object o;
1590
1591                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1592                 public bool callee () {
1593                         return (string)o == "ABC";
1594                 }
1595         }
1596
1597         class CallPatching : IFaceCallPatching {
1598                 public bool caller<T, T2> () {
1599                         var c = new CallPatching2<T> ();
1600                         c.o = "ABC";
1601                         return c.callee ();
1602                 }
1603         }
1604
1605         //
1606         // This tests that generic calls made from gsharedvt methods are not patched normally.
1607         // If they are, the first call to 'caller' would patch in the gshared version of
1608         // 'callee', causing the second call to fail because the gshared version of callee
1609         // wouldn't work with CallPatching2<bool> since it has a different object layout.
1610         //
1611         public static int test_0_call_patching () {
1612                 IFaceCallPatching c = new CallPatching ();
1613                 c.caller<object, bool> ();
1614                 if (!c.caller<bool, bool> ())
1615                         return 1;
1616                 return 0;
1617         }
1618
1619         struct EmptyStruct {
1620         }
1621
1622         public struct BStruct {
1623                 public int a, b, c, d;
1624         }
1625
1626         interface IFoo3<T> {
1627                 int Bytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1628                                    byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8);
1629                 int SBytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1630                                         sbyte b1, sbyte b2, sbyte b3, sbyte b4);
1631                 int Shorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1632                                         short b1, short b2, short b3, short b4);
1633                 int UShorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1634                                         ushort b1, ushort b2, ushort b3, ushort b4);
1635                 int Ints (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1636                                   int i1, int i2, int i3, int i4);
1637                 int UInts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1638                                    uint i1, uint i2, uint i3, uint i4);
1639                 int Structs (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1640                                          BStruct s);
1641         }
1642
1643         class Foo3<T> : IFoo3<T> {
1644                 public int Bytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1645                                                   byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8) {
1646                         return b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8;
1647                 }
1648                 public int SBytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1649                                                   sbyte b1, sbyte b2, sbyte b3, sbyte b4) {
1650                         return b1 + b2 + b3 + b4;
1651                 }
1652                 public int Shorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1653                                                    short b1, short b2, short b3, short b4) {
1654                         return b1 + b2 + b3 + b4;
1655                 }
1656                 public int UShorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1657                                                         ushort b1, ushort b2, ushort b3, ushort b4) {
1658                         return b1 + b2 + b3 + b4;
1659                 }
1660                 public int Ints (T t, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8,
1661                                                    int i1, int i2, int i3, int i4) {
1662                         return i1 + i2 + i3 + i4;
1663                 }
1664                 public int UInts (T t, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8,
1665                                                   uint i1, uint i2, uint i3, uint i4) {
1666                         return (int)(i1 + i2 + i3 + i4);
1667                 }
1668                 public int Structs (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1669                                                         BStruct s) {
1670                         return s.a + s.b + s.c + s.d;
1671                 }
1672         }
1673
1674         // Passing small normal arguments on the stack
1675         public static int test_0_arm64_small_stack_args () {
1676                 IFoo3<EmptyStruct> o = (IFoo3<EmptyStruct>)Activator.CreateInstance (typeof (Foo3<>).MakeGenericType (new Type [] { typeof (EmptyStruct) }));
1677                 int res = o.Bytes (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8);
1678                 if (res != 36)
1679                         return 1;
1680                 int res2 = o.SBytes (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1681                 if (res2 != -10)
1682                         return 2;
1683                 int res3 = o.Shorts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1684                 if (res3 != -10)
1685                         return 3;
1686                 int res4 = o.UShorts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
1687                 if (res4 != 10)
1688                         return 4;
1689                 int res5 = o.Ints (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1690                 if (res5 != -10)
1691                         return 5;
1692                 int res6 = o.UInts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
1693                 if (res6 != 10)
1694                         return 6;
1695                 return 0;
1696         }
1697
1698         // Passing vtype normal arguments on the stack
1699         public static int test_0_arm64_vtype_stack_args () {
1700                 IFoo3<EmptyStruct> o = (IFoo3<EmptyStruct>)Activator.CreateInstance (typeof (Foo3<>).MakeGenericType (new Type [] { typeof (EmptyStruct) }));
1701                 int res = o.Structs (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, new BStruct () { a = 1, b = 2, c = 3, d = 4 });
1702                 if (res != 10)
1703                         return 1;
1704                 return 0;
1705         }
1706
1707         interface IFoo4<T> {
1708                 T Get(T[,] arr, T t);
1709         }
1710
1711         class Foo4<T> : IFoo4<T> {
1712                 public T Get(T[,] arr, T t) {
1713                         arr [1, 1] = t;
1714                         return arr [1, 1];
1715                 }
1716         }
1717
1718         struct AStruct {
1719                 public int a, b;
1720         }
1721
1722         public static int test_0_multi_dim_arrays_2 () {
1723                 IFoo4<int> foo = new Foo4<int> ();
1724                 var arr = new int [10, 10];
1725                 int res = foo.Get (arr, 10);
1726                 if (res != 10)
1727                         return 1;
1728
1729                 IFoo4<AStruct> foo2 = new Foo4<AStruct> ();
1730                 var arr2 = new AStruct [10, 10];
1731                 var res2 = foo2.Get (arr2, new AStruct () { a = 1, b = 2 });
1732                 if (res2.a != 1 || res2.b != 2)
1733                         return 2;
1734                 return 0;
1735         }
1736
1737         public interface IFaceTest {
1738                 int iface_method ();
1739         }
1740
1741         public interface IFaceConstrainedIFace {
1742                 int foo<T, T2> (ref T val) where T: IFaceTest;
1743         }
1744
1745         class ConstrainedIFace : IFaceConstrainedIFace {
1746                 public int foo<T, T2> (ref T val) where T: IFaceTest {
1747                         return val.iface_method ();
1748                 }
1749         }
1750
1751         class ClassTest : IFaceTest {
1752                 public int iface_method () {
1753                         return 42;
1754                 }
1755         }
1756
1757         // Test constrained calls on an interface made from gsharedvt methods
1758         public static int test_42_gsharedvt_constrained_iface () {
1759                 IFaceConstrainedIFace obj = new ConstrainedIFace ();
1760                 IFaceTest t = new ClassTest ();
1761                 return obj.foo<IFaceTest, int> (ref t);
1762         }
1763 }
1764
1765 // #13191
1766 public class MobileServiceCollection<TTable, TCol>
1767 {
1768         public async Task<int> LoadMoreItemsAsync(int count = 0) {
1769                 await Task.Delay (1000);
1770                 int results = await ProcessQueryAsync ();
1771                 return results;
1772         }
1773
1774         protected async virtual Task<int> ProcessQueryAsync() {
1775                 await Task.Delay (1000);
1776                 throw new Exception ();
1777         }
1778 }
1779
1780 #if !__MOBILE__
1781 public class GSharedTests : Tests {
1782 }
1783 #endif