[2019-12] [jit] Avoid passing a vtable argument to DIM methods when making calls...
[mono-project.git] / mono / mini / gshared.cs
blob7dffba3769aace1070ba7c2d851cc5e4da29f6a8
1 using System;
2 using System.Collections.Generic;
3 using System.Collections.ObjectModel;
4 using System.Runtime.CompilerServices;
5 using System.Threading.Tasks;
7 public struct Foo {
8 public int i, j, k, l, m, n;
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;
21 struct GFoo2<T> {
22 public T t, t2, t3;
25 class GFoo3<T> {
26 public T t, t2;
28 public GFoo3 () {
31 [MethodImplAttribute (MethodImplOptions.NoInlining)]
32 public GFoo3 (T i1, T i2) {
33 t = i1;
34 t2 = i2;
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.
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.
49 // FIXME: Add mixed ref/noref tests, i.e. Dictionary<string, int>
51 #if __MOBILE__
52 public class GSharedTests
53 #else
54 public class Tests
55 #endif
57 #if !__MOBILE__
58 public static int Main (String[] args) {
59 return TestDriver.RunTests (typeof (Tests), args);
61 #endif
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;
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" };
74 gshared<string> (sarr, 0, 1);
76 Foo[] arr = new Foo [2];
77 arr [0] = new Foo () { i = 1, j = 2 };
78 arr [1] = new Foo () { i = 3, j = 4 };
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;
86 return 0;
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;
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 };
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;
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;
111 return 0;
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;
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 };
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;
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;
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;
157 [MethodImplAttribute (MethodImplOptions.NoInlining)]
158 private static void box<T1, T> (T [] array, object[] arr) {
159 object x = array [0];
160 arr [0] = x;
163 public static int test_0_vt_box () {
164 Foo[] arr = new Foo [2];
165 arr [0] = new Foo () { i = 1, j = 2 };
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;
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;
189 public static int test_0_vt_unbox_any () {
190 int[] iarr = new int [16];
191 unbox_any<int> (iarr, new object [] { 12 });
193 Foo[] arr = new Foo [2];
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;
203 interface IFaceUnbox {
204 T Unbox<T, T2> (T t, T2 t2, object o);
207 class ClassUnbox : IFaceUnbox {
208 public T Unbox<T, T2> (T t, T2 t2, object o) {
209 return (T)o;
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;
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;
236 [MethodImplAttribute (MethodImplOptions.NoInlining)]
237 static void ldfld_nongeneric<T> (GFoo<T>[] foo, int[] arr) {
238 arr [0] = foo [0].i;
241 [MethodImplAttribute (MethodImplOptions.NoInlining)]
242 static void ldfld<T> (GFoo<T>[] foo, T[] arr) {
243 arr [0] = foo [0].t;
246 [MethodImplAttribute (MethodImplOptions.NoInlining)]
247 static void stfld_nongeneric<T> (GFoo<T>[] foo, int[] arr) {
248 foo [0].i = arr [0];
251 [MethodImplAttribute (MethodImplOptions.NoInlining)]
252 static void stfld<T> (GFoo<T>[] foo, T[] arr) {
253 foo [0].t = arr [0];
256 [MethodImplAttribute (MethodImplOptions.NoInlining)]
257 static void ldflda<T> (GFoo<T>[] foo, int[] arr) {
258 arr [0] = foo [0].f.i;
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 };
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;
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;
285 ldflda<Foo> (farr, iarr);
286 if (iarr [0] != 5)
287 return 5;
289 return 0;
292 [MethodImplAttribute (MethodImplOptions.NoInlining)]
293 static void stsfld<T> (T[] arr) {
294 GFoo<T>.static_t = arr [0];
297 [MethodImplAttribute (MethodImplOptions.NoInlining)]
298 static void ldsfld<T> (T[] arr) {
299 arr [0] = GFoo<T>.static_t;
302 [MethodImplAttribute (MethodImplOptions.NoInlining)]
303 static void ldsflda<T> (int[] iarr) {
304 iarr [0] = GFoo<T>.static_f.i;
307 public static int test_0_stsfld () {
308 Foo[] farr = new Foo [] { new Foo () { i = 1, j = 2 } };
309 stsfld<Foo> (farr);
311 if (GFoo<Foo>.static_t.i != 1 || GFoo<Foo>.static_t.j != 2)
312 return 1;
314 Foo[] farr2 = new Foo [1];
315 ldsfld<Foo> (farr2);
316 if (farr2 [0].i != 1 || farr2 [0].j != 2)
317 return 2;
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;
325 return 0;
328 [MethodImplAttribute (MethodImplOptions.NoInlining)]
329 static object newarr<T> () {
330 object o = new T[10];
331 return o;
334 public static int test_0_vt_newarr () {
335 object o = newarr<Foo> ();
336 if (!(o is Foo[]))
337 return 1;
338 return 0;
341 [MethodImplAttribute (MethodImplOptions.NoInlining)]
342 static Type ldtoken<T> () {
343 return typeof (GFoo<T>);
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;
354 return 0;
357 public static int test_0_vtype_list () {
358 List<int> l = new List<int> ();
360 l.Add (5);
361 if (l.Count != 1)
362 return 1;
363 return 0;
366 [MethodImplAttribute (MethodImplOptions.NoInlining)]
367 static int args_simple<T> (T t, int i) {
368 return i;
371 [MethodImplAttribute (MethodImplOptions.NoInlining)]
372 static int args_simple<T> (T t, int i, T t2) {
373 return i;
376 [MethodImplAttribute (MethodImplOptions.NoInlining)]
377 static Type args_rgctx<T> (T t, int i) {
378 return typeof (T);
381 [MethodImplAttribute (MethodImplOptions.NoInlining)]
382 static Type eh_in<T> (T t, int i) {
383 throw new OverflowException ();
386 [MethodImplAttribute (MethodImplOptions.NoInlining)]
387 static T return_t<T> (T t) {
388 return t;
391 [MethodImplAttribute (MethodImplOptions.NoInlining)]
392 T return_this_t<T> (T t) {
393 return t;
396 interface IFaceGSharedVtIn {
397 T return_t<T> (T t);
400 class ClassGSharedVtIn : IFaceGSharedVtIn {
401 public T return_t<T> (T t) {
402 return t;
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) {
426 return 0;
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;
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;
467 class DelClass {
468 [MethodImplAttribute (MethodImplOptions.NoInlining)]
469 public static T return_t<T> (T t) {
470 return t;
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;
482 [MethodImplAttribute (MethodImplOptions.NoInlining)]
483 static T return2_t<T> (T t) {
484 return return_t (t);
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;
497 static GFoo3<T> newobj<T> (T t1, T t2) {
498 return new GFoo3<T> (t1, t2);
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;
509 return 0;
512 [MethodImplAttribute (MethodImplOptions.NoInlining)]
513 static GFoo2<T> newobj_vt<T> (T t1, T t2) {
514 return new GFoo2<T> () { t = t1, t2 = t2 };
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;
528 // Tests for transitioning out of gsharedvt code
531 // T1=Nullable<..> is not currently supported by gsharedvt
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;
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;
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 };
555 [MethodImplAttribute (MethodImplOptions.NoInlining)]
556 static T return2_t_out<T> (T t) {
557 return return_t_nogshared<T, int?> (t);
560 [MethodImplAttribute (MethodImplOptions.NoInlining)]
561 static int return2_int_out<T> (T t) {
562 return return_int_nogshared<T, int?> (t);
565 [MethodImplAttribute (MethodImplOptions.NoInlining)]
566 static A return2_vtype_out<T> (T t) {
567 return return_vtype_nogshared<T, int?> (t);
570 struct A {
571 public int a, b, c;
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;
597 public class GenericClass<T> {
598 public static T Z (IList<T> x, int index)
600 return x [index];
604 public static int test_0_generic_array_helpers () {
605 int[] x = new int[] {100, 200};
607 // Generic array helpers should be treated as gsharedvt-out
608 if (GenericClass<int>.Z (x, 0) != 100)
609 return 1;
611 return 0;
614 internal class IntComparer : IComparer<int>
616 public int Compare (int ix, int iy)
618 if (ix == iy)
619 return 0;
621 if (((uint) ix) < ((uint) iy))
622 return -1;
623 return 1;
627 [MethodImplAttribute (MethodImplOptions.NoInlining)]
628 static int gshared_out_iface<T> (T t1, T t2, IComparer<T> comp) {
629 return comp.Compare (t1, t2);
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;
639 struct Foo1 {
640 public int i1, i2, i3;
643 struct Foo2<T> {
644 int i1, i2, i3, i4, i5;
645 public T foo;
648 [MethodImplAttribute (MethodImplOptions.NoInlining)]
649 public static void locals<T> (T t) {
650 Foo2<T> t2 = new Foo2<T> ();
651 object o = t2;
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;
663 public interface IFace<T> {
664 T return_t_iface (T t);
667 public class Parent<T> {
668 public virtual T return_t_vcall (T t) {
669 throw new Exception ();
670 return t;
674 public class Child<T> : Parent<T>, IFace<T> {
675 public override T return_t_vcall (T t) {
676 return t;
678 public T return_t_iface (T t) {
679 return t;
683 [MethodImplAttribute (MethodImplOptions.NoInlining)]
684 static T return_t_vcall<T> (Parent<T> r, T t) {
685 return r.return_t_vcall (t);
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;
696 if (return_t_vcall (new Child<double> (), 2.0) != 2.0)
697 return 3;
698 return 0;
701 [MethodImplAttribute (MethodImplOptions.NoInlining)]
702 static T return_t_iface<T> (IFace<T> r, T t) {
703 return r.return_t_iface (t);
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;
714 interface IFaceKVP {
715 T do_kvp<T> (T a);
718 static KeyValuePair<T1, T2> make_kvp<T1, T2> (T1 t1, T2 t2) {
719 return new KeyValuePair<T1, T2> (t1, t2);
722 static T2 use_kvp<T1, T2> (KeyValuePair<T1, T2> kvp) {
723 return kvp.Value;
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);
734 public static int test_0_gsharedvt_ginstvt_constructed_arg () {
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);
742 IFaceKVP c = new ClassKVP ();
743 if (c.do_kvp<long> (1) != 1)
744 return 1;
745 return 0;
748 public static int test_0_gsharedvt_ginstvt_constructed_arg_float () {
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);
756 IFaceKVP c = new ClassKVP ();
757 if (c.do_kvp<double> (1) != 1)
758 return 1;
759 return 0;
762 interface IGetter
764 T Get<T>();
767 class Getter : IGetter
769 public T Get<T>() { return default(T); }
772 abstract class Session
774 public abstract IGetter Getter { get; }
777 class IosSession : Session
779 private IGetter getter = new Getter();
780 public override IGetter Getter { get { return getter; } }
783 enum ENUM_TYPE {
786 public static int test_0_regress_5156 () {
787 new IosSession().Getter.Get<ENUM_TYPE>();
788 return 0;
791 public struct VT
793 public Action a;
796 public class D
800 public class A3
802 public void OuterMethod<TArg1>(TArg1 value)
804 this.InnerMethod<TArg1, long>(value, 0);
807 private void InnerMethod<TArg1, TArg2>(TArg1 v1, TArg2 v2)
809 //Console.WriteLine("{0} {1}",v1,v2);
813 public static int test_0_regress_2096 () {
814 var a = new A3();
816 // The following work:
817 a.OuterMethod<int>(1);
818 a.OuterMethod<DateTime>(DateTime.Now);
820 var v = new VT();
821 a.OuterMethod<VT>(v);
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;
830 public class B
832 public void Test<T>()
834 //System.Console.WriteLine(typeof(T));
838 public class A<T>
840 public void Test()
842 new B().Test<System.Collections.Generic.KeyValuePair<T, T>>();
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;
854 class ArrayContainer<T> {
855 private T[,] container = new T[1,1];
857 public T Prop {
858 [MethodImplAttribute (MethodImplOptions.NoInlining)]
859 get {
860 return container [0, 0];
862 [MethodImplAttribute (MethodImplOptions.NoInlining)]
863 set {
864 container [0, 0] = value;
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;
876 [MethodImplAttribute (MethodImplOptions.NoInlining)]
877 static T2 rgctx_in_call_innner_inner<T1, T2> (T1 t1, T2 t2) {
878 return t2;
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> ());
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;
894 [MethodImplAttribute (MethodImplOptions.NoInlining)]
895 static void arm_params1<T> (T t1, T t2, T t3, T t4, T t5, T t6) {
898 [MethodImplAttribute (MethodImplOptions.NoInlining)]
899 static void arm_params2<T> (T t1, T t2, T t3, long t4, T t5, T t6) {
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;
908 sealed class ScheduledItem<TAbsolute, TValue> {
909 private readonly object _scheduler;
910 private readonly TValue _state;
911 private readonly object _action;
913 public ScheduledItem(object o, TValue state, object action, TAbsolute dueTime) {
914 _state = state;
918 abstract class VirtualTimeSchedulerBase<TAbsolute, TRelative> {
919 public abstract void ScheduleAbsolute<TState>(TState state, TAbsolute dueTime);
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);
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;
934 public class Base {
935 public virtual T foo<T> (T t) {
936 return t;
940 class Class1 : Base {
941 public object o;
943 public override T foo<T> (T t) {
944 o = t;
945 return t;
949 class Class2 : Base {
950 public object o;
952 public override T foo<T> (T t) {
953 o = t;
954 return t;
958 [MethodImplAttribute (MethodImplOptions.NoInlining)]
959 public static void bar<T> (Base b, T t) {
960 b.foo (t);
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;
983 public interface IFace1<T> {
984 void m1 ();
985 void m2 ();
986 void m3 ();
987 void m4 ();
988 void m5 ();
991 public class ClassIFace<T> : IFace1<T> {
992 public void m1 () {
994 public void m2 () {
996 public void m3 () {
998 public void m4 () {
1000 public void m5 () {
1004 interface IFaceIFaceCall {
1005 void call<T, T2> (IFace1<object> iface);
1008 class MakeIFaceCall : IFaceIFaceCall {
1009 public void call<T, T2> (IFace1<object> iface) {
1010 iface.m1 ();
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> ();
1018 IFaceIFaceCall c = new MakeIFaceCall ();
1020 c.call<object, int> (c1);
1021 return 0;
1024 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1025 static string to_string<T, T2>(T t, T2 t2) {
1026 return t.ToString ();
1029 public enum AnEnum {
1030 One,
1034 class GetHashBase1 {
1035 public override int GetHashCode () {
1036 return 1;
1040 class GetHashClass1 : GetHashBase1 {
1041 public override int GetHashCode () {
1042 return 2;
1046 interface GetHashIFace {
1047 int get_hash<T, T2> (T t, T2 t2);
1050 class GetHashImpl : GetHashIFace {
1051 public int get_hash<T, T2> (T t, T2 t2) {
1052 return t.GetHashCode ();
1056 public static int test_0_constrained_tostring () {
1057 if (to_string<int, int> (1, 1) != "1")
1058 return 1;
1059 if (to_string<AnEnum, int> (AnEnum.One, 1) != "One")
1060 return 2;
1061 if (to_string<string, int> ("A", 1) != "A")
1062 return 3;
1063 return 0;
1066 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1067 static int get_hash<T, T2>(T t, T2 t2) {
1068 return t.GetHashCode ();
1071 public static int test_0_constrained_get_hash () {
1072 if (get_hash<int, int> (1, 1) != 1.GetHashCode ())
1073 return 1;
1074 if (get_hash<double, int> (1.0, 1) != 1.0.GetHashCode ())
1075 return 2;
1076 if (get_hash<AnEnum, int> (AnEnum.One, 1) != AnEnum.One.GetHashCode ())
1077 return 3;
1078 if (get_hash<string, int> ("A", 1) != "A".GetHashCode ())
1079 return 4;
1080 GetHashIFace iface = new GetHashImpl ();
1081 if (iface.get_hash<GetHashBase1, int> (new GetHashClass1 (), 1) != 2)
1082 return 5;
1083 return 0;
1086 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1087 static bool equals<T, T2>(T t, T2 t2) {
1088 return t.Equals (t);
1091 public static int test_0_constrained_equals () {
1092 if (equals<int, int> (1, 1) != true)
1093 return 1;
1094 if (equals<double, int> (1.0, 1) != true)
1095 return 2;
1096 if (equals<AnEnum, int> (AnEnum.One, 1) != true)
1097 return 3;
1098 if (equals<string, int> ("A", 1) != true)
1099 return 4;
1100 return 0;
1103 interface IGetType {
1104 Type gettype<T, T2>(T t, T2 t2);
1107 public class CGetType : IGetType {
1108 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1109 public Type gettype<T, T2>(T t, T2 t2) {
1110 return t.GetType ();
1113 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1114 public Type gettype2<T>(T t) {
1115 return t.GetType ();
1119 public static int test_0_constrained_gettype () {
1120 IGetType c = new CGetType ();
1121 if (c.gettype<int, int> (1, 1) != typeof (int))
1122 return 1;
1123 if (c.gettype<string, int> ("A", 1) != typeof (string))
1124 return 2;
1125 /* Partial sharing */
1126 var c2 = new CGetType ();
1127 if (c2.gettype2<long> (1) != typeof (long))
1128 return 3;
1129 return 0;
1132 interface IConstrainedCalls {
1133 Pair<int, int> vtype_ret<T, T2>(T t, T2 t2) where T: IReturnVType;
1134 AnEnum enum_ret<T, T2>(T t, T2 t2) where T: IReturnVType;
1135 int normal_args<T, T2> (T t, T2 t2, int i1, int i2, string s, ref int i3, Foo foo) where T : IConstrained2;
1138 public interface IReturnVType {
1139 Pair<int, int> return_vtype ();
1140 AnEnum return_enum ();
1143 public interface IConstrained2 {
1144 int normal_args (int i1, int i2, string s, ref int i3, Foo foo);
1147 public class CConstrainedCalls : IConstrainedCalls {
1148 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1149 public Pair<int, int> vtype_ret<T, T2>(T t, T2 t2) where T : IReturnVType {
1150 return t.return_vtype ();
1153 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1154 public AnEnum enum_ret<T, T2>(T t, T2 t2) where T : IReturnVType {
1155 return t.return_enum ();
1158 public int normal_args<T, T2> (T t, T2 t2, int i1, int i2, string s, ref int i3, Foo foo) where T : IConstrained2 {
1159 return t.normal_args (i1, i2, s, ref i3, foo);
1163 class ReturnVType : IReturnVType {
1164 public Pair<int, int> return_vtype () {
1165 return new Pair<int, int> () { First = 1, Second = 2 };
1167 public AnEnum return_enum () {
1168 return AnEnum.Two;
1172 class ConstrainedCalls : IConstrained2 {
1173 public int normal_args (int i1, int i2, string s, ref int i3, Foo foo) {
1174 i3 = i3 + 1;
1175 return i1 + i2 + i3 + s.Length + foo.i + foo.n;
1179 public static int test_0_constrained_vtype_ret () {
1180 IConstrainedCalls c = new CConstrainedCalls ();
1181 var r = c.vtype_ret<ReturnVType, int> (new ReturnVType (), 1);
1182 if (r.First != 1 || r.Second != 2)
1183 return 1;
1184 return 0;
1187 public static int test_0_constrained_enum_ret () {
1188 IConstrainedCalls c = new CConstrainedCalls ();
1189 var r = c.enum_ret<ReturnVType, int> (new ReturnVType (), 1);
1190 if (r != AnEnum.Two)
1191 return 1;
1192 return 0;
1195 public static int test_25_constrained_normal_args () {
1196 IConstrainedCalls c = new CConstrainedCalls ();
1198 Foo foo = new Foo () { i = 5, n = 6 };
1199 int val = 3;
1200 var r = c.normal_args<ConstrainedCalls, int> (new ConstrainedCalls (), 0, 1, 2, "ABC", ref val, foo);
1201 return r + val;
1204 public struct Pair<T1, T2> {
1205 public T1 First;
1206 public T2 Second;
1209 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1210 public static TState call_del<TState>(TState state, Func<object, TState, TState> action) {
1211 return action(null, state);
1214 [Category ("!FULLAOT")]
1215 public static int test_0_delegate_wrappers () {
1216 Func<object, Pair<int, int>, Pair<int, int>> del1 = delegate (object o, Pair<int, int> p) { return p; };
1217 Func<object, Pair<int, int>, Pair<int, int>> del2 = delegate (object o, Pair<int, int> p) { return p; };
1218 Func<object, Pair<double, int>, Pair<double, int>> del3 = delegate (object o, Pair<double, int> p) { return p; };
1219 var r1 = call_del<Pair<int, int>> (new Pair<int, int> { First = 1, Second = 2}, del1);
1220 if (r1.First != 1 || r1.Second != 2)
1221 return 1;
1222 var r2 = call_del<Pair<int, int>> (new Pair<int, int> { First = 3, Second = 4}, del2);
1223 if (r2.First != 3 || r2.Second != 4)
1224 return 2;
1225 var r3 = call_del<Pair<double, int>> (new Pair<double, int> { First = 1.0, Second = 2}, del3);
1226 if (r3.First != 1.0 || r3.Second != 2)
1227 return 3;
1228 return 0;
1231 class Base<T> {
1232 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1233 public object foo<T1> (T1 t1, T t, object o) {
1234 return o;
1238 class AClass : Base<long> {
1240 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1241 public object bar<T> (T t, long time, object o) {
1242 return foo (t, time, o);
1246 public static int test_0_out_in_wrappers () {
1247 var a = new AClass ();
1248 object o1 = "A";
1249 object o2 = a.bar<long> (1024, 0, o1);
1250 if (o1 != o2)
1251 return 1;
1252 return 0;
1255 interface BIFace {
1256 object AMethod ();
1259 class Base<TAbsolute, T2> : BIFace {
1261 public TAbsolute Clock { get; set; }
1263 public virtual object AMethod () {
1264 return Clock;
1268 class BClass : Base<long, long> {
1271 public static int test_0_regress_1 () {
1272 BIFace c = new BClass ();
1273 object o = c.AMethod ();
1274 if (!(o is long) || ((long)o != 0))
1275 return 1;
1276 return 0;
1279 interface IFace3 {
1280 T unbox_any<T> (object o);
1283 class Class3 : IFace3 {
1284 public virtual T unbox_any<T> (object o) {
1285 return (T)o;
1289 public static int test_0_unbox_any () {
1290 IFace3 o = new Class3 ();
1291 if (o.unbox_any<int> (16) != 16)
1292 return 1;
1293 if (o.unbox_any<long> ((long)32) != 32)
1294 return 2;
1295 if (o.unbox_any<double> (2.0) != 2.0)
1296 return 3;
1297 try {
1298 o.unbox_any<int> (2.0);
1299 return 4;
1300 } catch (Exception) {
1302 return 0;
1305 interface IFace4 {
1306 TSource Catch<TSource, TException>(TSource t) where TException : Exception;
1309 class Class4 : IFace4 {
1310 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1311 public TSource Catch<TSource, TException>(TSource t) where TException : Exception {
1312 return t;
1316 // Check that mixed instantiations are correctly created/found in AOT
1317 public static int test_0_constraints () {
1318 IFace4 o = new Class4 ();
1319 o.Catch<int, Exception> (1);
1320 return 0;
1323 internal static Type Process<TSource, TElement> (TSource[] arr, Action<TElement, TElement> call) {
1324 arr [0] = default (TSource);
1325 return typeof (TSource);
1328 interface IFace5 {
1329 Type foo<T> ();
1332 class Class5 : IFace5 {
1333 public Type foo<T> () {
1334 return Process<KeyValuePair<long, T>, T> (new KeyValuePair<long, T> [10], null);
1338 public static int test_0_rgctx_call_from_gshared_code () {
1339 var c = new Class5 ();
1340 if (c.foo<string> () != typeof (KeyValuePair<long, string>))
1341 return 1;
1342 return 0;
1345 public class Enumbers<T> {
1346 public object Enumerate (List<KeyValuePair<T, string>> alist)
1348 return alist.ToArray ();
1352 public static int test_0_checkthis_gshared_call () {
1353 Enumbers<string> e = new Enumbers<string> ();
1354 try {
1355 e.Enumerate (null);
1356 return 1;
1358 catch (NullReferenceException) {
1360 return 0;
1363 interface IFace6 {
1364 T[] Del<T> (T t);
1367 class Class6 : IFace6 {
1368 public T[] Del<T> (T t) {
1369 var res = new T [5];
1370 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; };
1371 var v = func.BeginInvoke(t, t, t, t, null, null);
1372 res [4] = func.EndInvoke (v);
1373 return res;
1377 // FIXME: Wasm is single threaded and can't handle blocking waits
1378 [Category ("!WASM")]
1379 public static int test_0_begin_end_invoke () {
1380 IFace6 o = new Class6 ();
1381 var arr1 = o.Del (1);
1382 if (arr1 [0] != 1 || arr1 [1] != 1 || arr1 [2] != 1 || arr1 [3] != 1 || arr1 [4] != 1)
1383 return 1;
1384 var arr2 = o.Del (2.0);
1385 if (arr2 [0] != 2.0 || arr2 [1] != 2.0 || arr2 [2] != 2.0 || arr2 [3] != 2.0 || arr2 [4] != 2.0)
1386 return 2;
1387 return 0;
1390 public class TAbstractTableItem<TC> {
1391 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1392 public static void SetProperty<TV> () { }
1394 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1395 public static void Test () {
1396 SetProperty<bool> ();
1400 public static int test_0_gsharedvt_method_on_shared_class () {
1401 TAbstractTableItem<object>.Test ();
1402 return 0;
1405 interface IFaceBox {
1406 object box<T> (T t);
1407 bool is_null<T> (T t);
1410 class ClassBox : IFaceBox {
1411 public object box<T> (T t) {
1412 object o = t;
1413 return o;
1416 public bool is_null<T> (T t) {
1417 if (!(default(T) == null))
1418 return false;
1419 return true;
1423 public static int test_0_nullable_box () {
1424 IFaceBox c = new ClassBox ();
1425 int i = 5;
1426 object o = c.box<int?> (i);
1427 if ((int)o != i)
1428 return 1;
1429 if (c.box<int?> (null) != null)
1430 return 2;
1431 long l = Int64.MaxValue - 1;
1432 o = c.box<long?> (l);
1433 if ((long)o != l)
1434 return 3;
1435 if (c.box<long?> (null) != null)
1436 return 4;
1437 string s = "A";
1438 if (c.box<string> (s) != (object)s)
1439 return 5;
1440 return 0;
1443 public static int test_0_nullable_box_brtrue_opt () {
1444 IFaceBox c = new ClassBox ();
1446 if (c.is_null<double?> (null))
1447 return 0;
1448 else
1449 return 1;
1452 interface IFaceUnbox2 {
1453 T unbox<T> (object o);
1456 class ClassUnbox2 : IFaceUnbox2 {
1457 public T unbox<T> (object o) {
1458 return (T)o;
1462 public static int test_0_nullable_unbox () {
1463 IFaceUnbox2 c = new ClassUnbox2 ();
1464 int? i = c.unbox<int?> (5);
1465 if (i != 5)
1466 return 1;
1467 int? j = c.unbox<int?> (null);
1468 if (j != null)
1469 return 2;
1470 return 0;
1473 interface IConstrained {
1474 void foo ();
1475 void foo_ref_arg (string s);
1478 interface IConstrained<T3> {
1479 void foo_gsharedvt_arg (T3 s);
1480 T3 foo_gsharedvt_ret (T3 s);
1483 static object constrained_res;
1485 struct ConsStruct : IConstrained {
1486 public int i;
1488 public void foo () {
1489 constrained_res = i;
1492 public void foo_ref_arg (string s) {
1493 constrained_res = s == "A" ? 42 : 0;
1497 class ConsClass : IConstrained {
1498 public int i;
1500 public void foo () {
1501 constrained_res = i;
1504 public void foo_ref_arg (string s) {
1505 constrained_res = s == "A" ? 43 : 0;
1509 struct ConsStruct<T> : IConstrained<T> {
1510 public void foo_gsharedvt_arg (T s) {
1511 constrained_res = s;
1514 public T foo_gsharedvt_ret (T s) {
1515 return s;
1519 struct ConsStructThrow : IConstrained {
1520 public void foo () {
1521 throw new Exception ();
1524 public void foo_ref_arg (string s) {
1528 interface IFaceConstrained {
1529 void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained;
1530 void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained;
1531 void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1532 T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1533 T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass;
1536 class ClassConstrained : IFaceConstrained {
1537 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1538 public void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained {
1539 t2.foo ();
1542 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1543 public void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained {
1544 t2.foo_ref_arg ("A");
1547 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1548 public void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1549 t2.foo_gsharedvt_arg (t);
1552 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1553 public T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1554 return t2.foo_gsharedvt_ret (t);
1557 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1558 public T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass {
1559 /* This becomes a constrained call even through 't2' is forced to be a reference type by the constraint */
1560 return (T2)t2.foo (5);
1564 class VClass {
1565 public virtual VClass foo (int i) {
1566 return this;
1570 public static int test_0_constrained_void_iface_call () {
1571 IFaceConstrained c = new ClassConstrained ();
1572 var s = new ConsStruct () { i = 42 };
1573 constrained_res = null;
1574 c.constrained_void_iface_call<int, ConsStruct> (1, s);
1575 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1576 return 1;
1577 constrained_res = null;
1578 c.constrained_void_iface_call_ref_arg<int, ConsStruct> (1, s);
1579 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1580 return 2;
1581 var s2 = new ConsClass () { i = 43 };
1582 constrained_res = null;
1583 c.constrained_void_iface_call<int, ConsClass> (1, s2);
1584 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1585 return 3;
1586 constrained_res = null;
1587 c.constrained_void_iface_call_ref_arg<int, ConsClass> (1, s2);
1588 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1589 return 4;
1590 return 0;
1593 public static int test_0_constrained_eh () {
1594 var s2 = new ConsStructThrow () { };
1595 try {
1596 IFaceConstrained c = new ClassConstrained ();
1597 c.constrained_void_iface_call<int, ConsStructThrow> (1, s2);
1598 return 1;
1599 } catch (Exception) {
1600 return 0;
1604 public static int test_0_constrained_void_iface_call_gsharedvt_arg () {
1605 // This tests constrained calls through interfaces with one gsharedvt arg, like IComparable<T>.CompareTo ()
1606 IFaceConstrained c = new ClassConstrained ();
1608 var s = new ConsStruct<int> ();
1609 constrained_res = null;
1610 c.constrained_void_iface_call_gsharedvt_arg<int, ConsStruct<int>, int> (42, s, 55);
1611 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1612 return 1;
1614 var s2 = new ConsStruct<string> ();
1615 constrained_res = null;
1616 c.constrained_void_iface_call_gsharedvt_arg<string, ConsStruct<string>, int> ("A", s2, 55);
1617 if (!(constrained_res is string) || ((string)constrained_res) != "A")
1618 return 2;
1620 return 0;
1623 public static int test_0_constrained_iface_call_gsharedvt_ret () {
1624 IFaceConstrained c = new ClassConstrained ();
1626 var s = new ConsStruct<int> ();
1627 int ires = c.constrained_iface_call_gsharedvt_ret<int, ConsStruct<int>, int> (42, s, 55);
1628 if (ires != 42)
1629 return 1;
1631 var s2 = new ConsStruct<string> ();
1632 string sres = c.constrained_iface_call_gsharedvt_ret<string, ConsStruct<string>, int> ("A", s2, 55);
1633 if (sres != "A")
1634 return 2;
1636 return 0;
1639 public static int test_0_constrained_normal_call () {
1640 IFaceConstrained c = new ClassConstrained ();
1642 var o = new VClass ();
1643 var res = c.constrained_normal_call<int, VClass> (1, o);
1644 return res == o ? 0 : 1;
1647 public static async Task<T> FooAsync<T> (int i, int j) {
1648 Task<int> t = new Task<int> (delegate () { return 42; });
1649 var response = await t;
1650 return default(T);
1653 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1654 public static void call_async<T> (int i, int j) {
1655 Task<T> t = FooAsync<T> (1, 2);
1656 // FIXME: This doesn't work
1657 //t.RunSynchronously ();
1660 // In AOT mode, the async infrastructure depends on gsharedvt methods
1661 public static int test_0_async_call_from_generic () {
1662 call_async<string> (1, 2);
1663 return 0;
1666 public static int test_0_array_helper_gsharedvt () {
1667 var arr = new AnEnum [16];
1668 var c = new ReadOnlyCollection<AnEnum> (arr);
1669 return c.Contains (AnEnum.Two) == false ? 0 : 1;
1672 interface IFaceCallPatching {
1673 bool caller<T, T2> ();
1676 class CallPatching2<T> {
1677 T t;
1678 public object o;
1680 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1681 public bool callee () {
1682 return (string)o == "ABC";
1686 class CallPatching : IFaceCallPatching {
1687 public bool caller<T, T2> () {
1688 var c = new CallPatching2<T> ();
1689 c.o = "ABC";
1690 return c.callee ();
1695 // This tests that generic calls made from gsharedvt methods are not patched normally.
1696 // If they are, the first call to 'caller' would patch in the gshared version of
1697 // 'callee', causing the second call to fail because the gshared version of callee
1698 // wouldn't work with CallPatching2<bool> since it has a different object layout.
1700 public static int test_0_call_patching () {
1701 IFaceCallPatching c = new CallPatching ();
1702 c.caller<object, bool> ();
1703 if (!c.caller<bool, bool> ())
1704 return 1;
1705 return 0;
1708 struct EmptyStruct {
1711 public struct BStruct {
1712 public int a, b, c, d;
1715 interface IFoo3<T> {
1716 int Bytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1717 byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8);
1718 int SBytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1719 sbyte b1, sbyte b2, sbyte b3, sbyte b4);
1720 int Shorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1721 short b1, short b2, short b3, short b4);
1722 int UShorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1723 ushort b1, ushort b2, ushort b3, ushort b4);
1724 int Ints (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1725 int i1, int i2, int i3, int i4);
1726 int UInts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1727 uint i1, uint i2, uint i3, uint i4);
1728 int Structs (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1729 BStruct s);
1730 int Floats (T t, double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8,
1731 double d9, double d10, float s11, float s12);
1732 void Generic<T2> (T t, T2[] arr, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1733 T2 i1, T2 i2, T2 i3, T2 i4);
1736 class Foo3<T> : IFoo3<T> {
1737 public int Bytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1738 byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8) {
1739 return b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8;
1741 public int SBytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1742 sbyte b1, sbyte b2, sbyte b3, sbyte b4) {
1743 return b1 + b2 + b3 + b4;
1745 public int Shorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1746 short b1, short b2, short b3, short b4) {
1747 return b1 + b2 + b3 + b4;
1749 public int UShorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1750 ushort b1, ushort b2, ushort b3, ushort b4) {
1751 return b1 + b2 + b3 + b4;
1753 public int Ints (T t, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8,
1754 int i1, int i2, int i3, int i4) {
1755 return i1 + i2 + i3 + i4;
1757 public int UInts (T t, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8,
1758 uint i1, uint i2, uint i3, uint i4) {
1759 return (int)(i1 + i2 + i3 + i4);
1761 public int Structs (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1762 BStruct s) {
1763 return s.a + s.b + s.c + s.d;
1765 public int Floats (T t, double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8,
1766 double d9, double d10, float s11, float s12) {
1767 return (int)d9 + (int)d10 + (int)s11 + (int)s12;
1769 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) {
1770 arr [0] = i1;
1771 arr [1] = i2;
1772 arr [2] = i3;
1773 arr [3] = i4;
1777 // Passing small normal arguments on the stack
1778 public static int test_0_arm64_small_stack_args () {
1779 IFoo3<EmptyStruct> o = (IFoo3<EmptyStruct>)Activator.CreateInstance (typeof (Foo3<>).MakeGenericType (new Type [] { typeof (EmptyStruct) }));
1780 int res = o.Bytes (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8);
1781 if (res != 36)
1782 return 1;
1783 int res2 = o.SBytes (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1784 if (res2 != -10)
1785 return 2;
1786 int res3 = o.Shorts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1787 if (res3 != -10)
1788 return 3;
1789 int res4 = o.UShorts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
1790 if (res4 != 10)
1791 return 4;
1792 int res5 = o.Ints (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1793 if (res5 != -10)
1794 return 5;
1795 int res6 = o.UInts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
1796 if (res6 != 10)
1797 return 6;
1798 int res7 = o.Floats (new EmptyStruct (), 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 10.0, 20.0, 30.0f, 40.0f);
1799 if (res7 != 100)
1800 return 7;
1801 int[] arr = new int [4];
1802 o.Generic<int> (new EmptyStruct (), arr, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
1803 if (arr [0] != 1 || arr [1] != 2 || arr [2] != 3 || arr [3] != 4)
1804 return 8;
1805 return 0;
1808 interface ISmallArg {
1809 T foo<T> (string s1, string s2, string s3, string s4, string s5, string s6, string s7, string s8,
1810 string s9, string s10, string s11, string s12, string s13, T t);
1813 class SmallArgClass : ISmallArg {
1814 public T foo<T> (string s1, string s2, string s3, string s4, string s5, string s6, string s7, string s8,
1815 string s9, string s10, string s11, string s12, string s13, T t) {
1816 return t;
1820 public static int test_1_small_gsharedvt_stack_arg_ios () {
1821 ISmallArg o = new SmallArgClass ();
1822 return o.foo<int> ("", "", "", "", "", "", "", "", "", "", "", "", "", 1);
1825 // Passing vtype normal arguments on the stack
1826 public static int test_0_arm64_vtype_stack_args () {
1827 IFoo3<EmptyStruct> o = (IFoo3<EmptyStruct>)Activator.CreateInstance (typeof (Foo3<>).MakeGenericType (new Type [] { typeof (EmptyStruct) }));
1828 int res = o.Structs (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, new BStruct () { a = 1, b = 2, c = 3, d = 4 });
1829 if (res != 10)
1830 return 1;
1831 return 0;
1834 interface IFoo4<T> {
1835 T Get(T[,] arr, T t);
1838 class Foo4<T> : IFoo4<T> {
1839 public T Get(T[,] arr, T t) {
1840 arr [1, 1] = t;
1841 return arr [1, 1];
1845 struct AStruct {
1846 public int a, b;
1848 public override int GetHashCode () {
1849 return 0;
1852 public override bool Equals (object o) {
1853 if (!(o is AStruct))
1854 return false;
1855 AStruct s = (AStruct)o;
1856 return a == s.a && b == s.b;
1860 public static int test_0_multi_dim_arrays_2 () {
1861 IFoo4<int> foo = new Foo4<int> ();
1862 var arr = new int [10, 10];
1863 int res = foo.Get (arr, 10);
1864 if (res != 10)
1865 return 1;
1867 IFoo4<AStruct> foo2 = new Foo4<AStruct> ();
1868 var arr2 = new AStruct [10, 10];
1869 var res2 = foo2.Get (arr2, new AStruct () { a = 1, b = 2 });
1870 if (res2.a != 1 || res2.b != 2)
1871 return 2;
1872 return 0;
1875 public interface IFaceTest {
1876 int iface_method ();
1879 public interface IFaceConstrainedIFace {
1880 int foo<T, T2> (ref T val) where T: IFaceTest;
1883 class ConstrainedIFace : IFaceConstrainedIFace {
1884 public int foo<T, T2> (ref T val) where T: IFaceTest {
1885 return val.iface_method ();
1889 class ClassTest : IFaceTest {
1890 public int iface_method () {
1891 return 42;
1895 struct StructTest : IFaceTest {
1897 int i;
1899 public StructTest (int arg) {
1900 i = arg;
1903 public int iface_method () {
1904 return i;
1908 // Test constrained calls on an interface made from gsharedvt methods
1909 public static int test_42_gsharedvt_constrained_iface () {
1910 IFaceConstrainedIFace obj = new ConstrainedIFace ();
1911 IFaceTest t = new ClassTest ();
1912 return obj.foo<IFaceTest, int> (ref t);
1915 public static int test_42_gsharedvt_constrained_iface_vtype () {
1916 IFaceConstrainedIFace obj = new ConstrainedIFace ();
1917 IFaceTest t = new StructTest (42);
1918 return obj.foo<IFaceTest, int> (ref t);
1922 class MyBaseTest<TOutput> {
1923 public void Verify<TInput> (Func<TInput, TOutput> convert, TInput[] testValues, TOutput[] expectedValues) {
1924 MyAssert.Equal (expectedValues.Length, testValues.Length);
1926 for (int i = 0; i < testValues.Length; i++) {
1927 TOutput result = convert (testValues[i]);
1928 MyAssert.Equal (expectedValues[i], result);
1933 class MyAssert {
1934 public static void Equal<T>(T expected, T actual) {
1935 if (!GetEqualityComparer<T> ().Equals (expected, actual))
1936 throw new MyEqualException (expected, actual);
1939 static IEqualityComparer<T> GetEqualityComparer<T>() {
1940 return new AssertEqualityComparer<T>();
1944 class AssertEqualityComparer<T> : IEqualityComparer<T> {
1945 public AssertEqualityComparer() { }
1947 public bool Equals(T x, T y) {
1948 var equatable = x as IEquatable<T>;
1949 if (equatable != null)
1950 return equatable.Equals (y);
1951 throw new NotImplementedException( );
1954 public int GetHashCode(T obj) {
1955 throw new NotImplementedException();
1959 class MyEqualException : Exception {
1960 public MyEqualException (object expected, object actual) {
1961 Console.WriteLine ("MyEqualException: expected = " + expected + " vs. actual = " + actual);
1965 class SByteTestClass : MyBaseTest<sbyte> {
1966 public static int execute () {
1967 Int32[] testValues = { 100, -100, 0 };
1968 SByte[] expectedValues = { 100, -100, 0 };
1969 try {
1970 new SByteTestClass ().Verify (Convert.ToSByte, testValues, expectedValues);
1971 return 0;
1972 } catch (MyEqualException) {
1973 return 1;
1975 return 2;
1978 static int test_0_out_sbyte () {
1979 return SByteTestClass.execute ();
1982 class Int16TestClass : MyBaseTest<Int16> {
1983 public static int execute () {
1984 Int32[] testValues = { 100, -100, 0 };
1985 Int16[] expectedValues = { 100, -100, 0 };
1986 try {
1987 new Int16TestClass ().Verify (Convert.ToInt16, testValues, expectedValues);
1988 return 0;
1989 } catch (MyEqualException) {
1990 return 1;
1992 return 2;
1995 static int test_0_out_int16 () {
1996 return Int16TestClass.execute ();
1999 // Sign extension tests
2000 // 0x55 == 85 == 01010101
2001 // 0xAA == 170 == 10101010
2002 // 0x5555 == 21845 == 0101010101010101
2003 // 0xAAAA == 43690 == 1010101010101010
2004 // 0x55555555 == 1431655765
2005 // 0xAAAAAAAA == 2863311530
2006 // 0x5555555555555555 == 6148914691236517205
2007 // 0xAAAAAAAAAAAAAAAA == 12297829382473034410
2009 public interface SEFace<T> {
2010 T Copy (int a, int b, int c, int d, T t);
2013 class SEClass<T> : SEFace<T> {
2014 public T Copy (int a, int b, int c, int d, T t) {
2015 return t;
2019 // Test extension
2020 static int test_20_signextension_sbyte () {
2021 Type t = typeof (sbyte);
2022 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
2023 var i = (SEFace<sbyte>)o;
2025 long zz = i.Copy (1,2,3,4,(sbyte)(-0x55));
2027 bool success = zz == -0x55;
2028 return success ? 20 : 1;
2031 static int test_20_signextension_byte () {
2032 Type t = typeof (byte);
2033 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
2034 var i = (SEFace<byte>)o;
2036 ulong zz = i.Copy (1,2,3,4,(byte)(0xAA));
2038 bool success = zz == 0xAA;
2039 return success ? 20 : 1;
2042 static int test_20_signextension_short () {
2043 Type t = typeof (short);
2044 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
2045 var i = (SEFace<short>)o;
2047 long zz = i.Copy (1,2,3,4,(short)(-0x5555));
2049 bool success = zz == -0x5555;
2050 return success ? 20 : 1;
2053 static int test_20_signextension_ushort () {
2054 Type t = typeof (ushort);
2055 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
2056 var i = (SEFace<ushort>)o;
2058 ulong zz = i.Copy (1,2,3,4,(ushort)(0xAAAA));
2060 bool success = zz == 0xAAAA;
2061 return success ? 20 : 1;
2064 static int test_20_signextension_int () {
2065 Type t = typeof (int);
2066 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
2067 var i = (SEFace<int>)o;
2069 long zz = i.Copy (1,2,3,4,(int)(-0x55555555));
2071 bool success = zz == -0x55555555;
2072 return success ? 20 : 1;
2075 static int test_20_signextension_uint () {
2076 Type t = typeof (uint);
2077 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
2078 var i = (SEFace<uint>)o;
2080 ulong zz = i.Copy (1,2,3,4,(uint)(0xAAAAAAAA));
2082 bool success = zz == 0xAAAAAAAA;
2083 return success ? 20 : 1;
2086 static int test_20_signextension_long () {
2087 Type t = typeof (long);
2088 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
2089 var i = (SEFace<long>)o;
2091 long zz = i.Copy (1,2,3,4,(long)(-0x5555555555555555));
2093 bool success = zz == -0x5555555555555555;
2094 return success ? 20 : 1;
2097 static int test_20_signextension_ulong () {
2098 Type t = typeof (ulong);
2099 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
2100 var i = (SEFace<ulong>)o;
2102 ulong zz = i.Copy (1,2,3,4,(ulong)(0xAAAAAAAAAAAAAAAA));
2104 bool success = zz == 0xAAAAAAAAAAAAAAAA;
2105 return success ? 20 : 1;
2108 void gsharedvt_try_at_offset_0<T> (ref T disposable)
2109 where T : class, IDisposable {
2110 try {
2111 disposable.Dispose ();
2112 } finally {
2113 disposable = null;
2117 [MethodImplAttribute (MethodImplOptions.NoInlining)]
2118 static DateTimeOffset gsharedvt_vphi_inner<T> (T t) {
2119 return DateTimeOffset.MinValue;
2122 static DateTimeOffset gsharedvt_vphi<T> (T t) {
2123 int[] arr = new int [10];
2125 try {
2126 DateTimeOffset v;
2127 if (arr [0] == 0)
2128 v = gsharedvt_vphi_inner (t);
2129 else
2130 v = gsharedvt_vphi_inner (t);
2131 return v;
2132 } catch {
2133 return DateTimeOffset.MinValue;
2137 static int test_0_gsharedvt_vphi_volatile () {
2138 gsharedvt_vphi (0);
2139 return 0;
2142 struct AStruct3<T1, T2, T3> {
2143 T1 t1;
2144 T2 t2;
2145 T3 t3;
2148 interface IFaceIsRef {
2149 bool is_ref<T> ();
2152 class ClassIsRef : IFaceIsRef {
2153 [MethodImplAttribute (MethodImplOptions.NoInlining)]
2154 public bool is_ref<T> () {
2155 return RuntimeHelpers.IsReferenceOrContainsReferences<T> ();
2159 public static int test_0_isreference_intrins () {
2160 IFaceIsRef iface = new ClassIsRef ();
2161 if (iface.is_ref<AStruct3<int, int, int>> ())
2162 return 1;
2163 if (!iface.is_ref<AStruct3<string, int, int>> ())
2164 return 2;
2165 return 0;
2168 interface IFace59956 {
2169 int foo<T> ();
2172 class Impl59956 : IFace59956 {
2173 public int foo<T> () {
2174 var builder = new SparseArrayBuilder<T>(true);
2176 return builder.Markers._count;
2180 public static int test_1_59956_regress () {
2181 IFace59956 iface = new Impl59956 ();
2182 return iface.foo<int> ();
2185 interface IFaceSpan {
2186 int foo<T> (T t);
2189 class ImplSpan : IFaceSpan {
2190 public int foo<T> (T t) {
2191 var arr = new T[10];
2192 var arr2 = new T[10];
2193 var s = new Span<T> (arr);
2195 s [0] = t;
2196 T t2 = s [0];
2197 if (!t.Equals (t2))
2198 return 1;
2200 var s2 = new Span<T> (arr2);
2201 s.CopyTo (s2);
2202 t2 = s2 [0];
2203 if (!t.Equals (t2))
2204 return 2;
2206 s.Clear ();
2207 t2 = s [0];
2208 if (!t2.Equals (default(T)))
2209 return 3;
2211 return 0;
2215 public static int test_0_span () {
2216 IFaceSpan iface = new ImplSpan ();
2217 var s = new AStruct () { a = 1, b = 2 };
2218 return iface.foo<AStruct> (s);
2221 interface IFaceOpenDel {
2222 object AMethod<T> ();
2225 class ClassOpenDel : IFaceOpenDel {
2226 public Nullable<int> field;
2228 public Nullable<int> getField () {
2229 return field;
2232 public object AMethod<T> () {
2233 var d = (Func<ClassOpenDel, T>)Delegate.CreateDelegate (typeof (Func<ClassOpenDel, T>), typeof (ClassOpenDel).GetMethod ("getField"));
2234 return d (this);
2238 // Open instance delegate returning a gsharedvt value
2239 public static int test_0_open_delegate () {
2240 IFaceOpenDel iface = new ClassOpenDel () { field = 42 };
2241 var res = (Nullable<int>)iface.AMethod<Nullable<int>> ();
2242 return res == 42 ? 0 : 1;
2245 #if !__MonoCS__
2246 public static int test_0_gsharedvt_out_dim () {
2247 var c = new Outer<object>();
2248 c.prop = new H ();
2249 return (c.Foo () == "abcd") ? 0 : 1;
2251 #endif
2254 // #13191
2255 public class MobileServiceCollection<TTable, TCol>
2257 public async Task<int> LoadMoreItemsAsync(int count = 0) {
2258 await Task.Delay (1000);
2259 int results = await ProcessQueryAsync ();
2260 return results;
2263 protected async virtual Task<int> ProcessQueryAsync() {
2264 await Task.Delay (1000);
2265 throw new Exception ();
2269 // #59956
2270 internal struct Marker
2272 public Marker(int count, int index) {
2276 public struct ArrayBuilder<T>
2278 private T[] _array;
2279 public int _count;
2281 public ArrayBuilder(int capacity) {
2282 _array = new T[capacity];
2283 _count = 1;
2287 internal struct SparseArrayBuilder<T>
2289 private ArrayBuilder<Marker> _markers;
2291 public SparseArrayBuilder(bool initialize) : this () {
2292 _markers = new ArrayBuilder<Marker> (10);
2295 public ArrayBuilder<Marker> Markers => _markers;
2298 // #18276
2299 #if !__MonoCS__
2300 public class Outer<Q> {
2301 public interface ID {
2302 string Foo () {
2303 return null;
2307 public ID prop;
2309 public string Foo () {
2310 return prop?.Foo();
2314 public class H : Outer<object>.ID {
2315 string Outer<object>.ID.Foo () {
2316 return "abcd";
2319 #endif
2321 #if !__MOBILE__
2322 public class GSharedTests : Tests {
2324 #endif