mirror of
https://github.com/danbulant/Cosmos
synced 2026-06-12 03:01:32 +00:00
Fixed try..finally blocks.
Added test for try..finally inside a finally.
This commit is contained in:
parent
39ea6ee678
commit
e36451b6f9
4 changed files with 68 additions and 21 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -642,7 +642,7 @@ namespace Cosmos.IL2CPU
|
|||
}
|
||||
}
|
||||
}
|
||||
if ((xHandler.Flags & ExceptionHandlingClauseOptions.Filter) > 0)
|
||||
if (xHandler.Flags.HasFlag(ExceptionHandlingClauseOptions.Filter))
|
||||
{
|
||||
if (xHandler.FilterOffset > 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue