Merge pull request #5714 from alexischr/update_bockbuild
[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                 {
736                         // AOT: Force a instantiation of use_kvp<long>
737                         long a = 1;
738                         var t = make_kvp (a, a);
739                         var z = use_kvp (t);
740                 }
741
742                 IFaceKVP c = new ClassKVP ();
743                 if (c.do_kvp<long> (1) != 1)
744                         return 1;
745                 return 0;
746         }
747
748         public static int test_0_gsharedvt_ginstvt_constructed_arg_float () {
749                 {
750                         // AOT: Force a instantiation of use_kvp<double>
751                         double a = 1;
752                         var t = make_kvp (a, a);
753                         var z = use_kvp (t);
754                 }
755
756                 IFaceKVP c = new ClassKVP ();
757                 if (c.do_kvp<double> (1) != 1)
758                         return 1;
759                 return 0;
760         }
761
762         interface IGetter
763         {
764                 T Get<T>();
765         }
766
767         class Getter : IGetter
768         {
769                 public T Get<T>() { return default(T); }
770         }
771
772         abstract class Session
773         {
774                 public abstract IGetter Getter { get; }
775         }
776
777         class IosSession : Session
778         {
779                 private IGetter getter = new Getter();
780                 public override IGetter Getter { get { return getter; } }
781         }
782
783         enum ENUM_TYPE {
784         }
785
786         public static int test_0_regress_5156 () {
787                 new IosSession().Getter.Get<ENUM_TYPE>();
788                 return 0;
789         }
790
791         public struct VT
792         {
793                 public Action a;
794         }
795
796         public class D
797         {
798         }
799
800         public class A3
801         {
802                 public void OuterMethod<TArg1>(TArg1 value)
803                 {
804                         this.InnerMethod<TArg1, long>(value, 0);
805                 }
806
807                 private void InnerMethod<TArg1, TArg2>(TArg1 v1, TArg2 v2)
808                 {
809                         //Console.WriteLine("{0} {1}",v1,v2);
810                 }
811         }
812
813         public static int test_0_regress_2096 () {
814                 var a = new A3();
815
816                 // The following work:
817                 a.OuterMethod<int>(1);
818                 a.OuterMethod<DateTime>(DateTime.Now);
819
820                 var v = new VT();
821                 a.OuterMethod<VT>(v);
822
823                 var x = new D();
824                 // Next line will crash with Attempting to JIT compile method on device
825                 //  Attempting to JIT compile method
826                 a.OuterMethod<D>(x);
827                 return 0;
828         }
829
830         public class B
831         {
832                 public void Test<T>()
833                 {
834                         //System.Console.WriteLine(typeof(T));
835                 }
836         }
837
838         public class A<T>
839         {
840                 public void Test()
841                 {
842                         new B().Test<System.Collections.Generic.KeyValuePair<T, T>>();
843                 }
844         }
845
846     public static int test_0_regress_6040 () {
847         //new B().Test<System.Collections.Generic.KeyValuePair<string, string>>();
848         new A<int>().Test();
849         new A<object>().Test();
850         new A<string>().Test();
851                 return 0;
852     }
853
854         class ArrayContainer<T> {
855                 private T[,] container = new T[1,1];
856
857                 public T Prop {
858                         [MethodImplAttribute (MethodImplOptions.NoInlining)]
859                         get {
860                                 return container [0, 0];
861                         }
862                         [MethodImplAttribute (MethodImplOptions.NoInlining)]
863                         set {
864                                 container [0, 0] = value;
865                         }
866                 }
867         }
868
869         [MethodImplAttribute (MethodImplOptions.NoInlining)]
870         public static int test_0_multi_dim_arrays () {
871                 var c = new ArrayContainer<int> ();
872                 c.Prop = 5;
873                 return c.Prop == 5 ? 0 : 1;
874         }
875
876         [MethodImplAttribute (MethodImplOptions.NoInlining)]
877         static T2 rgctx_in_call_innner_inner<T1, T2> (T1 t1, T2 t2) {
878                 return t2;
879         }
880
881         [MethodImplAttribute (MethodImplOptions.NoInlining)]
882         static GFoo3<T> rgctx_in_call_inner<T> (T t) {
883                 return rgctx_in_call_innner_inner (1, new GFoo3<T> ());
884         }
885
886     public static int test_0_rgctx_in_call () {
887                 // The call is made through the rgctx call, and it needs an IN trampoline
888                 var t = rgctx_in_call_inner (1);
889                 if (t is GFoo3<int>)
890                         return 0;
891                 return 1;
892         }
893
894         [MethodImplAttribute (MethodImplOptions.NoInlining)]
895         static void arm_params1<T> (T t1, T t2, T t3, T t4, T t5, T t6) {
896         }
897
898         [MethodImplAttribute (MethodImplOptions.NoInlining)]
899         static void arm_params2<T> (T t1, T t2, T t3, long t4, T t5, T t6) {
900         }
901
902         public static int test_0_arm_param_passing () {
903                 arm_params1<int> (1, 2, 3, 4, 5, 6);
904                 arm_params1<int> (1, 2, 3, 4, 5, 6);
905                 return 0;
906         }
907
908         sealed class ScheduledItem<TAbsolute, TValue> {
909                 private readonly object _scheduler;
910                 private readonly TValue _state;
911                 private readonly object _action;
912
913                 public ScheduledItem(object o, TValue state, object action, TAbsolute dueTime) {
914                         _state = state;
915                 }
916         }
917
918     abstract class VirtualTimeSchedulerBase<TAbsolute, TRelative> {
919         public abstract void ScheduleAbsolute<TState>(TState state, TAbsolute dueTime);
920         }
921
922         class VirtualTimeScheduler<TAbsolute, TRelative> : VirtualTimeSchedulerBase<TAbsolute, TRelative> {
923                 public override void ScheduleAbsolute<TState>(TState state, TAbsolute dueTime) {
924                         var si = new ScheduledItem<TAbsolute, TState>(this, state, null, dueTime);
925                 }
926         }
927
928         public static int test_0_rx_mixed_regress () {
929                 var v = new VirtualTimeScheduler<long, long> ();
930                 v.ScheduleAbsolute<Action> (null, 22);
931                 return 0;
932         }
933
934         public class Base {
935                 public virtual T foo<T> (T t) {
936                         return t;
937                 }
938         }
939
940         class Class1 : Base {
941                 public object o;
942
943                 public override T foo<T> (T t) {
944                         o = t;
945                         return t;
946                 }
947         }
948
949         class Class2 : Base {
950                 public object o;
951
952                 public override T foo<T> (T t) {
953                         o = t;
954                         return t;
955                 }
956         }
957
958         [MethodImplAttribute (MethodImplOptions.NoInlining)]
959         public static void bar<T> (Base b, T t) {
960                 b.foo (t);
961         }
962
963         public static int test_0_virtual_generic () {
964                 Class1 c1 = new Class1 ();
965                 Class2 c2 = new Class2 ();
966                 bar (c1, 5);
967                 if (!(c1.o is int) || ((int)c1.o != 5))
968                         return 1;
969                 bar (c1, 6.0);
970                 if (!(c1.o is double) || ((double)c1.o != 6.0))
971                         return 2;
972                 bar (c1, 7.0f);
973                 if (!(c1.o is float) || ((float)c1.o != 7.0f))
974                         return 3;
975                 bar (c2, 5);
976                 if (!(c2.o is int) || ((int)c2.o != 5))
977                         return 4;
978                 bar (c2, 6.0);
979                 bar (c2, 7.0f);
980                 return 0;
981         }
982
983         public interface IFace1<T> {
984                 void m1 ();
985                 void m2 ();
986                 void m3 ();
987                 void m4 ();
988                 void m5 ();
989         }
990
991         public class ClassIFace<T> : IFace1<T> {
992                 public void m1 () {
993                 }
994                 public void m2 () {
995                 }
996                 public void m3 () {
997                 }
998                 public void m4 () {
999                 }
1000                 public void m5 () {
1001                 }
1002         }
1003
1004         interface IFaceIFaceCall {
1005                 void call<T, T2> (IFace1<object> iface);
1006         }
1007
1008         class MakeIFaceCall : IFaceIFaceCall {
1009                 public void call<T, T2> (IFace1<object> iface) {
1010                         iface.m1 ();
1011                 }
1012         }
1013
1014         // Check normal interface calls from gsharedvt call to fully instantiated methods
1015         public static int test_0_instatiated_iface_call () {
1016                 ClassIFace<object> c1 = new ClassIFace<object> ();
1017
1018                 IFaceIFaceCall c = new MakeIFaceCall ();
1019
1020                 c.call<object, int> (c1);
1021                 return 0;
1022         }
1023
1024         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1025         static string to_string<T, T2>(T t, T2 t2) {
1026                 return t.ToString ();
1027         }
1028
1029         public enum AnEnum {
1030                 One,
1031                 Two
1032         };
1033
1034         public static int test_0_constrained_tostring () {
1035                 if (to_string<int, int> (1, 1) != "1")
1036                         return 1;
1037                 if (to_string<AnEnum, int> (AnEnum.One, 1) != "One")
1038                         return 2;
1039                 if (to_string<string, int> ("A", 1) != "A")
1040                         return 3;
1041                 return 0;
1042         }
1043
1044         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1045         static int get_hash<T, T2>(T t, T2 t2) {
1046                 return t.GetHashCode ();
1047         }
1048
1049         public static int test_0_constrained_get_hash () {
1050                 if (get_hash<int, int> (1, 1) != 1.GetHashCode ())
1051                         return 1;
1052                 if (get_hash<double, int> (1.0, 1) != 1.0.GetHashCode ())
1053                         return 2;
1054                 if (get_hash<AnEnum, int> (AnEnum.One, 1) != AnEnum.One.GetHashCode ())
1055                         return 3;
1056                 if (get_hash<string, int> ("A", 1) != "A".GetHashCode ())
1057                         return 4;
1058                 return 0;
1059         }
1060
1061         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1062         static bool equals<T, T2>(T t, T2 t2) {
1063                 return t.Equals (t);
1064         }
1065
1066         public static int test_0_constrained_equals () {
1067                 if (equals<int, int> (1, 1) != true)
1068                         return 1;
1069                 if (equals<double, int> (1.0, 1) != true)
1070                         return 2;
1071                 if (equals<AnEnum, int> (AnEnum.One, 1) != true)
1072                         return 3;
1073                 if (equals<string, int> ("A", 1) != true)
1074                         return 4;
1075                 return 0;
1076         }
1077
1078         interface IGetType {
1079                 Type gettype<T, T2>(T t, T2 t2);
1080         }
1081
1082         public class CGetType : IGetType {
1083                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1084                 public Type gettype<T, T2>(T t, T2 t2) {
1085                         return t.GetType ();
1086                 }
1087
1088                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1089                 public Type gettype2<T>(T t) {
1090                         return t.GetType ();
1091                 }
1092         }
1093
1094         public static int test_0_constrained_gettype () {
1095                 IGetType c = new CGetType ();
1096                 if (c.gettype<int, int> (1, 1) != typeof (int))
1097                         return 1;
1098                 if (c.gettype<string, int> ("A", 1) != typeof (string))
1099                         return 2;
1100                 /* Partial sharing */
1101                 var c2 = new CGetType ();
1102                 if (c2.gettype2<long> (1) != typeof (long))
1103                         return 3;
1104                 return 0;
1105         }
1106
1107         interface IConstrainedCalls {
1108                 Pair<int, int> vtype_ret<T, T2>(T t, T2 t2) where T: IReturnVType;
1109                 AnEnum enum_ret<T, T2>(T t, T2 t2) where T: IReturnVType;
1110         }
1111
1112         public interface IReturnVType {
1113                 Pair<int, int> return_vtype ();
1114                 AnEnum return_enum ();
1115         }
1116
1117         public class CConstrainedCalls : IConstrainedCalls {
1118                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1119                 public Pair<int, int> vtype_ret<T, T2>(T t, T2 t2) where T : IReturnVType {
1120                         return t.return_vtype ();
1121                 }
1122
1123                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1124                 public AnEnum enum_ret<T, T2>(T t, T2 t2) where T : IReturnVType {
1125                         return t.return_enum ();
1126                 }
1127         }
1128
1129         class ReturnVType : IReturnVType {
1130                 public Pair<int, int> return_vtype () {
1131                         return new Pair<int, int> () { First = 1, Second = 2 };
1132                 }
1133                 public AnEnum return_enum () {
1134                         return AnEnum.Two;
1135                 }
1136         }
1137
1138         public static int test_0_constrained_vtype_ret () {
1139                 IConstrainedCalls c = new CConstrainedCalls ();
1140                 var r = c.vtype_ret<ReturnVType, int> (new ReturnVType (), 1);
1141                 if (r.First != 1 || r.Second != 2)
1142                         return 1;
1143                 return 0;
1144         }
1145
1146         public static int test_0_constrained_enum_ret () {
1147                 IConstrainedCalls c = new CConstrainedCalls ();
1148                 var r = c.enum_ret<ReturnVType, int> (new ReturnVType (), 1);
1149                 if (r != AnEnum.Two)
1150                         return 1;
1151                 return 0;
1152         }
1153
1154         public struct Pair<T1, T2> {
1155                 public T1 First;
1156                 public T2 Second;
1157         }
1158
1159         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1160         public static TState call_del<TState>(TState state, Func<object, TState, TState> action) {
1161                 return action(null, state);
1162         }
1163
1164         [Category ("!FULLAOT")]
1165         public static int test_0_delegate_wrappers () {
1166                 Func<object, Pair<int, int>, Pair<int, int>> del1 = delegate (object o, Pair<int, int> p) { return p; };
1167                 Func<object, Pair<int, int>, Pair<int, int>> del2 = delegate (object o, Pair<int, int> p) { return p; };
1168                 Func<object, Pair<double, int>, Pair<double, int>> del3 = delegate (object o, Pair<double, int> p) { return p; };
1169                 var r1 = call_del<Pair<int, int>> (new Pair<int, int> { First = 1, Second = 2}, del1);
1170                 if (r1.First != 1 || r1.Second != 2)
1171                         return 1;
1172                 var r2 = call_del<Pair<int, int>> (new Pair<int, int> { First = 3, Second = 4}, del2);
1173                 if (r2.First != 3 || r2.Second != 4)
1174                         return 2;
1175                 var r3 = call_del<Pair<double, int>> (new Pair<double, int> { First = 1.0, Second = 2}, del3);
1176                 if (r3.First != 1.0 || r3.Second != 2)
1177                         return 3;
1178                 return 0;
1179         }
1180
1181         class Base<T> {
1182                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1183                 public object foo<T1> (T1 t1, T t, object o) {
1184                         return o;
1185                 }
1186         }
1187
1188         class AClass : Base<long> {
1189
1190                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1191                 public object bar<T> (T t, long time, object o) {
1192                         return foo (t, time, o);
1193                 }
1194         }
1195
1196         public static int test_0_out_in_wrappers () {
1197                 var a = new AClass ();
1198                 object o1 = "A";
1199                 object o2 = a.bar<long> (1024, 0, o1);
1200                 if (o1 != o2)
1201                         return 1;
1202                 return 0;               
1203         }
1204
1205                 interface BIFace {
1206                         object AMethod ();
1207                 }
1208
1209                 class Base<TAbsolute, T2> : BIFace {
1210
1211                         public TAbsolute Clock { get; set; }
1212
1213                         public virtual object AMethod () {
1214                                 return Clock;
1215                         }
1216                 }
1217
1218                 class BClass : Base<long, long> {
1219                 }
1220
1221         public static int test_0_regress_1 () {
1222                 BIFace c = new BClass ();
1223                 object o = c.AMethod ();
1224                 if (!(o is long) || ((long)o != 0))
1225                         return 1;
1226                 return 0;
1227         }
1228
1229         interface IFace3 {
1230                 T unbox_any<T> (object o);
1231         }
1232
1233         class Class3 : IFace3 {
1234                 public virtual T unbox_any<T> (object o) {
1235                         return (T)o;
1236                 }
1237         }
1238
1239         public static int test_0_unbox_any () {
1240                 IFace3 o = new Class3 ();
1241                 if (o.unbox_any<int> (16) != 16)
1242                         return 1;
1243                 if (o.unbox_any<long> ((long)32) != 32)
1244                         return 2;
1245                 if (o.unbox_any<double> (2.0) != 2.0)
1246                         return 3;
1247                 try {
1248                         o.unbox_any<int> (2.0);
1249                         return 4;
1250                 } catch (Exception) {
1251                 }
1252                 return 0;
1253         }
1254
1255         interface IFace4 {
1256                 TSource Catch<TSource, TException>(TSource t)  where TException : Exception;
1257         }
1258
1259         class Class4 : IFace4 {
1260                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1261                         public TSource Catch<TSource, TException>(TSource t)  where TException : Exception {
1262                         return t;
1263                 }
1264         }
1265
1266         // Check that mixed instantiations are correctly created/found in AOT
1267         public static int test_0_constraints () {
1268                 IFace4 o = new Class4 ();
1269                 o.Catch<int, Exception> (1);
1270                 return 0;
1271         }
1272
1273         internal static Type Process<TSource, TElement> (TSource[] arr, Action<TElement, TElement> call) {
1274                 arr [0] = default (TSource);
1275                 return typeof (TSource);
1276         }
1277
1278         interface IFace5 {
1279                 Type foo<T> ();
1280         }
1281
1282         class Class5 : IFace5 {
1283                 public Type foo<T> () {
1284                         return Process<KeyValuePair<long, T>, T> (new KeyValuePair<long, T> [10], null);
1285                 }
1286         }
1287
1288         public static int test_0_rgctx_call_from_gshared_code () {
1289                 var c = new Class5 ();
1290                 if (c.foo<string> () != typeof (KeyValuePair<long, string>))
1291                         return 1;
1292                 return 0;
1293         }
1294
1295         public class Enumbers<T> {
1296                 public object Enumerate (List<KeyValuePair<T, string>> alist)
1297                 {
1298                         return alist.ToArray ();
1299                 }
1300         }
1301
1302         public static int test_0_checkthis_gshared_call () {
1303                 Enumbers<string> e = new Enumbers<string> ();
1304                 try {
1305                         e.Enumerate (null);
1306                         return 1;
1307                 }
1308                 catch (NullReferenceException) {
1309                 }
1310                 return 0;
1311         }
1312
1313         interface IFace6 {
1314                 T[] Del<T> (T t);
1315         }
1316
1317         class Class6 : IFace6 {
1318                 public T[] Del<T> (T t) {
1319                         var res = new T [5];
1320                         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; };
1321                         var v = func.BeginInvoke(t, t, t, t, null, null);
1322                         res [4] = func.EndInvoke (v);
1323                         return res;
1324                 }
1325         }
1326
1327         // FIXME: The runtime-invoke wrapper used by BeginInvoke is not found
1328         [Category ("!FULLAOT")]
1329         public static int test_0_begin_end_invoke () {
1330                 IFace6 o = new Class6 ();
1331                 var arr1 = o.Del (1);
1332                 if (arr1 [0] != 1 || arr1 [1] != 1 || arr1 [2] != 1 || arr1 [3] != 1 || arr1 [4] != 1)
1333                         return 1;
1334                 var arr2 = o.Del (2.0);
1335                 if (arr2 [0] != 2.0 || arr2 [1] != 2.0 || arr2 [2] != 2.0 || arr2 [3] != 2.0 || arr2 [4] != 2.0)
1336                         return 2;
1337                 return 0;
1338         }
1339
1340         public class TAbstractTableItem<TC> {
1341                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1342                 public static void SetProperty<TV> () {    }
1343
1344                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1345                 public static void Test () {
1346                         SetProperty<bool> ();
1347                 }
1348         }
1349
1350         public static int test_0_gsharedvt_method_on_shared_class () {
1351        TAbstractTableItem<object>.Test ();
1352            return 0;
1353         }
1354
1355         interface IFaceBox {
1356                 object box<T> (T t);
1357                 bool is_null<T> (T t);
1358         }
1359
1360         class ClassBox : IFaceBox {
1361                 public object box<T> (T t) {
1362                         object o = t;
1363                         return o;
1364                 }
1365
1366                 public bool is_null<T> (T t) {
1367                         if (!(default(T) == null))
1368                                 return false;
1369                         return true;
1370                 }
1371         }
1372
1373         public static int test_0_nullable_box () {
1374                 IFaceBox c = new ClassBox ();
1375                 int i = 5;
1376                 object o = c.box<int?> (i);
1377                 if ((int)o != i)
1378                         return 1;
1379                 if (c.box<int?> (null) != null)
1380                         return 2;
1381                 long l = Int64.MaxValue - 1;
1382                 o = c.box<long?> (l);
1383                 if ((long)o != l)
1384                         return 3;
1385                 if (c.box<long?> (null) != null)
1386                         return 4;
1387                 string s = "A";
1388                 if (c.box<string> (s) != (object)s)
1389                         return 5;
1390                 return 0;
1391         }
1392
1393         public static int test_0_nullable_box_brtrue_opt () {
1394                 IFaceBox c = new ClassBox ();
1395
1396                 if (c.is_null<double?> (null))
1397                         return 0;
1398                 else
1399                         return 1;
1400         }
1401
1402         interface IFaceUnbox2 {
1403                 T unbox<T> (object o);
1404         }
1405
1406         class ClassUnbox2 : IFaceUnbox2 {
1407                 public T unbox<T> (object o) {
1408                         return (T)o;
1409                 }
1410         }
1411
1412         public static int test_0_nullable_unbox () {    
1413                 IFaceUnbox2 c = new ClassUnbox2 ();
1414                 int? i = c.unbox<int?> (5);
1415                 if (i != 5)
1416                         return 1;
1417                 int? j = c.unbox<int?> (null);
1418                 if (j != null)
1419                         return 2;
1420                 return 0;
1421         }
1422
1423         interface IConstrained {
1424                 void foo ();
1425                 void foo_ref_arg (string s);
1426         }
1427
1428         interface IConstrained<T3> {
1429                 void foo_gsharedvt_arg (T3 s);
1430                 T3 foo_gsharedvt_ret (T3 s);
1431         }
1432
1433         static object constrained_res;
1434
1435         struct ConsStruct : IConstrained {
1436                 public int i;
1437
1438                 public void foo () {
1439                         constrained_res = i;
1440                 }
1441
1442                 public void foo_ref_arg (string s) {
1443                         constrained_res = s == "A" ? 42 : 0;
1444                 }
1445         }
1446
1447         class ConsClass : IConstrained {
1448                 public int i;
1449
1450                 public void foo () {
1451                         constrained_res = i;
1452                 }
1453
1454                 public void foo_ref_arg (string s) {
1455                         constrained_res = s == "A" ? 43 : 0;
1456                 }
1457         }
1458
1459         struct ConsStruct<T> : IConstrained<T> {
1460                 public void foo_gsharedvt_arg (T s) {
1461                         constrained_res = s;
1462                 }
1463
1464                 public T foo_gsharedvt_ret (T s) {
1465                         return s;
1466                 }
1467         }
1468
1469         struct ConsStructThrow : IConstrained {
1470                 public void foo () {
1471                         throw new Exception ();
1472                 }
1473
1474                 public void foo_ref_arg (string s) {
1475                 }
1476         }
1477
1478         interface IFaceConstrained {
1479                 void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained;
1480                 void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained;
1481                 void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1482                 T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1483                 T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass;
1484         }
1485
1486         class ClassConstrained : IFaceConstrained {
1487                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1488                 public void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained {
1489                         t2.foo ();
1490                 }
1491
1492                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1493                 public void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained {
1494                         t2.foo_ref_arg ("A");
1495                 }
1496
1497                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1498                 public void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1499                         t2.foo_gsharedvt_arg (t);
1500                 }
1501
1502                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1503                 public T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1504                         return t2.foo_gsharedvt_ret (t);
1505                 }
1506
1507                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1508                 public T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass {
1509                         /* This becomes a constrained call even through 't2' is forced to be a reference type by the constraint */
1510                         return (T2)t2.foo (5);
1511                 }
1512         }
1513
1514         class VClass {
1515                 public virtual VClass foo (int i) {
1516                         return this;
1517                 }
1518         }
1519
1520         public static int test_0_constrained_void_iface_call () {
1521                 IFaceConstrained c = new ClassConstrained ();
1522                 var s = new ConsStruct () { i = 42 };
1523                 constrained_res = null;
1524                 c.constrained_void_iface_call<int, ConsStruct> (1, s);
1525                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1526                         return 1;
1527                 constrained_res = null;
1528                 c.constrained_void_iface_call_ref_arg<int, ConsStruct> (1, s);
1529                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1530                         return 2;
1531                 var s2 = new ConsClass () { i = 43 };
1532                 constrained_res = null;
1533                 c.constrained_void_iface_call<int, ConsClass> (1, s2);
1534                 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1535                         return 3;
1536                 constrained_res = null;
1537                 c.constrained_void_iface_call_ref_arg<int, ConsClass> (1, s2);
1538                 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1539                         return 4;
1540                 return 0;
1541         }
1542
1543         public static int test_0_constrained_eh () {
1544                 var s2 = new ConsStructThrow () { };
1545                 try {
1546                         IFaceConstrained c = new ClassConstrained ();
1547                         c.constrained_void_iface_call<int, ConsStructThrow> (1, s2);
1548                         return 1;
1549                 } catch (Exception) {
1550                         return 0;
1551                 }
1552         }
1553
1554         public static int test_0_constrained_void_iface_call_gsharedvt_arg () {
1555                 // This tests constrained calls through interfaces with one gsharedvt arg, like IComparable<T>.CompareTo ()
1556                 IFaceConstrained c = new ClassConstrained ();
1557
1558                 var s = new ConsStruct<int> ();
1559                 constrained_res = null;
1560                 c.constrained_void_iface_call_gsharedvt_arg<int, ConsStruct<int>, int> (42, s, 55);
1561                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1562                         return 1;
1563
1564                 var s2 = new ConsStruct<string> ();
1565                 constrained_res = null;
1566                 c.constrained_void_iface_call_gsharedvt_arg<string, ConsStruct<string>, int> ("A", s2, 55);
1567                 if (!(constrained_res is string) || ((string)constrained_res) != "A")
1568                         return 2;
1569
1570                 return 0;
1571         }
1572
1573         public static int test_0_constrained_iface_call_gsharedvt_ret () {
1574                 IFaceConstrained c = new ClassConstrained ();
1575
1576                 var s = new ConsStruct<int> ();
1577                 int ires = c.constrained_iface_call_gsharedvt_ret<int, ConsStruct<int>, int> (42, s, 55);
1578                 if (ires != 42)
1579                         return 1;
1580
1581                 var s2 = new ConsStruct<string> ();
1582                 string sres = c.constrained_iface_call_gsharedvt_ret<string, ConsStruct<string>, int> ("A", s2, 55);
1583                 if (sres != "A")
1584                         return 2;
1585
1586                 return 0;
1587         }
1588
1589         public static int test_0_constrained_normal_call () {
1590                 IFaceConstrained c = new ClassConstrained ();
1591
1592                 var o = new VClass ();
1593                 var res = c.constrained_normal_call<int, VClass> (1, o);
1594                 return res == o ? 0 : 1;
1595         }
1596
1597         public static async Task<T> FooAsync<T> (int i, int j) {
1598                 Task<int> t = new Task<int> (delegate () { return 42; });
1599                 var response = await t;
1600                 return default(T);
1601         }
1602
1603         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1604         public static void call_async<T> (int i, int j) {
1605                 Task<T> t = FooAsync<T> (1, 2);
1606                 // FIXME: This doesn't work
1607                 //t.RunSynchronously ();
1608         }
1609
1610         // In AOT mode, the async infrastructure depends on gsharedvt methods
1611         public static int test_0_async_call_from_generic () {
1612                 call_async<string> (1, 2);
1613                 return 0;
1614         }
1615
1616         public static int test_0_array_helper_gsharedvt () {
1617                 var arr = new AnEnum [16];
1618                 var c = new ReadOnlyCollection<AnEnum> (arr);
1619                 return c.Contains (AnEnum.Two) == false ? 0 : 1;
1620         }
1621
1622         interface IFaceCallPatching {
1623                 bool caller<T, T2> ();
1624         }
1625
1626         class CallPatching2<T> {
1627                 T t;
1628                 public object o;
1629
1630                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1631                 public bool callee () {
1632                         return (string)o == "ABC";
1633                 }
1634         }
1635
1636         class CallPatching : IFaceCallPatching {
1637                 public bool caller<T, T2> () {
1638                         var c = new CallPatching2<T> ();
1639                         c.o = "ABC";
1640                         return c.callee ();
1641                 }
1642         }
1643
1644         //
1645         // This tests that generic calls made from gsharedvt methods are not patched normally.
1646         // If they are, the first call to 'caller' would patch in the gshared version of
1647         // 'callee', causing the second call to fail because the gshared version of callee
1648         // wouldn't work with CallPatching2<bool> since it has a different object layout.
1649         //
1650         public static int test_0_call_patching () {
1651                 IFaceCallPatching c = new CallPatching ();
1652                 c.caller<object, bool> ();
1653                 if (!c.caller<bool, bool> ())
1654                         return 1;
1655                 return 0;
1656         }
1657
1658         struct EmptyStruct {
1659         }
1660
1661         public struct BStruct {
1662                 public int a, b, c, d;
1663         }
1664
1665         interface IFoo3<T> {
1666                 int Bytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1667                                    byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8);
1668                 int SBytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1669                                         sbyte b1, sbyte b2, sbyte b3, sbyte b4);
1670                 int Shorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1671                                         short b1, short b2, short b3, short b4);
1672                 int UShorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1673                                         ushort b1, ushort b2, ushort b3, ushort b4);
1674                 int Ints (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1675                                   int i1, int i2, int i3, int i4);
1676                 int UInts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1677                                    uint i1, uint i2, uint i3, uint i4);
1678                 int Structs (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1679                                          BStruct s);
1680                 void Generic<T2> (T t, T2[] arr, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1681                                                   T2 i1, T2 i2, T2 i3, T2 i4);
1682         }
1683
1684         class Foo3<T> : IFoo3<T> {
1685                 public int Bytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1686                                                   byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8) {
1687                         return b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8;
1688                 }
1689                 public int SBytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1690                                                   sbyte b1, sbyte b2, sbyte b3, sbyte b4) {
1691                         return b1 + b2 + b3 + b4;
1692                 }
1693                 public int Shorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1694                                                    short b1, short b2, short b3, short b4) {
1695                         return b1 + b2 + b3 + b4;
1696                 }
1697                 public int UShorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1698                                                         ushort b1, ushort b2, ushort b3, ushort b4) {
1699                         return b1 + b2 + b3 + b4;
1700                 }
1701                 public int Ints (T t, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8,
1702                                                    int i1, int i2, int i3, int i4) {
1703                         return i1 + i2 + i3 + i4;
1704                 }
1705                 public int UInts (T t, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8,
1706                                                   uint i1, uint i2, uint i3, uint i4) {
1707                         return (int)(i1 + i2 + i3 + i4);
1708                 }
1709                 public int Structs (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1710                                                         BStruct s) {
1711                         return s.a + s.b + s.c + s.d;
1712                 }
1713
1714                 public void Generic<T2> (T t, T2[] arr, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, T2 i1, T2 i2, T2 i3, T2 i4) {
1715                         arr [0] = i1;
1716                         arr [1] = i2;
1717                         arr [2] = i3;
1718                         arr [3] = i4;
1719                 }
1720         }
1721
1722         // Passing small normal arguments on the stack
1723         public static int test_0_arm64_small_stack_args () {
1724                 IFoo3<EmptyStruct> o = (IFoo3<EmptyStruct>)Activator.CreateInstance (typeof (Foo3<>).MakeGenericType (new Type [] { typeof (EmptyStruct) }));
1725                 int res = o.Bytes (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8);
1726                 if (res != 36)
1727                         return 1;
1728                 int res2 = o.SBytes (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1729                 if (res2 != -10)
1730                         return 2;
1731                 int res3 = o.Shorts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1732                 if (res3 != -10)
1733                         return 3;
1734                 int res4 = o.UShorts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
1735                 if (res4 != 10)
1736                         return 4;
1737                 int res5 = o.Ints (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1738                 if (res5 != -10)
1739                         return 5;
1740                 int res6 = o.UInts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
1741                 if (res6 != 10)
1742                         return 6;
1743                 int[] arr = new int [4];
1744                 o.Generic<int> (new EmptyStruct (), arr, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
1745                 if (arr [0] != 1 || arr [1] != 2 || arr [2] != 3 || arr [3] != 4)
1746                         return 7;
1747                 return 0;
1748         }
1749
1750         interface ISmallArg {
1751                 T foo<T> (string s1, string s2, string s3, string s4, string s5, string s6, string s7, string s8,
1752                                   string s9, string s10, string s11, string s12, string s13, T t);
1753         }
1754
1755         class SmallArgClass : ISmallArg {
1756                         public T foo<T> (string s1, string s2, string s3, string s4, string s5, string s6, string s7, string s8,
1757                                                          string s9, string s10, string s11, string s12, string s13, T t) {
1758                                 return t;
1759                         }
1760                 }
1761
1762         public static int test_1_small_gsharedvt_stack_arg_ios () {
1763                 ISmallArg o = new SmallArgClass ();
1764                 return o.foo<int> ("", "", "", "", "", "", "", "", "", "", "", "", "", 1);
1765         }
1766
1767         // Passing vtype normal arguments on the stack
1768         public static int test_0_arm64_vtype_stack_args () {
1769                 IFoo3<EmptyStruct> o = (IFoo3<EmptyStruct>)Activator.CreateInstance (typeof (Foo3<>).MakeGenericType (new Type [] { typeof (EmptyStruct) }));
1770                 int res = o.Structs (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, new BStruct () { a = 1, b = 2, c = 3, d = 4 });
1771                 if (res != 10)
1772                         return 1;
1773                 return 0;
1774         }
1775
1776         interface IFoo4<T> {
1777                 T Get(T[,] arr, T t);
1778         }
1779
1780         class Foo4<T> : IFoo4<T> {
1781                 public T Get(T[,] arr, T t) {
1782                         arr [1, 1] = t;
1783                         return arr [1, 1];
1784                 }
1785         }
1786
1787         struct AStruct {
1788                 public int a, b;
1789         }
1790
1791         public static int test_0_multi_dim_arrays_2 () {
1792                 IFoo4<int> foo = new Foo4<int> ();
1793                 var arr = new int [10, 10];
1794                 int res = foo.Get (arr, 10);
1795                 if (res != 10)
1796                         return 1;
1797
1798                 IFoo4<AStruct> foo2 = new Foo4<AStruct> ();
1799                 var arr2 = new AStruct [10, 10];
1800                 var res2 = foo2.Get (arr2, new AStruct () { a = 1, b = 2 });
1801                 if (res2.a != 1 || res2.b != 2)
1802                         return 2;
1803                 return 0;
1804         }
1805
1806         public interface IFaceTest {
1807                 int iface_method ();
1808         }
1809
1810         public interface IFaceConstrainedIFace {
1811                 int foo<T, T2> (ref T val) where T: IFaceTest;
1812         }
1813
1814         class ConstrainedIFace : IFaceConstrainedIFace {
1815                 public int foo<T, T2> (ref T val) where T: IFaceTest {
1816                         return val.iface_method ();
1817                 }
1818         }
1819
1820         class ClassTest : IFaceTest {
1821                 public int iface_method () {
1822                         return 42;
1823                 }
1824         }
1825
1826         struct StructTest : IFaceTest {
1827
1828                 int i;
1829
1830                 public StructTest (int arg) {
1831                         i = arg;
1832                 }
1833
1834                 public int iface_method () {
1835                         return i;
1836                 }
1837         }
1838
1839         // Test constrained calls on an interface made from gsharedvt methods
1840         public static int test_42_gsharedvt_constrained_iface () {
1841                 IFaceConstrainedIFace obj = new ConstrainedIFace ();
1842                 IFaceTest t = new ClassTest ();
1843                 return obj.foo<IFaceTest, int> (ref t);
1844         }
1845
1846         public static int test_42_gsharedvt_constrained_iface_vtype () {
1847                 IFaceConstrainedIFace obj = new ConstrainedIFace ();
1848                 IFaceTest t = new StructTest (42);
1849                 return obj.foo<IFaceTest, int> (ref t);
1850         }
1851
1852         // Sign extension tests
1853         // 0x55   == 85    == 01010101
1854         // 0xAA   == 170   == 10101010
1855         // 0x5555 == 21845 == 0101010101010101
1856         // 0xAAAA == 43690 == 1010101010101010
1857         // 0x55555555 == 1431655765
1858         // 0xAAAAAAAA == 2863311530
1859         // 0x5555555555555555 == 6148914691236517205
1860         // 0xAAAAAAAAAAAAAAAA == 12297829382473034410
1861
1862         public interface SEFace<T> {
1863                 T Copy (int a, int b, int c, int d, T t);
1864         }
1865
1866         class SEClass<T> : SEFace<T> {
1867                 public T Copy (int a, int b, int c, int d, T t) {
1868                         return t;
1869                 }
1870         }
1871
1872         // Test extension
1873         static int test_20_signextension_sbyte () {
1874                 Type t = typeof (sbyte);
1875                 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
1876                 var i = (SEFace<sbyte>)o;
1877
1878                 long zz = i.Copy (1,2,3,4,(sbyte)(-0x55));
1879
1880                 bool success = zz == -0x55;
1881                 return success ? 20 : 1;
1882         }
1883
1884         static int test_20_signextension_byte () {
1885                 Type t = typeof (byte);
1886                 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
1887                 var i = (SEFace<byte>)o;
1888
1889                 ulong zz = i.Copy (1,2,3,4,(byte)(0xAA));
1890
1891                 bool success = zz == 0xAA;
1892                 return success ? 20 : 1;
1893         }
1894
1895         static int test_20_signextension_short () {
1896                 Type t = typeof (short);
1897                 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
1898                 var i = (SEFace<short>)o;
1899
1900                 long zz = i.Copy (1,2,3,4,(short)(-0x5555));
1901
1902                 bool success = zz == -0x5555;
1903                 return success ? 20 : 1;
1904         }
1905
1906         static int test_20_signextension_ushort () {
1907                 Type t = typeof (ushort);
1908                 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
1909                 var i = (SEFace<ushort>)o;
1910
1911                 ulong zz = i.Copy (1,2,3,4,(ushort)(0xAAAA));
1912
1913                 bool success = zz == 0xAAAA;
1914                 return success ? 20 : 1;
1915         }
1916
1917         static int test_20_signextension_int () {
1918                 Type t = typeof (int);
1919                 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
1920                 var i = (SEFace<int>)o;
1921
1922                 long zz = i.Copy (1,2,3,4,(int)(-0x55555555));
1923
1924                 bool success = zz == -0x55555555;
1925                 return success ? 20 : 1;
1926         }
1927
1928         static int test_20_signextension_uint () {
1929                 Type t = typeof (uint);
1930                 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
1931                 var i = (SEFace<uint>)o;
1932
1933                 ulong zz = i.Copy (1,2,3,4,(uint)(0xAAAAAAAA));
1934
1935                 bool success = zz == 0xAAAAAAAA;
1936                 return success ? 20 : 1;
1937         }
1938
1939         static int test_20_signextension_long () {
1940                 Type t = typeof (long);
1941                 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
1942                 var i = (SEFace<long>)o;
1943
1944                 long zz = i.Copy (1,2,3,4,(long)(-0x5555555555555555));
1945
1946                 bool success = zz == -0x5555555555555555;
1947                 return success ? 20 : 1;
1948         }
1949
1950         static int test_20_signextension_ulong () {
1951                 Type t = typeof (ulong);
1952                 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
1953                 var i = (SEFace<ulong>)o;
1954
1955                 ulong zz = i.Copy (1,2,3,4,(ulong)(0xAAAAAAAAAAAAAAAA));
1956
1957                 bool success = zz == 0xAAAAAAAAAAAAAAAA;
1958                 return success ? 20 : 1;
1959         }
1960
1961         void gsharedvt_try_at_offset_0<T> (ref T disposable)
1962                 where T : class, IDisposable {
1963                         try {
1964                                 disposable.Dispose ();
1965                         } finally {
1966                                 disposable = null;
1967                         }
1968                 }
1969
1970         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1971         static DateTimeOffset gsharedvt_vphi_inner<T> (T t) {
1972                 return DateTimeOffset.MinValue;
1973         }
1974
1975         static DateTimeOffset gsharedvt_vphi<T> (T t) {
1976                 int[] arr = new int [10];
1977
1978                 try {
1979                         DateTimeOffset v;
1980                         if (arr [0] == 0)
1981                                 v = gsharedvt_vphi_inner (t);
1982                         else
1983                                 v = gsharedvt_vphi_inner (t);
1984                         return v;
1985                 } catch {
1986                         return DateTimeOffset.MinValue;
1987                 }
1988         }
1989
1990         static int test_0_gsharedvt_vphi_volatile () {
1991                 gsharedvt_vphi (0);
1992                 return 0;
1993         }
1994
1995         struct AStruct3<T1, T2, T3> {
1996                 T1 t1;
1997                 T2 t2;
1998                 T3 t3;
1999         }
2000
2001         interface IFaceIsRef {
2002                 bool is_ref<T> ();
2003         }
2004
2005         class ClassIsRef : IFaceIsRef {
2006                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
2007                 public bool is_ref<T> () {
2008                         return RuntimeHelpers.IsReferenceOrContainsReferences<T> ();
2009                 }
2010         }
2011
2012         public static int test_0_isreference_intrins () {
2013                 IFaceIsRef iface = new ClassIsRef ();
2014                 if (iface.is_ref<AStruct3<int, int, int>> ())
2015                         return 1;
2016                 if (!iface.is_ref<AStruct3<string, int, int>> ())
2017                         return 2;
2018                 return 0;
2019         }
2020 }
2021
2022 // #13191
2023 public class MobileServiceCollection<TTable, TCol>
2024 {
2025         public async Task<int> LoadMoreItemsAsync(int count = 0) {
2026                 await Task.Delay (1000);
2027                 int results = await ProcessQueryAsync ();
2028                 return results;
2029         }
2030
2031         protected async virtual Task<int> ProcessQueryAsync() {
2032                 await Task.Delay (1000);
2033                 throw new Exception ();
2034         }
2035 }
2036
2037 #if !__MOBILE__
2038 public class GSharedTests : Tests {
2039 }
2040 #endif