Merge pull request #1991 from esdrubal/seq_test_fix
[mono.git] / mcs / class / corlib / Test / System.Reflection.Emit / DynamicMethodTest.cs
index 4aecf73b87e49354ba00c42e6d6a9d769df8297f..c9a00481185d6374280d065700948e97c184f999 100644 (file)
@@ -6,13 +6,14 @@
 //
 // (C) 2006 Novell
 
-#if NET_2_0
 
 using System;
 using System.Reflection;
 using System.Reflection.Emit;
 using System.Runtime.InteropServices;
 using System.Text;
+using System.Diagnostics;
+using System.Runtime.ExceptionServices;
 
 using NUnit.Framework;
 
@@ -478,6 +479,106 @@ namespace MonoTests.System.Reflection.Emit
                        public string Name;
                }
 
+               class ExceptionHandling_Test_Support
+               {
+                       public static Exception Caught;
+                       public static string CaughtStackTrace;
+
+                       public static void ThrowMe ()
+                       {
+                               Caught = null;
+                               CaughtStackTrace = null;
+                               throw new Exception("test");
+                       }
+
+                       public static void Handler (Exception e)
+                       {
+                               Caught = e;
+                               CaughtStackTrace = e.StackTrace.ToString ();
+                       }
+               }
+
+               [Test]
+               public void ExceptionHandling ()
+               {
+                       var method = new DynamicMethod ("", typeof(void), new[] { typeof(int) }, typeof (DynamicMethodTest));
+                       var ig = method.GetILGenerator ();
+
+                       ig.BeginExceptionBlock();
+                       ig.Emit(OpCodes.Call, typeof(ExceptionHandling_Test_Support).GetMethod("ThrowMe"));
+
+                       ig.BeginCatchBlock(typeof(Exception));
+                       ig.Emit(OpCodes.Call, typeof(ExceptionHandling_Test_Support).GetMethod("Handler"));
+                       ig.EndExceptionBlock();
+
+                       ig.Emit(OpCodes.Ret);
+
+                       var invoke = (Action<int>) method.CreateDelegate (typeof(Action<int>));
+                       invoke (456324);
+
+                       Assert.IsNotNull (ExceptionHandling_Test_Support.Caught, "#1");
+                       Assert.AreEqual (2, ExceptionHandling_Test_Support.CaughtStackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.None).Length, "#2");
+
+                       var st = new StackTrace (ExceptionHandling_Test_Support.Caught, 0, true);
+
+                       // Caught stack trace when dynamic method is gone
+                       Assert.AreEqual (ExceptionHandling_Test_Support.CaughtStackTrace, st.ToString (), "#3");
+
+                       // Catch handler stack trace inside dynamic method match
+                       Assert.AreEqual (ExceptionHandling_Test_Support.Caught.StackTrace, st.ToString (), "#4");
+               }
+
+               class ExceptionHandlingWithExceptionDispatchInfo_Test_Support
+               {
+                       public static Exception Caught;
+                       public static string CaughtStackTrace;
+
+                       public static void ThrowMe ()
+                       {
+                               Caught = null;
+                               CaughtStackTrace = null;
+
+                               Exception e;
+                               try {
+                                       throw new Exception("test");
+                               } catch (Exception e2) {
+                                       e = e2;
+                               }
+
+                               var edi = ExceptionDispatchInfo.Capture(e);
+
+                               edi.Throw();
+                       }
+
+                       public static void Handler (Exception e)
+                       {
+                               var split = e.StackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
+                               Assert.AreEqual (5, split.Length, "#1");
+                               Assert.IsTrue (split [1].Contains ("---"), "#2");
+                       }
+               }
+
+               [Test]
+               public void ExceptionHandlingWithExceptionDispatchInfo ()
+               {
+                       var method = new DynamicMethod ("", typeof(void), new[] { typeof(int) }, typeof (DynamicMethodTest));
+                       var ig = method.GetILGenerator ();
+
+                       ig.BeginExceptionBlock();
+                       ig.Emit(OpCodes.Call, typeof(ExceptionHandlingWithExceptionDispatchInfo_Test_Support).GetMethod("ThrowMe"));
+
+                       ig.BeginCatchBlock(typeof(Exception));
+                       ig.Emit(OpCodes.Call, typeof(ExceptionHandlingWithExceptionDispatchInfo_Test_Support).GetMethod("Handler"));
+                       ig.EndExceptionBlock();
+
+                       ig.Emit(OpCodes.Ret);
+
+                       var invoke = (Action<int>) method.CreateDelegate (typeof(Action<int>));
+                       invoke (444);
+               }
+
+#if !MONODROID
+               // RUNTIME: crash
                [Test]
                public void TypedRef ()
                {
@@ -509,7 +610,7 @@ namespace MonoTests.System.Reflection.Emit
                {
                        Assert.AreEqual (typeof (TypedRefTarget), TypedReference.GetTargetType (tr));
                }
+#endif
        }
 }
 
-#endif