diff --git a/Tests/Cosmos.Compiler.Tests.SimpleWriteLine.Kernel/TestTryFinally.cs b/Tests/Cosmos.Compiler.Tests.SimpleWriteLine.Kernel/TestTryFinally.cs index 011f789f4..ed6ed3612 100644 --- a/Tests/Cosmos.Compiler.Tests.SimpleWriteLine.Kernel/TestTryFinally.cs +++ b/Tests/Cosmos.Compiler.Tests.SimpleWriteLine.Kernel/TestTryFinally.cs @@ -23,6 +23,16 @@ namespace Cosmos.Compiler.Tests.SimpleWriteLine.Kernel Assert.IsTrue(mWasInTry, "ExplicitReturnNoReturnValue.WasInTry"); Assert.IsTrue(mWasInFinally, "ExplicitReturnNoReturnValue.WasInFinally"); Assert.IsFalse(mWasAfterFinally, "ExplicitReturnNoReturnValue.WasAfterFinally"); + + ClearToggles(); + TestNestedFinally(); + + Assert.IsTrue(mWasBeforeTry, "ExplicitReturnNoReturnValue.WasBeforeTry"); + Assert.IsTrue(mWasInTry, "ExplicitReturnNoReturnValue.WasInTry"); + Assert.IsTrue(mWasInFinally, "ExplicitReturnNoReturnValue.WasInFinally"); + Assert.IsTrue(mWasInTry2, "ExplicitReturnNoReturnValue.WasInTry2"); + Assert.IsTrue(mWasInFinally2, "ExplicitReturnNoReturnValue.WasInFinally2"); + Assert.IsTrue(mWasAfterFinally, "ExplicitReturnNoReturnValue.WasAfterFinally"); } private static bool mWasBeforeTry; @@ -30,17 +40,24 @@ namespace Cosmos.Compiler.Tests.SimpleWriteLine.Kernel private static bool mWasInFinally; private static bool mWasAfterFinally; + private static bool mWasInTry2; + private static bool mWasInFinally2; + private static void ClearToggles() { mWasBeforeTry = false; mWasInTry = false; mWasInFinally = false; mWasAfterFinally = false; + + mWasInTry2 = false; + mWasInFinally2 = false; } private static void TestNormalFlowNoReturnValue() { mWasBeforeTry = true; + try { mWasInTry = true; @@ -49,12 +66,14 @@ namespace Cosmos.Compiler.Tests.SimpleWriteLine.Kernel { mWasInFinally = true; } + mWasAfterFinally = true; } private static void TestExplicitReturnNoReturnValue() { mWasBeforeTry = true; + try { mWasInTry = true; @@ -64,6 +83,32 @@ namespace Cosmos.Compiler.Tests.SimpleWriteLine.Kernel { mWasInFinally = true; } + + mWasAfterFinally = true; + } + + public static void TestNestedFinally() + { + mWasBeforeTry = true; + + try + { + mWasInTry = true; + } + finally + { + try + { + mWasInTry2 = true; + } + finally + { + mWasInFinally2 = true; + } + + mWasInFinally = true; + } + mWasAfterFinally = true; } } diff --git a/source/Cosmos.IL2CPU/AppAssembler.cs b/source/Cosmos.IL2CPU/AppAssembler.cs index b36c15db9..d430d65c2 100644 --- a/source/Cosmos.IL2CPU/AppAssembler.cs +++ b/source/Cosmos.IL2CPU/AppAssembler.cs @@ -642,7 +642,7 @@ namespace Cosmos.IL2CPU } } } - if ((xHandler.Flags & ExceptionHandlingClauseOptions.Filter) > 0) + if (xHandler.Flags.HasFlag(ExceptionHandlingClauseOptions.Filter)) { if (xHandler.FilterOffset > 0) { diff --git a/source/Cosmos.IL2CPU/IL/Endfinally.cs b/source/Cosmos.IL2CPU/IL/Endfinally.cs index 506c2cc55..a6a0eb375 100644 --- a/source/Cosmos.IL2CPU/IL/Endfinally.cs +++ b/source/Cosmos.IL2CPU/IL/Endfinally.cs @@ -1,17 +1,21 @@ -using System; +using CPUx86 = Cosmos.Assembler.x86; +using XSharp.Compiler; +using static XSharp.Compiler.XSRegisters; namespace Cosmos.IL2CPU.X86.IL { - [Cosmos.IL2CPU.OpCode(ILOpCode.Code.Endfinally)] - public class Endfinally: ILOp - { - public Endfinally(Cosmos.Assembler.Assembler aAsmblr):base(aAsmblr) - { - } + [OpCode(ILOpCode.Code.Endfinally)] + public class Endfinally : ILOp + { + public Endfinally(Cosmos.Assembler.Assembler aAsmblr) : base(aAsmblr) + { + } - public override void Execute(MethodInfo aMethod, ILOpCode aOpCode) { - // throw new NotImplementedException(); + public override void Execute(MethodInfo aMethod, ILOpCode aOpCode) + { + XS.DataMember(aMethod.MethodBase.GetFullName() + "_" + "LeaveAddress_" + aOpCode.CurrentExceptionHandler.HandlerOffset.ToString("X2"), 0); + XS.Set(EAX, aMethod.MethodBase.GetFullName() + "_" + "LeaveAddress_" + aOpCode.CurrentExceptionHandler.HandlerOffset.ToString("X2")); + new CPUx86.Jump { DestinationReg = EAX, DestinationIsIndirect = true }; + } } - - } -} \ No newline at end of file +} diff --git a/source/Cosmos.IL2CPU/IL/Leave.cs b/source/Cosmos.IL2CPU/IL/Leave.cs index ecbb9e539..db917b888 100644 --- a/source/Cosmos.IL2CPU/IL/Leave.cs +++ b/source/Cosmos.IL2CPU/IL/Leave.cs @@ -1,7 +1,7 @@ using System.Reflection; -using Cosmos.IL2CPU.ILOpCodes; using XSharp.Compiler; +using static XSharp.Compiler.XSRegisters; namespace Cosmos.IL2CPU.X86.IL { @@ -17,17 +17,15 @@ namespace Cosmos.IL2CPU.X86.IL { // apparently, Roslyn changed something to the output. We now have to figure out where to jump to. if (aOpCode.CurrentExceptionHandler.Flags.HasFlag(ExceptionHandlingClauseOptions.Finally) - && aOpCode.CurrentExceptionHandler.HandlerOffset > aOpCode.Position - && ((OpBranch)aOpCode).Value <= aOpCode.CurrentExceptionHandler.HandlerOffset + aOpCode.CurrentExceptionHandler.HandlerLength) + && aOpCode.CurrentExceptionHandler.HandlerOffset > aOpCode.Position) { + XS.Set(aMethod.MethodBase.GetFullName() + "_" + "LeaveAddress_" + aOpCode.CurrentExceptionHandler.HandlerOffset.ToString("X2"), Assembler.CurrentIlLabel + "." + (Assembler.AsmIlIdx + 2).ToString("X2"), destinationIsIndirect: true, size: RegisterSize.Int32); XS.Jump(AppAssembler.TmpPosLabel(aMethod, aOpCode.CurrentExceptionHandler.HandlerOffset)); //new CPUx86.Jump {DestinationLabel = AppAssembler.TmpPosLabel(aMethod, aOpCode.CurrentExceptionHandler.HandlerOffset + aOpCode.CurrentExceptionHandler.HandlerLength) }; } - else - { - XS.Jump(AppAssembler.TmpBranchLabel(aMethod, aOpCode)); - //new CPUx86.Jump {DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode)}; - } + + XS.Jump(AppAssembler.TmpBranchLabel(aMethod, aOpCode)); + //new CPUx86.Jump {DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode)}; }