Fixed try..finally blocks.

Added test for try..finally inside a finally.
This commit is contained in:
José Pedro 2016-11-12 18:32:13 +00:00
parent 39ea6ee678
commit e36451b6f9
4 changed files with 68 additions and 21 deletions

View file

@ -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;
}
}

View file

@ -642,7 +642,7 @@ namespace Cosmos.IL2CPU
}
}
}
if ((xHandler.Flags & ExceptionHandlingClauseOptions.Filter) > 0)
if (xHandler.Flags.HasFlag(ExceptionHandlingClauseOptions.Filter))
{
if (xHandler.FilterOffset > 0)
{

View file

@ -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 };
}
}
}
}
}

View file

@ -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)};
}