[mips] Disable div with mul on 32bit mips
[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         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         }
1110
1111         public interface IReturnVType {
1112                 Pair<int, int> return_vtype ();
1113         }
1114
1115         public class CConstrainedCalls : IConstrainedCalls {
1116                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1117                 public Pair<int, int> vtype_ret<T, T2>(T t, T2 t2) where T : IReturnVType {
1118                         return t.return_vtype ();
1119                 }
1120         }
1121
1122         class ReturnVType : IReturnVType {
1123                 public Pair<int, int> return_vtype () {
1124                         return new Pair<int, int> () { First = 1, Second = 2 };
1125                 }
1126         }
1127
1128         public static int test_0_constrained_vtype_ret () {
1129                 IConstrainedCalls c = new CConstrainedCalls ();
1130                 var r = c.vtype_ret<ReturnVType, int> (new ReturnVType (), 1);
1131                 if (r.First != 1 || r.Second != 2)
1132                         return 1;
1133                 return 0;
1134         }
1135
1136         public struct Pair<T1, T2> {
1137                 public T1 First;
1138                 public T2 Second;
1139         }
1140
1141         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1142         public static TState call_del<TState>(TState state, Func<object, TState, TState> action) {
1143                 return action(null, state);
1144         }
1145
1146         [Category ("!FULLAOT")]
1147         public static int test_0_delegate_wrappers () {
1148                 Func<object, Pair<int, int>, Pair<int, int>> del1 = delegate (object o, Pair<int, int> p) { return p; };
1149                 Func<object, Pair<int, int>, Pair<int, int>> del2 = delegate (object o, Pair<int, int> p) { return p; };
1150                 Func<object, Pair<double, int>, Pair<double, int>> del3 = delegate (object o, Pair<double, int> p) { return p; };
1151                 var r1 = call_del<Pair<int, int>> (new Pair<int, int> { First = 1, Second = 2}, del1);
1152                 if (r1.First != 1 || r1.Second != 2)
1153                         return 1;
1154                 var r2 = call_del<Pair<int, int>> (new Pair<int, int> { First = 3, Second = 4}, del2);
1155                 if (r2.First != 3 || r2.Second != 4)
1156                         return 2;
1157                 var r3 = call_del<Pair<double, int>> (new Pair<double, int> { First = 1.0, Second = 2}, del3);
1158                 if (r3.First != 1.0 || r3.Second != 2)
1159                         return 3;
1160                 return 0;
1161         }
1162
1163         class Base<T> {
1164                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1165                 public object foo<T1> (T1 t1, T t, object o) {
1166                         return o;
1167                 }
1168         }
1169
1170         class AClass : Base<long> {
1171
1172                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1173                 public object bar<T> (T t, long time, object o) {
1174                         return foo (t, time, o);
1175                 }
1176         }
1177
1178         public static int test_0_out_in_wrappers () {
1179                 var a = new AClass ();
1180                 object o1 = "A";
1181                 object o2 = a.bar<long> (1024, 0, o1);
1182                 if (o1 != o2)
1183                         return 1;
1184                 return 0;               
1185         }
1186
1187                 interface BIFace {
1188                         object AMethod ();
1189                 }
1190
1191                 class Base<TAbsolute, T2> : BIFace {
1192
1193                         public TAbsolute Clock { get; set; }
1194
1195                         public virtual object AMethod () {
1196                                 return Clock;
1197                         }
1198                 }
1199
1200                 class BClass : Base<long, long> {
1201                 }
1202
1203         public static int test_0_regress_1 () {
1204                 BIFace c = new BClass ();
1205                 object o = c.AMethod ();
1206                 if (!(o is long) || ((long)o != 0))
1207                         return 1;
1208                 return 0;
1209         }
1210
1211         interface IFace3 {
1212                 T unbox_any<T> (object o);
1213         }
1214
1215         class Class3 : IFace3 {
1216                 public virtual T unbox_any<T> (object o) {
1217                         return (T)o;
1218                 }
1219         }
1220
1221         public static int test_0_unbox_any () {
1222                 IFace3 o = new Class3 ();
1223                 if (o.unbox_any<int> (16) != 16)
1224                         return 1;
1225                 if (o.unbox_any<long> ((long)32) != 32)
1226                         return 2;
1227                 if (o.unbox_any<double> (2.0) != 2.0)
1228                         return 3;
1229                 try {
1230                         o.unbox_any<int> (2.0);
1231                         return 4;
1232                 } catch (Exception) {
1233                 }
1234                 return 0;
1235         }
1236
1237         interface IFace4 {
1238                 TSource Catch<TSource, TException>(TSource t)  where TException : Exception;
1239         }
1240
1241         class Class4 : IFace4 {
1242                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1243                         public TSource Catch<TSource, TException>(TSource t)  where TException : Exception {
1244                         return t;
1245                 }
1246         }
1247
1248         // Check that mixed instantiations are correctly created/found in AOT
1249         public static int test_0_constraints () {
1250                 IFace4 o = new Class4 ();
1251                 o.Catch<int, Exception> (1);
1252                 return 0;
1253         }
1254
1255         internal static Type Process<TSource, TElement> (TSource[] arr, Action<TElement, TElement> call) {
1256                 arr [0] = default (TSource);
1257                 return typeof (TSource);
1258         }
1259
1260         interface IFace5 {
1261                 Type foo<T> ();
1262         }
1263
1264         class Class5 : IFace5 {
1265                 public Type foo<T> () {
1266                         return Process<KeyValuePair<long, T>, T> (new KeyValuePair<long, T> [10], null);
1267                 }
1268         }
1269
1270         public static int test_0_rgctx_call_from_gshared_code () {
1271                 var c = new Class5 ();
1272                 if (c.foo<string> () != typeof (KeyValuePair<long, string>))
1273                         return 1;
1274                 return 0;
1275         }
1276
1277         public class Enumbers<T> {
1278                 public object Enumerate (List<KeyValuePair<T, string>> alist)
1279                 {
1280                         return alist.ToArray ();
1281                 }
1282         }
1283
1284         public static int test_0_checkthis_gshared_call () {
1285                 Enumbers<string> e = new Enumbers<string> ();
1286                 try {
1287                         e.Enumerate (null);
1288                         return 1;
1289                 }
1290                 catch (NullReferenceException) {
1291                 }
1292                 return 0;
1293         }
1294
1295         interface IFace6 {
1296                 T[] Del<T> (T t);
1297         }
1298
1299         class Class6 : IFace6 {
1300                 public T[] Del<T> (T t) {
1301                         var res = new T [5];
1302                         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; };
1303                         var v = func.BeginInvoke(t, t, t, t, null, null);
1304                         res [4] = func.EndInvoke (v);
1305                         return res;
1306                 }
1307         }
1308
1309         // FIXME: The runtime-invoke wrapper used by BeginInvoke is not found
1310         [Category ("!FULLAOT")]
1311         public static int test_0_begin_end_invoke () {
1312                 IFace6 o = new Class6 ();
1313                 var arr1 = o.Del (1);
1314                 if (arr1 [0] != 1 || arr1 [1] != 1 || arr1 [2] != 1 || arr1 [3] != 1 || arr1 [4] != 1)
1315                         return 1;
1316                 var arr2 = o.Del (2.0);
1317                 if (arr2 [0] != 2.0 || arr2 [1] != 2.0 || arr2 [2] != 2.0 || arr2 [3] != 2.0 || arr2 [4] != 2.0)
1318                         return 2;
1319                 return 0;
1320         }
1321
1322         public class TAbstractTableItem<TC> {
1323                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1324                 public static void SetProperty<TV> () {    }
1325
1326                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1327                 public static void Test () {
1328                         SetProperty<bool> ();
1329                 }
1330         }
1331
1332         public static int test_0_gsharedvt_method_on_shared_class () {
1333        TAbstractTableItem<object>.Test ();
1334            return 0;
1335         }
1336
1337         interface IFaceBox {
1338                 object box<T> (T t);
1339                 bool is_null<T> (T t);
1340         }
1341
1342         class ClassBox : IFaceBox {
1343                 public object box<T> (T t) {
1344                         object o = t;
1345                         return o;
1346                 }
1347
1348                 public bool is_null<T> (T t) {
1349                         if (!(default(T) == null))
1350                                 return false;
1351                         return true;
1352                 }
1353         }
1354
1355         public static int test_0_nullable_box () {
1356                 IFaceBox c = new ClassBox ();
1357                 int i = 5;
1358                 object o = c.box<int?> (i);
1359                 if ((int)o != i)
1360                         return 1;
1361                 if (c.box<int?> (null) != null)
1362                         return 2;
1363                 long l = Int64.MaxValue - 1;
1364                 o = c.box<long?> (l);
1365                 if ((long)o != l)
1366                         return 3;
1367                 if (c.box<long?> (null) != null)
1368                         return 4;
1369                 string s = "A";
1370                 if (c.box<string> (s) != (object)s)
1371                         return 5;
1372                 return 0;
1373         }
1374
1375         public static int test_0_nullable_box_brtrue_opt () {
1376                 IFaceBox c = new ClassBox ();
1377
1378                 if (c.is_null<double?> (null))
1379                         return 0;
1380                 else
1381                         return 1;
1382         }
1383
1384         interface IFaceUnbox2 {
1385                 T unbox<T> (object o);
1386         }
1387
1388         class ClassUnbox2 : IFaceUnbox2 {
1389                 public T unbox<T> (object o) {
1390                         return (T)o;
1391                 }
1392         }
1393
1394         public static int test_0_nullable_unbox () {    
1395                 IFaceUnbox2 c = new ClassUnbox2 ();
1396                 int? i = c.unbox<int?> (5);
1397                 if (i != 5)
1398                         return 1;
1399                 int? j = c.unbox<int?> (null);
1400                 if (j != null)
1401                         return 2;
1402                 return 0;
1403         }
1404
1405         interface IConstrained {
1406                 void foo ();
1407                 void foo_ref_arg (string s);
1408         }
1409
1410         interface IConstrained<T3> {
1411                 void foo_gsharedvt_arg (T3 s);
1412                 T3 foo_gsharedvt_ret (T3 s);
1413         }
1414
1415         static object constrained_res;
1416
1417         struct ConsStruct : IConstrained {
1418                 public int i;
1419
1420                 public void foo () {
1421                         constrained_res = i;
1422                 }
1423
1424                 public void foo_ref_arg (string s) {
1425                         constrained_res = s == "A" ? 42 : 0;
1426                 }
1427         }
1428
1429         class ConsClass : IConstrained {
1430                 public int i;
1431
1432                 public void foo () {
1433                         constrained_res = i;
1434                 }
1435
1436                 public void foo_ref_arg (string s) {
1437                         constrained_res = s == "A" ? 43 : 0;
1438                 }
1439         }
1440
1441         struct ConsStruct<T> : IConstrained<T> {
1442                 public void foo_gsharedvt_arg (T s) {
1443                         constrained_res = s;
1444                 }
1445
1446                 public T foo_gsharedvt_ret (T s) {
1447                         return s;
1448                 }
1449         }
1450
1451         struct ConsStructThrow : IConstrained {
1452                 public void foo () {
1453                         throw new Exception ();
1454                 }
1455
1456                 public void foo_ref_arg (string s) {
1457                 }
1458         }
1459
1460         interface IFaceConstrained {
1461                 void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained;
1462                 void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained;
1463                 void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1464                 T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1465                 T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass;
1466         }
1467
1468         class ClassConstrained : IFaceConstrained {
1469                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1470                 public void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained {
1471                         t2.foo ();
1472                 }
1473
1474                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1475                 public void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained {
1476                         t2.foo_ref_arg ("A");
1477                 }
1478
1479                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1480                 public void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1481                         t2.foo_gsharedvt_arg (t);
1482                 }
1483
1484                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1485                 public T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1486                         return t2.foo_gsharedvt_ret (t);
1487                 }
1488
1489                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1490                 public T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass {
1491                         /* This becomes a constrained call even through 't2' is forced to be a reference type by the constraint */
1492                         return (T2)t2.foo (5);
1493                 }
1494         }
1495
1496         class VClass {
1497                 public virtual VClass foo (int i) {
1498                         return this;
1499                 }
1500         }
1501
1502         public static int test_0_constrained_void_iface_call () {
1503                 IFaceConstrained c = new ClassConstrained ();
1504                 var s = new ConsStruct () { i = 42 };
1505                 constrained_res = null;
1506                 c.constrained_void_iface_call<int, ConsStruct> (1, s);
1507                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1508                         return 1;
1509                 constrained_res = null;
1510                 c.constrained_void_iface_call_ref_arg<int, ConsStruct> (1, s);
1511                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1512                         return 2;
1513                 var s2 = new ConsClass () { i = 43 };
1514                 constrained_res = null;
1515                 c.constrained_void_iface_call<int, ConsClass> (1, s2);
1516                 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1517                         return 3;
1518                 constrained_res = null;
1519                 c.constrained_void_iface_call_ref_arg<int, ConsClass> (1, s2);
1520                 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1521                         return 4;
1522                 return 0;
1523         }
1524
1525         public static int test_0_constrained_eh () {
1526                 var s2 = new ConsStructThrow () { };
1527                 try {
1528                         IFaceConstrained c = new ClassConstrained ();
1529                         c.constrained_void_iface_call<int, ConsStructThrow> (1, s2);
1530                         return 1;
1531                 } catch (Exception) {
1532                         return 0;
1533                 }
1534         }
1535
1536         public static int test_0_constrained_void_iface_call_gsharedvt_arg () {
1537                 // This tests constrained calls through interfaces with one gsharedvt arg, like IComparable<T>.CompareTo ()
1538                 IFaceConstrained c = new ClassConstrained ();
1539
1540                 var s = new ConsStruct<int> ();
1541                 constrained_res = null;
1542                 c.constrained_void_iface_call_gsharedvt_arg<int, ConsStruct<int>, int> (42, s, 55);
1543                 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1544                         return 1;
1545
1546                 var s2 = new ConsStruct<string> ();
1547                 constrained_res = null;
1548                 c.constrained_void_iface_call_gsharedvt_arg<string, ConsStruct<string>, int> ("A", s2, 55);
1549                 if (!(constrained_res is string) || ((string)constrained_res) != "A")
1550                         return 2;
1551
1552                 return 0;
1553         }
1554
1555         public static int test_0_constrained_iface_call_gsharedvt_ret () {
1556                 IFaceConstrained c = new ClassConstrained ();
1557
1558                 var s = new ConsStruct<int> ();
1559                 int ires = c.constrained_iface_call_gsharedvt_ret<int, ConsStruct<int>, int> (42, s, 55);
1560                 if (ires != 42)
1561                         return 1;
1562
1563                 var s2 = new ConsStruct<string> ();
1564                 string sres = c.constrained_iface_call_gsharedvt_ret<string, ConsStruct<string>, int> ("A", s2, 55);
1565                 if (sres != "A")
1566                         return 2;
1567
1568                 return 0;
1569         }
1570
1571         public static int test_0_constrained_normal_call () {
1572                 IFaceConstrained c = new ClassConstrained ();
1573
1574                 var o = new VClass ();
1575                 var res = c.constrained_normal_call<int, VClass> (1, o);
1576                 return res == o ? 0 : 1;
1577         }
1578
1579         public static async Task<T> FooAsync<T> (int i, int j) {
1580                 Task<int> t = new Task<int> (delegate () { return 42; });
1581                 var response = await t;
1582                 return default(T);
1583         }
1584
1585         [MethodImplAttribute (MethodImplOptions.NoInlining)]
1586         public static void call_async<T> (int i, int j) {
1587                 Task<T> t = FooAsync<T> (1, 2);
1588                 // FIXME: This doesn't work
1589                 //t.RunSynchronously ();
1590         }
1591
1592         // In AOT mode, the async infrastructure depends on gsharedvt methods
1593         public static int test_0_async_call_from_generic () {
1594                 call_async<string> (1, 2);
1595                 return 0;
1596         }
1597
1598         public static int test_0_array_helper_gsharedvt () {
1599                 var arr = new AnEnum [16];
1600                 var c = new ReadOnlyCollection<AnEnum> (arr);
1601                 return c.Contains (AnEnum.Two) == false ? 0 : 1;
1602         }
1603
1604         interface IFaceCallPatching {
1605                 bool caller<T, T2> ();
1606         }
1607
1608         class CallPatching2<T> {
1609                 T t;
1610                 public object o;
1611
1612                 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1613                 public bool callee () {
1614                         return (string)o == "ABC";
1615                 }
1616         }
1617
1618         class CallPatching : IFaceCallPatching {
1619                 public bool caller<T, T2> () {
1620                         var c = new CallPatching2<T> ();
1621                         c.o = "ABC";
1622                         return c.callee ();
1623                 }
1624         }
1625
1626         //
1627         // This tests that generic calls made from gsharedvt methods are not patched normally.
1628         // If they are, the first call to 'caller' would patch in the gshared version of
1629         // 'callee', causing the second call to fail because the gshared version of callee
1630         // wouldn't work with CallPatching2<bool> since it has a different object layout.
1631         //
1632         public static int test_0_call_patching () {
1633                 IFaceCallPatching c = new CallPatching ();
1634                 c.caller<object, bool> ();
1635                 if (!c.caller<bool, bool> ())
1636                         return 1;
1637                 return 0;
1638         }
1639
1640         struct EmptyStruct {
1641         }
1642
1643         public struct BStruct {
1644                 public int a, b, c, d;
1645         }
1646
1647         interface IFoo3<T> {
1648                 int Bytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1649                                    byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8);
1650                 int SBytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1651                                         sbyte b1, sbyte b2, sbyte b3, sbyte b4);
1652                 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                 int UShorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1655                                         ushort b1, ushort b2, ushort b3, ushort b4);
1656                 int Ints (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1657                                   int i1, int i2, int i3, int i4);
1658                 int UInts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1659                                    uint i1, uint i2, uint i3, uint i4);
1660                 int Structs (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1661                                          BStruct s);
1662         }
1663
1664         class Foo3<T> : IFoo3<T> {
1665                 public int Bytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1666                                                   byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8) {
1667                         return b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8;
1668                 }
1669                 public int SBytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1670                                                   sbyte b1, sbyte b2, sbyte b3, sbyte b4) {
1671                         return b1 + b2 + b3 + b4;
1672                 }
1673                 public int Shorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1674                                                    short b1, short b2, short b3, short b4) {
1675                         return b1 + b2 + b3 + b4;
1676                 }
1677                 public int UShorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1678                                                         ushort b1, ushort b2, ushort b3, ushort b4) {
1679                         return b1 + b2 + b3 + b4;
1680                 }
1681                 public int Ints (T t, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8,
1682                                                    int i1, int i2, int i3, int i4) {
1683                         return i1 + i2 + i3 + i4;
1684                 }
1685                 public int UInts (T t, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8,
1686                                                   uint i1, uint i2, uint i3, uint i4) {
1687                         return (int)(i1 + i2 + i3 + i4);
1688                 }
1689                 public int Structs (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1690                                                         BStruct s) {
1691                         return s.a + s.b + s.c + s.d;
1692                 }
1693         }
1694
1695         // Passing small normal arguments on the stack
1696         public static int test_0_arm64_small_stack_args () {
1697                 IFoo3<EmptyStruct> o = (IFoo3<EmptyStruct>)Activator.CreateInstance (typeof (Foo3<>).MakeGenericType (new Type [] { typeof (EmptyStruct) }));
1698                 int res = o.Bytes (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8);
1699                 if (res != 36)
1700                         return 1;
1701                 int res2 = o.SBytes (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1702                 if (res2 != -10)
1703                         return 2;
1704                 int res3 = o.Shorts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1705                 if (res3 != -10)
1706                         return 3;
1707                 int res4 = o.UShorts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
1708                 if (res4 != 10)
1709                         return 4;
1710                 int res5 = o.Ints (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1711                 if (res5 != -10)
1712                         return 5;
1713                 int res6 = o.UInts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
1714                 if (res6 != 10)
1715                         return 6;
1716                 return 0;
1717         }
1718
1719         interface ISmallArg {
1720                 T foo<T> (string s1, string s2, string s3, string s4, string s5, string s6, string s7, string s8,
1721                                   string s9, string s10, string s11, string s12, string s13, T t);
1722         }
1723
1724         class SmallArgClass : ISmallArg {
1725                         public T foo<T> (string s1, string s2, string s3, string s4, string s5, string s6, string s7, string s8,
1726                                                          string s9, string s10, string s11, string s12, string s13, T t) {
1727                                 return t;
1728                         }
1729                 }
1730
1731         public static int test_1_small_gsharedvt_stack_arg_ios () {
1732                 ISmallArg o = new SmallArgClass ();
1733                 return o.foo<int> ("", "", "", "", "", "", "", "", "", "", "", "", "", 1);
1734         }
1735
1736         // Passing vtype normal arguments on the stack
1737         public static int test_0_arm64_vtype_stack_args () {
1738                 IFoo3<EmptyStruct> o = (IFoo3<EmptyStruct>)Activator.CreateInstance (typeof (Foo3<>).MakeGenericType (new Type [] { typeof (EmptyStruct) }));
1739                 int res = o.Structs (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, new BStruct () { a = 1, b = 2, c = 3, d = 4 });
1740                 if (res != 10)
1741                         return 1;
1742                 return 0;
1743         }
1744
1745         interface IFoo4<T> {
1746                 T Get(T[,] arr, T t);
1747         }
1748
1749         class Foo4<T> : IFoo4<T> {
1750                 public T Get(T[,] arr, T t) {
1751                         arr [1, 1] = t;
1752                         return arr [1, 1];
1753                 }
1754         }
1755
1756         struct AStruct {
1757                 public int a, b;
1758         }
1759
1760         public static int test_0_multi_dim_arrays_2 () {
1761                 IFoo4<int> foo = new Foo4<int> ();
1762                 var arr = new int [10, 10];
1763                 int res = foo.Get (arr, 10);
1764                 if (res != 10)
1765                         return 1;
1766
1767                 IFoo4<AStruct> foo2 = new Foo4<AStruct> ();
1768                 var arr2 = new AStruct [10, 10];
1769                 var res2 = foo2.Get (arr2, new AStruct () { a = 1, b = 2 });
1770                 if (res2.a != 1 || res2.b != 2)
1771                         return 2;
1772                 return 0;
1773         }
1774
1775         public interface IFaceTest {
1776                 int iface_method ();
1777         }
1778
1779         public interface IFaceConstrainedIFace {
1780                 int foo<T, T2> (ref T val) where T: IFaceTest;
1781         }
1782
1783         class ConstrainedIFace : IFaceConstrainedIFace {
1784                 public int foo<T, T2> (ref T val) where T: IFaceTest {
1785                         return val.iface_method ();
1786                 }
1787         }
1788
1789         class ClassTest : IFaceTest {
1790                 public int iface_method () {
1791                         return 42;
1792                 }
1793         }
1794
1795         // Test constrained calls on an interface made from gsharedvt methods
1796         public static int test_42_gsharedvt_constrained_iface () {
1797                 IFaceConstrainedIFace obj = new ConstrainedIFace ();
1798                 IFaceTest t = new ClassTest ();
1799                 return obj.foo<IFaceTest, int> (ref t);
1800         }
1801
1802         // Sign extension tests
1803         // 0x55   == 85    == 01010101
1804         // 0xAA   == 170   == 10101010
1805         // 0x5555 == 21845 == 0101010101010101
1806         // 0xAAAA == 43690 == 1010101010101010
1807         // 0x55555555 == 1431655765
1808         // 0xAAAAAAAA == 2863311530
1809         // 0x5555555555555555 == 6148914691236517205
1810         // 0xAAAAAAAAAAAAAAAA == 12297829382473034410
1811
1812         public interface SEFace<T> {
1813                 T Copy (int a, int b, int c, int d, T t);
1814         }
1815
1816         class SEClass<T> : SEFace<T> {
1817                 public T Copy (int a, int b, int c, int d, T t) {
1818                         return t;
1819                 }
1820         }
1821
1822         // Test extension
1823         static int test_20_signextension_sbyte () {
1824                 Type t = typeof (sbyte);
1825                 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
1826                 var i = (SEFace<sbyte>)o;
1827
1828                 long zz = i.Copy (1,2,3,4,(sbyte)(-0x55));
1829
1830                 bool success = zz == -0x55;
1831                 return success ? 20 : 1;
1832         }
1833
1834         static int test_20_signextension_byte () {
1835                 Type t = typeof (byte);
1836                 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
1837                 var i = (SEFace<byte>)o;
1838
1839                 ulong zz = i.Copy (1,2,3,4,(byte)(0xAA));
1840
1841                 bool success = zz == 0xAA;
1842                 return success ? 20 : 1;
1843         }
1844
1845         static int test_20_signextension_short () {
1846                 Type t = typeof (short);
1847                 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
1848                 var i = (SEFace<short>)o;
1849
1850                 long zz = i.Copy (1,2,3,4,(short)(-0x5555));
1851
1852                 bool success = zz == -0x5555;
1853                 return success ? 20 : 1;
1854         }
1855
1856         static int test_20_signextension_ushort () {
1857                 Type t = typeof (ushort);
1858                 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
1859                 var i = (SEFace<ushort>)o;
1860
1861                 ulong zz = i.Copy (1,2,3,4,(ushort)(0xAAAA));
1862
1863                 bool success = zz == 0xAAAA;
1864                 return success ? 20 : 1;
1865         }
1866
1867         static int test_20_signextension_int () {
1868                 Type t = typeof (int);
1869                 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
1870                 var i = (SEFace<int>)o;
1871
1872                 long zz = i.Copy (1,2,3,4,(int)(-0x55555555));
1873
1874                 bool success = zz == -0x55555555;
1875                 return success ? 20 : 1;
1876         }
1877
1878         static int test_20_signextension_uint () {
1879                 Type t = typeof (uint);
1880                 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
1881                 var i = (SEFace<uint>)o;
1882
1883                 ulong zz = i.Copy (1,2,3,4,(uint)(0xAAAAAAAA));
1884
1885                 bool success = zz == 0xAAAAAAAA;
1886                 return success ? 20 : 1;
1887         }
1888
1889         static int test_20_signextension_long () {
1890                 Type t = typeof (long);
1891                 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
1892                 var i = (SEFace<long>)o;
1893
1894                 long zz = i.Copy (1,2,3,4,(long)(-0x5555555555555555));
1895
1896                 bool success = zz == -0x5555555555555555;
1897                 return success ? 20 : 1;
1898         }
1899
1900         static int test_20_signextension_ulong () {
1901                 Type t = typeof (ulong);
1902                 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
1903                 var i = (SEFace<ulong>)o;
1904
1905                 ulong zz = i.Copy (1,2,3,4,(ulong)(0xAAAAAAAAAAAAAAAA));
1906
1907                 bool success = zz == 0xAAAAAAAAAAAAAAAA;
1908                 return success ? 20 : 1;
1909         }
1910 }
1911
1912 // #13191
1913 public class MobileServiceCollection<TTable, TCol>
1914 {
1915         public async Task<int> LoadMoreItemsAsync(int count = 0) {
1916                 await Task.Delay (1000);
1917                 int results = await ProcessQueryAsync ();
1918                 return results;
1919         }
1920
1921         protected async virtual Task<int> ProcessQueryAsync() {
1922                 await Task.Delay (1000);
1923                 throw new Exception ();
1924         }
1925 }
1926
1927 #if !__MOBILE__
1928 public class GSharedTests : Tests {
1929 }
1930 #endif