2004-01-15 Zoltan Varga <vargaz@freemail.hu>
[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_multi_array_cast () {
248                 Duper[,] d = new Duper [1, 1];
249                 object[,] o = d;
250
251                 try {
252                         o [0, 0] = new Super ();
253                         return 1;
254                 }
255                 catch (ArrayTypeMismatchException) {
256                 }
257
258                 return 0;
259         }
260
261         static int test_0_enum_array_cast () {
262                 TypeCode[] tc = new TypeCode [0];
263                 object[] oa;
264                 ValueType[] vta;
265                 int[] inta;
266                 Array a = tc;
267                 bool ok;
268
269                 if (a is object[])
270                         return 1;
271                 if (a is ValueType[])
272                         return 2;
273                 if (a is Enum[])
274                         return 3;
275                 try {
276                         ok = false;
277                         oa = (object[])a;
278                 } catch {
279                         ok = true;
280                 }
281                 if (!ok)
282                         return 4;
283                 try {
284                         ok = false;
285                         vta = (ValueType[])a;
286                 } catch {
287                         ok = true;
288                 }
289                 if (!ok)
290                         return 5;
291                 try {
292                         ok = true;
293                         inta = (int[])a;
294                 } catch {
295                         ok = false;
296                 }
297                 if (!ok)
298                         return 6;
299                 return 0;
300         }
301
302         static int test_0_more_cast_corner_cases () {
303                 ValueType[] vta = new ValueType [0];
304                 Enum[] ea = new Enum [0];
305                 Array a = vta;
306                 object[] oa;
307                 bool ok;
308
309                 if (!(a is object[]))
310                         return 1;
311                 if (!(a is ValueType[]))
312                         return 2;
313                 if (a is Enum[])
314                         return 3;
315                 a = ea;
316                 if (!(a is object[]))
317                         return 4;
318                 if (!(a is ValueType[]))
319                         return 5;
320                 if (!(a is Enum[]))
321                         return 6;
322
323                 try {
324                         ok = true;
325                         oa = (object[])a;
326                 } catch {
327                         ok = false;
328                 }
329                 if (!ok)
330                         return 7;
331         
332                 try {
333                         ok = true;
334                         oa = (Enum[])a;
335                 } catch {
336                         ok = false;
337                 }
338                 if (!ok)
339                         return 8;
340         
341                 try {
342                         ok = true;
343                         oa = (ValueType[])a;
344                 } catch {
345                         ok = false;
346                 }
347                 if (!ok)
348                         return 9;
349
350                 a = vta;
351                 try {
352                         ok = true;
353                         oa = (object[])a;
354                 } catch {
355                         ok = false;
356                 }
357                 if (!ok)
358                         return 10;
359         
360                 try {
361                         ok = true;
362                         oa = (ValueType[])a;
363                 } catch {
364                         ok = false;
365                 }
366                 if (!ok)
367                         return 11;
368         
369                 try {
370                         ok = false;
371                         vta = (Enum[])a;
372                 } catch {
373                         ok = true;
374                 }
375                 if (!ok)
376                         return 12;
377                 return 0;
378         }
379
380         static int test_0_cast_iface_array () {
381                 object o = new ICloneable [0];
382                 object o2 = new Duper [0];
383                 object t;
384                 bool ok;
385
386                 if (!(o is object[]))
387                         return 1;
388                 if (!(o2 is ICloneable[]))
389                         return 2;
390
391                 try {
392                         ok = true;
393                         t = (object[])o;
394                 } catch {
395                         ok = false;
396                 }
397                 if (!ok)
398                         return 3;
399         
400                 try {
401                         ok = true;
402                         t = (ICloneable[])o2;
403                 } catch {
404                         ok = false;
405                 }
406                 if (!ok)
407                         return 4;
408
409                 try {
410                         ok = true;
411                         t = (ICloneable[])o;
412                 } catch {
413                         ok = false;
414                 }
415                 if (!ok)
416                         return 5;
417
418                 if (!(o is ICloneable[]))
419                         return 6;
420
421                 /* add tests for interfaces that 'inherit' interfaces */
422                 return 0;
423         }
424
425         private static int[] daysmonthleap = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
426
427         private static int AbsoluteDays (int year, int month, int day)
428         {
429                 int temp = 0, m = 1;
430                 int[] days = daysmonthleap;
431                 while (m < month)
432                         temp += days[m++];
433                 return ((day-1) + temp + (365* (year-1)) + ((year-1)/4) - ((year-1)/100) + ((year-1)/400));
434         }
435
436         static int test_719162_complex_div () {
437                 int adays = AbsoluteDays (1970, 1, 1);
438                 return adays;
439         }
440
441         delegate int GetIntDel ();
442
443         static int return4 () {
444                 return 4;
445         }
446
447         int return5 () {
448                 return 5;
449         }
450
451         static int test_2_static_delegate () {
452                 GetIntDel del = new GetIntDel (return4);
453                 int v = del ();
454                 if (v != 4)
455                         return 0;
456                 return 2;
457         }
458
459         static int test_2_instance_delegate () {
460                 Tests t = new Tests ();
461                 GetIntDel del = new GetIntDel (t.return5);
462                 int v = del ();
463                 if (v != 5)
464                         return 0;
465                 return 2;
466         }
467
468         static int test_1_store_decimal () {
469                 decimal[,] a = {{1}};
470
471                 if (a[0,0] != 1m)
472                         return 0;
473                 return 1;
474         }
475
476         static int test_2_intptr_stobj () {
477                 System.IntPtr [] arr = { new System.IntPtr () };
478
479                 if (arr [0] != (System.IntPtr)0)
480                         return 1;
481                 return 2;
482         }
483 }
484