2 using System.Collections.Generic;
3 using System.Runtime.CompilerServices;
14 public static T static_dummy;
15 public static T static_t;
16 public static Foo static_f;
29 [MethodImplAttribute (MethodImplOptions.NoInlining)]
30 public GFoo3 (T i1, T i2) {
37 // Tests for generic sharing of vtypes.
38 // The tests use arrays to pass/receive values to keep the calling convention of the methods stable, which is a current limitation of the runtime support for gsharedvt.
41 // FIXME: Add mixed ref/noref tests, i.e. Dictionary<string, int>
45 public static int Main (String[] args) {
46 return TestDriver.RunTests (typeof (Tests), args);
49 [MethodImplAttribute (MethodImplOptions.NoInlining)]
50 static void gshared<T> (T [] array, int i, int j) {
52 array [i] = array [j];
56 // Test that the gshared and gsharedvt versions don't mix
57 public static int test_0_vt_gshared () {
58 string[] sarr = new string [2] { "A", "B" };
60 gshared<string> (sarr, 0, 1);
62 Foo[] arr = new Foo [2];
63 arr [0] = new Foo () { i = 1, j = 2 };
64 arr [1] = new Foo () { i = 3, j = 4 };
66 gshared<Foo> (arr, 0, 1);
67 if (arr [0].i != 3 || arr [0].j != 4)
69 if (arr [1].i != 1 || arr [1].j != 2)
75 static void ldelem_stelem<T> (T [] array, int i, int j) {
77 array [i] = array [j];
81 public static int test_0_vt_ldelem_stelem () {
82 Foo[] arr = new Foo [2];
83 arr [0] = new Foo () { i = 1, j = 2 };
84 arr [1] = new Foo () { i = 3, j = 4 };
86 ldelem_stelem<Foo> (arr, 0, 1);
87 if (arr [0].i != 3 || arr [0].j != 4)
89 if (arr [1].i != 1 || arr [1].j != 2)
92 int[] arr2 = new int [2] { 1, 2 };
93 ldelem_stelem<int> (arr2, 0, 1);
94 if (arr2 [0] !=2 || arr2 [1] != 1)
100 [MethodImplAttribute (MethodImplOptions.NoInlining)]
101 private static void initobj<T> (T [] array, int i, int j) {
106 public static int test_0_vt_initobj () {
107 Foo[] arr = new Foo [2];
108 arr [0] = new Foo () { i = 1, j = 2 };
109 arr [1] = new Foo () { i = 3, j = 4 };
111 initobj<Foo> (arr, 0, 1);
112 if (arr [0].i != 0 || arr [0].j != 0)
114 if (arr [1].i != 3 || arr [1].j != 4)
119 [MethodImplAttribute (MethodImplOptions.NoInlining)]
120 static T ldobj_stobj<T> (ref T t1, ref T t2) {
127 public static int test_0_vt_ldobj_stobj () {
130 if (ldobj_stobj (ref i, ref j) != 6)
132 if (i != 6 || j != 0)
136 if (ldobj_stobj (ref d1, ref d2) != 2.0)
138 if (d1 != 2.0 || d2 != 0.0)
143 [MethodImplAttribute (MethodImplOptions.NoInlining)]
144 private static void box<T1, T> (T [] array, object[] arr) {
145 object x = array [0];
149 public static int test_0_vt_box () {
150 Foo[] arr = new Foo [2];
151 arr [0] = new Foo () { i = 1, j = 2 };
153 object[] arr2 = new object [16];
154 box<int, Foo> (arr, arr2);
155 if (arr2 [0].GetType () != typeof (Foo))
157 Foo f = (Foo)arr2 [0];
158 if (f.i != 1 || f.j != 2)
160 string[] arr3 = new string [16];
161 object[] arr4 = new object [16];
163 box<int, string> (arr3, arr4);
164 if (arr4 [0] != (object)arr3 [0])
169 [MethodImplAttribute (MethodImplOptions.NoInlining)]
170 private static void unbox_any<T> (T [] array, object[] arr) {
175 public static int test_0_vt_unbox_any () {
176 Foo[] arr = new Foo [2];
178 object[] arr2 = new object [16];
179 arr2 [0] = new Foo () { i = 1, j = 2 };
180 unbox_any<Foo> (arr, arr2);
181 if (arr [0].i != 1 || arr [0].j != 2)
186 [MethodImplAttribute (MethodImplOptions.NoInlining)]
187 static void ldfld_nongeneric<T> (GFoo<T>[] foo, int[] arr) {
191 [MethodImplAttribute (MethodImplOptions.NoInlining)]
192 static void ldfld<T> (GFoo<T>[] foo, T[] arr) {
196 [MethodImplAttribute (MethodImplOptions.NoInlining)]
197 static void stfld_nongeneric<T> (GFoo<T>[] foo, int[] arr) {
201 [MethodImplAttribute (MethodImplOptions.NoInlining)]
202 static void stfld<T> (GFoo<T>[] foo, T[] arr) {
206 [MethodImplAttribute (MethodImplOptions.NoInlining)]
207 static void ldflda<T> (GFoo<T>[] foo, int[] arr) {
208 arr [0] = foo [0].f.i;
211 public static int test_0_vt_ldfld_stfld () {
212 var foo = new GFoo<Foo> () { t = new Foo () { i = 1, j = 2 }, i = 5, f = new Foo () { i = 5, j = 6 } };
213 var farr = new GFoo<Foo>[] { foo };
215 /* Normal fields with a variable offset */
216 var iarr = new int [10];
217 ldfld_nongeneric<Foo> (farr, iarr);
221 stfld_nongeneric<Foo> (farr, iarr);
222 if (farr [0].i != 16)
225 /* Variable type field with a variable offset */
226 var arr = new Foo [10];
227 ldfld<Foo> (farr, arr);
228 if (arr [0].i != 1 || arr [0].j != 2)
230 arr [0] = new Foo () { i = 3, j = 4 };
231 stfld<Foo> (farr, arr);
232 if (farr [0].t.i != 3 || farr [0].t.j != 4)
235 ldflda<Foo> (farr, iarr);
242 [MethodImplAttribute (MethodImplOptions.NoInlining)]
243 static void stsfld<T> (T[] arr) {
244 GFoo<T>.static_t = arr [0];
247 [MethodImplAttribute (MethodImplOptions.NoInlining)]
248 static void ldsfld<T> (T[] arr) {
249 arr [0] = GFoo<T>.static_t;
252 [MethodImplAttribute (MethodImplOptions.NoInlining)]
253 static void ldsflda<T> (int[] iarr) {
254 iarr [0] = GFoo<T>.static_f.i;
257 public static int test_0_stsfld () {
258 Foo[] farr = new Foo [] { new Foo () { i = 1, j = 2 } };
261 if (GFoo<Foo>.static_t.i != 1 || GFoo<Foo>.static_t.j != 2)
264 Foo[] farr2 = new Foo [1];
266 if (farr2 [0].i != 1 || farr2 [0].j != 2)
269 var iarr = new int [10];
270 GFoo<Foo>.static_f = new Foo () { i = 5, j = 6 };
278 [MethodImplAttribute (MethodImplOptions.NoInlining)]
279 static object newarr<T> () {
280 object o = new T[10];
284 public static int test_0_vt_newarr () {
285 object o = newarr<Foo> ();
291 [MethodImplAttribute (MethodImplOptions.NoInlining)]
292 static Type ldtoken<T> () {
293 return typeof (GFoo<T>);
296 public static int test_0_vt_ldtoken () {
297 Type t = ldtoken<Foo> ();
298 if (t != typeof (GFoo<Foo>))
301 if (t != typeof (GFoo<int>))
307 public static int test_0_vtype_list () {
308 List<int> l = new List<int> ();
316 [MethodImplAttribute (MethodImplOptions.NoInlining)]
317 static int args_simple<T> (T t, int i) {
321 [MethodImplAttribute (MethodImplOptions.NoInlining)]
322 static int args_simple<T> (T t, int i, T t2) {
326 [MethodImplAttribute (MethodImplOptions.NoInlining)]
327 static Type args_rgctx<T> (T t, int i) {
331 [MethodImplAttribute (MethodImplOptions.NoInlining)]
332 static Type eh_in<T> (T t, int i) {
333 throw new OverflowException ();
336 [MethodImplAttribute (MethodImplOptions.NoInlining)]
337 static T return_t<T> (T t) {
341 [MethodImplAttribute (MethodImplOptions.NoInlining)]
342 T return_this_t<T> (T t) {
346 public static int test_0_gsharedvt_in () {
347 // Check that the non-generic argument is passed at the correct stack position
348 int r = args_simple<bool> (true, 42);
351 r = args_simple<Foo> (new Foo (), 43);
354 // Check that the proper rgctx is passed to the method
355 Type t = args_rgctx<int> (5, 42);
356 if (t != typeof (int))
358 var v = args_simple<GFoo2<int>> (new GFoo2<int> () { t = 11, t2 = 12 }, 44, new GFoo2<int> () { t = 11, t2 = 12 });
361 // Check that EH works properly
364 } catch (OverflowException) {
369 public static int test_0_gsharedvt_in_ret () {
370 int i = return_t<int> (42);
373 long l = return_t<long> (Int64.MaxValue);
374 if (l != Int64.MaxValue)
376 double d = return_t<double> (3.0);
379 float f = return_t<float> (3.0f);
382 short s = return_t<short> (16);
385 var v = new GFoo2<int> () { t = 55, t2 = 32 };
386 var v2 = return_t<GFoo2<int>> (v);
387 if (v2.t != 55 || v2.t2 != 32)
389 i = new Tests ().return_this_t<int> (42);
395 public static int test_0_gsharedvt_in_delegates () {
396 Func<int, int> f = new Func<int, int> (return_t<int>);
402 [MethodImplAttribute (MethodImplOptions.NoInlining)]
403 static T return2_t<T> (T t) {
407 public static int test_0_gsharedvt_calls () {
408 if (return2_t (2) != 2)
410 if (return2_t ("A") != "A")
412 if (return2_t (2.0) != 2.0)
417 static GFoo3<T> newobj<T> (T t1, T t2) {
418 return new GFoo3<T> (t1, t2);
421 public static int test_0_gshared_new () {
422 var g1 = newobj (1, 2);
423 if (g1.t != 1 || g1.t2 != 2)
425 var g2 = newobj (1.0, 2.0);
426 if (g1.t != 1.0 || g1.t2 != 2.0)
432 [MethodImplAttribute (MethodImplOptions.NoInlining)]
433 static GFoo2<T> newobj_vt<T> (T t1, T t2) {
434 return new GFoo2<T> () { t = t1, t2 = t2 };
437 public static int test_0_gshared_new_vt () {
438 GFoo2<int> v1 = newobj_vt (1, 2);
439 if (v1.t != 1 || v1.t2 != 2)
441 GFoo2<double> v2 = newobj_vt (1.0, 2.0);
442 if (v2.t != 1.0 || v2.t2 != 2.0)
448 // Tests for transitioning out of gsharedvt code
451 [MethodImplAttribute (MethodImplOptions.NoInlining)]
452 static T return_t_nogshared<T> (T t) {
453 // This is not currently supported by gsharedvt
456 //Console.WriteLine ("X: " + t);
460 [MethodImplAttribute (MethodImplOptions.NoInlining)]
461 static int return_int_nogshared<T> (T t) {
462 // This is not currently supported by gsharedvt
468 [MethodImplAttribute (MethodImplOptions.NoInlining)]
469 static A return_vtype_nogshared<T> (T t) {
470 // This is not currently supported by gsharedvt
473 return new A () { a = 1, b = 2, c = 3 };
476 [MethodImplAttribute (MethodImplOptions.NoInlining)]
477 static T return2_t_out<T> (T t) {
478 return return_t_nogshared (t);
481 [MethodImplAttribute (MethodImplOptions.NoInlining)]
482 static int return2_int_out<T> (T t) {
483 return return_int_nogshared (t);
486 [MethodImplAttribute (MethodImplOptions.NoInlining)]
487 static A return2_vtype_out<T> (T t) {
488 return return_vtype_nogshared (t);
495 public static int test_0_gsharedvt_out () {
496 if (return2_t_out (2) != 2)
498 if (return2_t_out ("A") != "A")
500 if (return2_t_out (2.0) != 2.0)
502 if (return2_t_out (2.0f) != 2.0f)
504 A a = new A () { a = 1, b = 2, c = 3 };
505 A a2 = return2_t_out (a);
506 if (a2.a != 1 || a2.b != 2 || a2.c != 3)
508 // Calls with non gsharedvt return types
509 if (return2_int_out (1) != 2)
511 A c = return2_vtype_out (a);
512 if (a2.a != 1 || a2.b != 2 || a2.c != 3)
517 public class GenericClass<T> {
518 public static T Z (IList<T> x, int index)
524 public static int test_0_generic_array_helpers () {
525 int[] x = new int[] {100, 200};
527 // Generic array helpers should be treated as gsharedvt-out
528 if (GenericClass<int>.Z (x, 0) != 100)
534 internal class IntComparer : IComparer<int>
536 public int Compare (int ix, int iy)
541 if (((uint) ix) < ((uint) iy))
547 [MethodImplAttribute (MethodImplOptions.NoInlining)]
548 static int gshared_out_iface<T> (T t1, T t2, IComparer<T> comp) {
549 return comp.Compare (t1, t2);
552 public static int test_0_gshared_out_iface () {
553 // Call out from gshared to a nongeneric method through a generic interface method
554 if (gshared_out_iface (2, 2, new IntComparer ()) != 0)
560 public int i1, i2, i3;
564 int i1, i2, i3, i4, i5;
568 [MethodImplAttribute (MethodImplOptions.NoInlining)]
569 public static void locals<T> (T t) {
570 Foo2<T> t2 = new Foo2<T> ();
574 public static int test_0_locals () {
575 // Test that instantiations of type parameters are allocated the proper local type
577 for (int j = 0; j < 10; ++j)
579 locals<Foo1> (new Foo1 () { i1 = 1, i2 = 2, i3 = 3 });
583 public interface IFace<T> {
584 T return_t_iface (T t);
587 public class Parent<T> {
588 public virtual T return_t_vcall (T t) {
589 throw new Exception ();
594 public class Child<T> : Parent<T>, IFace<T> {
595 public override T return_t_vcall (T t) {
598 public T return_t_iface (T t) {
603 [MethodImplAttribute (MethodImplOptions.NoInlining)]
604 static T return_t_vcall<T> (Parent<T> r, T t) {
605 return r.return_t_vcall (t);
608 public static int test_0_vcalls () {
609 if (return_t_vcall (new Child<int> (), 2) != 2)
612 for (int i = 0; i < 10; ++i) {
613 if (return_t_vcall (new Child<int> (), 2) != 2)
616 if (return_t_vcall (new Child<double> (), 2.0) != 2.0)
621 [MethodImplAttribute (MethodImplOptions.NoInlining)]
622 static T return_t_iface<T> (IFace<T> r, T t) {
623 return r.return_t_iface (t);
626 public static int test_0_iface_calls () {
627 if (return_t_iface (new Child<int> (), 2) != 2)
629 if (return_t_iface (new Child<double> (), 2.0) != 2.0)
634 static KeyValuePair<T1, T2> make_kvp<T1, T2> (T1 t1, T2 t2) {
635 return new KeyValuePair<T1, T2> (t1, t2);
638 static T2 use_kvp<T1, T2> (KeyValuePair<T1, T2> kvp) {
642 [MethodImplAttribute (MethodImplOptions.NoInlining)]
643 static T do_kvp<T> (T a) {
644 var t = make_kvp (a, a);
645 // argument is an instance of a vtype instantiated with gsharedvt type arguments
649 public static int test_0_gsharedvt_ginstvt_constructed_arg () {
650 if (do_kvp<long> (1) != 1)
660 class Getter : IGetter
662 public T Get<T>() { return default(T); }
665 abstract class Session
667 public abstract IGetter Getter { get; }
670 class IosSession : Session
672 private IGetter getter = new Getter();
673 public override IGetter Getter { get { return getter; } }
679 public static int test_0_regress_5156 () {
680 new IosSession().Getter.Get<ENUM_TYPE>();
695 public void OuterMethod<TArg1>(TArg1 value)
697 this.InnerMethod<TArg1, long>(value, 0);
700 private void InnerMethod<TArg1, TArg2>(TArg1 v1, TArg2 v2)
702 //Console.WriteLine("{0} {1}",v1,v2);
706 public static int test_0_regress_2096 () {
709 // The following work:
710 a.OuterMethod<int>(1);
711 a.OuterMethod<DateTime>(DateTime.Now);
714 a.OuterMethod<VT>(v);
717 // Next line will crash with Attempting to JIT compile method on device
718 // Attempting to JIT compile method
725 public void Test<T>()
727 //System.Console.WriteLine(typeof(T));
735 new B().Test<System.Collections.Generic.KeyValuePair<T, T>>();
739 public static int test_0_regress_6040 () {
740 //new B().Test<System.Collections.Generic.KeyValuePair<string, string>>();
742 new A<object>().Test();
743 new A<string>().Test();
747 class ArrayContainer<T> {
748 private T[,] container = new T[1,1];
751 [MethodImplAttribute (MethodImplOptions.NoInlining)]
753 return container [0, 0];
755 [MethodImplAttribute (MethodImplOptions.NoInlining)]
757 container [0, 0] = value;
762 [MethodImplAttribute (MethodImplOptions.NoInlining)]
763 public static int test_0_multi_dim_arrays () {
764 var c = new ArrayContainer<int> ();
766 return c.Prop == 5 ? 0 : 1;
769 [MethodImplAttribute (MethodImplOptions.NoInlining)]
770 static T2 rgctx_in_call_innner_inner<T1, T2> (T1 t1, T2 t2) {
774 [MethodImplAttribute (MethodImplOptions.NoInlining)]
775 static GFoo3<T> rgctx_in_call_inner<T> (T t) {
776 return rgctx_in_call_innner_inner (1, new GFoo3<T> ());
779 public static int test_0_rgctx_in_call () {
780 // The call is made through the rgctx call, and it needs an IN trampoline
781 var t = rgctx_in_call_inner (1);
787 [MethodImplAttribute (MethodImplOptions.NoInlining)]
788 static void arm_params1<T> (T t1, T t2, T t3, T t4, T t5, T t6) {
791 [MethodImplAttribute (MethodImplOptions.NoInlining)]
792 static void arm_params2<T> (T t1, T t2, T t3, long t4, T t5, T t6) {
795 public static int test_0_arm_param_passing () {
796 arm_params1<int> (1, 2, 3, 4, 5, 6);
797 arm_params1<int> (1, 2, 3, 4, 5, 6);
801 sealed class ScheduledItem<TAbsolute, TValue> {
802 private readonly object _scheduler;
803 private readonly TValue _state;
804 private readonly object _action;
806 public ScheduledItem(object o, TValue state, object action, TAbsolute dueTime) {
811 abstract class VirtualTimeSchedulerBase<TAbsolute, TRelative> {
812 public abstract void ScheduleAbsolute<TState>(TState state, TAbsolute dueTime);
815 class VirtualTimeScheduler<TAbsolute, TRelative> : VirtualTimeSchedulerBase<TAbsolute, TRelative> {
816 public override void ScheduleAbsolute<TState>(TState state, TAbsolute dueTime) {
817 var si = new ScheduledItem<TAbsolute, TState>(this, state, null, dueTime);
821 public static int test_0_rx_mixed_regress () {
822 var v = new VirtualTimeScheduler<long, long> ();
823 v.ScheduleAbsolute<Action> (null, 22);
828 public virtual T foo<T> (T t) {
833 class Class1 : Base {
836 public override T foo<T> (T t) {
842 class Class2 : Base {
845 public override T foo<T> (T t) {
851 [MethodImplAttribute (MethodImplOptions.NoInlining)]
852 public static void bar<T> (Base b, T t) {
856 public static int test_0_virtual_generic () {
857 Class1 c1 = new Class1 ();
858 Class2 c2 = new Class2 ();
860 if (!(c1.o is int) || ((int)c1.o != 5))
863 if (!(c1.o is double) || ((double)c1.o != 6.0))
866 if (!(c1.o is float) || ((float)c1.o != 7.0f))
869 if (!(c2.o is int) || ((int)c2.o != 5))
876 [MethodImplAttribute (MethodImplOptions.NoInlining)]
877 static string to_string<T, T2>(T t, T2 t2) {
878 return t.ToString ();
881 public static int test_0_constrained_tostring () {
882 if (to_string<int, int> (1, 1) != "1")
884 if (to_string<string, int> ("A", 1) != "A")
889 struct Pair<T1, T2> {
894 [MethodImplAttribute (MethodImplOptions.NoInlining)]
895 public static TState call_del<TState>(TState state, Func<object, TState, TState> action) {
896 return action(null, state);
899 public static int test_0_delegate_wrappers () {
900 Func<object, Pair<int, int>, Pair<int, int>> del1 = delegate (object o, Pair<int, int> p) { return p; };
901 Func<object, Pair<int, int>, Pair<int, int>> del2 = delegate (object o, Pair<int, int> p) { return p; };
902 Func<object, Pair<double, int>, Pair<double, int>> del3 = delegate (object o, Pair<double, int> p) { return p; };
903 var r1 = call_del<Pair<int, int>> (new Pair<int, int> { First = 1, Second = 2}, del1);
904 if (r1.First != 1 || r1.Second != 2)
906 var r2 = call_del<Pair<int, int>> (new Pair<int, int> { First = 3, Second = 4}, del2);
907 if (r2.First != 3 || r2.Second != 4)
909 var r3 = call_del<Pair<double, int>> (new Pair<double, int> { First = 1.0, Second = 2}, del3);
910 if (r3.First != 1.0 || r3.Second != 2)
916 [MethodImplAttribute (MethodImplOptions.NoInlining)]
917 public object foo<T1> (T1 t1, T t, object o) {
922 class AClass : Base<long> {
924 [MethodImplAttribute (MethodImplOptions.NoInlining)]
925 public object bar<T> (T t, long time, object o) {
926 return foo (t, time, o);
930 public static int test_0_out_in_wrappers () {
931 var a = new AClass ();
933 object o2 = a.bar<long> (1024, 0, o1);