[interp] Fix interp logging (#17636)
[mono-project.git] / mono / mini / mixed.cs
blob8ee0ac460febb5c60336a61111a75288ab2d93a4
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;
8 /*
9 * Regression tests for the mixed-mode execution.
10 * Run with --interp=jit=JitClass
13 struct AStruct {
14 public int i;
17 struct GStruct<T> {
18 public int i;
21 class InterpClass
23 [MethodImplAttribute (MethodImplOptions.NoInlining)]
24 public static void entry_void_0 () {
27 [MethodImplAttribute (MethodImplOptions.NoInlining)]
28 public static int entry_int_int (int i) {
29 return i + 1;
32 [MethodImplAttribute (MethodImplOptions.NoInlining)]
33 public int entry_int_this_int (int i) {
34 return i + 1;
37 [MethodImplAttribute (MethodImplOptions.NoInlining)]
38 public static string entry_string_string (string s1, string s2) {
39 return s1 + s2;
42 [MethodImplAttribute (MethodImplOptions.NoInlining)]
43 public static AStruct entry_struct_struct (AStruct l) {
44 return l;
47 [MethodImplAttribute (MethodImplOptions.NoInlining)]
48 public static List<string> entry_ginst_ginst (List<string> l) {
49 return l;
52 [MethodImplAttribute (MethodImplOptions.NoInlining)]
53 public static GStruct<string> entry_ginst_ginst_vtype (GStruct<string> l) {
54 return l;
57 [MethodImplAttribute (MethodImplOptions.NoInlining)]
58 public static void entry_void_byref_int (ref int i) {
59 i = i + 1;
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;
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;
72 [MethodImplAttribute (MethodImplOptions.NoInlining)]
73 public static IntPtr entry_intptr_intptr (IntPtr i) {
74 return i;
77 [MethodImplAttribute (MethodImplOptions.NoInlining)]
78 public static int entry_deep_generic_vt (int i, decimal? b) {
79 return i;
83 [MethodImplAttribute (MethodImplOptions.NoInlining)]
84 public static StackTrace get_stacktrace_interp () {
85 var o = new object ();
86 return new StackTrace (true);
89 [MethodImplAttribute (MethodImplOptions.NoInlining)]
90 public static StackTrace get_stacktrace_interp2 () {
91 return JitClass.get_stacktrace_jit ();
94 [MethodImplAttribute (MethodImplOptions.NoInlining)]
95 public static void throw_ex () {
96 JitClass.throw_ex ();
100 /* The methods in this class will always be JITted */
101 class JitClass
103 [MethodImplAttribute (MethodImplOptions.NoInlining)]
104 public static int entry () {
105 InterpClass.entry_void_0 ();
106 InterpClass.entry_void_0 ();
107 int res = InterpClass.entry_int_int (1);
108 if (res != 2)
109 return 1;
110 var c = new InterpClass ();
111 res = c.entry_int_this_int (1);
112 if (res != 2)
113 return 2;
114 var s = InterpClass.entry_string_string ("A", "B");
115 if (s != "AB")
116 return 3;
117 var astruct = new AStruct () { i = 1 };
118 var astruct2 = InterpClass.entry_struct_struct (astruct);
119 if (astruct2.i != 1)
120 return 4;
121 var l = new List<string> ();
122 var l2 = InterpClass.entry_ginst_ginst (l);
123 if (l != l2)
124 return 5;
125 var gstruct = new GStruct<string> () { i = 1 };
126 var gstruct2 = InterpClass.entry_ginst_ginst_vtype (gstruct);
127 if (gstruct2.i != 1)
128 return 6;
129 int val = 1;
130 InterpClass.entry_void_byref_int (ref val);
131 if (val != 2)
132 return 7;
133 res = InterpClass.entry_8_int_args (1, 2, 3, 4, 5, 6, 7, 8);
134 if (res != 36)
135 return 8;
136 res = InterpClass.entry_9_int_args (1, 2, 3, 4, 5, 6, 7, 8, 9);
137 if (res != 45)
138 return 9;
139 var ptr = new IntPtr (32);
140 var ptr2 = InterpClass.entry_intptr_intptr (ptr);
141 if (ptr != ptr2)
142 return 10;
143 var edgvt_ret = InterpClass.entry_deep_generic_vt (1337, 2m);
144 if (edgvt_ret != 1337)
145 return 11;
146 return 0;
149 [MethodImplAttribute (MethodImplOptions.NoInlining)]
150 public static AStruct exit_vtype (AStruct s) {
151 return s;
154 [MethodImplAttribute (MethodImplOptions.NoInlining)]
155 public static List<string> exit_ginst (List<string> l) {
156 return l;
159 [MethodImplAttribute (MethodImplOptions.NoInlining)]
160 public static GStruct<string> exit_ginst_vtype (GStruct<string> l) {
161 return l;
164 [MethodImplAttribute (MethodImplOptions.NoInlining)]
165 public static void exit_byref (ref int i) {
166 i += 1;
169 [MethodImplAttribute (MethodImplOptions.NoInlining)]
170 public static void throw_ex () {
171 throw new Exception ();
174 [MethodImplAttribute (MethodImplOptions.NoInlining)]
175 public static StackTrace get_stacktrace_jit () {
176 return InterpClass.get_stacktrace_interp ();
179 [MethodImplAttribute (MethodImplOptions.NoInlining)]
180 public static StackTrace get_stacktrace_jit2 () {
181 return InterpClass.get_stacktrace_interp2 ();
184 [MethodImplAttribute (MethodImplOptions.NoInlining)]
185 public static string string_from_interp ()
187 char [] buf = new char [10];
188 for (int i = 0; i < buf.Length; i++)
189 buf [i] = (char) ((int) 'a' + i);
190 return new string (buf, 0, 10);
194 #if __MOBILE__
195 class MixedTests
196 #else
197 class Tests
198 #endif
201 #if !__MOBILE__
202 public static int Main (string[] args) {
203 return TestDriver.RunTests (typeof (Tests), args);
205 #endif
207 public static int test_0_entry () {
208 // This does an interp->jit transition
209 return JitClass.entry ();
212 public static int test_0_exit () {
213 var astruct = new AStruct () { i = 1};
214 var astruct2 = JitClass.exit_vtype (astruct);
215 if (astruct2.i != 1)
216 return 1;
217 var ginst = new List<string> ();
218 var ginst2 = JitClass.exit_ginst (ginst);
219 if (ginst != ginst2)
220 return 2;
221 var gstruct = new GStruct<string> () { i = 1 };
222 var gstruct2 = JitClass.exit_ginst_vtype (gstruct);
223 if (gstruct2.i != 1)
224 return 3;
225 var anint = 1;
226 JitClass.exit_byref (ref anint);
227 if (anint != 2)
228 return 4;
229 return 0;
232 public static int test_0_throw () {
233 // Throw an exception from jitted code, catch it in interpreted code
234 try {
235 JitClass.throw_ex ();
236 } catch {
237 return 0;
239 return 1;
242 public static int test_0_throw_child () {
243 try {
244 InterpClass.throw_ex ();
245 } catch {
246 return 0;
248 return 1;
251 static bool finally_called;
253 public static void call_finally () {
254 try {
255 JitClass.throw_ex ();
256 } finally {
257 finally_called = true;
261 public static int test_0_eh2 () {
262 finally_called = false;
264 // Throw an exception from jitted code, execute finally in interpreted code
265 try {
266 call_finally ();
267 } catch {
268 return 0;
270 if (!finally_called)
271 return 2;
272 return 1;
275 [Category ("!WASM")] //Stack traces / EH are super broken on WASM + Interpreter
276 public static int test_0_stack_traces () {
278 // Get a stacktrace for an interp->jit->interp call stack
280 StackTrace st = JitClass.get_stacktrace_jit2 ();
282 var frame0 = st.GetFrame (0);
283 var frame1 = st.GetFrame (1);
284 var frame2 = st.GetFrame (2);
285 var frame3 = st.GetFrame (3);
286 var frame4 = st.GetFrame (4);
288 if (frame0.GetMethod ().Name != "get_stacktrace_interp")
289 return 1;
291 if (frame1.GetMethod ().Name != "get_stacktrace_jit")
292 return 2;
294 if (frame2.GetMethod ().Name != "get_stacktrace_interp2")
295 return 3;
297 if (frame3.GetMethod ().Name != "get_stacktrace_jit2")
298 return 4;
300 if (frame4.GetMethod ().Name != "test_0_stack_traces")
301 return 5;
302 return 0;
305 // Finally exception will be thrown from this stack : interp -> jit -> eh -> interp
306 // Test that we propagate the finally exception over the jitted frames
307 public static int test_0_finex () {
308 bool called_finally = false;
309 try {
310 try {
311 JitClass.throw_ex ();
312 return 3;
313 } finally {
314 called_finally = true;
315 throw new Exception ("E2");
317 } catch (Exception) {
318 if (!called_finally)
319 return 1;
320 return 0;
322 return 2;
325 public static int test_0_stringctor () {
326 string s = JitClass.string_from_interp ();
327 return s == "abcdefghij" ? 0 : 1;