diff options
author | jfrijters <jfrijters> | 2011-03-16 11:07:06 +0300 |
---|---|---|
committer | jfrijters <jfrijters> | 2011-03-16 11:07:06 +0300 |
commit | 2300f92c8252c1004a065d0c2a09343bda98b0a2 (patch) | |
tree | c8f069d7b85106564d0bc1b4e0548fe007766162 /reflect/Emit | |
parent | 944c74fd91cacc7aa77d0b477091dc4924e58b09 (diff) |
Bug fix. BeginExceptFilterBlock() should behave like BeginCatchBlock(), not BeginFinallyBlock().
Diffstat (limited to 'reflect/Emit')
-rw-r--r-- | reflect/Emit/ILGenerator.cs | 118 |
1 files changed, 81 insertions, 37 deletions
diff --git a/reflect/Emit/ILGenerator.cs b/reflect/Emit/ILGenerator.cs index 2f342ed1..934b1214 100644 --- a/reflect/Emit/ILGenerator.cs +++ b/reflect/Emit/ILGenerator.cs @@ -116,9 +116,39 @@ namespace IKVM.Reflection.Emit } } + sealed class MarkerType : Type + { + public override Type BaseType + { + get { throw new InvalidOperationException(); } + } + + public override TypeAttributes Attributes + { + get { throw new InvalidOperationException(); } + } + + public override string Name + { + get { throw new InvalidOperationException(); } + } + + public override string FullName + { + get { throw new InvalidOperationException(); } + } + + public override Module Module + { + get { throw new InvalidOperationException(); } + } + } + public sealed class ILGenerator { - private static readonly Type FAULT = new BakedType(null); // the type we use here doesn't matter, as long as it can never be used as a real exception type + private static readonly Type FAULT = new MarkerType(); + private static readonly Type FINALLY = new MarkerType(); + private static readonly Type FILTER = new MarkerType(); private readonly ModuleBuilder moduleBuilder; private readonly ByteBuffer code; private readonly List<LocalBuilder> locals = new List<LocalBuilder>(); @@ -152,7 +182,7 @@ namespace IKVM.Reflection.Emit internal int tryLength; internal int handlerOffset; internal int handlerLength; - internal Type exceptionType; // null = finally block or handler with filter, FAULT = fault block + internal Type exceptionType; // FINALLY = finally block, FILTER = handler with filter, FAULT = fault block internal int filterOffset; internal ExceptionBlock(int ordinal) @@ -270,24 +300,42 @@ namespace IKVM.Reflection.Emit } stackHeight = 0; UpdateStack(1); - if (block.tryLength == 0) + if (exceptionType == null) { - block.tryLength = code.Position - block.tryOffset; + if (block.exceptionType != FILTER || block.handlerOffset != 0) + { + throw new ArgumentNullException("exceptionType"); + } + block.handlerOffset = code.Position; } - else if (exceptionType != null) + else { - block.handlerLength = code.Position - block.handlerOffset; - exceptionStack.Pop(); - ExceptionBlock newBlock = new ExceptionBlock(exceptions.Count); - newBlock.labelEnd = block.labelEnd; - newBlock.tryOffset = block.tryOffset; - newBlock.tryLength = block.tryLength; - block = newBlock; - exceptions.Add(block); - exceptionStack.Push(block); + if (block.tryLength == 0) + { + block.tryLength = code.Position - block.tryOffset; + } + else + { + block.handlerLength = code.Position - block.handlerOffset; + exceptionStack.Pop(); + ExceptionBlock newBlock = new ExceptionBlock(exceptions.Count); + newBlock.labelEnd = block.labelEnd; + newBlock.tryOffset = block.tryOffset; + newBlock.tryLength = block.tryLength; + block = newBlock; + exceptions.Add(block); + exceptionStack.Push(block); + } + block.exceptionType = exceptionType; + if (exceptionType == FILTER) + { + block.filterOffset = code.Position; + } + else + { + block.handlerOffset = code.Position; + } } - block.handlerOffset = code.Position; - block.exceptionType = exceptionType; } public Label BeginExceptionBlock() @@ -303,25 +351,20 @@ namespace IKVM.Reflection.Emit public void BeginExceptFilterBlock() { - ExceptionBlock block = BeginFinallyFilterFaultBlock(); - block.filterOffset = code.Position; - UpdateStack(1); + BeginCatchBlock(FILTER); } public void BeginFaultBlock() { - ExceptionBlock block = BeginFinallyFilterFaultBlock(); - block.handlerOffset = code.Position; - block.exceptionType = FAULT; + BeginFinallyFaultBlock(FAULT); } public void BeginFinallyBlock() { - ExceptionBlock block = BeginFinallyFilterFaultBlock(); - block.handlerOffset = code.Position; + BeginFinallyFaultBlock(FINALLY); } - private ExceptionBlock BeginFinallyFilterFaultBlock() + private void BeginFinallyFaultBlock(Type type) { ExceptionBlock block = exceptionStack.Peek(); if (exceptionBlockAssistanceMode == EBAM_COMPAT || (exceptionBlockAssistanceMode == EBAM_CLEVER && stackHeight != -1)) @@ -355,8 +398,9 @@ namespace IKVM.Reflection.Emit exceptions.Add(block); exceptionStack.Push(block); } + block.handlerOffset = code.Position; + block.exceptionType = type; stackHeight = 0; - return block; } public void EndExceptionBlock() @@ -364,7 +408,7 @@ namespace IKVM.Reflection.Emit ExceptionBlock block = exceptionStack.Pop(); if (exceptionBlockAssistanceMode == EBAM_COMPAT || (exceptionBlockAssistanceMode == EBAM_CLEVER && stackHeight != -1)) { - if (block.filterOffset != 0 || (block.exceptionType != null && block.exceptionType != FAULT)) + if (block.filterOffset != 0 || (block.exceptionType != FINALLY && block.exceptionType != FAULT)) { Emit(OpCodes.Leave, block.labelEnd); } @@ -1040,23 +1084,23 @@ namespace IKVM.Reflection.Emit { bb.Write((int)COR_ILEXCEPTION_CLAUSE_FAULT); } - else if (block.filterOffset != 0) + else if (block.exceptionType == FILTER) { bb.Write((int)COR_ILEXCEPTION_CLAUSE_FILTER); } - else if (block.exceptionType != null) + else if (block.exceptionType == FINALLY) { - bb.Write((int)COR_ILEXCEPTION_CLAUSE_EXCEPTION); + bb.Write((int)COR_ILEXCEPTION_CLAUSE_FINALLY); } else { - bb.Write((int)COR_ILEXCEPTION_CLAUSE_FINALLY); + bb.Write((int)COR_ILEXCEPTION_CLAUSE_EXCEPTION); } bb.Write(block.tryOffset); bb.Write(block.tryLength); bb.Write(block.handlerOffset); bb.Write(block.handlerLength); - if (block.exceptionType != null && block.exceptionType != FAULT) + if (block.exceptionType != FAULT && block.exceptionType != FILTER && block.exceptionType != FINALLY) { bb.Write(moduleBuilder.GetTypeTokenForMemberRef(block.exceptionType)); } @@ -1077,23 +1121,23 @@ namespace IKVM.Reflection.Emit { bb.Write(COR_ILEXCEPTION_CLAUSE_FAULT); } - else if (block.filterOffset != 0) + else if (block.exceptionType == FILTER) { bb.Write(COR_ILEXCEPTION_CLAUSE_FILTER); } - else if (block.exceptionType != null) + else if (block.exceptionType == FINALLY) { - bb.Write(COR_ILEXCEPTION_CLAUSE_EXCEPTION); + bb.Write(COR_ILEXCEPTION_CLAUSE_FINALLY); } else { - bb.Write(COR_ILEXCEPTION_CLAUSE_FINALLY); + bb.Write(COR_ILEXCEPTION_CLAUSE_EXCEPTION); } bb.Write((short)block.tryOffset); bb.Write((byte)block.tryLength); bb.Write((short)block.handlerOffset); bb.Write((byte)block.handlerLength); - if (block.exceptionType != null && block.exceptionType != FAULT) + if (block.exceptionType != FAULT && block.exceptionType != FILTER && block.exceptionType != FINALLY) { bb.Write(moduleBuilder.GetTypeTokenForMemberRef(block.exceptionType)); } |