[wasm] Disable test that doesn't work with WASM
[mono.git] / mono / mini / mixed.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Reflection;
4 using System.Runtime.InteropServices;
5 using System.Runtime.CompilerServices;
6 using System.Diagnostics;
7
8 /*
9  * Regression tests for the mixed-mode execution.
10  * Run with --interp=jit=JitClass
11  */
12
13 struct AStruct {
14         public int i;
15 }
16
17 struct GStruct<T> {
18         public int i;
19 }
20
21 class InterpClass
22 {
23         [MethodImplAttribute (MethodImplOptions.NoInlining)]
24         public static void entry_void_0 () {
25         }
26
27         [MethodImplAttribute (MethodImplOptions.NoInlining)]
28         public static int entry_int_int (int i) {
29                 return i + 1;
30         }
31
32         [MethodImplAttribute (MethodImplOptions.NoInlining)]
33         public int entry_int_this_int (int i) {
34                 return i + 1;
35         }
36
37         [MethodImplAttribute (MethodImplOptions.NoInlining)]
38         public static string entry_string_string (string s1, string s2) {
39                 return s1 + s2;
40         }
41
42         [MethodImplAttribute (MethodImplOptions.NoInlining)]
43         public static AStruct entry_struct_struct (AStruct l) {
44                 return l;
45         }
46
47         [MethodImplAttribute (MethodImplOptions.NoInlining)]
48         public static List<string> entry_ginst_ginst (List<string> l) {
49                 return l;
50         }
51
52         [MethodImplAttribute (MethodImplOptions.NoInlining)]
53         public static GStruct<string> entry_ginst_ginst_vtype (GStruct<string> l) {
54                 return l;
55         }
56
57         [MethodImplAttribute (MethodImplOptions.NoInlining)]
58         public static void entry_void_byref_int (ref int i) {
59                 i = i + 1;
60         }
61
62         [MethodImplAttribute (MethodImplOptions.NoInlining)]
63         public static int entry_8_int_args (int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8) {
64                 return i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8;
65         }
66
67         [MethodImplAttribute (MethodImplOptions.NoInlining)]
68         public static int entry_9_int_args (int i1, int i2, int i3, int i4, int i5, int i6, int i7, int i8, int i9) {
69                 return i1 + i2 + i3 + i4 + i5 + i6 + i7 + i8 + i9;
70         }
71
72         [MethodImplAttribute (MethodImplOptions.NoInlining)]
73         public static IntPtr entry_intptr_intptr (IntPtr i) {
74                 return i;
75         }
76
77         [MethodImplAttribute (MethodImplOptions.NoInlining)]
78         public static StackTrace get_stacktrace_interp () {
79                 var o = new object ();
80                 return new StackTrace (true);
81         }
82
83         [MethodImplAttribute (MethodImplOptions.NoInlining)]
84         public static void throw_ex () {
85                 JitClass.throw_ex ();
86         }
87 }
88
89 /* The methods in this class will always be JITted */
90 class JitClass
91 {
92         [MethodImplAttribute (MethodImplOptions.NoInlining)]
93         public static int entry () {
94                 InterpClass.entry_void_0 ();
95                 InterpClass.entry_void_0 ();
96                 int res = InterpClass.entry_int_int (1);
97                 if (res != 2)
98                         return 1;
99                 var c = new InterpClass ();
100                 res = c.entry_int_this_int (1);
101                 if (res != 2)
102                         return 2;
103                 var s = InterpClass.entry_string_string ("A", "B");
104                 if (s != "AB")
105                         return 3;
106                 var astruct = new AStruct () { i = 1 };
107                 var astruct2 = InterpClass.entry_struct_struct (astruct);
108                 if (astruct2.i != 1)
109                         return 4;
110                 var l = new List<string> ();
111                 var l2 = InterpClass.entry_ginst_ginst (l);
112                 if (l != l2)
113                         return 5;
114                 var gstruct = new GStruct<string> () { i = 1 };
115                 var gstruct2 = InterpClass.entry_ginst_ginst_vtype (gstruct);
116                 if (gstruct2.i != 1)
117                         return 6;
118                 int val = 1;
119                 InterpClass.entry_void_byref_int (ref val);
120                 if (val != 2)
121                         return 7;
122                 res = InterpClass.entry_8_int_args (1, 2, 3, 4, 5, 6, 7, 8);
123                 if (res != 36)
124                         return 8;
125                 res = InterpClass.entry_9_int_args (1, 2, 3, 4, 5, 6, 7, 8, 9);
126                 if (res != 45)
127                         return 9;
128                 var ptr = new IntPtr (32);
129                 var ptr2 = InterpClass.entry_intptr_intptr (ptr);
130                 if (ptr != ptr2)
131                         return 10;
132                 return 0;
133         }
134
135         [MethodImplAttribute (MethodImplOptions.NoInlining)]
136         public static AStruct exit_vtype (AStruct s) {
137                 return s;
138         }
139
140         [MethodImplAttribute (MethodImplOptions.NoInlining)]
141         public static List<string> exit_ginst (List<string> l) {
142                 return l;
143         }
144
145         [MethodImplAttribute (MethodImplOptions.NoInlining)]
146         public static GStruct<string> exit_ginst_vtype (GStruct<string> l) {
147                 return l;
148         }
149
150         [MethodImplAttribute (MethodImplOptions.NoInlining)]
151         public static void exit_byref (ref int i) {
152                 i += 1;
153         }
154
155         [MethodImplAttribute (MethodImplOptions.NoInlining)]
156         public static void throw_ex () {
157                 throw new Exception ();
158         }
159
160         [MethodImplAttribute (MethodImplOptions.NoInlining)]
161         public static StackTrace get_stacktrace_jit () {
162                 return InterpClass.get_stacktrace_interp ();
163         }
164 }
165
166 #if __MOBILE__
167 class MixedTests
168 #else
169 class Tests
170 #endif
171 {
172
173 #if !__MOBILE__
174         public static int Main (string[] args) {
175                 return TestDriver.RunTests (typeof (Tests), args);
176         }
177 #endif
178
179         public static int test_0_entry () {
180                 // This does an interp->jit transition
181                 return JitClass.entry ();
182         }
183
184         public static int test_0_exit () {
185                 var astruct = new AStruct () { i = 1};
186                 var astruct2 = JitClass.exit_vtype (astruct);
187                 if (astruct2.i != 1)
188                         return 1;
189                 var ginst = new List<string> ();
190                 var ginst2 = JitClass.exit_ginst (ginst);
191                 if (ginst != ginst2)
192                         return 2;
193                 var gstruct = new GStruct<string> () { i = 1 };
194                 var gstruct2 = JitClass.exit_ginst_vtype (gstruct);
195                 if (gstruct2.i != 1)
196                         return 3;
197                 var anint = 1;
198                 JitClass.exit_byref (ref anint);
199                 if (anint != 2)
200                         return 4;
201                 return 0;
202         }
203
204         public static int test_0_throw () {
205                 // Throw an exception from jitted code, catch it in interpreted code
206                 try {
207                         JitClass.throw_ex ();
208                 } catch {
209                         return 0;
210                 }
211                 return 1;
212         }
213
214         public static int test_0_throw_child () {
215                 try {
216                         InterpClass.throw_ex ();
217                 } catch {
218                         return 0;
219                 }
220                 return 1;
221         }
222
223         static bool finally_called;
224
225         public static void call_finally () {
226                 try {
227                         JitClass.throw_ex ();
228                 } finally {
229                         finally_called = true;
230                 }
231         }
232
233         public static int test_0_eh2 () {
234                 finally_called = false;
235
236                 // Throw an exception from jitted code, execute finally in interpreted code
237                 try {
238                         call_finally ();
239                 } catch {
240                         return 0;
241                 }
242                 if (!finally_called)
243                         return 2;
244                 return 1;
245         }
246
247         [Category ("!WASM")] //Stack traces / EH are super broken on WASM + Interpreter
248         public static int test_0_stack_traces () {
249                 //
250                 // Get a stacktrace for an interp->jit->interp call stack
251                 //
252                 StackTrace st = JitClass.get_stacktrace_jit ();
253                 var frame = st.GetFrame (0);
254                 if (frame.GetMethod ().Name != "get_stacktrace_interp")
255                         return 1;
256                 frame = st.GetFrame (1);
257                 if (frame.GetMethod ().Name != "get_stacktrace_jit")
258                         return 2;
259                 frame = st.GetFrame (2);
260                 if (frame.GetMethod ().Name != "test_0_stack_traces")
261                         return 3;
262                 return 0;
263         }
264 }