In System.Reflection.Emit:
authorRolf Bjarne Kvinge <RKvinge@novell.com>
Fri, 17 Aug 2007 09:12:13 +0000 (09:12 -0000)
committerRolf Bjarne Kvinge <RKvinge@novell.com>
Fri, 17 Aug 2007 09:12:13 +0000 (09:12 -0000)
2007-08-17  Rolf Bjarne Kvinge  <RKvinge@novell.com>

* ILGenerator.cs: Change BeginCatchBlock to end the current filter block if called with a null exceptionType. Added ILExceptionBlock.FILTER_START to be able to track if we're in a filter block or not. Renamed PatchLastClauseStart to PatchFilterClause to match better what it does, and make it update the handler's type to FILTER. Fixes #81431.

In Test/System.Reflection.Emit:
2007-08-17  Rolf Bjarne Kvinge  <RKvinge@novell.com>

* ILGeneratorTest.cs: Added FilterAndCatchBlock (bug #81431), InvalidFilterBlock1, ValidFilterBlock1, ValidFilterBlock2.

svn path=/trunk/mcs/; revision=84262

mcs/class/corlib/System.Reflection.Emit/ChangeLog
mcs/class/corlib/System.Reflection.Emit/ILGenerator.cs
mcs/class/corlib/Test/System.Reflection.Emit/ChangeLog
mcs/class/corlib/Test/System.Reflection.Emit/ILGeneratorTest.cs

index 7fc38cd78993819e473c00b5e4fcaa2ac682a1c4..bc86be75b2299bcd8811b746904963493d32f486 100644 (file)
@@ -1,3 +1,7 @@
+2007-08-17  Rolf Bjarne Kvinge  <RKvinge@novell.com>
+
+       * ILGenerator.cs: Change BeginCatchBlock to end the current filter block if called with a null exceptionType. Added ILExceptionBlock.FILTER_START to be able to track if we're in a filter block or not. Renamed PatchLastClauseStart to PatchFilterClause to match better what it does, and make it update the handler's type to FILTER. Fixes #81431.
+
 2007-08-10  Zoltan Varga  <vargaz@gmail.com>
 
        * DynamicILInfo.cs: New file.
index 8c00fadf89474e0251f189a90d7e3ebd2a8ad364..140b0f3d063613c4f505b121d380068997434b91 100644 (file)
@@ -43,6 +43,7 @@ namespace System.Reflection.Emit {
                public const int FILTER = 1;
                public const int FINALLY = 2;
                public const int FAULT = 4;
+               public const int FILTER_START = -1;
 
                internal Type extype;
                internal int type;
@@ -110,7 +111,7 @@ namespace System.Reflection.Emit {
                        End (offset);
                        add_block (offset);
                        i = handlers.Length - 1;
-                       handlers [i].type = ILExceptionBlock.FILTER;
+                       handlers [i].type = ILExceptionBlock.FILTER_START;
                        handlers [i].extype = null;
                        handlers [i].filter_offset = offset;
                }
@@ -132,10 +133,12 @@ namespace System.Reflection.Emit {
                                return ILExceptionBlock.CATCH;
                }
 
-               internal void PatchLastClauseStart (int start)
+               internal void PatchFilterClause (int start)
                {
-                       if (handlers != null && handlers.Length > 0)
+                       if (handlers != null && handlers.Length > 0) {
                                handlers [handlers.Length - 1].start = start;
+                               handlers [handlers.Length - 1].type = ILExceptionBlock.FILTER;
+                       }
                }
 
                internal void Debug (int b)
@@ -343,6 +346,7 @@ namespace System.Reflection.Emit {
                        switch (ex_handlers [cur_block].LastClauseType ()) {
                        case ILExceptionBlock.CATCH:
                        case ILExceptionBlock.FILTER:
+                       case ILExceptionBlock.FILTER_START:
                                // how could we optimize code size here?
                                Emit (OpCodes.Leave, ex_handlers [cur_block].end);
                                break;
@@ -361,11 +365,11 @@ namespace System.Reflection.Emit {
                        if (open_blocks.Count <= 0)
                                throw new NotSupportedException ("Not in an exception block");
 
-                       if (ex_handlers [cur_block].LastClauseType () == ILExceptionBlock.FILTER) {
+                       if (ex_handlers [cur_block].LastClauseType () == ILExceptionBlock.FILTER_START) {
                                if (exceptionType != null)
                                        throw new ArgumentException ("Do not supply an exception type for filter clause");
                                Emit (OpCodes.Endfilter);
-                               ex_handlers [cur_block].PatchLastClauseStart (code_len);
+                               ex_handlers [cur_block].PatchFilterClause (code_len);
                        } else {
                                InternalEndClause ();
                                ex_handlers [cur_block].AddCatch (exceptionType, code_len);
@@ -417,6 +421,12 @@ namespace System.Reflection.Emit {
                        
                        if (open_blocks.Count <= 0)
                                throw new NotSupportedException ("Not in an exception block");
+
+                       if (ex_handlers [cur_block].LastClauseType () == ILExceptionBlock.FILTER_START) {
+                               Emit (OpCodes.Leave, ex_handlers [cur_block].end);
+                               ex_handlers [cur_block].PatchFilterClause (code_len);
+                       }
+                       
                        InternalEndClause ();
                        //System.Console.WriteLine ("Begin fault Block");
                        ex_handlers [cur_block].AddFault (code_len);
@@ -429,7 +439,14 @@ namespace System.Reflection.Emit {
                        
                        if (open_blocks.Count <= 0)
                                throw new NotSupportedException ("Not in an exception block");
+
                        InternalEndClause ();
+
+                       if (ex_handlers [cur_block].LastClauseType () == ILExceptionBlock.FILTER_START) {
+                               Emit (OpCodes.Leave, ex_handlers [cur_block].end);
+                               ex_handlers [cur_block].PatchFilterClause (code_len);
+                       }
+
                        //System.Console.WriteLine ("Begin finally Block");
                        ex_handlers [cur_block].AddFinally (code_len);
                }
@@ -875,6 +892,10 @@ namespace System.Reflection.Emit {
                        
                        if (open_blocks.Count <= 0)
                                throw new NotSupportedException ("Not in an exception block");
+
+                       if (ex_handlers [cur_block].LastClauseType () == ILExceptionBlock.FILTER_START)
+                               throw new InvalidOperationException ("Incorrect code generation for exception block.");
+
                        InternalEndClause ();
                        MarkLabel (ex_handlers [cur_block].end);
                        ex_handlers [cur_block].End (code_len);
index 44e71aafe13cb826338c91035a6bd2ade64b68f3..f916d64fafe3c92c47b88ee45ffef8982e5c8d23 100644 (file)
@@ -1,3 +1,7 @@
+2007-08-17  Rolf Bjarne Kvinge  <RKvinge@novell.com>
+
+       * ILGeneratorTest.cs: Added FilterAndCatchBlock (bug #81431), InvalidFilterBlock1, ValidFilterBlock1, ValidFilterBlock2.
+
 2007-08-16  Gert Driesen  <drieseng@users.sourceforge.net>
 
        * TypeBuilderTest.cs: Added IsDefined test with null value for
index 564c2851cf985b5f90341bf22b261ae0a2308b3e..aa260e20cf3620fa115b6e6b419f5934be65d456 100644 (file)
@@ -69,6 +69,51 @@ namespace MonoTests.System.Reflection.Emit {
                        il_gen.EndExceptionBlock ();
                }
                
+               // Bug 81431
+               [Test]
+               public void FilterAndCatchBlock ()
+               {
+                       DefineBasicMethod ();
+                       ILGenerator il = il_gen;
+                       il.BeginExceptionBlock ();
+                       il.BeginExceptFilterBlock ();
+                       il.BeginCatchBlock (null);
+                       il.BeginCatchBlock (typeof (SystemException));
+               }
+               
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void InvalidFilterBlock1 ()
+               {
+                       DefineBasicMethod ();
+                       ILGenerator il = il_gen;
+                       il.BeginExceptionBlock ();
+                       il.BeginExceptFilterBlock ();
+                       il.EndExceptionBlock ();
+               }
+               
+               [Test]
+               public void ValidFilterBlock1 ()
+               {
+                       DefineBasicMethod ();
+                       ILGenerator il = il_gen;
+                       il.BeginExceptionBlock ();
+                       il.BeginExceptFilterBlock ();
+                       il.BeginFaultBlock ();
+                       il.EndExceptionBlock ();
+               }
+               
+               [Test]
+               public void ValidFilterBlock2 ()
+               {
+                       DefineBasicMethod ();
+                       ILGenerator il = il_gen;
+                       il.BeginExceptionBlock ();
+                       il.BeginExceptFilterBlock ();
+                       il.BeginFinallyBlock ();
+                       il.EndExceptionBlock ();
+               }
+               
                /// <summary>
                /// Try to emit something like that:
                ///