From a8dca0d21d279d87b999d960269ec8a5f7c51048 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Pedro?= Date: Thu, 3 Nov 2016 22:43:21 +0000 Subject: [PATCH 1/3] Minor changes --- .../Cosmos.System.Plugs/System/DecimalImpl.cs | 2 - .../System/IO/DirectoryImpl.cs | 4 +- source/Cosmos.System/FileSystem/CosmosVFS.cs | 5 +++ .../FileSystem/FAT/FatFileSystem.cs | 13 +++--- .../FAT/Listing/FatDiretoryEntry.cs | 45 +++++++++++++++---- .../FileSystem/VFS/VFSManager.cs | 6 +-- 6 files changed, 55 insertions(+), 20 deletions(-) diff --git a/source/Cosmos.System.Plugs/System/DecimalImpl.cs b/source/Cosmos.System.Plugs/System/DecimalImpl.cs index 34c76a70f..80f629aa5 100644 --- a/source/Cosmos.System.Plugs/System/DecimalImpl.cs +++ b/source/Cosmos.System.Plugs/System/DecimalImpl.cs @@ -4,8 +4,6 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -using System; - using Cosmos.IL2CPU.Plugs; namespace Cosmos.System.Plugs.System diff --git a/source/Cosmos.System.Plugs/System/IO/DirectoryImpl.cs b/source/Cosmos.System.Plugs/System/IO/DirectoryImpl.cs index 0dd18b62e..67806f09d 100644 --- a/source/Cosmos.System.Plugs/System/IO/DirectoryImpl.cs +++ b/source/Cosmos.System.Plugs/System/IO/DirectoryImpl.cs @@ -53,12 +53,14 @@ namespace Cosmos.System.Plugs.System.IO } Global.mFileSystemDebugger.SendInternal($"Directory.CreateDirectory : aPath = {aPath}"); + var xEntry = VFSManager.CreateDirectory(aPath); + if (xEntry == null) { return null; } - + return new DirectoryInfo(aPath); } diff --git a/source/Cosmos.System/FileSystem/CosmosVFS.cs b/source/Cosmos.System/FileSystem/CosmosVFS.cs index c106bbd01..acf4e3353 100644 --- a/source/Cosmos.System/FileSystem/CosmosVFS.cs +++ b/source/Cosmos.System/FileSystem/CosmosVFS.cs @@ -124,24 +124,29 @@ namespace Cosmos.System.FileSystem Global.mFileSystemDebugger.SendInternal("Path already exists."); return GetDirectory(aPath); } + Global.mFileSystemDebugger.SendInternal("Path doesn't exist."); string xDirectoryToCreate = Path.GetFileName(aPath); + Global.mFileSystemDebugger.SendInternal("After GetFileName"); Global.mFileSystemDebugger.SendInternal("xDirectoryToCreate ="); Global.mFileSystemDebugger.SendInternal(xDirectoryToCreate); string xParentDirectory = aPath.Remove(aPath.Length - xDirectoryToCreate.Length); + Global.mFileSystemDebugger.SendInternal("After removing last path part"); Global.mFileSystemDebugger.SendInternal("xParentDirectory ="); Global.mFileSystemDebugger.SendInternal(xParentDirectory); DirectoryEntry xParentEntry = GetDirectory(xParentDirectory); + if (xParentEntry == null) { Global.mFileSystemDebugger.SendInternal("Parent directory doesn't exist."); xParentEntry = CreateDirectory(xParentDirectory); } + Global.mFileSystemDebugger.SendInternal("Parent directory exists."); var xFS = GetFileSystemFromPath(xParentDirectory); diff --git a/source/Cosmos.System/FileSystem/FAT/FatFileSystem.cs b/source/Cosmos.System/FileSystem/FAT/FatFileSystem.cs index ddec1f62d..cf510ae25 100644 --- a/source/Cosmos.System/FileSystem/FAT/FatFileSystem.cs +++ b/source/Cosmos.System/FileSystem/FAT/FatFileSystem.cs @@ -142,7 +142,7 @@ namespace Cosmos.System.FileSystem.FAT throw new Exception("Failed to find an unallocated FAT entry."); } - + /// /// Clears a fat entry. /// @@ -476,18 +476,19 @@ namespace Cosmos.System.FileSystem.FAT aSize = BytesPerCluster; } - byte[] xTempData; - Read(aCluster, out xTempData); - Array.Copy(aData, 0, xTempData, (long)aOffset, aData.Length); + byte[] xData; + + Read(aCluster, out xData); + Array.Copy(aData, 0, xData, aOffset, aData.Length); if (mFatType == FatTypeEnum.Fat32) { long xSector = DataSector + (aCluster - RootCluster) * SectorsPerCluster; - mDevice.WriteBlock((ulong) xSector, SectorsPerCluster, aData); + mDevice.WriteBlock((ulong) xSector, SectorsPerCluster, xData); } else { - mDevice.WriteBlock((ulong) aCluster, RootSectorCount, aData); + mDevice.WriteBlock((ulong) aCluster, RootSectorCount, xData); } } diff --git a/source/Cosmos.System/FileSystem/FAT/Listing/FatDiretoryEntry.cs b/source/Cosmos.System/FileSystem/FAT/Listing/FatDiretoryEntry.cs index fcba40d97..f5557c84d 100644 --- a/source/Cosmos.System/FileSystem/FAT/Listing/FatDiretoryEntry.cs +++ b/source/Cosmos.System/FileSystem/FAT/Listing/FatDiretoryEntry.cs @@ -1,11 +1,11 @@ //#define COSMOSDEBUG +using System; +using System.Collections.Generic; + using Cosmos.Common.Extensions; using Cosmos.System.FileSystem.Listing; -using global::System; -using global::System.Collections.Generic; - namespace Cosmos.System.FileSystem.FAT.Listing { using global::System.IO; @@ -114,9 +114,14 @@ namespace Cosmos.System.FileSystem.FAT.Listing private void AllocateDirectoryEntry() { - // TODO: Deal with short and long name. Global.mFileSystemDebugger.SendInternal("-- FatDirectoryEntry.AllocateDirectoryEntry --"); + // TODO: Deal with short and long name. + if (mName.Length > 12) + { + throw new Exception("FatDirectoryEntry: Long Names not supported in new Directory Entries"); + } + char[] xName = { (char)0x20, (char)0x20, (char)0x20, (char)0x20, (char)0x20, (char)0x20, (char)0x20, @@ -151,11 +156,11 @@ namespace Cosmos.System.FileSystem.FAT.Listing SetDirectoryEntryMetadataValue(FatDirectoryEntryMetadata.FirstClusterHigh, (uint)(mFirstClusterNum >> 16)); SetDirectoryEntryMetadataValue(FatDirectoryEntryMetadata.FirstClusterLow, (uint)(mFirstClusterNum & 0xFFFF)); - byte[] xData = GetDirectoryEntryData(); + //byte[] xData = GetDirectoryEntryData(); - SetDirectoryEntryData(xData); + //SetDirectoryEntryData(xData); } - + public FatDirectoryEntry AddDirectoryEntry(string aName, DirectoryEntryTypeEnum aType) { Global.mFileSystemDebugger.SendInternal("-- FatDirectoryEntry.AddDirectoryEntry --"); @@ -182,6 +187,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing return xNewEntry; } + throw new ArgumentOutOfRangeException(nameof(aType), "Unknown directory entry type."); } @@ -190,9 +196,28 @@ namespace Cosmos.System.FileSystem.FAT.Listing if (mEntryType == DirectoryEntryTypeEnum.Unknown) throw new NotImplementedException(); + if (mParent != null) + { + var xData = ((FatDirectoryEntry)mParent).GetDirectoryEntryData(); + + var xEntryOffset = mEntryHeaderDataOffset - 32; + + while (xData[xEntryOffset + 11] == FatDirectoryEntryAttributeConsts.LongName) + { + xData[xEntryOffset] = FatDirectoryEntryAttributeConsts.UnusedOrDeletedEntry; + xEntryOffset -= 32; + } + + ((FatDirectoryEntry)mParent).SetDirectoryEntryData(xData); + } + SetDirectoryEntryMetadataValue(FatDirectoryEntryMetadata.FirstByte, FatDirectoryEntryAttributeConsts.UnusedOrDeletedEntry); } + /// + /// Retrieves a of objects that represent the Directory Entries inside this Directory + /// + /// Returns a of the Directory Entries inside this Directory public List ReadDirectoryContents() { Global.mFileSystemDebugger.SendInternal("-- FatDirectoryEntry.ReadDirectoryContents --"); @@ -357,6 +382,10 @@ namespace Cosmos.System.FileSystem.FAT.Listing return xResult; } + /// + /// Tries to find an empty space for a directory entry and returns the offset to that space if successful, otherwise throws an exception. + /// + /// Returns the offset to the next unallocated directory entry. private uint GetNextUnallocatedDirectoryEntry() { Global.mFileSystemDebugger.SendInternal("-- FatDirectoryEntry.GetNextUnallocatedDirectoryEntry --"); @@ -376,7 +405,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing } } - // TODO: What should we return if no available entry is found. + // TODO: What should we return if no available entry is found. - Update Method description above. throw new Exception("Failed to find an unallocated directory entry."); } diff --git a/source/Cosmos.System/FileSystem/VFS/VFSManager.cs b/source/Cosmos.System/FileSystem/VFS/VFSManager.cs index db4a259cf..0676b3482 100644 --- a/source/Cosmos.System/FileSystem/VFS/VFSManager.cs +++ b/source/Cosmos.System/FileSystem/VFS/VFSManager.cs @@ -1,8 +1,8 @@ //#define COSMOSDEBUG -using global::System; -using global::System.Collections.Generic; -using global::System.IO; +using System; +using System.Collections.Generic; +using System.IO; using Cosmos.System.FileSystem.Listing; From 39ea6ee6781ea2e09a39489bb5d2f063d1bed17e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Pedro?= Date: Wed, 9 Nov 2016 00:08:23 +0000 Subject: [PATCH 2/3] Fixed return on foreach Fixed Array.Clear Minor changes --- .../CSharp/ForeachLoopTests.cs | 12 ++++++++++ source/Cosmos.Core.Plugs/System/ArrayImpl.cs | 3 +-- source/Cosmos.IL2CPU/ExceptionHelper.cs | 2 +- source/Cosmos.IL2CPU/IL/Br.cs | 16 ++++++------- source/Cosmos.IL2CPU/IL/Dup.cs | 11 +++++---- source/Cosmos.IL2CPU/IL/Leave.cs | 23 +++++++++++-------- source/Cosmos.IL2CPU/IL/Ret.cs | 2 +- source/Cosmos.IL2CPU/ILOp.cs | 6 +++-- .../FAT/Listing/FatDiretoryEntry.cs | 2 +- 9 files changed, 48 insertions(+), 29 deletions(-) diff --git a/Tests/Cosmos.Compiler.Tests.Bcl/CSharp/ForeachLoopTests.cs b/Tests/Cosmos.Compiler.Tests.Bcl/CSharp/ForeachLoopTests.cs index 45a55ede8..2f6d08d18 100644 --- a/Tests/Cosmos.Compiler.Tests.Bcl/CSharp/ForeachLoopTests.cs +++ b/Tests/Cosmos.Compiler.Tests.Bcl/CSharp/ForeachLoopTests.cs @@ -31,6 +31,7 @@ namespace Cosmos.Compiler.Tests.Bcl.CSharp { int xFindMe = 3; int[] xArray = {1, 2, 3, 4, 5}; + foreach (int i in xArray) { if (i == xFindMe) @@ -38,6 +39,7 @@ namespace Cosmos.Compiler.Tests.Bcl.CSharp return true; } } + return false; } @@ -45,6 +47,7 @@ namespace Cosmos.Compiler.Tests.Bcl.CSharp { int xFindMe = 3; var xList = new List {1, 2, 3, 4, 5}; + foreach (int i in xList) { if (i == xFindMe) @@ -52,6 +55,7 @@ namespace Cosmos.Compiler.Tests.Bcl.CSharp return true; } } + return false; } @@ -60,6 +64,7 @@ namespace Cosmos.Compiler.Tests.Bcl.CSharp bool xResult = false; int xFindMe = 3; int[] xArray = {1, 2, 3, 4, 5}; + foreach (int i in xArray) { if (i == xFindMe) @@ -67,7 +72,10 @@ namespace Cosmos.Compiler.Tests.Bcl.CSharp xResult = true; break; } + + xResult = false; } + return xResult; } @@ -76,6 +84,7 @@ namespace Cosmos.Compiler.Tests.Bcl.CSharp bool xResult = false; int xFindMe = 3; var xList = new List {1, 2, 3, 4, 5}; + foreach (int i in xList) { if (i == xFindMe) @@ -83,7 +92,10 @@ namespace Cosmos.Compiler.Tests.Bcl.CSharp xResult = true; break; } + + xResult = false; } + return xResult; } } diff --git a/source/Cosmos.Core.Plugs/System/ArrayImpl.cs b/source/Cosmos.Core.Plugs/System/ArrayImpl.cs index ba33753e9..9c87dbcd7 100644 --- a/source/Cosmos.Core.Plugs/System/ArrayImpl.cs +++ b/source/Cosmos.Core.Plugs/System/ArrayImpl.cs @@ -1,6 +1,5 @@ using System; using Cosmos.IL2CPU.Plugs; -using Cosmos.IL2CPU.Plugs.Assemblers; using Cosmos.IL2CPU.Plugs.Assemblers.Array; namespace Cosmos.Core.Plugs.System @@ -10,7 +9,7 @@ namespace Cosmos.Core.Plugs.System { [PlugMethod(Signature = "System_Void__System_Array_Clear_System_Array__System_Int32__System_Int32_")] - public static unsafe void Clear(uint* aArray, uint aIndex, uint aLength) + public static unsafe void Clear([ObjectPointerAccess]uint* aArray, uint aIndex, uint aLength) { aArray = (uint*)aArray[0]; aArray += 3; diff --git a/source/Cosmos.IL2CPU/ExceptionHelper.cs b/source/Cosmos.IL2CPU/ExceptionHelper.cs index 394b26bdf..a52f34c19 100644 --- a/source/Cosmos.IL2CPU/ExceptionHelper.cs +++ b/source/Cosmos.IL2CPU/ExceptionHelper.cs @@ -25,4 +25,4 @@ namespace Cosmos.IL2CPU { CurrentExceptionRef = typeof(ExceptionHelper).GetField("CurrentException"); } } -} \ No newline at end of file +} diff --git a/source/Cosmos.IL2CPU/IL/Br.cs b/source/Cosmos.IL2CPU/IL/Br.cs index 202eb46a4..3fb33b977 100644 --- a/source/Cosmos.IL2CPU/IL/Br.cs +++ b/source/Cosmos.IL2CPU/IL/Br.cs @@ -1,20 +1,20 @@ -using System; -using CPU = Cosmos.Assembler.x86; +using XSharp.Compiler; namespace Cosmos.IL2CPU.X86.IL { - [Cosmos.IL2CPU.OpCode( ILOpCode.Code.Br )] + [OpCode(ILOpCode.Code.Br)] public class Br : ILOp { - public Br( Cosmos.Assembler.Assembler aAsmblr ) - : base( aAsmblr ) + public Br(Cosmos.Assembler.Assembler aAsmblr) + : base(aAsmblr) { } - public override void Execute( MethodInfo aMethod, ILOpCode aOpCode ) + public override void Execute(MethodInfo aMethod, ILOpCode aOpCode) { - new CPU.Jump { DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; - } + XS.Jump(AppAssembler.TmpBranchLabel(aMethod, aOpCode)); + //new CPU.Jump { DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; } + } } diff --git a/source/Cosmos.IL2CPU/IL/Dup.cs b/source/Cosmos.IL2CPU/IL/Dup.cs index e3b4aa006..08f8d44e4 100644 --- a/source/Cosmos.IL2CPU/IL/Dup.cs +++ b/source/Cosmos.IL2CPU/IL/Dup.cs @@ -1,9 +1,9 @@ -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.Dup)] + [OpCode(ILOpCode.Code.Dup)] public class Dup : ILOp { public Dup(Cosmos.Assembler.Assembler aAsmblr) @@ -19,9 +19,10 @@ namespace Cosmos.IL2CPU.X86.IL for (int i = StackSize; i > 0; i--) { - new CPUx86.Push { DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true, DestinationDisplacement = (int)((StackSize - 1) * 4) }; + XS.Push(ESP, true, (StackSize - 1) * 4); + //new CPUx86.Push { DestinationReg = CPUx86.RegistersEnum.ESP, DestinationIsIndirect = true, DestinationDisplacement = (int)((StackSize - 1) * 4) }; } } } -} \ No newline at end of file +} diff --git a/source/Cosmos.IL2CPU/IL/Leave.cs b/source/Cosmos.IL2CPU/IL/Leave.cs index 220ece9ac..ecbb9e539 100644 --- a/source/Cosmos.IL2CPU/IL/Leave.cs +++ b/source/Cosmos.IL2CPU/IL/Leave.cs @@ -1,27 +1,32 @@ -using System; using System.Reflection; -using CPUx86 = Cosmos.Assembler.x86; + +using Cosmos.IL2CPU.ILOpCodes; +using XSharp.Compiler; + namespace Cosmos.IL2CPU.X86.IL { - [Cosmos.IL2CPU.OpCode( ILOpCode.Code.Leave )] + [OpCode(ILOpCode.Code.Leave)] public class Leave : ILOp { - public Leave( Cosmos.Assembler.Assembler aAsmblr ) - : base( aAsmblr ) + public Leave(Cosmos.Assembler.Assembler aAsmblr) + : base(aAsmblr) { } - public override void Execute( MethodInfo aMethod, ILOpCode aOpCode ) + 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) + && aOpCode.CurrentExceptionHandler.HandlerOffset > aOpCode.Position + && ((OpBranch)aOpCode).Value <= aOpCode.CurrentExceptionHandler.HandlerOffset + aOpCode.CurrentExceptionHandler.HandlerLength) { - new CPUx86.Jump {DestinationLabel = AppAssembler.TmpPosLabel(aMethod, aOpCode.CurrentExceptionHandler.HandlerOffset)}; + XS.Jump(AppAssembler.TmpPosLabel(aMethod, aOpCode.CurrentExceptionHandler.HandlerOffset)); + //new CPUx86.Jump {DestinationLabel = AppAssembler.TmpPosLabel(aMethod, aOpCode.CurrentExceptionHandler.HandlerOffset + aOpCode.CurrentExceptionHandler.HandlerLength) }; } else { - new CPUx86.Jump {DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode)}; + XS.Jump(AppAssembler.TmpBranchLabel(aMethod, aOpCode)); + //new CPUx86.Jump {DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode)}; } } diff --git a/source/Cosmos.IL2CPU/IL/Ret.cs b/source/Cosmos.IL2CPU/IL/Ret.cs index 41b5fc330..40f85f221 100644 --- a/source/Cosmos.IL2CPU/IL/Ret.cs +++ b/source/Cosmos.IL2CPU/IL/Ret.cs @@ -18,4 +18,4 @@ namespace Cosmos.IL2CPU.X86.IL //XS.Jump(MethodFooterOp.EndOfMethodLabelNameNormal); } } -} \ No newline at end of file +} diff --git a/source/Cosmos.IL2CPU/ILOp.cs b/source/Cosmos.IL2CPU/ILOp.cs index 41764d7b3..4f928cab4 100644 --- a/source/Cosmos.IL2CPU/ILOp.cs +++ b/source/Cosmos.IL2CPU/ILOp.cs @@ -94,12 +94,14 @@ namespace Cosmos.IL2CPU protected static void Jump_Exception(MethodInfo aMethod) { // todo: port to numeric labels - new CPU.Jump { DestinationLabel = GetMethodLabel(aMethod) + AppAssembler.EndOfMethodLabelNameException }; + XS.Jump (GetMethodLabel(aMethod) + AppAssembler.EndOfMethodLabelNameException); + //new CPU.Jump { DestinationLabel = GetMethodLabel(aMethod) + AppAssembler.EndOfMethodLabelNameException }; } protected static void Jump_End(MethodInfo aMethod) { - new CPU.Jump { DestinationLabel = GetMethodLabel(aMethod) + AppAssembler.EndOfMethodLabelNameNormal }; + XS.Jump(GetMethodLabel(aMethod) + AppAssembler.EndOfMethodLabelNameNormal); + //new CPU.Jump { DestinationLabel = GetMethodLabel(aMethod) + AppAssembler.EndOfMethodLabelNameNormal }; } public static uint GetStackCountForLocal(MethodInfo aMethod, LocalVariableInfo aField) diff --git a/source/Cosmos.System/FileSystem/FAT/Listing/FatDiretoryEntry.cs b/source/Cosmos.System/FileSystem/FAT/Listing/FatDiretoryEntry.cs index 15f411e89..4309a600b 100644 --- a/source/Cosmos.System/FileSystem/FAT/Listing/FatDiretoryEntry.cs +++ b/source/Cosmos.System/FileSystem/FAT/Listing/FatDiretoryEntry.cs @@ -160,7 +160,7 @@ namespace Cosmos.System.FileSystem.FAT.Listing //SetDirectoryEntryData(xData); } - + public FatDirectoryEntry AddDirectoryEntry(string aName, DirectoryEntryTypeEnum aType) { Global.mFileSystemDebugger.SendInternal("-- FatDirectoryEntry.AddDirectoryEntry --"); From e36451b6f919f537da3024efbc7aa4b47985645b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Pedro?= Date: Sat, 12 Nov 2016 18:32:13 +0000 Subject: [PATCH 3/3] Fixed try..finally blocks. Added test for try..finally inside a finally. --- .../TestTryFinally.cs | 45 +++++++++++++++++++ source/Cosmos.IL2CPU/AppAssembler.cs | 2 +- source/Cosmos.IL2CPU/IL/Endfinally.cs | 28 +++++++----- source/Cosmos.IL2CPU/IL/Leave.cs | 14 +++--- 4 files changed, 68 insertions(+), 21 deletions(-) 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)}; }