[amd64] Remove the callee saved registers from MonoLMF, save/restore them normally...
[mono-project.git] / mono / mini / gshared.cs
blobfe65826ce4dd492759a57dec0abf4bd9a5cb5162
1 using System;
2 using System.Collections.Generic;
3 using System.Collections.ObjectModel;
4 using System.Runtime.CompilerServices;
5 using System.Threading.Tasks;
7 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.
43 // FIXME: Add mixed ref/noref tests, i.e. Dictionary<string, int>
45 #if MOBILE
46 public class GSharedTests
47 #else
48 public class Tests
49 #endif
51 #if !MOBILE
52 public static int Main (String[] args) {
53 return TestDriver.RunTests (typeof (Tests), args);
55 #endif
57 [MethodImplAttribute (MethodImplOptions.NoInlining)]
58 static void gshared<T> (T [] array, int i, int j) {
59 T tmp = array [i];
60 array [i] = array [j];
61 array [j] = tmp;
64 // Test that the gshared and gsharedvt versions don't mix
65 public static int test_0_vt_gshared () {
66 string[] sarr = new string [2] { "A", "B" };
68 gshared<string> (sarr, 0, 1);
70 Foo[] arr = new Foo [2];
71 arr [0] = new Foo () { i = 1, j = 2 };
72 arr [1] = new Foo () { i = 3, j = 4 };
74 gshared<Foo> (arr, 0, 1);
75 if (arr [0].i != 3 || arr [0].j != 4)
76 return 1;
77 if (arr [1].i != 1 || arr [1].j != 2)
78 return 2;
80 return 0;
83 static void ldelem_stelem<T> (T [] array, int i, int j) {
84 T tmp = array [i];
85 array [i] = array [j];
86 array [j] = tmp;
89 public static int test_0_vt_ldelem_stelem () {
90 Foo[] arr = new Foo [2];
91 arr [0] = new Foo () { i = 1, j = 2 };
92 arr [1] = new Foo () { i = 3, j = 4 };
94 ldelem_stelem<Foo> (arr, 0, 1);
95 if (arr [0].i != 3 || arr [0].j != 4)
96 return 1;
97 if (arr [1].i != 1 || arr [1].j != 2)
98 return 2;
100 int[] arr2 = new int [2] { 1, 2 };
101 ldelem_stelem<int> (arr2, 0, 1);
102 if (arr2 [0] !=2 || arr2 [1] != 1)
103 return 3;
105 return 0;
108 [MethodImplAttribute (MethodImplOptions.NoInlining)]
109 private static void initobj<T> (T [] array, int i, int j) {
110 T x = default(T);
111 array [i] = x;
114 public static int test_0_vt_initobj () {
115 Foo[] arr = new Foo [2];
116 arr [0] = new Foo () { i = 1, j = 2 };
117 arr [1] = new Foo () { i = 3, j = 4 };
119 initobj<Foo> (arr, 0, 1);
120 if (arr [0].i != 0 || arr [0].j != 0)
121 return 1;
122 if (arr [1].i != 3 || arr [1].j != 4)
123 return 2;
124 return 0;
127 [MethodImplAttribute (MethodImplOptions.NoInlining)]
128 static T ldobj_stobj<T> (ref T t1, ref T t2) {
129 t1 = t2;
130 T t = t2;
131 t2 = default(T);
132 return t;
135 public static int test_0_vt_ldobj_stobj () {
136 int i = 5;
137 int j = 6;
138 if (ldobj_stobj (ref i, ref j) != 6)
139 return 1;
140 if (i != 6 || j != 0)
141 return 2;
142 double d1 = 1.0;
143 double d2 = 2.0;
144 if (ldobj_stobj (ref d1, ref d2) != 2.0)
145 return 3;
146 if (d1 != 2.0 || d2 != 0.0)
147 return 4;
148 return 0;
151 [MethodImplAttribute (MethodImplOptions.NoInlining)]
152 private static void box<T1, T> (T [] array, object[] arr) {
153 object x = array [0];
154 arr [0] = x;
157 public static int test_0_vt_box () {
158 Foo[] arr = new Foo [2];
159 arr [0] = new Foo () { i = 1, j = 2 };
161 object[] arr2 = new object [16];
162 box<int, Foo> (arr, arr2);
163 if (arr2 [0].GetType () != typeof (Foo))
164 return 1;
165 Foo f = (Foo)arr2 [0];
166 if (f.i != 1 || f.j != 2)
167 return 2;
168 string[] arr3 = new string [16];
169 object[] arr4 = new object [16];
170 arr3 [0] = "OK";
171 box<int, string> (arr3, arr4);
172 if (arr4 [0] != (object)arr3 [0])
173 return 3;
174 return 0;
177 [MethodImplAttribute (MethodImplOptions.NoInlining)]
178 private static void unbox_any<T> (T [] array, object[] arr) {
179 T t = (T)arr [0];
180 array [0] = t;
183 public static int test_0_vt_unbox_any () {
184 int[] iarr = new int [16];
185 unbox_any<int> (iarr, new object [] { 12 });
187 Foo[] arr = new Foo [2];
189 object[] arr2 = new object [16];
190 arr2 [0] = new Foo () { i = 1, j = 2 };
191 unbox_any<Foo> (arr, arr2);
192 if (arr [0].i != 1 || arr [0].j != 2)
193 return 2;
194 return 0;
197 interface IFaceUnbox {
198 T Unbox<T, T2> (T t, T2 t2, object o);
201 class ClassUnbox : IFaceUnbox {
202 public T Unbox<T, T2> (T t, T2 t2, object o) {
203 return (T)o;
207 // unbox.any on a ref type in a gsharedvt method
208 public static int test_0_ref_gsharedvt_aot_unbox_any () {
209 IFaceUnbox iface = new ClassUnbox ();
210 string s = iface.Unbox<string, int> ("A", 2, "A");
211 if (s != "A")
212 return 1;
213 return 0;
216 public static int test_0_unbox_any_enum () {
217 IFaceUnbox iface = new ClassUnbox ();
218 AnEnum res = iface.Unbox<AnEnum, int> (AnEnum.One, 0, 1);
219 if (res != AnEnum.Two)
220 return 1;
221 res = iface.Unbox<AnEnum, int> (AnEnum.One, 0, AnEnum.Two);
222 if (res != AnEnum.Two)
223 return 2;
224 return 0;
227 [MethodImplAttribute (MethodImplOptions.NoInlining)]
228 static void ldfld_nongeneric<T> (GFoo<T>[] foo, int[] arr) {
229 arr [0] = foo [0].i;
232 [MethodImplAttribute (MethodImplOptions.NoInlining)]
233 static void ldfld<T> (GFoo<T>[] foo, T[] arr) {
234 arr [0] = foo [0].t;
237 [MethodImplAttribute (MethodImplOptions.NoInlining)]
238 static void stfld_nongeneric<T> (GFoo<T>[] foo, int[] arr) {
239 foo [0].i = arr [0];
242 [MethodImplAttribute (MethodImplOptions.NoInlining)]
243 static void stfld<T> (GFoo<T>[] foo, T[] arr) {
244 foo [0].t = arr [0];
247 [MethodImplAttribute (MethodImplOptions.NoInlining)]
248 static void ldflda<T> (GFoo<T>[] foo, int[] arr) {
249 arr [0] = foo [0].f.i;
252 public static int test_0_vt_ldfld_stfld () {
253 var foo = new GFoo<Foo> () { t = new Foo () { i = 1, j = 2 }, i = 5, f = new Foo () { i = 5, j = 6 } };
254 var farr = new GFoo<Foo>[] { foo };
256 /* Normal fields with a variable offset */
257 var iarr = new int [10];
258 ldfld_nongeneric<Foo> (farr, iarr);
259 if (iarr [0] != 5)
260 return 1;
261 iarr [0] = 16;
262 stfld_nongeneric<Foo> (farr, iarr);
263 if (farr [0].i != 16)
264 return 2;
266 /* Variable type field with a variable offset */
267 var arr = new Foo [10];
268 ldfld<Foo> (farr, arr);
269 if (arr [0].i != 1 || arr [0].j != 2)
270 return 3;
271 arr [0] = new Foo () { i = 3, j = 4 };
272 stfld<Foo> (farr, arr);
273 if (farr [0].t.i != 3 || farr [0].t.j != 4)
274 return 4;
276 ldflda<Foo> (farr, iarr);
277 if (iarr [0] != 5)
278 return 5;
280 return 0;
283 [MethodImplAttribute (MethodImplOptions.NoInlining)]
284 static void stsfld<T> (T[] arr) {
285 GFoo<T>.static_t = arr [0];
288 [MethodImplAttribute (MethodImplOptions.NoInlining)]
289 static void ldsfld<T> (T[] arr) {
290 arr [0] = GFoo<T>.static_t;
293 [MethodImplAttribute (MethodImplOptions.NoInlining)]
294 static void ldsflda<T> (int[] iarr) {
295 iarr [0] = GFoo<T>.static_f.i;
298 public static int test_0_stsfld () {
299 Foo[] farr = new Foo [] { new Foo () { i = 1, j = 2 } };
300 stsfld<Foo> (farr);
302 if (GFoo<Foo>.static_t.i != 1 || GFoo<Foo>.static_t.j != 2)
303 return 1;
305 Foo[] farr2 = new Foo [1];
306 ldsfld<Foo> (farr2);
307 if (farr2 [0].i != 1 || farr2 [0].j != 2)
308 return 2;
310 var iarr = new int [10];
311 GFoo<Foo>.static_f = new Foo () { i = 5, j = 6 };
312 ldsflda<Foo> (iarr);
313 if (iarr [0] != 5)
314 return 3;
316 return 0;
319 [MethodImplAttribute (MethodImplOptions.NoInlining)]
320 static object newarr<T> () {
321 object o = new T[10];
322 return o;
325 public static int test_0_vt_newarr () {
326 object o = newarr<Foo> ();
327 if (!(o is Foo[]))
328 return 1;
329 return 0;
332 [MethodImplAttribute (MethodImplOptions.NoInlining)]
333 static Type ldtoken<T> () {
334 return typeof (GFoo<T>);
337 public static int test_0_vt_ldtoken () {
338 Type t = ldtoken<Foo> ();
339 if (t != typeof (GFoo<Foo>))
340 return 1;
341 t = ldtoken<int> ();
342 if (t != typeof (GFoo<int>))
343 return 2;
345 return 0;
348 public static int test_0_vtype_list () {
349 List<int> l = new List<int> ();
351 l.Add (5);
352 if (l.Count != 1)
353 return 1;
354 return 0;
357 [MethodImplAttribute (MethodImplOptions.NoInlining)]
358 static int args_simple<T> (T t, int i) {
359 return i;
362 [MethodImplAttribute (MethodImplOptions.NoInlining)]
363 static int args_simple<T> (T t, int i, T t2) {
364 return i;
367 [MethodImplAttribute (MethodImplOptions.NoInlining)]
368 static Type args_rgctx<T> (T t, int i) {
369 return typeof (T);
372 [MethodImplAttribute (MethodImplOptions.NoInlining)]
373 static Type eh_in<T> (T t, int i) {
374 throw new OverflowException ();
377 [MethodImplAttribute (MethodImplOptions.NoInlining)]
378 static T return_t<T> (T t) {
379 return t;
382 [MethodImplAttribute (MethodImplOptions.NoInlining)]
383 T return_this_t<T> (T t) {
384 return t;
387 interface IFaceGSharedVtIn {
388 T return_t<T> (T t);
391 class ClassGSharedVtIn : IFaceGSharedVtIn {
392 public T return_t<T> (T t) {
393 return t;
397 public static int test_0_gsharedvt_in () {
398 // Check that the non-generic argument is passed at the correct stack position
399 int r = args_simple<bool> (true, 42);
400 if (r != 42)
401 return 1;
402 r = args_simple<Foo> (new Foo (), 43);
403 if (r != 43)
404 return 2;
405 // Check that the proper rgctx is passed to the method
406 Type t = args_rgctx<int> (5, 42);
407 if (t != typeof (int))
408 return 3;
409 var v = args_simple<GFoo2<int>> (new GFoo2<int> () { t = 11, t2 = 12 }, 44, new GFoo2<int> () { t = 11, t2 = 12 });
410 if (v != 44)
411 return 4;
412 // Check that EH works properly
413 try {
414 eh_in<int> (1, 2);
415 } catch (OverflowException) {
417 return 0;
420 public static int test_0_gsharedvt_in_ret () {
421 int i = return_t<int> (42);
422 if (i != 42)
423 return 1;
424 long l = return_t<long> (Int64.MaxValue);
425 if (l != Int64.MaxValue)
426 return 2;
427 double d = return_t<double> (3.0);
428 if (d != 3.0)
429 return 3;
430 float f = return_t<float> (3.0f);
431 if (f != 3.0f)
432 return 4;
433 short s = return_t<short> (16);
434 if (s != 16)
435 return 5;
436 var v = new GFoo2<int> () { t = 55, t2 = 32 };
437 var v2 = return_t<GFoo2<int>> (v);
438 if (v2.t != 55 || v2.t2 != 32)
439 return 6;
440 IFaceGSharedVtIn o = new ClassGSharedVtIn ();
441 var v3 = new GFoo2<long> () { t = 55, t2 = 32 };
442 var v4 = o.return_t<GFoo2<long>> (v3);
443 if (v4.t != 55 || v4.t2 != 32)
444 return 7;
445 i = new GSharedTests ().return_this_t<int> (42);
446 if (i != 42)
447 return 8;
448 return 0;
451 public static int test_0_gsharedvt_in_delegates () {
452 Func<int, int> f = new Func<int, int> (return_t<int>);
453 if (f (42) != 42)
454 return 1;
455 return 0;
458 [MethodImplAttribute (MethodImplOptions.NoInlining)]
459 static T return2_t<T> (T t) {
460 return return_t (t);
463 public static int test_0_gsharedvt_calls () {
464 if (return2_t (2) != 2)
465 return 1;
466 if (return2_t ("A") != "A")
467 return 2;
468 if (return2_t (2.0) != 2.0)
469 return 3;
470 return 0;
473 static GFoo3<T> newobj<T> (T t1, T t2) {
474 return new GFoo3<T> (t1, t2);
477 public static int test_0_gshared_new () {
478 var g1 = newobj (1, 2);
479 if (g1.t != 1 || g1.t2 != 2)
480 return 1;
481 var g2 = newobj (1.0, 2.0);
482 if (g1.t != 1.0 || g1.t2 != 2.0)
483 return 2;
485 return 0;
488 [MethodImplAttribute (MethodImplOptions.NoInlining)]
489 static GFoo2<T> newobj_vt<T> (T t1, T t2) {
490 return new GFoo2<T> () { t = t1, t2 = t2 };
493 public static int test_0_gshared_new_vt () {
494 GFoo2<int> v1 = newobj_vt (1, 2);
495 if (v1.t != 1 || v1.t2 != 2)
496 return 1;
497 GFoo2<double> v2 = newobj_vt (1.0, 2.0);
498 if (v2.t != 1.0 || v2.t2 != 2.0)
499 return 2;
500 return 0;
504 // Tests for transitioning out of gsharedvt code
507 // T1=Nullable<..> is not currently supported by gsharedvt
509 [MethodImplAttribute (MethodImplOptions.NoInlining)]
510 static T return_t_nogshared<T,T1> (T t) {
511 object o = t;
512 T t2 = (T)o;
513 //Console.WriteLine ("X: " + t);
514 return t;
517 [MethodImplAttribute (MethodImplOptions.NoInlining)]
518 static int return_int_nogshared<T,T1> (T t) {
519 object o = t;
520 T t2 = (T)o;
521 return 2;
524 [MethodImplAttribute (MethodImplOptions.NoInlining)]
525 static A return_vtype_nogshared<T,T1> (T t) {
526 object o = t;
527 T t2 = (T)o;
528 return new A () { a = 1, b = 2, c = 3 };
531 [MethodImplAttribute (MethodImplOptions.NoInlining)]
532 static T return2_t_out<T> (T t) {
533 return return_t_nogshared<T, int?> (t);
536 [MethodImplAttribute (MethodImplOptions.NoInlining)]
537 static int return2_int_out<T> (T t) {
538 return return_int_nogshared<T, int?> (t);
541 [MethodImplAttribute (MethodImplOptions.NoInlining)]
542 static A return2_vtype_out<T> (T t) {
543 return return_vtype_nogshared<T, int?> (t);
546 struct A {
547 public int a, b, c;
550 [Category ("!FULLAOT")]
551 public static int test_0_gsharedvt_out () {
552 if (return2_t_out (2) != 2)
553 return 1;
554 if (return2_t_out ("A") != "A")
555 return 2;
556 if (return2_t_out (2.0) != 2.0)
557 return 3;
558 if (return2_t_out (2.0f) != 2.0f)
559 return 4;
560 A a = new A () { a = 1, b = 2, c = 3 };
561 A a2 = return2_t_out (a);
562 if (a2.a != 1 || a2.b != 2 || a2.c != 3)
563 return 5;
564 // Calls with non gsharedvt return types
565 if (return2_int_out (1) != 2)
566 return 6;
567 A c = return2_vtype_out (a);
568 if (a2.a != 1 || a2.b != 2 || a2.c != 3)
569 return 7;
570 return 0;
573 public class GenericClass<T> {
574 public static T Z (IList<T> x, int index)
576 return x [index];
580 public static int test_0_generic_array_helpers () {
581 int[] x = new int[] {100, 200};
583 // Generic array helpers should be treated as gsharedvt-out
584 if (GenericClass<int>.Z (x, 0) != 100)
585 return 1;
587 return 0;
590 internal class IntComparer : IComparer<int>
592 public int Compare (int ix, int iy)
594 if (ix == iy)
595 return 0;
597 if (((uint) ix) < ((uint) iy))
598 return -1;
599 return 1;
603 [MethodImplAttribute (MethodImplOptions.NoInlining)]
604 static int gshared_out_iface<T> (T t1, T t2, IComparer<T> comp) {
605 return comp.Compare (t1, t2);
608 public static int test_0_gshared_out_iface () {
609 // Call out from gshared to a nongeneric method through a generic interface method
610 if (gshared_out_iface (2, 2, new IntComparer ()) != 0)
611 return 1;
612 return 0;
615 struct Foo1 {
616 public int i1, i2, i3;
619 struct Foo2<T> {
620 int i1, i2, i3, i4, i5;
621 public T foo;
624 [MethodImplAttribute (MethodImplOptions.NoInlining)]
625 public static void locals<T> (T t) {
626 Foo2<T> t2 = new Foo2<T> ();
627 object o = t2;
630 public static int test_0_locals () {
631 // Test that instantiations of type parameters are allocated the proper local type
632 int i = 1;
633 for (int j = 0; j < 10; ++j)
634 i ++;
635 locals<Foo1> (new Foo1 () { i1 = 1, i2 = 2, i3 = 3 });
636 return 0;
639 public interface IFace<T> {
640 T return_t_iface (T t);
643 public class Parent<T> {
644 public virtual T return_t_vcall (T t) {
645 throw new Exception ();
646 return t;
650 public class Child<T> : Parent<T>, IFace<T> {
651 public override T return_t_vcall (T t) {
652 return t;
654 public T return_t_iface (T t) {
655 return t;
659 [MethodImplAttribute (MethodImplOptions.NoInlining)]
660 static T return_t_vcall<T> (Parent<T> r, T t) {
661 return r.return_t_vcall (t);
664 public static int test_0_vcalls () {
665 if (return_t_vcall (new Child<int> (), 2) != 2)
666 return 1;
667 // Patching
668 for (int i = 0; i < 10; ++i) {
669 if (return_t_vcall (new Child<int> (), 2) != 2)
670 return 2;
672 if (return_t_vcall (new Child<double> (), 2.0) != 2.0)
673 return 3;
674 return 0;
677 [MethodImplAttribute (MethodImplOptions.NoInlining)]
678 static T return_t_iface<T> (IFace<T> r, T t) {
679 return r.return_t_iface (t);
682 public static int test_0_iface_calls () {
683 if (return_t_iface (new Child<int> (), 2) != 2)
684 return 1;
685 if (return_t_iface (new Child<double> (), 2.0) != 2.0)
686 return 3;
687 return 0;
690 interface IFaceKVP {
691 T do_kvp<T> (T a);
694 static KeyValuePair<T1, T2> make_kvp<T1, T2> (T1 t1, T2 t2) {
695 return new KeyValuePair<T1, T2> (t1, t2);
698 static T2 use_kvp<T1, T2> (KeyValuePair<T1, T2> kvp) {
699 return kvp.Value;
702 class ClassKVP : IFaceKVP {
703 public T do_kvp<T> (T a) {
704 var t = make_kvp (a, a);
705 // argument is an instance of a vtype instantiated with gsharedvt type arguments
706 return use_kvp (t);
710 public static int test_0_gsharedvt_ginstvt_constructed_arg () {
711 IFaceKVP c = new ClassKVP ();
712 if (c.do_kvp<long> (1) != 1)
713 return 1;
714 return 0;
717 interface IGetter
719 T Get<T>();
722 class Getter : IGetter
724 public T Get<T>() { return default(T); }
727 abstract class Session
729 public abstract IGetter Getter { get; }
732 class IosSession : Session
734 private IGetter getter = new Getter();
735 public override IGetter Getter { get { return getter; } }
738 enum ENUM_TYPE {
741 public static int test_0_regress_5156 () {
742 new IosSession().Getter.Get<ENUM_TYPE>();
743 return 0;
746 public struct VT
748 public Action a;
751 public class D
755 public class A3
757 public void OuterMethod<TArg1>(TArg1 value)
759 this.InnerMethod<TArg1, long>(value, 0);
762 private void InnerMethod<TArg1, TArg2>(TArg1 v1, TArg2 v2)
764 //Console.WriteLine("{0} {1}",v1,v2);
768 public static int test_0_regress_2096 () {
769 var a = new A3();
771 // The following work:
772 a.OuterMethod<int>(1);
773 a.OuterMethod<DateTime>(DateTime.Now);
775 var v = new VT();
776 a.OuterMethod<VT>(v);
778 var x = new D();
779 // Next line will crash with Attempting to JIT compile method on device
780 // Attempting to JIT compile method
781 a.OuterMethod<D>(x);
782 return 0;
785 public class B
787 public void Test<T>()
789 //System.Console.WriteLine(typeof(T));
793 public class A<T>
795 public void Test()
797 new B().Test<System.Collections.Generic.KeyValuePair<T, T>>();
801 public static int test_0_regress_6040 () {
802 //new B().Test<System.Collections.Generic.KeyValuePair<string, string>>();
803 new A<int>().Test();
804 new A<object>().Test();
805 new A<string>().Test();
806 return 0;
809 class ArrayContainer<T> {
810 private T[,] container = new T[1,1];
812 public T Prop {
813 [MethodImplAttribute (MethodImplOptions.NoInlining)]
814 get {
815 return container [0, 0];
817 [MethodImplAttribute (MethodImplOptions.NoInlining)]
818 set {
819 container [0, 0] = value;
824 [MethodImplAttribute (MethodImplOptions.NoInlining)]
825 public static int test_0_multi_dim_arrays () {
826 var c = new ArrayContainer<int> ();
827 c.Prop = 5;
828 return c.Prop == 5 ? 0 : 1;
831 [MethodImplAttribute (MethodImplOptions.NoInlining)]
832 static T2 rgctx_in_call_innner_inner<T1, T2> (T1 t1, T2 t2) {
833 return t2;
836 [MethodImplAttribute (MethodImplOptions.NoInlining)]
837 static GFoo3<T> rgctx_in_call_inner<T> (T t) {
838 return rgctx_in_call_innner_inner (1, new GFoo3<T> ());
841 public static int test_0_rgctx_in_call () {
842 // The call is made through the rgctx call, and it needs an IN trampoline
843 var t = rgctx_in_call_inner (1);
844 if (t is GFoo3<int>)
845 return 0;
846 return 1;
849 [MethodImplAttribute (MethodImplOptions.NoInlining)]
850 static void arm_params1<T> (T t1, T t2, T t3, T t4, T t5, T t6) {
853 [MethodImplAttribute (MethodImplOptions.NoInlining)]
854 static void arm_params2<T> (T t1, T t2, T t3, long t4, T t5, T t6) {
857 public static int test_0_arm_param_passing () {
858 arm_params1<int> (1, 2, 3, 4, 5, 6);
859 arm_params1<int> (1, 2, 3, 4, 5, 6);
860 return 0;
863 sealed class ScheduledItem<TAbsolute, TValue> {
864 private readonly object _scheduler;
865 private readonly TValue _state;
866 private readonly object _action;
868 public ScheduledItem(object o, TValue state, object action, TAbsolute dueTime) {
869 _state = state;
873 abstract class VirtualTimeSchedulerBase<TAbsolute, TRelative> {
874 public abstract void ScheduleAbsolute<TState>(TState state, TAbsolute dueTime);
877 class VirtualTimeScheduler<TAbsolute, TRelative> : VirtualTimeSchedulerBase<TAbsolute, TRelative> {
878 public override void ScheduleAbsolute<TState>(TState state, TAbsolute dueTime) {
879 var si = new ScheduledItem<TAbsolute, TState>(this, state, null, dueTime);
883 public static int test_0_rx_mixed_regress () {
884 var v = new VirtualTimeScheduler<long, long> ();
885 v.ScheduleAbsolute<Action> (null, 22);
886 return 0;
889 public class Base {
890 public virtual T foo<T> (T t) {
891 return t;
895 class Class1 : Base {
896 public object o;
898 public override T foo<T> (T t) {
899 o = t;
900 return t;
904 class Class2 : Base {
905 public object o;
907 public override T foo<T> (T t) {
908 o = t;
909 return t;
913 [MethodImplAttribute (MethodImplOptions.NoInlining)]
914 public static void bar<T> (Base b, T t) {
915 b.foo (t);
918 public static int test_0_virtual_generic () {
919 Class1 c1 = new Class1 ();
920 Class2 c2 = new Class2 ();
921 bar (c1, 5);
922 if (!(c1.o is int) || ((int)c1.o != 5))
923 return 1;
924 bar (c1, 6.0);
925 if (!(c1.o is double) || ((double)c1.o != 6.0))
926 return 2;
927 bar (c1, 7.0f);
928 if (!(c1.o is float) || ((float)c1.o != 7.0f))
929 return 3;
930 bar (c2, 5);
931 if (!(c2.o is int) || ((int)c2.o != 5))
932 return 4;
933 bar (c2, 6.0);
934 bar (c2, 7.0f);
935 return 0;
938 [MethodImplAttribute (MethodImplOptions.NoInlining)]
939 static string to_string<T, T2>(T t, T2 t2) {
940 return t.ToString ();
943 enum AnEnum {
944 One,
948 public static int test_0_constrained_tostring () {
949 if (to_string<int, int> (1, 1) != "1")
950 return 1;
951 if (to_string<AnEnum, int> (AnEnum.One, 1) != "One")
952 return 2;
953 if (to_string<string, int> ("A", 1) != "A")
954 return 3;
955 return 0;
958 [MethodImplAttribute (MethodImplOptions.NoInlining)]
959 static int get_hash<T, T2>(T t, T2 t2) {
960 return t.GetHashCode ();
963 public static int test_0_constrained_get_hash () {
964 if (get_hash<int, int> (1, 1) != 1.GetHashCode ())
965 return 1;
966 if (get_hash<double, int> (1.0, 1) != 1.0.GetHashCode ())
967 return 2;
968 if (get_hash<AnEnum, int> (AnEnum.One, 1) != AnEnum.One.GetHashCode ())
969 return 3;
970 if (get_hash<string, int> ("A", 1) != "A".GetHashCode ())
971 return 4;
972 return 0;
975 [MethodImplAttribute (MethodImplOptions.NoInlining)]
976 static bool equals<T, T2>(T t, T2 t2) {
977 return t.Equals (t);
980 public static int test_0_constrained_equals () {
981 if (equals<int, int> (1, 1) != true)
982 return 1;
983 if (equals<double, int> (1.0, 1) != true)
984 return 2;
985 if (equals<AnEnum, int> (AnEnum.One, 1) != true)
986 return 3;
987 if (equals<string, int> ("A", 1) != true)
988 return 4;
989 return 0;
992 interface IGetType {
993 Type gettype<T, T2>(T t, T2 t2);
996 public class CGetType : IGetType {
997 [MethodImplAttribute (MethodImplOptions.NoInlining)]
998 public Type gettype<T, T2>(T t, T2 t2) {
999 return t.GetType ();
1003 public static int test_0_constrained_gettype () {
1004 IGetType c = new CGetType ();
1005 if (c.gettype<int, int> (1, 1) != typeof (int))
1006 return 1;
1007 if (c.gettype<string, int> ("A", 1) != typeof (string))
1008 return 2;
1009 return 0;
1012 struct Pair<T1, T2> {
1013 public T1 First;
1014 public T2 Second;
1017 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1018 public static TState call_del<TState>(TState state, Func<object, TState, TState> action) {
1019 return action(null, state);
1022 public static int test_0_delegate_wrappers () {
1023 Func<object, Pair<int, int>, Pair<int, int>> del1 = delegate (object o, Pair<int, int> p) { return p; };
1024 Func<object, Pair<int, int>, Pair<int, int>> del2 = delegate (object o, Pair<int, int> p) { return p; };
1025 Func<object, Pair<double, int>, Pair<double, int>> del3 = delegate (object o, Pair<double, int> p) { return p; };
1026 var r1 = call_del<Pair<int, int>> (new Pair<int, int> { First = 1, Second = 2}, del1);
1027 if (r1.First != 1 || r1.Second != 2)
1028 return 1;
1029 var r2 = call_del<Pair<int, int>> (new Pair<int, int> { First = 3, Second = 4}, del2);
1030 if (r2.First != 3 || r2.Second != 4)
1031 return 2;
1032 var r3 = call_del<Pair<double, int>> (new Pair<double, int> { First = 1.0, Second = 2}, del3);
1033 if (r3.First != 1.0 || r3.Second != 2)
1034 return 3;
1035 return 0;
1038 class Base<T> {
1039 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1040 public object foo<T1> (T1 t1, T t, object o) {
1041 return o;
1045 class AClass : Base<long> {
1047 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1048 public object bar<T> (T t, long time, object o) {
1049 return foo (t, time, o);
1053 public static int test_0_out_in_wrappers () {
1054 var a = new AClass ();
1055 object o1 = "A";
1056 object o2 = a.bar<long> (1024, 0, o1);
1057 if (o1 != o2)
1058 return 1;
1059 return 0;
1062 interface BIFace {
1063 object AMethod ();
1066 class Base<TAbsolute, T2> : BIFace {
1068 public TAbsolute Clock { get; set; }
1070 public virtual object AMethod () {
1071 return Clock;
1075 class BClass : Base<long, long> {
1078 public static int test_0_regress_1 () {
1079 BIFace c = new BClass ();
1080 object o = c.AMethod ();
1081 if (!(o is long) || ((long)o != 0))
1082 return 1;
1083 return 0;
1086 interface IFace3 {
1087 T unbox_any<T> (object o);
1090 class Class3 : IFace3 {
1091 public virtual T unbox_any<T> (object o) {
1092 return (T)o;
1096 public static int test_0_unbox_any () {
1097 IFace3 o = new Class3 ();
1098 if (o.unbox_any<int> (16) != 16)
1099 return 1;
1100 if (o.unbox_any<long> ((long)32) != 32)
1101 return 2;
1102 if (o.unbox_any<double> (2.0) != 2.0)
1103 return 3;
1104 try {
1105 o.unbox_any<int> (2.0);
1106 return 4;
1107 } catch (Exception) {
1109 return 0;
1112 interface IFace4 {
1113 TSource Catch<TSource, TException>(TSource t) where TException : Exception;
1116 class Class4 : IFace4 {
1117 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1118 public TSource Catch<TSource, TException>(TSource t) where TException : Exception {
1119 return t;
1123 // Check that mixed instantiations are correctly created/found in AOT
1124 public static int test_0_constraints () {
1125 IFace4 o = new Class4 ();
1126 o.Catch<int, Exception> (1);
1127 return 0;
1130 internal static Type Process<TSource, TElement> (TSource[] arr, Action<TElement, TElement> call) {
1131 arr [0] = default (TSource);
1132 return typeof (TSource);
1135 interface IFace5 {
1136 Type foo<T> ();
1139 class Class5 : IFace5 {
1140 public Type foo<T> () {
1141 return Process<KeyValuePair<long, T>, T> (new KeyValuePair<long, T> [10], null);
1145 public static int test_0_rgctx_call_from_gshared_code () {
1146 var c = new Class5 ();
1147 if (c.foo<string> () != typeof (KeyValuePair<long, string>))
1148 return 1;
1149 return 0;
1152 public class Enumbers<T> {
1153 public object Enumerate (List<KeyValuePair<T, string>> alist)
1155 return alist.ToArray ();
1159 public static int test_0_checkthis_gshared_call () {
1160 Enumbers<string> e = new Enumbers<string> ();
1161 try {
1162 e.Enumerate (null);
1163 return 1;
1165 catch (NullReferenceException) {
1167 return 0;
1170 interface IFace6 {
1171 T[] Del<T> (T t);
1174 class Class6 : IFace6 {
1175 public T[] Del<T> (T t) {
1176 var res = new T [5];
1177 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; };
1178 var v = func.BeginInvoke(t, t, t, t, null, null);
1179 res [4] = func.EndInvoke (v);
1180 return res;
1184 // FIXME: The runtime-invoke wrapper used by BeginInvoke is not found
1185 [Category ("!FULLAOT")]
1186 public static int test_0_begin_end_invoke () {
1187 IFace6 o = new Class6 ();
1188 var arr1 = o.Del (1);
1189 if (arr1 [0] != 1 || arr1 [1] != 1 || arr1 [2] != 1 || arr1 [3] != 1 || arr1 [4] != 1)
1190 return 1;
1191 var arr2 = o.Del (2.0);
1192 if (arr2 [0] != 2.0 || arr2 [1] != 2.0 || arr2 [2] != 2.0 || arr2 [3] != 2.0 || arr2 [4] != 2.0)
1193 return 2;
1194 return 0;
1197 public class TAbstractTableItem<TC> {
1198 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1199 public static void SetProperty<TV> () { }
1201 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1202 public static void Test () {
1203 SetProperty<bool> ();
1207 public static int test_0_gsharedvt_method_on_shared_class () {
1208 TAbstractTableItem<object>.Test ();
1209 return 0;
1212 interface IFaceBox {
1213 object box<T> (T t);
1216 class ClassBox : IFaceBox {
1217 public object box<T> (T t) {
1218 object o = t;
1219 return o;
1223 public static int test_0_nullable_box () {
1224 IFaceBox c = new ClassBox ();
1225 int i = 5;
1226 object o = c.box<int?> (i);
1227 if ((int)o != i)
1228 return 1;
1229 if (c.box<int?> (null) != null)
1230 return 2;
1231 long l = Int64.MaxValue - 1;
1232 o = c.box<long?> (l);
1233 if ((long)o != l)
1234 return 3;
1235 if (c.box<long?> (null) != null)
1236 return 4;
1237 string s = "A";
1238 if (c.box<string> (s) != (object)s)
1239 return 5;
1240 return 0;
1243 interface IFaceUnbox2 {
1244 T unbox<T> (object o);
1247 class ClassUnbox2 : IFaceUnbox2 {
1248 public T unbox<T> (object o) {
1249 return (T)o;
1253 public static int test_0_nullable_unbox () {
1254 IFaceUnbox2 c = new ClassUnbox2 ();
1255 int? i = c.unbox<int?> (5);
1256 if (i != 5)
1257 return 1;
1258 int? j = c.unbox<int?> (null);
1259 if (j != null)
1260 return 2;
1261 return 0;
1264 interface IConstrained {
1265 void foo ();
1266 void foo_ref_arg (string s);
1269 interface IConstrained<T3> {
1270 void foo_gsharedvt_arg (T3 s);
1271 T3 foo_gsharedvt_ret (T3 s);
1274 static object constrained_res;
1276 struct ConsStruct : IConstrained {
1277 public int i;
1279 public void foo () {
1280 constrained_res = i;
1283 public void foo_ref_arg (string s) {
1284 constrained_res = s == "A" ? 42 : 0;
1288 class ConsClass : IConstrained {
1289 public int i;
1291 public void foo () {
1292 constrained_res = i;
1295 public void foo_ref_arg (string s) {
1296 constrained_res = s == "A" ? 43 : 0;
1300 struct ConsStruct<T> : IConstrained<T> {
1301 public void foo_gsharedvt_arg (T s) {
1302 constrained_res = s;
1305 public T foo_gsharedvt_ret (T s) {
1306 return s;
1310 struct ConsStructThrow : IConstrained {
1311 public void foo () {
1312 throw new Exception ();
1315 public void foo_ref_arg (string s) {
1319 interface IFaceConstrained {
1320 void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained;
1321 void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained;
1322 void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1323 T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T>;
1324 T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass;
1327 class ClassConstrained : IFaceConstrained {
1328 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1329 public void constrained_void_iface_call<T, T2>(T t, T2 t2) where T2 : IConstrained {
1330 t2.foo ();
1333 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1334 public void constrained_void_iface_call_ref_arg<T, T2>(T t, T2 t2) where T2 : IConstrained {
1335 t2.foo_ref_arg ("A");
1338 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1339 public void constrained_void_iface_call_gsharedvt_arg<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1340 t2.foo_gsharedvt_arg (t);
1343 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1344 public T constrained_iface_call_gsharedvt_ret<T, T2, T3>(T t, T2 t2, T3 t3) where T2 : IConstrained<T> {
1345 return t2.foo_gsharedvt_ret (t);
1348 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1349 public T2 constrained_normal_call<T, T2>(T t, T2 t2) where T2 : VClass {
1350 /* This becomes a constrained call even through 't2' is forced to be a reference type by the constraint */
1351 return (T2)t2.foo (5);
1355 class VClass {
1356 public virtual VClass foo (int i) {
1357 return this;
1361 public static int test_0_constrained_void_iface_call () {
1362 IFaceConstrained c = new ClassConstrained ();
1363 var s = new ConsStruct () { i = 42 };
1364 constrained_res = null;
1365 c.constrained_void_iface_call<int, ConsStruct> (1, s);
1366 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1367 return 1;
1368 constrained_res = null;
1369 c.constrained_void_iface_call_ref_arg<int, ConsStruct> (1, s);
1370 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1371 return 2;
1372 var s2 = new ConsClass () { i = 43 };
1373 constrained_res = null;
1374 c.constrained_void_iface_call<int, ConsClass> (1, s2);
1375 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1376 return 3;
1377 constrained_res = null;
1378 c.constrained_void_iface_call_ref_arg<int, ConsClass> (1, s2);
1379 if (!(constrained_res is int) || ((int)constrained_res) != 43)
1380 return 4;
1381 return 0;
1384 public static int test_0_constrained_eh () {
1385 var s2 = new ConsStructThrow () { };
1386 try {
1387 IFaceConstrained c = new ClassConstrained ();
1388 c.constrained_void_iface_call<int, ConsStructThrow> (1, s2);
1389 return 1;
1390 } catch (Exception) {
1391 return 0;
1395 public static int test_0_constrained_void_iface_call_gsharedvt_arg () {
1396 // This tests constrained calls through interfaces with one gsharedvt arg, like IComparable<T>.CompareTo ()
1397 IFaceConstrained c = new ClassConstrained ();
1399 var s = new ConsStruct<int> ();
1400 constrained_res = null;
1401 c.constrained_void_iface_call_gsharedvt_arg<int, ConsStruct<int>, int> (42, s, 55);
1402 if (!(constrained_res is int) || ((int)constrained_res) != 42)
1403 return 1;
1405 var s2 = new ConsStruct<string> ();
1406 constrained_res = null;
1407 c.constrained_void_iface_call_gsharedvt_arg<string, ConsStruct<string>, int> ("A", s2, 55);
1408 if (!(constrained_res is string) || ((string)constrained_res) != "A")
1409 return 2;
1411 return 0;
1414 public static int test_0_constrained_iface_call_gsharedvt_ret () {
1415 IFaceConstrained c = new ClassConstrained ();
1417 var s = new ConsStruct<int> ();
1418 int ires = c.constrained_iface_call_gsharedvt_ret<int, ConsStruct<int>, int> (42, s, 55);
1419 if (ires != 42)
1420 return 1;
1422 var s2 = new ConsStruct<string> ();
1423 string sres = c.constrained_iface_call_gsharedvt_ret<string, ConsStruct<string>, int> ("A", s2, 55);
1424 if (sres != "A")
1425 return 2;
1427 return 0;
1430 public static int test_0_constrained_normal_call () {
1431 IFaceConstrained c = new ClassConstrained ();
1433 var o = new VClass ();
1434 var res = c.constrained_normal_call<int, VClass> (1, o);
1435 return res == o ? 0 : 1;
1438 public static async Task<T> FooAsync<T> (int i, int j) {
1439 Task<int> t = new Task<int> (delegate () { return 42; });
1440 var response = await t;
1441 return default(T);
1444 [MethodImplAttribute (MethodImplOptions.NoInlining)]
1445 public static void call_async<T> (int i, int j) {
1446 Task<T> t = FooAsync<T> (1, 2);
1447 // FIXME: This doesn't work
1448 //t.RunSynchronously ();
1451 // In AOT mode, the async infrastructure depends on gsharedvt methods
1452 public static int test_0_async_call_from_generic () {
1453 call_async<string> (1, 2);
1454 return 0;
1457 public static int test_0_array_helper_gsharedvt () {
1458 var arr = new AnEnum [16];
1459 var c = new ReadOnlyCollection<AnEnum> (arr);
1460 return c.Contains (AnEnum.Two) == false ? 0 : 1;
1464 // #13191
1465 public class MobileServiceCollection<TTable, TCol>
1467 public async Task<int> LoadMoreItemsAsync(int count = 0) {
1468 await Task.Delay (1000);
1469 int results = await ProcessQueryAsync ();
1470 return results;
1473 protected async virtual Task<int> ProcessQueryAsync() {
1474 await Task.Delay (1000);
1475 throw new Exception ();
1479 #if !MOBILE
1480 public class GSharedTests : Tests {
1482 #endif