[interp] Remove varargs from InterpFrame and recompute it instead (#16598)
[mono-project.git] / mono / mini / gshared.cs
blobdb44168ab53535048e18ae8dc09f039a2ceaa9c6
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 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;
1044 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1045 static int get_hash<T, T2>(T t, T2 t2) {
1046 return t.GetHashCode ();
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;
1061 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1062 static bool equals<T, T2>(T t, T2 t2) {
1063 return t.Equals (t);
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;
1078 interface IGetType {
1079 Type gettype<T, T2>(T t, T2 t2);
1082 public class CGetType : IGetType {
1083 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1084 public Type gettype<T, T2>(T t, T2 t2) {
1085 return t.GetType ();
1088 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1089 public Type gettype2<T>(T t) {
1090 return t.GetType ();
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;
1107 interface IConstrainedCalls {
1108 Pair<int, int> vtype_ret<T, T2>(T t, T2 t2) where T: IReturnVType;
1109 AnEnum enum_ret<T, T2>(T t, T2 t2) where T: IReturnVType;
1110 int normal_args<T, T2> (T t, T2 t2, int i1, int i2, string s, ref int i3, Foo foo) where T : IConstrained2;
1113 public interface IReturnVType {
1114 Pair<int, int> return_vtype ();
1115 AnEnum return_enum ();
1118 public interface IConstrained2 {
1119 int normal_args (int i1, int i2, string s, ref int i3, Foo foo);
1122 public class CConstrainedCalls : IConstrainedCalls {
1123 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1124 public Pair<int, int> vtype_ret<T, T2>(T t, T2 t2) where T : IReturnVType {
1125 return t.return_vtype ();
1128 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1129 public AnEnum enum_ret<T, T2>(T t, T2 t2) where T : IReturnVType {
1130 return t.return_enum ();
1133 public int normal_args<T, T2> (T t, T2 t2, int i1, int i2, string s, ref int i3, Foo foo) where T : IConstrained2 {
1134 return t.normal_args (i1, i2, s, ref i3, foo);
1138 class ReturnVType : IReturnVType {
1139 public Pair<int, int> return_vtype () {
1140 return new Pair<int, int> () { First = 1, Second = 2 };
1142 public AnEnum return_enum () {
1143 return AnEnum.Two;
1147 class ConstrainedCalls : IConstrained2 {
1148 public int normal_args (int i1, int i2, string s, ref int i3, Foo foo) {
1149 i3 = i3 + 1;
1150 return i1 + i2 + i3 + s.Length + foo.i + foo.n;
1154 public static int test_0_constrained_vtype_ret () {
1155 IConstrainedCalls c = new CConstrainedCalls ();
1156 var r = c.vtype_ret<ReturnVType, int> (new ReturnVType (), 1);
1157 if (r.First != 1 || r.Second != 2)
1158 return 1;
1159 return 0;
1162 public static int test_0_constrained_enum_ret () {
1163 IConstrainedCalls c = new CConstrainedCalls ();
1164 var r = c.enum_ret<ReturnVType, int> (new ReturnVType (), 1);
1165 if (r != AnEnum.Two)
1166 return 1;
1167 return 0;
1170 public static int test_25_constrained_normal_args () {
1171 IConstrainedCalls c = new CConstrainedCalls ();
1173 Foo foo = new Foo () { i = 5, n = 6 };
1174 int val = 3;
1175 var r = c.normal_args<ConstrainedCalls, int> (new ConstrainedCalls (), 0, 1, 2, "ABC", ref val, foo);
1176 return r + val;
1179 public struct Pair<T1, T2> {
1180 public T1 First;
1181 public T2 Second;
1184 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1185 public static TState call_del<TState>(TState state, Func<object, TState, TState> action) {
1186 return action(null, state);
1189 [Category ("!FULLAOT")]
1190 public static int test_0_delegate_wrappers () {
1191 Func<object, Pair<int, int>, Pair<int, int>> del1 = delegate (object o, Pair<int, int> p) { return p; };
1192 Func<object, Pair<int, int>, Pair<int, int>> del2 = delegate (object o, Pair<int, int> p) { return p; };
1193 Func<object, Pair<double, int>, Pair<double, int>> del3 = delegate (object o, Pair<double, int> p) { return p; };
1194 var r1 = call_del<Pair<int, int>> (new Pair<int, int> { First = 1, Second = 2}, del1);
1195 if (r1.First != 1 || r1.Second != 2)
1196 return 1;
1197 var r2 = call_del<Pair<int, int>> (new Pair<int, int> { First = 3, Second = 4}, del2);
1198 if (r2.First != 3 || r2.Second != 4)
1199 return 2;
1200 var r3 = call_del<Pair<double, int>> (new Pair<double, int> { First = 1.0, Second = 2}, del3);
1201 if (r3.First != 1.0 || r3.Second != 2)
1202 return 3;
1203 return 0;
1206 class Base<T> {
1207 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1208 public object foo<T1> (T1 t1, T t, object o) {
1209 return o;
1213 class AClass : Base<long> {
1215 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1216 public object bar<T> (T t, long time, object o) {
1217 return foo (t, time, o);
1221 public static int test_0_out_in_wrappers () {
1222 var a = new AClass ();
1223 object o1 = "A";
1224 object o2 = a.bar<long> (1024, 0, o1);
1225 if (o1 != o2)
1226 return 1;
1227 return 0;
1230 interface BIFace {
1231 object AMethod ();
1234 class Base<TAbsolute, T2> : BIFace {
1236 public TAbsolute Clock { get; set; }
1238 public virtual object AMethod () {
1239 return Clock;
1243 class BClass : Base<long, long> {
1246 public static int test_0_regress_1 () {
1247 BIFace c = new BClass ();
1248 object o = c.AMethod ();
1249 if (!(o is long) || ((long)o != 0))
1250 return 1;
1251 return 0;
1254 interface IFace3 {
1255 T unbox_any<T> (object o);
1258 class Class3 : IFace3 {
1259 public virtual T unbox_any<T> (object o) {
1260 return (T)o;
1264 public static int test_0_unbox_any () {
1265 IFace3 o = new Class3 ();
1266 if (o.unbox_any<int> (16) != 16)
1267 return 1;
1268 if (o.unbox_any<long> ((long)32) != 32)
1269 return 2;
1270 if (o.unbox_any<double> (2.0) != 2.0)
1271 return 3;
1272 try {
1273 o.unbox_any<int> (2.0);
1274 return 4;
1275 } catch (Exception) {
1277 return 0;
1280 interface IFace4 {
1281 TSource Catch<TSource, TException>(TSource t) where TException : Exception;
1284 class Class4 : IFace4 {
1285 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1286 public TSource Catch<TSource, TException>(TSource t) where TException : Exception {
1287 return t;
1291 // Check that mixed instantiations are correctly created/found in AOT
1292 public static int test_0_constraints () {
1293 IFace4 o = new Class4 ();
1294 o.Catch<int, Exception> (1);
1295 return 0;
1298 internal static Type Process<TSource, TElement> (TSource[] arr, Action<TElement, TElement> call) {
1299 arr [0] = default (TSource);
1300 return typeof (TSource);
1303 interface IFace5 {
1304 Type foo<T> ();
1307 class Class5 : IFace5 {
1308 public Type foo<T> () {
1309 return Process<KeyValuePair<long, T>, T> (new KeyValuePair<long, T> [10], null);
1313 public static int test_0_rgctx_call_from_gshared_code () {
1314 var c = new Class5 ();
1315 if (c.foo<string> () != typeof (KeyValuePair<long, string>))
1316 return 1;
1317 return 0;
1320 public class Enumbers<T> {
1321 public object Enumerate (List<KeyValuePair<T, string>> alist)
1323 return alist.ToArray ();
1327 public static int test_0_checkthis_gshared_call () {
1328 Enumbers<string> e = new Enumbers<string> ();
1329 try {
1330 e.Enumerate (null);
1331 return 1;
1333 catch (NullReferenceException) {
1335 return 0;
1338 interface IFace6 {
1339 T[] Del<T> (T t);
1342 class Class6 : IFace6 {
1343 public T[] Del<T> (T t) {
1344 var res = new T [5];
1345 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; };
1346 var v = func.BeginInvoke(t, t, t, t, null, null);
1347 res [4] = func.EndInvoke (v);
1348 return res;
1352 // FIXME: Wasm is single threaded and can't handle blocking waits
1353 [Category ("!WASM")]
1354 public static int test_0_begin_end_invoke () {
1355 IFace6 o = new Class6 ();
1356 var arr1 = o.Del (1);
1357 if (arr1 [0] != 1 || arr1 [1] != 1 || arr1 [2] != 1 || arr1 [3] != 1 || arr1 [4] != 1)
1358 return 1;
1359 var arr2 = o.Del (2.0);
1360 if (arr2 [0] != 2.0 || arr2 [1] != 2.0 || arr2 [2] != 2.0 || arr2 [3] != 2.0 || arr2 [4] != 2.0)
1361 return 2;
1362 return 0;
1365 public class TAbstractTableItem<TC> {
1366 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1367 public static void SetProperty<TV> () { }
1369 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1370 public static void Test () {
1371 SetProperty<bool> ();
1375 public static int test_0_gsharedvt_method_on_shared_class () {
1376 TAbstractTableItem<object>.Test ();
1377 return 0;
1380 interface IFaceBox {
1381 object box<T> (T t);
1382 bool is_null<T> (T t);
1385 class ClassBox : IFaceBox {
1386 public object box<T> (T t) {
1387 object o = t;
1388 return o;
1391 public bool is_null<T> (T t) {
1392 if (!(default(T) == null))
1393 return false;
1394 return true;
1398 public static int test_0_nullable_box () {
1399 IFaceBox c = new ClassBox ();
1400 int i = 5;
1401 object o = c.box<int?> (i);
1402 if ((int)o != i)
1403 return 1;
1404 if (c.box<int?> (null) != null)
1405 return 2;
1406 long l = Int64.MaxValue - 1;
1407 o = c.box<long?> (l);
1408 if ((long)o != l)
1409 return 3;
1410 if (c.box<long?> (null) != null)
1411 return 4;
1412 string s = "A";
1413 if (c.box<string> (s) != (object)s)
1414 return 5;
1415 return 0;
1418 public static int test_0_nullable_box_brtrue_opt () {
1419 IFaceBox c = new ClassBox ();
1421 if (c.is_null<double?> (null))
1422 return 0;
1423 else
1424 return 1;
1427 interface IFaceUnbox2 {
1428 T unbox<T> (object o);
1431 class ClassUnbox2 : IFaceUnbox2 {
1432 public T unbox<T> (object o) {
1433 return (T)o;
1437 public static int test_0_nullable_unbox () {
1438 IFaceUnbox2 c = new ClassUnbox2 ();
1439 int? i = c.unbox<int?> (5);
1440 if (i != 5)
1441 return 1;
1442 int? j = c.unbox<int?> (null);
1443 if (j != null)
1444 return 2;
1445 return 0;
1448 interface IConstrained {
1449 void foo ();
1450 void foo_ref_arg (string s);
1453 interface IConstrained<T3> {
1454 void foo_gsharedvt_arg (T3 s);
1455 T3 foo_gsharedvt_ret (T3 s);
1458 static object constrained_res;
1460 struct ConsStruct : IConstrained {
1461 public int i;
1463 public void foo () {
1464 constrained_res = i;
1467 public void foo_ref_arg (string s) {
1468 constrained_res = s == "A" ? 42 : 0;
1472 class ConsClass : IConstrained {
1473 public int i;
1475 public void foo () {
1476 constrained_res = i;
1479 public void foo_ref_arg (string s) {
1480 constrained_res = s == "A" ? 43 : 0;
1484 struct ConsStruct<T> : IConstrained<T> {
1485 public void foo_gsharedvt_arg (T s) {
1486 constrained_res = s;
1489 public T foo_gsharedvt_ret (T s) {
1490 return s;
1494 struct ConsStructThrow : IConstrained {
1495 public void foo () {
1496 throw new Exception ();
1499 public void foo_ref_arg (string s) {
1503 interface IFaceConstrained {
1504 void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained;
1505 void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained;
1506 void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1507 T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1508 T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass;
1511 class ClassConstrained : IFaceConstrained {
1512 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1513 public void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained {
1514 t2.foo ();
1517 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1518 public void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained {
1519 t2.foo_ref_arg ("A");
1522 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1523 public void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1524 t2.foo_gsharedvt_arg (t);
1527 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1528 public T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1529 return t2.foo_gsharedvt_ret (t);
1532 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1533 public T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass {
1534 /* This becomes a constrained call even through 't2' is forced to be a reference type by the constraint */
1535 return (T2)t2.foo (5);
1539 class VClass {
1540 public virtual VClass foo (int i) {
1541 return this;
1545 public static int test_0_constrained_void_iface_call () {
1546 IFaceConstrained c = new ClassConstrained ();
1547 var s = new ConsStruct () { i = 42 };
1548 constrained_res = null;
1549 c.constrained_void_iface_call<int, ConsStruct> (1, s);
1550 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1551 return 1;
1552 constrained_res = null;
1553 c.constrained_void_iface_call_ref_arg<int, ConsStruct> (1, s);
1554 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1555 return 2;
1556 var s2 = new ConsClass () { i = 43 };
1557 constrained_res = null;
1558 c.constrained_void_iface_call<int, ConsClass> (1, s2);
1559 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1560 return 3;
1561 constrained_res = null;
1562 c.constrained_void_iface_call_ref_arg<int, ConsClass> (1, s2);
1563 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1564 return 4;
1565 return 0;
1568 public static int test_0_constrained_eh () {
1569 var s2 = new ConsStructThrow () { };
1570 try {
1571 IFaceConstrained c = new ClassConstrained ();
1572 c.constrained_void_iface_call<int, ConsStructThrow> (1, s2);
1573 return 1;
1574 } catch (Exception) {
1575 return 0;
1579 public static int test_0_constrained_void_iface_call_gsharedvt_arg () {
1580 // This tests constrained calls through interfaces with one gsharedvt arg, like IComparable<T>.CompareTo ()
1581 IFaceConstrained c = new ClassConstrained ();
1583 var s = new ConsStruct<int> ();
1584 constrained_res = null;
1585 c.constrained_void_iface_call_gsharedvt_arg<int, ConsStruct<int>, int> (42, s, 55);
1586 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1587 return 1;
1589 var s2 = new ConsStruct<string> ();
1590 constrained_res = null;
1591 c.constrained_void_iface_call_gsharedvt_arg<string, ConsStruct<string>, int> ("A", s2, 55);
1592 if (!(constrained_res is string) || ((string)constrained_res) != "A")
1593 return 2;
1595 return 0;
1598 public static int test_0_constrained_iface_call_gsharedvt_ret () {
1599 IFaceConstrained c = new ClassConstrained ();
1601 var s = new ConsStruct<int> ();
1602 int ires = c.constrained_iface_call_gsharedvt_ret<int, ConsStruct<int>, int> (42, s, 55);
1603 if (ires != 42)
1604 return 1;
1606 var s2 = new ConsStruct<string> ();
1607 string sres = c.constrained_iface_call_gsharedvt_ret<string, ConsStruct<string>, int> ("A", s2, 55);
1608 if (sres != "A")
1609 return 2;
1611 return 0;
1614 public static int test_0_constrained_normal_call () {
1615 IFaceConstrained c = new ClassConstrained ();
1617 var o = new VClass ();
1618 var res = c.constrained_normal_call<int, VClass> (1, o);
1619 return res == o ? 0 : 1;
1622 public static async Task<T> FooAsync<T> (int i, int j) {
1623 Task<int> t = new Task<int> (delegate () { return 42; });
1624 var response = await t;
1625 return default(T);
1628 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1629 public static void call_async<T> (int i, int j) {
1630 Task<T> t = FooAsync<T> (1, 2);
1631 // FIXME: This doesn't work
1632 //t.RunSynchronously ();
1635 // In AOT mode, the async infrastructure depends on gsharedvt methods
1636 public static int test_0_async_call_from_generic () {
1637 call_async<string> (1, 2);
1638 return 0;
1641 public static int test_0_array_helper_gsharedvt () {
1642 var arr = new AnEnum [16];
1643 var c = new ReadOnlyCollection<AnEnum> (arr);
1644 return c.Contains (AnEnum.Two) == false ? 0 : 1;
1647 interface IFaceCallPatching {
1648 bool caller<T, T2> ();
1651 class CallPatching2<T> {
1652 T t;
1653 public object o;
1655 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1656 public bool callee () {
1657 return (string)o == "ABC";
1661 class CallPatching : IFaceCallPatching {
1662 public bool caller<T, T2> () {
1663 var c = new CallPatching2<T> ();
1664 c.o = "ABC";
1665 return c.callee ();
1670 // This tests that generic calls made from gsharedvt methods are not patched normally.
1671 // If they are, the first call to 'caller' would patch in the gshared version of
1672 // 'callee', causing the second call to fail because the gshared version of callee
1673 // wouldn't work with CallPatching2<bool> since it has a different object layout.
1675 public static int test_0_call_patching () {
1676 IFaceCallPatching c = new CallPatching ();
1677 c.caller<object, bool> ();
1678 if (!c.caller<bool, bool> ())
1679 return 1;
1680 return 0;
1683 struct EmptyStruct {
1686 public struct BStruct {
1687 public int a, b, c, d;
1690 interface IFoo3<T> {
1691 int Bytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1692 byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8);
1693 int SBytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1694 sbyte b1, sbyte b2, sbyte b3, sbyte b4);
1695 int Shorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1696 short b1, short b2, short b3, short b4);
1697 int UShorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1698 ushort b1, ushort b2, ushort b3, ushort b4);
1699 int Ints (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1700 int i1, int i2, int i3, int i4);
1701 int UInts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1702 uint i1, uint i2, uint i3, uint i4);
1703 int Structs (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1704 BStruct s);
1705 int Floats (T t, double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8,
1706 double d9, double d10, float s11, float s12);
1707 void Generic<T2> (T t, T2[] arr, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1708 T2 i1, T2 i2, T2 i3, T2 i4);
1711 class Foo3<T> : IFoo3<T> {
1712 public int Bytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1713 byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7, byte b8) {
1714 return b1 + b2 + b3 + b4 + b5 + b6 + b7 + b8;
1716 public int SBytes (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1717 sbyte b1, sbyte b2, sbyte b3, sbyte b4) {
1718 return b1 + b2 + b3 + b4;
1720 public 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 return b1 + b2 + b3 + b4;
1724 public int UShorts (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1725 ushort b1, ushort b2, ushort b3, ushort b4) {
1726 return b1 + b2 + b3 + b4;
1728 public int Ints (T t, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8,
1729 int i1, int i2, int i3, int i4) {
1730 return i1 + i2 + i3 + i4;
1732 public int UInts (T t, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8,
1733 uint i1, uint i2, uint i3, uint i4) {
1734 return (int)(i1 + i2 + i3 + i4);
1736 public int Structs (T t, int dummy1, int a2, int a3, int a4, int a5, int a6, int a7, int dummy8,
1737 BStruct s) {
1738 return s.a + s.b + s.c + s.d;
1740 public int Floats (T t, double d1, double d2, double d3, double d4, double d5, double d6, double d7, double d8,
1741 double d9, double d10, float s11, float s12) {
1742 return (int)d9 + (int)d10 + (int)s11 + (int)s12;
1744 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) {
1745 arr [0] = i1;
1746 arr [1] = i2;
1747 arr [2] = i3;
1748 arr [3] = i4;
1752 // Passing small normal arguments on the stack
1753 public static int test_0_arm64_small_stack_args () {
1754 IFoo3<EmptyStruct> o = (IFoo3<EmptyStruct>)Activator.CreateInstance (typeof (Foo3<>).MakeGenericType (new Type [] { typeof (EmptyStruct) }));
1755 int res = o.Bytes (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8);
1756 if (res != 36)
1757 return 1;
1758 int res2 = o.SBytes (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1759 if (res2 != -10)
1760 return 2;
1761 int res3 = o.Shorts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1762 if (res3 != -10)
1763 return 3;
1764 int res4 = o.UShorts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
1765 if (res4 != 10)
1766 return 4;
1767 int res5 = o.Ints (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, -1, -2, -3, -4);
1768 if (res5 != -10)
1769 return 5;
1770 int res6 = o.UInts (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
1771 if (res6 != 10)
1772 return 6;
1773 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);
1774 if (res7 != 100)
1775 return 7;
1776 int[] arr = new int [4];
1777 o.Generic<int> (new EmptyStruct (), arr, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
1778 if (arr [0] != 1 || arr [1] != 2 || arr [2] != 3 || arr [3] != 4)
1779 return 8;
1780 return 0;
1783 interface ISmallArg {
1784 T foo<T> (string s1, string s2, string s3, string s4, string s5, string s6, string s7, string s8,
1785 string s9, string s10, string s11, string s12, string s13, T t);
1788 class SmallArgClass : ISmallArg {
1789 public T foo<T> (string s1, string s2, string s3, string s4, string s5, string s6, string s7, string s8,
1790 string s9, string s10, string s11, string s12, string s13, T t) {
1791 return t;
1795 public static int test_1_small_gsharedvt_stack_arg_ios () {
1796 ISmallArg o = new SmallArgClass ();
1797 return o.foo<int> ("", "", "", "", "", "", "", "", "", "", "", "", "", 1);
1800 // Passing vtype normal arguments on the stack
1801 public static int test_0_arm64_vtype_stack_args () {
1802 IFoo3<EmptyStruct> o = (IFoo3<EmptyStruct>)Activator.CreateInstance (typeof (Foo3<>).MakeGenericType (new Type [] { typeof (EmptyStruct) }));
1803 int res = o.Structs (new EmptyStruct (), 1, 2, 3, 4, 5, 6, 7, 8, new BStruct () { a = 1, b = 2, c = 3, d = 4 });
1804 if (res != 10)
1805 return 1;
1806 return 0;
1809 interface IFoo4<T> {
1810 T Get(T[,] arr, T t);
1813 class Foo4<T> : IFoo4<T> {
1814 public T Get(T[,] arr, T t) {
1815 arr [1, 1] = t;
1816 return arr [1, 1];
1820 struct AStruct {
1821 public int a, b;
1823 public override int GetHashCode () {
1824 return 0;
1827 public override bool Equals (object o) {
1828 if (!(o is AStruct))
1829 return false;
1830 AStruct s = (AStruct)o;
1831 return a == s.a && b == s.b;
1835 public static int test_0_multi_dim_arrays_2 () {
1836 IFoo4<int> foo = new Foo4<int> ();
1837 var arr = new int [10, 10];
1838 int res = foo.Get (arr, 10);
1839 if (res != 10)
1840 return 1;
1842 IFoo4<AStruct> foo2 = new Foo4<AStruct> ();
1843 var arr2 = new AStruct [10, 10];
1844 var res2 = foo2.Get (arr2, new AStruct () { a = 1, b = 2 });
1845 if (res2.a != 1 || res2.b != 2)
1846 return 2;
1847 return 0;
1850 public interface IFaceTest {
1851 int iface_method ();
1854 public interface IFaceConstrainedIFace {
1855 int foo<T, T2> (ref T val) where T: IFaceTest;
1858 class ConstrainedIFace : IFaceConstrainedIFace {
1859 public int foo<T, T2> (ref T val) where T: IFaceTest {
1860 return val.iface_method ();
1864 class ClassTest : IFaceTest {
1865 public int iface_method () {
1866 return 42;
1870 struct StructTest : IFaceTest {
1872 int i;
1874 public StructTest (int arg) {
1875 i = arg;
1878 public int iface_method () {
1879 return i;
1883 // Test constrained calls on an interface made from gsharedvt methods
1884 public static int test_42_gsharedvt_constrained_iface () {
1885 IFaceConstrainedIFace obj = new ConstrainedIFace ();
1886 IFaceTest t = new ClassTest ();
1887 return obj.foo<IFaceTest, int> (ref t);
1890 public static int test_42_gsharedvt_constrained_iface_vtype () {
1891 IFaceConstrainedIFace obj = new ConstrainedIFace ();
1892 IFaceTest t = new StructTest (42);
1893 return obj.foo<IFaceTest, int> (ref t);
1897 class MyBaseTest<TOutput> {
1898 public void Verify<TInput> (Func<TInput, TOutput> convert, TInput[] testValues, TOutput[] expectedValues) {
1899 MyAssert.Equal (expectedValues.Length, testValues.Length);
1901 for (int i = 0; i < testValues.Length; i++) {
1902 TOutput result = convert (testValues[i]);
1903 MyAssert.Equal (expectedValues[i], result);
1908 class MyAssert {
1909 public static void Equal<T>(T expected, T actual) {
1910 if (!GetEqualityComparer<T> ().Equals (expected, actual))
1911 throw new MyEqualException (expected, actual);
1914 static IEqualityComparer<T> GetEqualityComparer<T>() {
1915 return new AssertEqualityComparer<T>();
1919 class AssertEqualityComparer<T> : IEqualityComparer<T> {
1920 public AssertEqualityComparer() { }
1922 public bool Equals(T x, T y) {
1923 var equatable = x as IEquatable<T>;
1924 if (equatable != null)
1925 return equatable.Equals (y);
1926 throw new NotImplementedException( );
1929 public int GetHashCode(T obj) {
1930 throw new NotImplementedException();
1934 class MyEqualException : Exception {
1935 public MyEqualException (object expected, object actual) {
1936 Console.WriteLine ("MyEqualException: expected = " + expected + " vs. actual = " + actual);
1940 class SByteTestClass : MyBaseTest<sbyte> {
1941 public static int execute () {
1942 Int32[] testValues = { 100, -100, 0 };
1943 SByte[] expectedValues = { 100, -100, 0 };
1944 try {
1945 new SByteTestClass ().Verify (Convert.ToSByte, testValues, expectedValues);
1946 return 0;
1947 } catch (MyEqualException) {
1948 return 1;
1950 return 2;
1953 static int test_0_out_sbyte () {
1954 return SByteTestClass.execute ();
1957 class Int16TestClass : MyBaseTest<Int16> {
1958 public static int execute () {
1959 Int32[] testValues = { 100, -100, 0 };
1960 Int16[] expectedValues = { 100, -100, 0 };
1961 try {
1962 new Int16TestClass ().Verify (Convert.ToInt16, testValues, expectedValues);
1963 return 0;
1964 } catch (MyEqualException) {
1965 return 1;
1967 return 2;
1970 static int test_0_out_int16 () {
1971 return Int16TestClass.execute ();
1974 // Sign extension tests
1975 // 0x55 == 85 == 01010101
1976 // 0xAA == 170 == 10101010
1977 // 0x5555 == 21845 == 0101010101010101
1978 // 0xAAAA == 43690 == 1010101010101010
1979 // 0x55555555 == 1431655765
1980 // 0xAAAAAAAA == 2863311530
1981 // 0x5555555555555555 == 6148914691236517205
1982 // 0xAAAAAAAAAAAAAAAA == 12297829382473034410
1984 public interface SEFace<T> {
1985 T Copy (int a, int b, int c, int d, T t);
1988 class SEClass<T> : SEFace<T> {
1989 public T Copy (int a, int b, int c, int d, T t) {
1990 return t;
1994 // Test extension
1995 static int test_20_signextension_sbyte () {
1996 Type t = typeof (sbyte);
1997 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
1998 var i = (SEFace<sbyte>)o;
2000 long zz = i.Copy (1,2,3,4,(sbyte)(-0x55));
2002 bool success = zz == -0x55;
2003 return success ? 20 : 1;
2006 static int test_20_signextension_byte () {
2007 Type t = typeof (byte);
2008 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
2009 var i = (SEFace<byte>)o;
2011 ulong zz = i.Copy (1,2,3,4,(byte)(0xAA));
2013 bool success = zz == 0xAA;
2014 return success ? 20 : 1;
2017 static int test_20_signextension_short () {
2018 Type t = typeof (short);
2019 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
2020 var i = (SEFace<short>)o;
2022 long zz = i.Copy (1,2,3,4,(short)(-0x5555));
2024 bool success = zz == -0x5555;
2025 return success ? 20 : 1;
2028 static int test_20_signextension_ushort () {
2029 Type t = typeof (ushort);
2030 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
2031 var i = (SEFace<ushort>)o;
2033 ulong zz = i.Copy (1,2,3,4,(ushort)(0xAAAA));
2035 bool success = zz == 0xAAAA;
2036 return success ? 20 : 1;
2039 static int test_20_signextension_int () {
2040 Type t = typeof (int);
2041 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
2042 var i = (SEFace<int>)o;
2044 long zz = i.Copy (1,2,3,4,(int)(-0x55555555));
2046 bool success = zz == -0x55555555;
2047 return success ? 20 : 1;
2050 static int test_20_signextension_uint () {
2051 Type t = typeof (uint);
2052 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
2053 var i = (SEFace<uint>)o;
2055 ulong zz = i.Copy (1,2,3,4,(uint)(0xAAAAAAAA));
2057 bool success = zz == 0xAAAAAAAA;
2058 return success ? 20 : 1;
2061 static int test_20_signextension_long () {
2062 Type t = typeof (long);
2063 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
2064 var i = (SEFace<long>)o;
2066 long zz = i.Copy (1,2,3,4,(long)(-0x5555555555555555));
2068 bool success = zz == -0x5555555555555555;
2069 return success ? 20 : 1;
2072 static int test_20_signextension_ulong () {
2073 Type t = typeof (ulong);
2074 object o = Activator.CreateInstance (typeof (SEClass<>).MakeGenericType (new Type[] { t }));
2075 var i = (SEFace<ulong>)o;
2077 ulong zz = i.Copy (1,2,3,4,(ulong)(0xAAAAAAAAAAAAAAAA));
2079 bool success = zz == 0xAAAAAAAAAAAAAAAA;
2080 return success ? 20 : 1;
2083 void gsharedvt_try_at_offset_0<T> (ref T disposable)
2084 where T : class, IDisposable {
2085 try {
2086 disposable.Dispose ();
2087 } finally {
2088 disposable = null;
2092 [MethodImplAttribute (MethodImplOptions.NoInlining)]
2093 static DateTimeOffset gsharedvt_vphi_inner<T> (T t) {
2094 return DateTimeOffset.MinValue;
2097 static DateTimeOffset gsharedvt_vphi<T> (T t) {
2098 int[] arr = new int [10];
2100 try {
2101 DateTimeOffset v;
2102 if (arr [0] == 0)
2103 v = gsharedvt_vphi_inner (t);
2104 else
2105 v = gsharedvt_vphi_inner (t);
2106 return v;
2107 } catch {
2108 return DateTimeOffset.MinValue;
2112 static int test_0_gsharedvt_vphi_volatile () {
2113 gsharedvt_vphi (0);
2114 return 0;
2117 struct AStruct3<T1, T2, T3> {
2118 T1 t1;
2119 T2 t2;
2120 T3 t3;
2123 interface IFaceIsRef {
2124 bool is_ref<T> ();
2127 class ClassIsRef : IFaceIsRef {
2128 [MethodImplAttribute (MethodImplOptions.NoInlining)]
2129 public bool is_ref<T> () {
2130 return RuntimeHelpers.IsReferenceOrContainsReferences<T> ();
2134 public static int test_0_isreference_intrins () {
2135 IFaceIsRef iface = new ClassIsRef ();
2136 if (iface.is_ref<AStruct3<int, int, int>> ())
2137 return 1;
2138 if (!iface.is_ref<AStruct3<string, int, int>> ())
2139 return 2;
2140 return 0;
2143 interface IFace59956 {
2144 int foo<T> ();
2147 class Impl59956 : IFace59956 {
2148 public int foo<T> () {
2149 var builder = new SparseArrayBuilder<T>(true);
2151 return builder.Markers._count;
2155 public static int test_1_59956_regress () {
2156 IFace59956 iface = new Impl59956 ();
2157 return iface.foo<int> ();
2160 interface IFaceSpan {
2161 int foo<T> (T t);
2164 class ImplSpan : IFaceSpan {
2165 public int foo<T> (T t) {
2166 var arr = new T[10];
2167 var arr2 = new T[10];
2168 var s = new Span<T> (arr);
2170 s [0] = t;
2171 T t2 = s [0];
2172 if (!t.Equals (t2))
2173 return 1;
2175 var s2 = new Span<T> (arr2);
2176 s.CopyTo (s2);
2177 t2 = s2 [0];
2178 if (!t.Equals (t2))
2179 return 2;
2181 s.Clear ();
2182 t2 = s [0];
2183 if (!t2.Equals (default(T)))
2184 return 3;
2186 return 0;
2190 public static int test_0_span () {
2191 IFaceSpan iface = new ImplSpan ();
2192 var s = new AStruct () { a = 1, b = 2 };
2193 return iface.foo<AStruct> (s);
2197 // #13191
2198 public class MobileServiceCollection<TTable, TCol>
2200 public async Task<int> LoadMoreItemsAsync(int count = 0) {
2201 await Task.Delay (1000);
2202 int results = await ProcessQueryAsync ();
2203 return results;
2206 protected async virtual Task<int> ProcessQueryAsync() {
2207 await Task.Delay (1000);
2208 throw new Exception ();
2212 // #59956
2213 internal struct Marker
2215 public Marker(int count, int index) {
2219 public struct ArrayBuilder<T>
2221 private T[] _array;
2222 public int _count;
2224 public ArrayBuilder(int capacity) {
2225 _array = new T[capacity];
2226 _count = 1;
2230 internal struct SparseArrayBuilder<T>
2232 private ArrayBuilder<Marker> _markers;
2234 public SparseArrayBuilder(bool initialize) : this () {
2235 _markers = new ArrayBuilder<Marker> (10);
2238 public ArrayBuilder<Marker> Markers => _markers;
2241 #if !__MOBILE__
2242 public class GSharedTests : Tests {
2244 #endif