Fri Dec 12 21:25:14 CET 2003 Paolo Molaro <lupus@ximian.com>
[mono.git] / mono / mini / objects.cs
1 using System;
2 using System.Reflection;
3
4 /*
5  * Regression tests for the mono JIT.
6  *
7  * Each test needs to be of the form:
8  *
9  * static int test_<result>_<name> ();
10  *
11  * where <result> is an integer (the value that needs to be returned by
12  * the method to make it pass.
13  * <name> is a user-displayed name used to identify the test.
14  *
15  * The tests can be driven in two ways:
16  * *) running the program directly: Main() uses reflection to find and invoke
17  *      the test methods (this is useful mostly to check that the tests are correct)
18  * *) with the --regression switch of the jit (this is the preferred way since
19  *      all the tests will be run with optimizations on and off)
20  *
21  * The reflection logic could be moved to a .dll since we need at least another
22  * regression test file written in IL code to have better control on how
23  * the IL code looks.
24  */
25
26 struct Simple {
27         public int a;
28         public byte b;
29         public short c;
30         public long d;
31 }
32
33 class Sample {
34         public int a;
35         public Sample (int v) {
36                 a = v;
37         }
38 }
39
40 enum SampleEnum {
41         A,
42         B,
43         C
44 }
45
46 class Tests {
47
48         static int Main () {
49                 return TestDriver.RunTests (typeof (Tests));
50         }
51         
52         static int test_0_return () {
53                 Simple s;
54                 s.a = 1;
55                 s.b = 2;
56                 s.c = (short)(s.a + s.b);
57                 s.d = 4;
58                 return s.a - 1;
59         }
60
61         static int test_0_string_access () {
62                 string s = "Hello";
63                 if (s [1] != 'e')
64                         return 1;
65                 return 0;
66         }
67
68         static int test_0_string_virtual_call () {
69                 string s = "Hello";
70                 string s2 = s.ToString ();
71                 if (s2 [1] != 'e')
72                         return 1;
73                 return 0;
74         }
75
76         static int test_0_iface_call () {
77                 string s = "Hello";
78                 object o = ((ICloneable)s).Clone ();
79                 return 0;
80         }
81
82         static int test_5_newobj () {
83                 Sample s = new Sample (5);
84                 return s.a;
85         }
86
87         static int test_4_box () {
88                 object obj = 4;
89                 return (int)obj;
90         }
91
92         static int test_0_enum_unbox () {
93                 SampleEnum x = SampleEnum.A;
94                 object o = x;
95                 
96                 int res = 1;
97
98                 res = (int)o;
99                 
100                 return res;
101         }
102         
103         static Simple get_simple (int v) {
104                 Simple r = new Simple ();
105                 r.a = v;
106                 r.b = (byte)(v + 1);
107                 r.c = (short)(v + 2);
108                 r.d = v + 3;
109
110                 return r;
111         }
112
113         static int test_3_return_struct () {
114                 Simple v = get_simple (1);
115
116                 if (v.a != 1)
117                         return 0;
118                 if (v.b != 2)
119                         return 0;
120                 if (v.c != 3)
121                         return 0;
122                 if (v.d != 4)
123                         return 0;
124                 return 3;
125         }
126
127         public virtual Simple v_get_simple (int v)
128         {
129                 return get_simple (v);
130         }
131         
132         static int test_2_return_struct_virtual () {
133                 Tests t = new Tests ();
134                 Simple v = t.v_get_simple (2);
135
136                 if (v.a != 2)
137                         return 0;
138                 if (v.b != 3)
139                         return 0;
140                 if (v.c != 4)
141                         return 0;
142                 if (v.d != 5)
143                         return 0;
144                 return 2;
145         }
146
147         static int receive_simple (int a, Simple v, int b) {
148                 if (v.a != 1)
149                         return 1;
150                 if (v.b != 2)
151                         return 2;
152                 if (v.c != 3)
153                         return 3;
154                 if (v.d != 4)
155                         return 4;
156                 if (a != 7)
157                         return 5;
158                 if (b != 9)
159                         return 6;
160                 return 0;
161         }
162         
163         static int test_5_pass_struct () {
164                 Simple v = get_simple (1);
165                 if (receive_simple (7, v, 9) != 0)
166                         return 0;
167                 if (receive_simple (7, get_simple (1), 9) != 0)
168                         return 1;
169                 return 5;
170         }
171
172         class TestRegA {
173
174                 long buf_start;
175                 int buf_length, buf_offset;
176         
177                 public long Seek (long position) {
178                         long pos = position;
179                         /* interaction between the register allocator and
180                          * allocating arguments to registers */
181                         if (pos >= buf_start && pos <= buf_start + buf_length) {
182                                 buf_offset = (int) (pos - buf_start);
183                                 return pos;
184                         }
185                         return buf_start;
186                 }
187
188         }
189
190         static int test_0_seektest () {
191                 TestRegA t = new TestRegA ();
192                 return (int)t.Seek (0);
193         }
194
195         class Super : ICloneable {
196                 public virtual object Clone () {
197                         return null;
198                 }
199         }
200         class Duper: Super {
201         }
202         
203         static int test_0_super_cast () {
204                 Duper d = new Duper ();
205                 Super sup = d;
206                 Object o = d;
207
208                 if (!(o is Super))
209                         return 1;
210                 try {
211                         d = (Duper)sup;
212                 } catch {
213                         return 2;
214                 }
215                 if (!(d is Object))
216                         return 3;
217                 try {
218                         d = (Duper)(object)sup;
219                 } catch {
220                         return 4;
221                 }
222                 return 0;
223         }
224
225         static int test_0_super_cast_array () {
226                 Duper[] d = new Duper [0];
227                 Super[] sup = d;
228                 Object[] o = d;
229
230                 if (!(o is Super[]))
231                         return 1;
232                 try {
233                         d = (Duper[])sup;
234                 } catch {
235                         return 2;
236                 }
237                 if (!(d is Object[]))
238                         return 3;
239                 try {
240                         d = (Duper[])(object[])sup;
241                 } catch {
242                         return 4;
243                 }
244                 return 0;
245         }
246
247         static int test_0_enum_array_cast () {
248                 TypeCode[] tc = new TypeCode [0];
249                 object[] oa;
250                 ValueType[] vta;
251                 int[] inta;
252                 Array a = tc;
253                 bool ok;
254
255                 if (a is object[])
256                         return 1;
257                 if (a is ValueType[])
258                         return 2;
259                 if (a is Enum[])
260                         return 3;
261                 try {
262                         ok = false;
263                         oa = (object[])a;
264                 } catch {
265                         ok = true;
266                 }
267                 if (!ok)
268                         return 4;
269                 try {
270                         ok = false;
271                         vta = (ValueType[])a;
272                 } catch {
273                         ok = true;
274                 }
275                 if (!ok)
276                         return 5;
277                 try {
278                         ok = true;
279                         inta = (int[])a;
280                 } catch {
281                         ok = false;
282                 }
283                 if (!ok)
284                         return 6;
285                 return 0;
286         }
287
288         static int test_0_more_cast_corner_cases () {
289                 ValueType[] vta = new ValueType [0];
290                 Enum[] ea = new Enum [0];
291                 Array a = vta;
292                 object[] oa;
293                 bool ok;
294
295                 if (!(a is object[]))
296                         return 1;
297                 if (!(a is ValueType[]))
298                         return 2;
299                 if (a is Enum[])
300                         return 3;
301                 a = ea;
302                 if (!(a is object[]))
303                         return 4;
304                 if (!(a is ValueType[]))
305                         return 5;
306                 if (!(a is Enum[]))
307                         return 6;
308
309                 try {
310                         ok = true;
311                         oa = (object[])a;
312                 } catch {
313                         ok = false;
314                 }
315                 if (!ok)
316                         return 7;
317         
318                 try {
319                         ok = true;
320                         oa = (Enum[])a;
321                 } catch {
322                         ok = false;
323                 }
324                 if (!ok)
325                         return 8;
326         
327                 try {
328                         ok = true;
329                         oa = (ValueType[])a;
330                 } catch {
331                         ok = false;
332                 }
333                 if (!ok)
334                         return 9;
335
336                 a = vta;
337                 try {
338                         ok = true;
339                         oa = (object[])a;
340                 } catch {
341                         ok = false;
342                 }
343                 if (!ok)
344                         return 10;
345         
346                 try {
347                         ok = true;
348                         oa = (ValueType[])a;
349                 } catch {
350                         ok = false;
351                 }
352                 if (!ok)
353                         return 11;
354         
355                 try {
356                         ok = false;
357                         vta = (Enum[])a;
358                 } catch {
359                         ok = true;
360                 }
361                 if (!ok)
362                         return 12;
363                 return 0;
364         }
365
366         static int test_0_cast_iface_array () {
367                 object o = new ICloneable [0];
368                 object o2 = new Duper [0];
369                 object t;
370                 bool ok;
371
372                 if (!(o is object[]))
373                         return 1;
374                 if (!(o2 is ICloneable[]))
375                         return 2;
376
377                 try {
378                         ok = true;
379                         t = (object[])o;
380                 } catch {
381                         ok = false;
382                 }
383                 if (!ok)
384                         return 3;
385         
386                 try {
387                         ok = true;
388                         t = (ICloneable[])o2;
389                 } catch {
390                         ok = false;
391                 }
392                 if (!ok)
393                         return 4;
394
395                 try {
396                         ok = true;
397                         t = (ICloneable[])o;
398                 } catch {
399                         ok = false;
400                 }
401                 if (!ok)
402                         return 5;
403
404                 if (!(o is ICloneable[]))
405                         return 6;
406
407                 /* add tests for interfaces that 'inherit' interfaces */
408                 return 0;
409         }
410
411         private static int[] daysmonthleap = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
412
413         private static int AbsoluteDays (int year, int month, int day)
414         {
415                 int temp = 0, m = 1;
416                 int[] days = daysmonthleap;
417                 while (m < month)
418                         temp += days[m++];
419                 return ((day-1) + temp + (365* (year-1)) + ((year-1)/4) - ((year-1)/100) + ((year-1)/400));
420         }
421
422         static int test_719162_complex_div () {
423                 int adays = AbsoluteDays (1970, 1, 1);
424                 return adays;
425         }
426
427         delegate int GetIntDel ();
428
429         static int return4 () {
430                 return 4;
431         }
432
433         int return5 () {
434                 return 5;
435         }
436
437         static int test_2_static_delegate () {
438                 GetIntDel del = new GetIntDel (return4);
439                 int v = del ();
440                 if (v != 4)
441                         return 0;
442                 return 2;
443         }
444
445         static int test_2_instance_delegate () {
446                 Tests t = new Tests ();
447                 GetIntDel del = new GetIntDel (t.return5);
448                 int v = del ();
449                 if (v != 5)
450                         return 0;
451                 return 2;
452         }
453
454         static int test_1_store_decimal () {
455                 decimal[,] a = {{1}};
456
457                 if (a[0,0] != 1m)
458                         return 0;
459                 return 1;
460         }
461
462         static int test_2_intptr_stobj () {
463                 System.IntPtr [] arr = { new System.IntPtr () };
464
465                 if (arr [0] != (System.IntPtr)0)
466                         return 1;
467                 return 2;
468         }
469 }
470