Skip to content

Commit

Permalink
Fixed try..finally blocks.
Browse files Browse the repository at this point in the history
Added test for try..finally inside a finally.
  • Loading branch information
jp2masa committed Nov 12, 2016
1 parent 39ea6ee commit e36451b
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,41 @@ public static void Execute()
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;
private static bool mWasInTry;
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;
Expand All @@ -49,12 +66,14 @@ private static void TestNormalFlowNoReturnValue()
{
mWasInFinally = true;
}

mWasAfterFinally = true;
}

private static void TestExplicitReturnNoReturnValue()
{
mWasBeforeTry = true;

try
{
mWasInTry = true;
Expand All @@ -64,6 +83,32 @@ private static void TestExplicitReturnNoReturnValue()
{
mWasInFinally = true;
}

mWasAfterFinally = true;
}

public static void TestNestedFinally()
{
mWasBeforeTry = true;

try
{
mWasInTry = true;
}
finally
{
try
{
mWasInTry2 = true;
}
finally
{
mWasInFinally2 = true;
}

mWasInFinally = true;
}

mWasAfterFinally = true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion source/Cosmos.IL2CPU/AppAssembler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,7 @@ private void EmitInstructions(MethodInfo aMethod, List<ILOpCode> aCurrentGroup,
}
}
}
if ((xHandler.Flags & ExceptionHandlingClauseOptions.Filter) > 0)
if (xHandler.Flags.HasFlag(ExceptionHandlingClauseOptions.Filter))
{
if (xHandler.FilterOffset > 0)
{
Expand Down
28 changes: 16 additions & 12 deletions source/Cosmos.IL2CPU/IL/Endfinally.cs
Original file line number Diff line number Diff line change
@@ -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 };
}
}

}
}
}
14 changes: 6 additions & 8 deletions source/Cosmos.IL2CPU/IL/Leave.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Reflection;

using Cosmos.IL2CPU.ILOpCodes;
using XSharp.Compiler;
using static XSharp.Compiler.XSRegisters;

namespace Cosmos.IL2CPU.X86.IL
{
Expand All @@ -17,17 +17,15 @@ public override void Execute(MethodInfo aMethod, ILOpCode aOpCode)
{
// 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)};
}


Expand Down

0 comments on commit e36451b

Please sign in to comment.