Merge pull request #507 from jp2masa/Bugfixes

General Bugfixes and Minor Changes
This commit is contained in:
Charles Betros 2016-11-12 13:58:02 -06:00 committed by GitHub
commit c7196ff873
17 changed files with 162 additions and 61 deletions

View file

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

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

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

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

@ -25,4 +25,4 @@ namespace Cosmos.IL2CPU {
CurrentExceptionRef = typeof(ExceptionHelper).GetField("CurrentException");
}
}
}
}

View file

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

View file

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

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,28 +1,31 @@
using System;
using System.Reflection;
using CPUx86 = Cosmos.Assembler.x86;
using XSharp.Compiler;
using static XSharp.Compiler.XSRegisters;
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)
{
new CPUx86.Jump {DestinationLabel = AppAssembler.TmpPosLabel(aMethod, aOpCode.CurrentExceptionHandler.HandlerOffset)};
}
else
{
new CPUx86.Jump {DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode)};
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) };
}
XS.Jump(AppAssembler.TmpBranchLabel(aMethod, aOpCode));
//new CPUx86.Jump {DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode)};
}

View file

@ -18,4 +18,4 @@ namespace Cosmos.IL2CPU.X86.IL
//XS.Jump(MethodFooterOp.EndOfMethodLabelNameNormal);
}
}
}
}

View file

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

View file

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

View file

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

View file

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

View file

@ -489,18 +489,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);
}
}

View file

@ -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,9 +156,9 @@ 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)
@ -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);
}
/// <summary>
/// Retrieves a <see cref="List{T}"/> of <see cref="FatDirectoryEntry"/> objects that represent the Directory Entries inside this Directory
/// </summary>
/// <returns>Returns a <see cref="List{T}"/> of the Directory Entries inside this Directory</returns>
public List<FatDirectoryEntry> ReadDirectoryContents()
{
Global.mFileSystemDebugger.SendInternal("-- FatDirectoryEntry.ReadDirectoryContents --");
@ -357,6 +382,10 @@ namespace Cosmos.System.FileSystem.FAT.Listing
return xResult;
}
/// <summary>
/// Tries to find an empty space for a directory entry and returns the offset to that space if successful, otherwise throws an exception.
/// </summary>
/// <returns>Returns the offset to the next unallocated directory entry.</returns>
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.");
}

View file

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