[netcore] Ongoing work. (#13391)
[mono-project.git] / mono / tests / install_eh_callback.cs
blob95fcf43ce9449fec54b1bbe64bbb219ee9ac0075
1 using System;
2 using System.Runtime.InteropServices;
3 using System.Runtime.CompilerServices;
5 public class MonoPInvokeCallbackAttribute : Attribute {
6 public MonoPInvokeCallbackAttribute (Type delegateType) { }
9 public class Tests {
11 [DllImport ("libtest")]
12 public static extern void mono_test_setjmp_and_call (VoidVoidDelegate del, out IntPtr handle);
14 [DllImport ("libtest")]
15 public static extern void mono_test_setup_ftnptr_eh_callback (VoidVoidDelegate del, VoidHandleHandleOutDelegate inside_eh_callback);
17 [DllImport ("libtest")]
18 public static extern void mono_test_cleanup_ftptr_eh_callback ();
20 public delegate void VoidVoidDelegate ();
21 public delegate void VoidHandleHandleOutDelegate (uint handle, out int exception_handle);
23 public class SpecialExn : Exception {
26 public class SomeOtherExn : Exception {
29 [MethodImpl (MethodImplOptions.NoInlining)]
30 private static void callee (ref bool called) {
31 called = true;
32 throw new SpecialExn ();
35 public class Caller {
36 public static bool called;
37 public static bool finally_called;
39 public static void Setup () {
40 called = false;
41 finally_called = false;
44 [MonoPInvokeCallback (typeof (VoidVoidDelegate))]
45 public static void M1 () {
46 try {
47 callee (ref called);
48 throw new Exception ("unexpected return from callee");
49 } catch (SomeOtherExn) {
50 } finally {
51 finally_called = true;
55 [MonoPInvokeCallback (typeof (VoidVoidDelegate))]
56 public static void M2 () {
57 try {
58 callee (ref called);
59 throw new Exception ("unexpected return from callee");
60 } catch (SomeOtherExn) {
65 public static int test_0_setjmp_exn_handler ()
67 IntPtr res;
68 Caller.Setup ();
69 VoidVoidDelegate f = new VoidVoidDelegate (Caller.M1);
71 try {
72 mono_test_setjmp_and_call (f, out res);
73 } catch (SpecialExn) {
74 Console.Error.WriteLine ("should not have caught a SpecialExn");
75 return 1;
77 if (!Caller.called) {
78 Console.Error.WriteLine ("delegate not even called");
79 return 2;
81 if (!Caller.finally_called) {
82 Console.Error.WriteLine ("finally not reached");
83 return 3;
85 if (res == IntPtr.Zero) {
86 Console.Error.WriteLine ("res should be a GCHandle, was 0");
87 return 4;
89 GCHandle h = GCHandle.FromIntPtr (res);
90 object o = h.Target;
91 h.Free ();
92 if (o == null) {
93 Console.Error.WriteLine ("GCHandle target was null");
94 return 5;
96 else if (o is SpecialExn)
97 return 0;
98 else {
99 Console.Error.WriteLine ("o was not a SpecialExn, it is {0}", o);
100 return 6;
104 public class Caller2 {
105 public static bool rethrow_called;
106 public static bool exception_caught;
107 public static bool return_from_inner_managed_callback;
109 public static void Setup () {
110 rethrow_called = false;
111 exception_caught = false;
112 return_from_inner_managed_callback = false;
115 public static void RethrowException (uint original_exception) {
116 var e = (Exception) GCHandle.FromIntPtr ((IntPtr) original_exception).Target;
117 rethrow_called = true;
118 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture (e).Throw ();
121 [MonoPInvokeCallback (typeof (VoidHandleHandleOutDelegate))]
122 public static void Del2 (uint original_exception, out int exception_handle) {
123 exception_handle = 0;
124 try {
125 RethrowException (original_exception);
126 } catch (Exception ex) {
127 var handle = GCHandle.Alloc (ex, GCHandleType.Normal);
128 exception_handle = GCHandle.ToIntPtr (handle).ToInt32 ();
129 exception_caught = true;
131 return_from_inner_managed_callback = true;
135 public static int test_0_throw_and_raise_exception ()
137 Caller.Setup ();
138 Caller2.Setup ();
139 VoidVoidDelegate f = new VoidVoidDelegate (Caller.M2);
140 VoidHandleHandleOutDelegate del2 = new VoidHandleHandleOutDelegate (Caller2.Del2);
141 bool outer_managed_callback = false;
142 try {
143 mono_test_setup_ftnptr_eh_callback (f, del2);
144 } catch (Exception e) {
145 outer_managed_callback = true;
148 if (!outer_managed_callback) {
149 Console.Error.WriteLine ("outer managed callback did not throw exception");
150 return 1;
152 if (!Caller2.rethrow_called) {
153 Console.Error.WriteLine ("exception was not rethrown by eh callback");
154 return 2;
156 if (!Caller2.exception_caught) {
157 Console.Error.WriteLine ("rethrown exception was not caught");
158 return 3;
160 if (!Caller2.return_from_inner_managed_callback) {
161 Console.Error.WriteLine ("managed callback called from native eh callback did not return");
162 return 4;
165 mono_test_cleanup_ftptr_eh_callback ();
166 return 0;
169 static int Main ()
171 return TestDriver.RunTests (typeof (Tests));