[mini] set MONO_ARCH_HAVE_INIT_LMF_EXT on architectures that implement mono_arch_init...
[mono-project.git] / mono / mini / aot-tests.cs
blob36c7a15a3e8fe91e1c44ebe8d40cf6546c441994
1 using System;
2 using System.Text;
3 using System.Linq;
4 using System.Reflection;
5 using System.Runtime.InteropServices;
6 using System.Runtime.CompilerServices;
7 using System.Collections.Generic;
8 using System.Collections.ObjectModel;
11 * Regression tests for the AOT/FULL-AOT code.
14 #if __MOBILE__
15 class AotTests
16 #else
17 class Tests
18 #endif
20 #if !__MOBILE__
21 static int Main (String[] args) {
22 return TestDriver.RunTests (typeof (Tests), args);
24 #endif
26 public delegate void ArrayDelegate (int[,] arr);
28 static int test_0_array_delegate_full_aot () {
29 ArrayDelegate d = delegate (int[,] arr) {
31 int[,] a = new int[5, 6];
32 d.BeginInvoke (a, null, null);
33 return 0;
36 struct Struct1 {
37 public double a, b;
40 struct Struct2 {
41 public float a, b;
44 class Foo<T> {
45 /* The 'd' argument is used to shift the register indexes so 't' doesn't start at the first reg */
46 public static T Get_T (double d, T t) {
47 return t;
51 class Foo2<T> {
52 public static T Get_T (double d, T t) {
53 return t;
55 public static T Get_T2 (double d, int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, T t) {
56 return t;
60 class Foo3<T> {
61 public static T Get_T (double d, T t) {
62 return Foo2<T>.Get_T (d, t);
66 [Category ("DYNCALL")]
67 static int test_0_arm64_dyncall_double () {
68 double arg1 = 1.0f;
69 double s = 2.0f;
70 var res = (double)typeof (Foo<double>).GetMethod ("Get_T").Invoke (null, new object [] { arg1, s });
71 if (res != 2.0f)
72 return 1;
73 return 0;
76 [Category ("DYNCALL")]
77 static int test_0_arm64_dyncall_float () {
78 double arg1 = 1.0f;
79 float s = 2.0f;
80 var res = (float)typeof (Foo<float>).GetMethod ("Get_T").Invoke (null, new object [] { arg1, s });
81 if (res != 2.0f)
82 return 1;
83 return 0;
86 [Category ("DYNCALL")]
87 [Category ("!FULLAOT-AMD64")]
88 static int test_0_arm64_dyncall_hfa_double () {
89 double arg1 = 1.0f;
90 // HFA with double members
91 var s = new Struct1 ();
92 s.a = 1.0f;
93 s.b = 2.0f;
94 var s_res = (Struct1)typeof (Foo<Struct1>).GetMethod ("Get_T").Invoke (null, new object [] { arg1, s });
95 if (s_res.a != 1.0f || s_res.b != 2.0f)
96 return 1;
97 return 0;
100 [Category ("DYNCALL")]
101 [Category ("!FULLAOT-AMD64")]
102 static int test_0_arm64_dyncall_hfa_float () {
103 double arg1 = 1.0f;
104 var s = new Struct2 ();
105 s.a = 1.0f;
106 s.b = 2.0f;
107 var s_res = (Struct2)typeof (Foo<Struct2>).GetMethod ("Get_T").Invoke (null, new object [] { arg1, s });
108 if (s_res.a != 1.0f || s_res.b != 2.0f)
109 return 1;
110 return 0;
113 [Category ("DYNCALL")]
114 [Category ("GSHAREDVT")]
115 [Category ("!FULLAOT-AMD64")]
116 static int test_0_arm64_dyncall_gsharedvt_out_hfa_double () {
117 /* gsharedvt out trampoline with double hfa argument */
118 double arg1 = 1.0f;
120 var s = new Struct1 ();
121 s.a = 1.0f;
122 s.b = 2.0f;
123 // Call Foo2.Get_T directly, so its gets an instance
124 Foo2<Struct1>.Get_T (arg1, s);
125 Type t = typeof (Foo3<>).MakeGenericType (new Type [] { typeof (Struct1) });
126 // Call Foo3.Get_T, this will call the gsharedvt instance, which will call the non-gsharedvt instance
127 var s_res = (Struct1)t.GetMethod ("Get_T").Invoke (null, new object [] { arg1, s });
128 if (s_res.a != 1.0f || s_res.b != 2.0f)
129 return 1;
130 return 0;
133 [Category ("DYNCALL")]
134 [Category ("GSHAREDVT")]
135 [Category ("!FULLAOT-AMD64")]
136 static int test_0_arm64_dyncall_gsharedvt_out_hfa_float () {
137 /* gsharedvt out trampoline with double hfa argument */
138 double arg1 = 1.0f;
140 var s = new Struct2 ();
141 s.a = 1.0f;
142 s.b = 2.0f;
143 // Call Foo2.Get_T directly, so its gets an instance
144 Foo2<Struct2>.Get_T (arg1, s);
145 Type t = typeof (Foo3<>).MakeGenericType (new Type [] { typeof (Struct2) });
146 // Call Foo3.Get_T, this will call the gsharedvt instance, which will call the non-gsharedvt instance
147 var s_res = (Struct2)t.GetMethod ("Get_T").Invoke (null, new object [] { arg1, s });
148 if (s_res.a != 1.0f || s_res.b != 2.0f)
149 return 1;
150 return 0;
153 interface IFaceFoo4<T> {
154 T Get_T (double d, T t);
155 T Get_T2 (double d, T t);
158 class Foo4<T> : IFaceFoo4<T> {
159 public T Get_T (double d, T t) {
160 return Foo2<T>.Get_T (d, t);
162 public T Get_T2 (double d, T t) {
163 return Foo2<T>.Get_T2 (d, 1, 2, 3, 4, 5, 6, 7, 8, t);
167 struct VTypeByRefStruct {
168 public long o1, o2, o3;
171 [Category ("GSHAREDVT")]
172 public static int test_0_arm64_gsharedvt_out_vtypebyref () {
173 /* gsharedvt out trampoline with vtypebyref argument */
174 var s = new VTypeByRefStruct () { o1 = 1, o2 = 2, o3 = 3 };
176 // Call Foo2.Get_T directly, so its gets an instance
177 Foo2<VTypeByRefStruct>.Get_T (1.0f, s);
178 var o = (IFaceFoo4<VTypeByRefStruct>)Activator.CreateInstance (typeof (Foo4<>).MakeGenericType (new Type [] { typeof (VTypeByRefStruct) }));
179 // Call Foo4.Get_T, this will call the gsharedvt instance, which will call the non-gsharedvt instance
180 var s_res = o.Get_T (1.0f, s);
181 if (s_res.o1 != 1 || s_res.o2 != 2 || s_res.o3 != 3)
182 return 1;
183 // Same with the byref argument passed on the stack
184 s_res = o.Get_T2 (1.0f, s);
185 if (s_res.o1 != 1 || s_res.o2 != 2 || s_res.o3 != 3)
186 return 2;
187 return 0;
190 class Foo5<T> {
191 public static T Get_T (object o) {
192 return (T)o;
196 [Category ("DYNCALL")]
197 [Category ("GSHAREDVT")]
198 [Category ("!FULLAOT-AMD64")]
199 static int test_0_arm64_dyncall_vtypebyref_ret () {
200 var s = new VTypeByRefStruct () { o1 = 1, o2 = 2, o3 = 3 };
201 Type t = typeof (Foo5<>).MakeGenericType (new Type [] { typeof (VTypeByRefStruct) });
202 var o = Activator.CreateInstance (t);
203 try {
204 var s_res = (VTypeByRefStruct)t.GetMethod ("Get_T").Invoke (o, new object [] { s });
205 if (s_res.o1 != 1 || s_res.o2 != 2 || s_res.o3 != 3)
206 return 1;
207 } catch (TargetInvocationException) {
208 return 2;
210 return 0;
213 class Foo6 {
214 public T reg_stack_split_inner<T> (int i, int j, T l) {
215 return l;
219 [Category ("DYNCALL")]
220 [Category ("GSHAREDVT")]
221 static int test_0_arm_dyncall_reg_stack_split () {
222 var m = typeof (Foo6).GetMethod ("reg_stack_split_inner").MakeGenericMethod (new Type[] { typeof (long) });
223 var o = new Foo6 ();
224 if ((long)m.Invoke (o, new object [] { 1, 2, 3 }) != 3)
225 return 1;
226 if ((long)m.Invoke (o, new object [] { 1, 2, Int64.MaxValue }) != Int64.MaxValue)
227 return 2;
228 return 0;
231 static int test_0_partial_sharing_regress_30204 () {
232 var t = typeof (System.Collections.Generic.Comparer<System.Collections.Generic.KeyValuePair<string, string>>);
233 var d = new SortedDictionary<string, string> ();
234 d.Add ("key1", "banana");
235 return d ["key1"] == "banana" ? 0 : 1;
238 class NullableMethods {
239 [MethodImplAttribute (MethodImplOptions.NoInlining)]
240 public static bool GetHasValue<T>(Nullable<T> value) where T : struct {
241 return value.HasValue;
244 [MethodImplAttribute (MethodImplOptions.NoInlining)]
245 public static T GetValue<T>(Nullable<T> value) where T : struct {
246 return value.Value;
249 [MethodImplAttribute (MethodImplOptions.NoInlining)]
250 public static Nullable<T> Get<T>(T t) where T : struct {
251 return t;
254 [MethodImplAttribute (MethodImplOptions.NoInlining)]
255 public static Nullable<T> GetNull<T>() where T : struct {
256 return null;
260 [Category ("DYNCALL")]
261 [Category ("!FULLAOT-AMD64")]
262 public static int test_0_dyncall_nullable () {
263 int? v;
265 v = 42;
266 NullableMethods.GetHasValue (v);
267 bool b = (bool)typeof (NullableMethods).GetMethod ("GetHasValue").MakeGenericMethod (new Type [] { typeof (int) }).Invoke (null, new object [] { v });
268 if (!b)
269 return 1;
270 v = null;
271 b = (bool)typeof (NullableMethods).GetMethod ("GetHasValue").MakeGenericMethod (new Type [] { typeof (int) }).Invoke (null, new object [] { v });
272 if (b)
273 return 2;
275 v = 42;
276 NullableMethods.GetValue (v);
277 var res = (int)typeof (NullableMethods).GetMethod ("GetValue").MakeGenericMethod (new Type [] { typeof (int) }).Invoke (null, new object [] { v });
278 if (res != 42)
279 return 3;
281 NullableMethods.Get (42);
282 var res2 = (int?)typeof (NullableMethods).GetMethod ("Get").MakeGenericMethod (new Type [] { typeof (int) }).Invoke (null, new object [] { 42 });
283 if (res2 != 42)
284 return 4;
285 res2 = (int?)typeof (NullableMethods).GetMethod ("GetNull").MakeGenericMethod (new Type [] { typeof (int) }).Invoke (null, new object [] { });
286 if (res2.HasValue)
287 return 5;
288 return 0;
291 enum AnEnum {
292 A = 0,
293 B = 1
296 public static int test_0_enum_eq_comparer () {
297 var c = EqualityComparer<AnEnum>.Default;
298 return (!c.Equals (AnEnum.A, AnEnum.B) && c.Equals (AnEnum.A, AnEnum.A)) ? 0 : 1;
301 public static int test_0_enum_comparer () {
302 var c = Comparer<AnEnum>.Default;
303 return c.Compare (AnEnum.A, AnEnum.A);
306 private static Dictionary<long, TValue> ConvertDictionary<TValue>(Dictionary<long, IList<TValue>> source) {
307 return source.ToDictionary(pair => pair.Key, pair => pair.Value[0]);
310 [Category ("GSHAREDVT")]
311 public static int test_0_gsharedvt_non_variable_arg () {
312 Dictionary<long, IList<int>> data = new Dictionary<long, IList<int>>
314 {123L, new List<int> {2}}
316 Dictionary<long, int> newDict = ConvertDictionary(data);
317 if (newDict.Count != 1)
318 return 1;
319 return 0;
322 enum LongEnum : ulong {
323 A = 1
326 public static int test_0_long_enum_eq_comparer () {
327 var c = EqualityComparer<LongEnum>.Default;
328 c.GetHashCode (LongEnum.A);
329 return 0;
332 enum UInt32Enum : uint {
333 A = 1
336 enum Int32Enum : int {
337 A = 1
340 enum Int16Enum : short {
341 A = 1
344 enum UInt16Enum : ushort {
345 A = 1
348 enum Int8Enum : sbyte {
349 A = 1
352 enum UInt8Enum : byte {
353 A = 1
356 public static int test_0_int_enum_eq_comparer () {
357 var t1 = new Dictionary<Int32Enum, object> ();
358 t1 [Int32Enum.A] = "foo";
360 var t2 = new Dictionary<UInt32Enum, object> ();
361 t2 [UInt32Enum.A] = "foo";
363 var t3 = new Dictionary<UInt16Enum, object> ();
364 t3 [UInt16Enum.A] = "foo";
366 var t4 = new Dictionary<Int16Enum, object> ();
367 t4 [Int16Enum.A] = "foo";
369 var t5 = new Dictionary<Int8Enum, object> ();
370 t5 [Int8Enum.A] = "foo";
372 var t6 = new Dictionary<UInt8Enum, object> ();
373 t6 [UInt8Enum.A] = "foo";
375 return 0;
378 [Category ("DYNCALL")]
379 public static int test_0_array_accessor_runtime_invoke_ref () {
380 var t = typeof (string[]);
381 var arr = Array.CreateInstance (typeof (string), 1);
382 arr.GetType ().GetMethod ("Set").Invoke (arr, new object [] { 0, "A" });
383 var res = (string)arr.GetType ().GetMethod ("Get").Invoke (arr, new object [] { 0 });
384 if (res != "A")
385 return 1;
386 return 0;
389 public static void SetArrayValue_<T> (T[] values) {
390 values.Select (x => x).ToArray ();
393 [Category ("GSHAREDVT")]
394 public static int test_0_delegate_invoke_wrappers_gsharedvt () {
395 var enums = new LongEnum [] { LongEnum.A };
396 SetArrayValue_ (enums);
397 return 0;
400 struct LargeStruct {
401 public int a, b, c, d;
404 [MethodImplAttribute (MethodImplOptions.NoInlining)]
405 public static bool GetHasValue<T>(T? value) where T : struct
407 return value.HasValue;
410 [Category ("DYNCALL")]
411 [Category ("!FULLAOT-AMD64")]
412 public static int test_0_large_nullable_invoke () {
413 var s = new LargeStruct () { a = 1, b = 2, c = 3, d = 4 };
415 GetHasValue<LargeStruct> (s);
417 #if __MOBILE__
418 var m = typeof(AotTests).GetMethod("GetHasValue", BindingFlags.Static | BindingFlags.Public);
419 #else
420 var m = typeof(Tests).GetMethod("GetHasValue", BindingFlags.Static | BindingFlags.Public);
421 #endif
423 Type type = typeof (LargeStruct?).GetGenericArguments () [0];
424 bool b1 = (bool)m.MakeGenericMethod (new Type[] {type}).Invoke (null, new object[] { s });
425 if (!b1)
426 return 1;
427 bool b2 = (bool)m.MakeGenericMethod (new Type[] {type}).Invoke (null, new object[] { null });
428 if (b2)
429 return 2;
430 return 0;
433 struct FpStruct {
434 public float a, b, c;
437 struct LargeStruct2 {
438 public FpStruct x;
439 public int a, b, c, d, e, f, g, h;
442 [MethodImplAttribute (MethodImplOptions.NoInlining)]
443 static int pass_hfa_on_stack (FpStruct s1, FpStruct s2, FpStruct s3) {
444 return (int)s3.c;
447 public static int test_10_arm64_hfa_on_stack_llvm () {
448 var arr = new LargeStruct2 [10, 10];
449 for (int i = 0; i < 10; ++i)
450 for (int j = 0; j < 10; ++j)
451 arr [i, j].x = new FpStruct ();
453 var s1 = new FpStruct () { a = 1, b = 1, c = 10 };
454 return pass_hfa_on_stack (s1, s1, s1);
457 public static int test_0_get_current_method () {
458 var m = MethodBase.GetCurrentMethod ();
459 #if __MOBILE__
460 var m2 = typeof (AotTests).GetMethod ("test_0_get_current_method");
461 #else
462 var m2 = typeof (Tests).GetMethod ("test_0_get_current_method");
463 #endif
464 return m == m2 ? 0 : 1;
467 class GetCurrentMethodClass<T> {
468 [MethodImplAttribute (MethodImplOptions.NoInlining)]
469 public MethodBase get_current () {
470 return MethodBase.GetCurrentMethod ();
474 public static int test_0_get_current_method_generic () {
475 var c = new GetCurrentMethodClass<string> ();
476 var m = c.get_current ();
477 var m2 = typeof (GetCurrentMethodClass<>).GetMethod ("get_current");
478 return m == m2 ? 0 : 1;
481 public static int test_0_array_wrappers_runtime_invoke () {
482 string[][] arr = new string [10][];
483 IEnumerable<string[]> iface = arr;
484 var m = typeof(IEnumerable<string[]>).GetMethod ("GetEnumerator");
485 m.Invoke (arr, null);
486 return 0;