diff --git a/Build/Cosmos/Sub-Compile.ps1 b/Build/Cosmos/Sub-Compile.ps1 index 323f339b6..288eaaa92 100644 --- a/Build/Cosmos/Sub-Compile.ps1 +++ b/Build/Cosmos/Sub-Compile.ps1 @@ -1,4 +1,4 @@ # ----------- Compile with IL2CPU remove-item output.asm -ea SilentlyContinue -..\..\source\il2cpu\bin\Debug\il2cpu "-in:..\..\source\Cosmos\Cosmos.Shell.Console\bin\Debug\Cosmos.Shell.Console.exe" "-plug:..\..\source\Cosmos\Cosmos.Kernel.Plugs\bin\Debug\Cosmos.Kernel.Plugs.dll" "-out:output.obj" "-platform:nativex86" "-asm:.\" +..\..\source\il2cpu\bin\Debug\il2cpu "-in:..\..\source\Cosmos\Cosmos.Shell.Console\bin\Debug\Cosmos.Shell.Console.exe" "-plug:..\..\source\Cosmos\Cosmos.Kernel.Plugs\bin\Debug\Cosmos.Kernel.Plugs.dll" "-out:output.obj" "-platform:nativex86" "-asm:.\asm" diff --git a/source/Cosmos/Cosmos.Hardware/Screen/Text.cs b/source/Cosmos/Cosmos.Hardware/Screen/Text.cs index 33e862ab3..5db9c2875 100644 --- a/source/Cosmos/Cosmos.Hardware/Screen/Text.cs +++ b/source/Cosmos/Cosmos.Hardware/Screen/Text.cs @@ -7,13 +7,15 @@ namespace Cosmos.Hardware.Screen { public const int Columns = 80; public const int Lines = 24; public const uint VideoAddr = 0xB8000; - private static uint Color = 7; + private static byte Color = 7; public static unsafe void Clear() { - for (int i = 0; i < Columns * Lines * 2; i++) { + for (int i = 0; i < Columns * Lines; i++) { byte* xScreenPtr = (byte*)VideoAddr; - xScreenPtr += i; + xScreenPtr += i*2; *xScreenPtr = 0; + xScreenPtr += 1; + *xScreenPtr = Color; } } @@ -28,7 +30,7 @@ namespace Cosmos.Hardware.Screen { byte* xScreenPtr = (byte*)(VideoAddr + (i + Lines * Columns) * 2); *xScreenPtr = 0; xScreenPtr += 1; - *xScreenPtr = 0; + *xScreenPtr = Color; } } @@ -38,12 +40,11 @@ namespace Cosmos.Hardware.Screen { byte xVal = (byte)aChar; *xScreenPtr = (byte)(xVal & 0xFF); xScreenPtr += 1; - *xScreenPtr = (byte)Color; + *xScreenPtr = Color; } - public static void SetColors(ConsoleColor foreground, ConsoleColor background) - { - Color = (uint)((byte)foreground | ((byte)background << 4)); - } - } + public static void SetColors(ConsoleColor foreground, ConsoleColor background) { + Color = (byte)((byte)foreground | ((byte)background << 4)); + } + } } diff --git a/source/Cosmos/Cosmos.Kernel.Plugs/Assemblers/CreateIDT.cs b/source/Cosmos/Cosmos.Kernel.Plugs/Assemblers/CreateIDT.cs index fdb7ebd3a..cfb4f3862 100644 --- a/source/Cosmos/Cosmos.Kernel.Plugs/Assemblers/CreateIDT.cs +++ b/source/Cosmos/Cosmos.Kernel.Plugs/Assemblers/CreateIDT.cs @@ -25,7 +25,7 @@ namespace Cosmos.Kernel.Plugs.Assemblers { } } if (aErrorWhenNotFound) { - throw new Exception("Method '" + aType + "::" + aMethodName + "' not found!"); + throw new System.Exception("Method '" + aType + "::" + aMethodName + "' not found!"); } return null; } diff --git a/source/Cosmos/Cosmos.Kernel.Plugs/Console.cs b/source/Cosmos/Cosmos.Kernel.Plugs/Console.cs index c0361011f..300a16547 100644 --- a/source/Cosmos/Cosmos.Kernel.Plugs/Console.cs +++ b/source/Cosmos/Cosmos.Kernel.Plugs/Console.cs @@ -46,6 +46,14 @@ namespace Cosmos.Kernel.Plugs { return TextScreen.CurrentLine; } + public static int get_WindowHeight() { + return TextScreen.WindowHeight; + } + + public static int get_WindowWidth() { + return TextScreen.WindowWidth; + } + public static void set_CursorTop(int y) { TextScreen.CurrentLine = y; } diff --git a/source/Cosmos/Cosmos.Kernel/TextScreen.cs b/source/Cosmos/Cosmos.Kernel/TextScreen.cs index 31c83bb7c..4af0f75cd 100644 --- a/source/Cosmos/Cosmos.Kernel/TextScreen.cs +++ b/source/Cosmos/Cosmos.Kernel/TextScreen.cs @@ -8,6 +8,18 @@ namespace Cosmos.Kernel { public static int CurrentLine = 0; public static int CurrentChar = 0; + public static int WindowHeight { + get { + return HW.Text.Lines; + } + } + + public static int WindowWidth { + get { + return HW.Text.Columns; + } + } + /// /// Sets the console colors. /// diff --git a/source/Cosmos/Cosmos.Shell.Console/Commands/MatthijsCommand.cs b/source/Cosmos/Cosmos.Shell.Console/Commands/MatthijsCommand.cs index ca8d9aa9e..8f2a8d368 100644 --- a/source/Cosmos/Cosmos.Shell.Console/Commands/MatthijsCommand.cs +++ b/source/Cosmos/Cosmos.Shell.Console/Commands/MatthijsCommand.cs @@ -17,7 +17,9 @@ namespace Cosmos.Shell.Console.Commands { } public override void Execute(string param) { - Kernel.FileSystem.TestsMatthijs.TestNewATA(); + //Kernel.FileSystem.TestsMatthijs.TestNewATA(); + //System.Diagnostics.Debugger.Break(); + throw new Exception("Hello, Error!"); } public override void Help() { diff --git a/source/Indy.IL2CPU.Assembler.X86.Native/Assembler.cs b/source/Indy.IL2CPU.Assembler.X86.Native/Assembler.cs index 605dc9155..ec5b3d435 100644 --- a/source/Indy.IL2CPU.Assembler.X86.Native/Assembler.cs +++ b/source/Indy.IL2CPU.Assembler.X86.Native/Assembler.cs @@ -13,8 +13,6 @@ namespace Indy.IL2CPU.Assembler.X86.Native { public Assembler(Func aGetStreamForGroup) : base(aGetStreamForGroup) { } - - protected override void EmitCodeSectionHeader(string aGroup, StreamWriter aOutputWriter) { base.EmitCodeSectionHeader(aGroup, aOutputWriter); diff --git a/source/Indy.IL2CPU.Assembler.X86/Assembler.cs b/source/Indy.IL2CPU.Assembler.X86/Assembler.cs index 359798fd0..f5472cd8f 100644 --- a/source/Indy.IL2CPU.Assembler.X86/Assembler.cs +++ b/source/Indy.IL2CPU.Assembler.X86/Assembler.cs @@ -15,7 +15,7 @@ namespace Indy.IL2CPU.Assembler.X86 { } private static string GetValidGroupName(string aGroup) { - return aGroup; + return aGroup.Replace('-','_').Replace('.', '_'); } protected override void EmitHeader(string aGroup, StreamWriter aOutputWriter) { diff --git a/source/Indy.IL2CPU.Assembler.X86/Indy.IL2CPU.Assembler.X86.csproj b/source/Indy.IL2CPU.Assembler.X86/Indy.IL2CPU.Assembler.X86.csproj index 2be630850..719784bb3 100644 --- a/source/Indy.IL2CPU.Assembler.X86/Indy.IL2CPU.Assembler.X86.csproj +++ b/source/Indy.IL2CPU.Assembler.X86/Indy.IL2CPU.Assembler.X86.csproj @@ -35,6 +35,10 @@ 4 + + False + ..\..\Tools\I4O\i4o.dll + 3.5 diff --git a/source/Indy.IL2CPU.Assembler.X86/JumpBase.cs b/source/Indy.IL2CPU.Assembler.X86/JumpBase.cs index 4a4d4fb7a..b197593a2 100644 --- a/source/Indy.IL2CPU.Assembler.X86/JumpBase.cs +++ b/source/Indy.IL2CPU.Assembler.X86/JumpBase.cs @@ -10,10 +10,10 @@ namespace Indy.IL2CPU.Assembler.X86 { protected JumpBase(string aAddress) { Address = aAddress; if (Address.StartsWith(".")) { - string xPrefix = (from item in Assembler.CurrentInstance.Instructions - let xTheLabel = item.Value as Label - where xTheLabel != null && !xTheLabel.Name.StartsWith(".") - select xTheLabel.Name).Last(); + //string xPrefix = (from item in Assembler.CurrentInstance.Instructions + // where !Label.GetLabel(item).StartsWith(".") + // select Label.GetLabel(item)).Last(); + string xPrefix = Label.LastFullLabel; Address = xPrefix + "__DOT__" + Address.Substring(1); } } diff --git a/source/Indy.IL2CPU.Assembler/Assembler.cs b/source/Indy.IL2CPU.Assembler/Assembler.cs index dd7636871..a42bcf3b7 100644 --- a/source/Indy.IL2CPU.Assembler/Assembler.cs +++ b/source/Indy.IL2CPU.Assembler/Assembler.cs @@ -4,11 +4,65 @@ using System.IO; using System.Linq; using System.Text; using i4o; +using Mono.Cecil; namespace Indy.IL2CPU.Assembler { public abstract class Assembler: IDisposable { + // TODO: When threading is being worked on, fix this to work multithreaded! + //public const string CurrentExceptionDataMember = "__CURRENT_EXCEPTION__"; + public static Exception CurrentException; + public static void PrintException() { + Console.BackgroundColor = ConsoleColor.Blue; + Console.ForegroundColor = ConsoleColor.White; + string xClearLine = new String(' ', Console.WindowWidth); + for (int i = 0; i < Console.WindowHeight; i++) { + Console.Write(" "); + } + //Console.Clear(); + System.Console.WriteLine("Cosmos Kernel. Copyright 2008 The Cosmos Project."); + System.Console.WriteLine("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); + Console.WriteLine(""); + Console.WriteLine(""); + Console.WriteLine(""); + Console.WriteLine(""); + Console.WriteLine(""); + Console.WriteLine(""); + Console.WriteLine("BSOD's Rule!"); + Console.WriteLine(""); + Console.Write("Unhandled error occurred: "); + Console.WriteLine(CurrentException.ToString()); + Console.WriteLine(""); + Console.WriteLine(""); + Console.WriteLine(""); + Console.WriteLine(""); + Console.WriteLine(""); + Console.WriteLine(""); + Console.WriteLine(""); + Console.WriteLine(""); + Console.WriteLine(""); + Console.WriteLine(""); + Console.WriteLine(""); + } + private static FieldDefinition mCurrentExceptionRef; + public static FieldDefinition CurrentExceptionRef { + get { + if (mCurrentExceptionRef == null) { + AssemblyDefinition xAsm = AssemblyFactory.GetAssembly(typeof(Assembler).Assembly.Location); + foreach (ModuleDefinition xMod in xAsm.Modules) { + if (xMod.Types.Contains(typeof(Assembler).FullName)) { + mCurrentExceptionRef = xMod.Types[typeof(Assembler).FullName].Fields.GetField("CurrentException"); + break; + } + } + if (mCurrentExceptionRef == null) { + throw new Exception("Couldn't find CurrentException field!"); + } + } + return mCurrentExceptionRef; + } + } public const string EntryPointName = "__ENGINE_ENTRYPOINT__"; - protected List> mInstructions = new List>(); + protected IndexableCollection> mInstructions = new IndexableCollection>(); private IndexableCollection> mDataMembers = new IndexableCollection>(); private List> mIncludes = new List>(); private IndexableCollection> mImportMembers = new IndexableCollection>(); @@ -37,9 +91,10 @@ namespace Indy.IL2CPU.Assembler { mGetFileNameForGroup = aGetFileNameForGroup; mInMetalMode = aInMetalMode; CurrentInstance = this; + //mInstructions.AddComplexIndexDefinition( } - public List> Instructions { + public IndexableCollection> Instructions { get { return mInstructions; } diff --git a/source/Indy.IL2CPU.Assembler/Label.cs b/source/Indy.IL2CPU.Assembler/Label.cs index 74d83e772..935412dd8 100644 --- a/source/Indy.IL2CPU.Assembler/Label.cs +++ b/source/Indy.IL2CPU.Assembler/Label.cs @@ -15,16 +15,31 @@ namespace Indy.IL2CPU.Assembler { } } + public static string GetLabel(object aObject) { + Label xLabel = aObject as Label; + if (xLabel == null) + return ""; + return xLabel.Name; + } + + public static string LastFullLabel { + get; + private set; + } + public Label(string aName) { mName = aName; + if (!aName.StartsWith(".")) { + LastFullLabel = aName; + } } public override string ToString() { return Name + ":"; } - public Label(string aType, params string[] aParamTypes) { - mName = Init(aType, typeof(void).FullName, ".ctor", aParamTypes); + public Label(string aType, params string[] aParamTypes) + : this(Init(aType, typeof(void).FullName, ".ctor", aParamTypes)) { } public static string GenerateLabelName(MethodReference aMethod) { @@ -36,16 +51,16 @@ namespace Indy.IL2CPU.Assembler { return Init(aMethod.DeclaringType.FullName, aMethod.ReturnType.ReturnType.FullName, aMethod.Name, xParams.ToArray()); } - public Label(MethodReference aMethod) { - mName = GenerateLabelName(aMethod); + public Label(MethodReference aMethod) + : this(GenerateLabelName(aMethod)) { } - public Label(string aType, string aMethodName, params string[] aParamTypes) { - mName = Init(aType, typeof(void).FullName, aMethodName, aParamTypes); + public Label(string aType, string aMethodName, params string[] aParamTypes) + : this(Init(aType, typeof(void).FullName, aMethodName, aParamTypes)) { } - public Label(string aType, string aReturnType, string aMethodName, params string[] aParamTypes) { - mName = Init(aType, aReturnType, aMethodName, aParamTypes); + public Label(string aType, string aReturnType, string aMethodName, params string[] aParamTypes) + : this(Init(aType, aReturnType, aMethodName, aParamTypes)) { } protected static string Init(string aType, string aReturnType, string aMethodName, params string[] aParamTypes) { diff --git a/source/Indy.IL2CPU.IL.X86/Call.cs b/source/Indy.IL2CPU.IL.X86/Call.cs index eb91a2461..558de1788 100644 --- a/source/Indy.IL2CPU.IL.X86/Call.cs +++ b/source/Indy.IL2CPU.IL.X86/Call.cs @@ -46,7 +46,7 @@ namespace Indy.IL2CPU.IL.X86 { ArgumentSizes = xArgumentSizes.ToArray(); foreach (ParameterDefinition xParam in xMethodDef.Parameters) { if (xParam.IsOut) { - needsCleanup = true; + needsCleanup = true; break; } } @@ -66,6 +66,10 @@ namespace Indy.IL2CPU.IL.X86 { } public void Assemble(string aMethod, int aArgumentCount) { new CPUx86.Call(aMethod); + if (!Assembler.InMetalMode) { + new CPUx86.Test("ecx", "2"); + new CPUx86.JumpIfNotEquals(MethodFooterOp.EndOfMethodLabelNameException); + } for (int i = 0; i < aArgumentCount; i++) { Assembler.StackSizes.Pop(); } diff --git a/source/Indy.IL2CPU.IL.X86/Callvirt.cs b/source/Indy.IL2CPU.IL.X86/Callvirt.cs index 70bf31831..997d2a6b2 100644 --- a/source/Indy.IL2CPU.IL.X86/Callvirt.cs +++ b/source/Indy.IL2CPU.IL.X86/Callvirt.cs @@ -14,8 +14,10 @@ namespace Indy.IL2CPU.IL.X86 { private readonly int mThisOffset; private readonly int mArgumentCount; private readonly int mReturnSize; + private readonly string mLabelName; public Callvirt(Instruction aInstruction, MethodInformation aMethodInfo) : base(aInstruction, aMethodInfo) { + mLabelName = GetInstructionLabel(aInstruction); int xThisOffSet = (from item in aMethodInfo.Locals select item.Offset + item.Size).LastOrDefault(); MethodReference xMethod = aInstruction.Operand as MethodReference; @@ -53,6 +55,10 @@ namespace Indy.IL2CPU.IL.X86 { new CPUx86.Call(CPU.Label.GenerateLabelName(VTablesImplRefs.GetMethodAddressForTypeRef)); new CPUx86.Call(CPUx86.Registers.EAX); } + if (!Assembler.InMetalMode) { + new CPUx86.Test("ecx", "2"); + new CPUx86.JumpIfNotEquals(MethodFooterOp.EndOfMethodLabelNameException); + } for (int i = 0; i < mArgumentCount; i++) { Assembler.StackSizes.Pop(); } diff --git a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/ExceptionImpl.cs b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/ExceptionImpl.cs new file mode 100644 index 000000000..a6d154956 --- /dev/null +++ b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/ExceptionImpl.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Indy.IL2CPU.Plugs; + +namespace Indy.IL2CPU.IL.X86.CustomImplementations.System { + [Plug(Target = typeof(Exception))] + public static class ExceptionImpl { + public static string ToString(Exception aThis) { + return aThis.Message; + } + + [PlugMethod(Signature = "System_String___System_Exception_GetClassName____")] + public static unsafe string GetClassName(uint* aThis) { + int xObjectType = (int)*aThis; + return VTablesImpl.GetTypeName(xObjectType); + } + } +} \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL.X86/Indy.IL2CPU.IL.X86.csproj b/source/Indy.IL2CPU.IL.X86/Indy.IL2CPU.IL.X86.csproj index 23f7a1477..1811d141c 100644 --- a/source/Indy.IL2CPU.IL.X86/Indy.IL2CPU.IL.X86.csproj +++ b/source/Indy.IL2CPU.IL.X86/Indy.IL2CPU.IL.X86.csproj @@ -139,6 +139,7 @@ + diff --git a/source/Indy.IL2CPU.IL.X86/Ret.cs b/source/Indy.IL2CPU.IL.X86/Ret.cs index 76adab63b..727ebc292 100644 --- a/source/Indy.IL2CPU.IL.X86/Ret.cs +++ b/source/Indy.IL2CPU.IL.X86/Ret.cs @@ -11,7 +11,7 @@ namespace Indy.IL2CPU.IL.X86 { : base(aInstruction, aMethodInfo) { } public override void DoAssemble() { - new CPU.JumpAlways(".END__OF__METHOD"); + new CPU.JumpAlways(MethodFooterOp.EndOfMethodLabelNameNormal); } } } \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL.X86/Throw.cs b/source/Indy.IL2CPU.IL.X86/Throw.cs index 0a53d4639..c80bd4922 100644 --- a/source/Indy.IL2CPU.IL.X86/Throw.cs +++ b/source/Indy.IL2CPU.IL.X86/Throw.cs @@ -3,26 +3,25 @@ using System.IO; using System.Linq; using Mono.Cecil; using Mono.Cecil.Cil; -using CPU = Indy.IL2CPU.Assembler.X86; +using CPU = Indy.IL2CPU.Assembler; +using CPUx86 = Indy.IL2CPU.Assembler.X86; namespace Indy.IL2CPU.IL.X86 { [OpCode(Code.Throw, false)] public class Throw: Op { - // TODO: When threading is being worked on, fix this to work multithreaded! - public const string CurrentExceptionDataMember = "__CURRENT_EXCEPTION__"; - public Throw(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo) : base(aInstruction, aMethodInfo) { } public override void DoAssemble() { - if ((from item in Assembler.DataMembers - where item.Value.Name == CurrentExceptionDataMember - select item).Count() == 0) { - Assembler.DataMembers.Add(new System.Collections.Generic.KeyValuePair("il2cpu-system", new Indy.IL2CPU.Assembler.DataMember(CurrentExceptionDataMember, "dd", "0"))); - } - new CPU.Pop("eax"); - new CPU.Move("[" + CurrentExceptionDataMember + "]", "eax"); - new CPU.JumpAlways(MethodFooterOp.EndOfMethodLabelNameException); + //if ((from item in Assembler.DataMembers + // where item.Value.Name == CPU.Assembler.CurrentExceptionDataMember + // select item).Count() == 0) { + // Assembler.DataMembers.Add(new System.Collections.Generic.KeyValuePair("il2cpu-system", new Indy.IL2CPU.Assembler.DataMember(CPU.Assembler.CurrentExceptionDataMember, "dd", "0"))); + //} + new CPUx86.Pop("eax"); + new CPUx86.Move("[" + CPU.DataMember.GetStaticFieldName(CPU.Assembler.CurrentExceptionRef) + "]", "eax"); + new CPUx86.Move("ecx", "3"); + new CPUx86.JumpAlways(MethodFooterOp.EndOfMethodLabelNameException); Assembler.StackSizes.Pop(); } } diff --git a/source/Indy.IL2CPU.IL.X86/X86MainEntryPointOp.cs b/source/Indy.IL2CPU.IL.X86/X86MainEntryPointOp.cs index 4c28f9038..ea9ce1dd2 100644 --- a/source/Indy.IL2CPU.IL.X86/X86MainEntryPointOp.cs +++ b/source/Indy.IL2CPU.IL.X86/X86MainEntryPointOp.cs @@ -18,9 +18,20 @@ namespace Indy.IL2CPU.IL.X86 { new CPUx86.Pushd(aValue); } + private int xLabelId = 0; + public override void Call(MethodDefinition aMethod) { Engine.QueueMethod(aMethod); Call(CPU.Label.GenerateLabelName(aMethod)); + if (!Assembler.InMetalMode) { + new CPUx86.Test("ecx", "2"); + string xLabel = ".Call_Part2_" + xLabelId++.ToString(); + new CPUx86.JumpIfEquals(xLabel); + new CPUx86.Call("_CODE_REQUESTED_BREAK_"); + Engine.QueueMethod(Engine.GetMethodDefinition(Engine.GetTypeDefinitionFromReflectionType(typeof(Assembler.Assembler)), "PrintException")); + new CPUx86.Call(CPU.Label.GenerateLabelName(Engine.GetMethodDefinition(Engine.GetTypeDefinitionFromReflectionType(typeof(Assembler.Assembler)), "PrintException"))); + new CPU.Label(xLabel); + } if(!aMethod.ReturnType.ReturnType.FullName.StartsWith("System.Void")) { new CPUx86.Pushd(CPUx86.Registers.EAX); } diff --git a/source/Indy.IL2CPU.IL.X86/X86MethodFooterOp.cs b/source/Indy.IL2CPU.IL.X86/X86MethodFooterOp.cs index e5d986ff2..bde89a121 100644 --- a/source/Indy.IL2CPU.IL.X86/X86MethodFooterOp.cs +++ b/source/Indy.IL2CPU.IL.X86/X86MethodFooterOp.cs @@ -35,6 +35,7 @@ namespace Indy.IL2CPU.IL.X86 { //new CPUx86.JumpAlways("._GENERIC_Footer"); new Label(EndOfMethodLabelNameException); if (!aAssembler.InMetalMode) { + new CPUx86.Push("ecx"); Engine.QueueMethodRef(GCImplementationRefs.DecRefCountRef); foreach (MethodInformation.Variable xLocal in aLocals) { if (xLocal.IsReferenceType) { @@ -48,6 +49,7 @@ namespace Indy.IL2CPU.IL.X86 { new CPUx86.Call(Label.GenerateLabelName(GCImplementationRefs.DecRefCountRef)); } } + new CPUx86.Pop("ecx"); } if (aReturnSize > 0) { if (aReturnSize > 8) { diff --git a/source/Indy.IL2CPU.IL/CustomImplementations/System/BooleanImpl.cs b/source/Indy.IL2CPU.IL/CustomImplementations/System/BooleanImpl.cs new file mode 100644 index 000000000..add72d5b2 --- /dev/null +++ b/source/Indy.IL2CPU.IL/CustomImplementations/System/BooleanImpl.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Indy.IL2CPU.Plugs; + +namespace Indy.IL2CPU.IL.CustomImplementations.System { + [Plug(Target=typeof(bool))] + public static class BooleanImpl { + public static string ToString(bool aThis) { + if (aThis) { + return "true"; + } else { + return "false"; + } + } + } +} \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL/CustomImplementations/System/ByteImpl.cs b/source/Indy.IL2CPU.IL/CustomImplementations/System/ByteImpl.cs new file mode 100644 index 000000000..a9882bc89 --- /dev/null +++ b/source/Indy.IL2CPU.IL/CustomImplementations/System/ByteImpl.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Indy.IL2CPU.Plugs; + +namespace Indy.IL2CPU.IL.CustomImplementations.System { + [Plug(Target = typeof(byte))] + public static class ByteImpl { + public static string ToString(byte aThis) { + char[] xResult = new char[4]; + string xDigits = "0123456789ABCDEF"; + xResult[0] = '0'; + xResult[1] = 'x'; + xResult[3] = xDigits[aThis & 0xF]; + xResult[2] = xDigits[aThis >> 4]; + return new String(xResult); + } + } +} \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL/CustomImplementations/System/CharImpl.cs b/source/Indy.IL2CPU.IL/CustomImplementations/System/CharImpl.cs new file mode 100644 index 000000000..2c1e39035 --- /dev/null +++ b/source/Indy.IL2CPU.IL/CustomImplementations/System/CharImpl.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Indy.IL2CPU.Plugs; + +namespace Indy.IL2CPU.IL.CustomImplementations.System { + [Plug(Target = typeof(char))] + public static class CharImpl { + public static string ToString(char aThis) { + ushort xValue = aThis; + return UInt16Impl.ToString(xValue); + } + } +} diff --git a/source/Indy.IL2CPU.IL/CustomImplementations/System/EnumImpl.cs b/source/Indy.IL2CPU.IL/CustomImplementations/System/EnumImpl.cs new file mode 100644 index 000000000..635b1071d --- /dev/null +++ b/source/Indy.IL2CPU.IL/CustomImplementations/System/EnumImpl.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Indy.IL2CPU.Plugs; + +namespace Indy.IL2CPU.IL.CustomImplementations.System { + [Plug(Target = typeof(Enum))] + public static class EnumImpl { + [PlugMethod(Signature = "System_String___System_Enum_ToString____")] + public static string ToString(uint aThis) { + return UInt32Impl.ToString(aThis); + } + } +} \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL/CustomImplementations/System/Int16Impl.cs b/source/Indy.IL2CPU.IL/CustomImplementations/System/Int16Impl.cs new file mode 100644 index 000000000..3fedbda45 --- /dev/null +++ b/source/Indy.IL2CPU.IL/CustomImplementations/System/Int16Impl.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Indy.IL2CPU.Plugs; + +namespace Indy.IL2CPU.IL.CustomImplementations.System { + [Plug(Target=typeof(short))] + public static class Int16Impl { + public static string ToString(short aThis) { + string xDigits = "0123456789ABCDEF"; + char[] xResult = new char[6]; + xResult[0] = '0'; + xResult[1] = 'x'; + xResult[2] = xDigits[aThis >> 12]; + xResult[3] = xDigits[aThis >> 8]; + xResult[4] = xDigits[aThis >> 4]; + xResult[5] = xDigits[aThis & 0xF]; + return new String(xResult); + } + } +} diff --git a/source/Indy.IL2CPU.IL/CustomImplementations/System/Int32Impl.cs b/source/Indy.IL2CPU.IL/CustomImplementations/System/Int32Impl.cs new file mode 100644 index 000000000..fcfaacf3c --- /dev/null +++ b/source/Indy.IL2CPU.IL/CustomImplementations/System/Int32Impl.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Indy.IL2CPU.Plugs; + +namespace Indy.IL2CPU.IL.CustomImplementations.System { + [Plug(Target=typeof(Int32))] + public static class Int32Impl { + public static string ToString(int aThis) { + return UInt32Impl.ToString((uint)aThis); + } + } +} \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL/CustomImplementations/System/IntPtrImpl.cs b/source/Indy.IL2CPU.IL/CustomImplementations/System/IntPtrImpl.cs new file mode 100644 index 000000000..f8bc8ff75 --- /dev/null +++ b/source/Indy.IL2CPU.IL/CustomImplementations/System/IntPtrImpl.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Indy.IL2CPU.Plugs; + +namespace Indy.IL2CPU.IL.CustomImplementations.System { + [Plug(Target=typeof(IntPtr))] + public static class IntPtrImpl { + [PlugMethod(Signature="System_String___System_IntPtr_ToString____")] + public static string ToString(uint aThis) { + return UInt32Impl.ToString(aThis); + } + } +} \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL/CustomImplementations/System/ObjectImpl.cs b/source/Indy.IL2CPU.IL/CustomImplementations/System/ObjectImpl.cs new file mode 100644 index 000000000..7c20a2602 --- /dev/null +++ b/source/Indy.IL2CPU.IL/CustomImplementations/System/ObjectImpl.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Indy.IL2CPU.Plugs; + +namespace Indy.IL2CPU.IL.CustomImplementations.System { + [Plug(Target=typeof(Object))] + public static class ObjectImpl { + public static string ToString(object aThis) { + return "--object--"; + } + } +} diff --git a/source/Indy.IL2CPU.IL/CustomImplementations/System/UInt16Impl.cs b/source/Indy.IL2CPU.IL/CustomImplementations/System/UInt16Impl.cs new file mode 100644 index 000000000..12be2536f --- /dev/null +++ b/source/Indy.IL2CPU.IL/CustomImplementations/System/UInt16Impl.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Indy.IL2CPU.Plugs; + +namespace Indy.IL2CPU.IL.CustomImplementations.System { + [Plug(Target=typeof(ushort))] + public static class UInt16Impl { + public static string ToString(ushort aThis) { + string xDigits = "0123456789ABCDEF"; + char[] xResult = new char[6]; + xResult[0] = '0'; + xResult[1] = 'x'; + xResult[2] = xDigits[aThis >> 12]; + xResult[3] = xDigits[aThis >> 8]; + xResult[4] = xDigits[aThis >> 4]; + xResult[5] = xDigits[aThis & 0xF]; + return new String(xResult); + } + } +} \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL/CustomImplementations/System/UInt32Impl.cs b/source/Indy.IL2CPU.IL/CustomImplementations/System/UInt32Impl.cs new file mode 100644 index 000000000..b18bd816c --- /dev/null +++ b/source/Indy.IL2CPU.IL/CustomImplementations/System/UInt32Impl.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Indy.IL2CPU.Plugs; + +namespace Indy.IL2CPU.IL.CustomImplementations.System { + [Plug(Target=typeof(UInt32))] + public static class UInt32Impl { + public static string ToString(uint aThis) { + string xDigits = "0123456789ABCDEF"; + char[] xResult = new char[10]; + xResult[0] = '0'; + xResult[1] = 'x'; + xResult[2] = xDigits[(int)(aThis >> 28) & 0xF]; + xResult[3] = xDigits[(int)(aThis >> 24) & 0xF]; + xResult[4] = xDigits[(int)(aThis >> 20) & 0xF]; + xResult[5] = xDigits[(int)(aThis >> 16) & 0xF]; + xResult[6] = xDigits[(int)(aThis >> 12) & 0xF]; + xResult[7] = xDigits[(int)(aThis >> 8) & 0xF]; + xResult[8] = xDigits[(int)(aThis >> 4) & 0xF]; + xResult[9] = xDigits[(int)aThis & 0xF]; + return new String(xResult); + } + } +} \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL/Indy.IL2CPU.IL.csproj b/source/Indy.IL2CPU.IL/Indy.IL2CPU.IL.csproj index 6e5502341..caf26cd1d 100644 --- a/source/Indy.IL2CPU.IL/Indy.IL2CPU.IL.csproj +++ b/source/Indy.IL2CPU.IL/Indy.IL2CPU.IL.csproj @@ -3,7 +3,7 @@ Debug AnyCPU - 9.0.20706 + 9.0.21022 2.0 {5A39A8DF-D99E-4112-9676-BD3EED969A9C} Library @@ -51,6 +51,16 @@ + + + + + + + + + + diff --git a/source/Indy.IL2CPU.IL/InitVmtImplementationOp.cs b/source/Indy.IL2CPU.IL/InitVmtImplementationOp.cs index cb252246f..53e5915f2 100644 --- a/source/Indy.IL2CPU.IL/InitVmtImplementationOp.cs +++ b/source/Indy.IL2CPU.IL/InitVmtImplementationOp.cs @@ -54,8 +54,8 @@ namespace Indy.IL2CPU.IL { select item.Value).FirstOrDefault(); if (xDataMember != null) { Assembler.DataMembers.Remove((from item in Assembler.DataMembers - where item.Value == xDataMember - select item).First()); + where item.Value == xDataMember + select item).First()); } StringBuilder xDataByteArray = new StringBuilder(); xDataByteArray.Append(BitConverter.GetBytes(ArrayTypeId).Aggregate("", (r, b) => r + b + ",")); @@ -67,8 +67,8 @@ namespace Indy.IL2CPU.IL { xDataByteArray.Append("0,"); } } - Assembler.DataMembers.Add(new KeyValuePair(Assembler.CurrentGroup, new DataMember(xTheName + "__Contents", "db", xDataByteArray.ToString().TrimEnd(',')))); - Assembler.DataMembers.Add(new KeyValuePair(Assembler.CurrentGroup, new DataMember(xTheName, "dd", xTheName + "__Contents"))); + Assembler.DataMembers.Add(new KeyValuePair(Assembler.CurrentGroup, new DataMember(xTheName + "__Contents", "db", xDataByteArray.ToString().TrimEnd(',')))); + Assembler.DataMembers.Add(new KeyValuePair(Assembler.CurrentGroup, new DataMember(xTheName, "dd", xTheName + "__Contents"))); Pushd("0" + mTypes.Count.ToString("X") + "h"); Call(LoadTypeTableRef); for (int i = 0; i < mTypes.Count; i++) { @@ -119,16 +119,21 @@ namespace Indy.IL2CPU.IL { } string xDataValue = xDataByteArray.ToString(); string xDataName = "____SYSTEM____TYPE___" + DataMember.FilterStringForIncorrectChars(mTypes[i].FullName) + "__MethodIndexesArray"; - Assembler.DataMembers.Add(new KeyValuePair(Assembler.CurrentGroup, new DataMember(xDataName, "db", xDataValue.TrimEnd(',')))); + Assembler.DataMembers.Add(new KeyValuePair(Assembler.CurrentGroup, new DataMember(xDataName, "db", xDataValue.TrimEnd(',')))); Pushd(xDataName); xDataName = "____SYSTEM____TYPE___" + DataMember.FilterStringForIncorrectChars(mTypes[i].FullName) + "__MethodAddressesArray"; - Assembler.DataMembers.Add(new KeyValuePair(Assembler.CurrentGroup, new DataMember(xDataName, "db", xDataValue.TrimEnd(',')))); + Assembler.DataMembers.Add(new KeyValuePair(Assembler.CurrentGroup, new DataMember(xDataName, "db", xDataValue.TrimEnd(',')))); Pushd(xDataName); - //xDataValue = Encoding.ASCII.GetBytes(mTypes[i].FullName + ", " + mTypes[i].Module.Assembly.Name.FullName).Aggregate("", (b, x) => b + x + ",") + "0"; - //xDataName = "____SYSTEM____TYPE___" + DataMember.FilterStringForIncorrectChars(mTypes[i].FullName); - //mAssembler.DataMembers.Add(new DataMember(xDataName, "db", xDataValue)); - //Pushd(xDataName); - Pushd("0"); + xDataByteArray.Remove(0, xDataByteArray.Length); + xDataByteArray.Append(BitConverter.GetBytes(ArrayTypeId).Aggregate("", (r, b) => r + b + ",")); + xDataByteArray.Append(BitConverter.GetBytes(0x80000002 /* EmbeddedArray */).Aggregate("", (r, b) => r + b + ",")); + xDataByteArray.Append(BitConverter.GetBytes((mTypes[i].FullName + ", " + mTypes[i].Module.Assembly.Name.FullName).Length).Aggregate("", (r, b) => r + b + ",")); + xDataByteArray.Append(BitConverter.GetBytes((uint)2).Aggregate("", (r, b) => r + b + ",")); + xDataByteArray.Append(Encoding.Unicode.GetBytes(mTypes[i].FullName + ", " + mTypes[i].Module.Assembly.Name.FullName).Aggregate("", (b, x) => b + x + ",") + "0"); + xDataName = "____SYSTEM____TYPE___" + DataMember.FilterStringForIncorrectChars(mTypes[i].FullName); + mAssembler.DataMembers.Add(new KeyValuePair(Assembler.CurrentGroup, new DataMember(xDataName, "db", xDataByteArray.ToString()))); + Pushd(xDataName); + //Pushd("0"); Call(SetTypeInfoRef); for (int j = 0; j < xEmittedMethods.Count; j++) { MethodDefinition xMethod = xEmittedMethods[j]; diff --git a/source/Indy.IL2CPU.IL/MethodFooterOp.cs b/source/Indy.IL2CPU.IL/MethodFooterOp.cs index bb2bab955..213d90329 100644 --- a/source/Indy.IL2CPU.IL/MethodFooterOp.cs +++ b/source/Indy.IL2CPU.IL/MethodFooterOp.cs @@ -7,7 +7,7 @@ using Mono.Cecil.Cil; namespace Indy.IL2CPU.IL { public abstract class MethodFooterOp: Op { public const string EndOfMethodLabelNameNormal = ".END__OF__METHOD_NORMAL"; - public const string EndOfMethodLabelNameException = ".END__OF__METHOD_NORMAL"; + public const string EndOfMethodLabelNameException = ".END__OF__METHOD_EXCEPTION"; public MethodFooterOp(Instruction aInstruction, MethodInformation aMethodInfo) : base(aInstruction, aMethodInfo) { diff --git a/source/Indy.IL2CPU/CustomImplementation/System/EnvironmentImpl.cs b/source/Indy.IL2CPU/CustomImplementation/System/EnvironmentImpl.cs index 7fae81515..01d1e72b1 100644 --- a/source/Indy.IL2CPU/CustomImplementation/System/EnvironmentImpl.cs +++ b/source/Indy.IL2CPU/CustomImplementation/System/EnvironmentImpl.cs @@ -2,12 +2,17 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using Indy.IL2CPU.Plugs; namespace Indy.IL2CPU.CustomImplementation.System { + [Plug(Target=typeof(Environment))] public static class EnvironmentImpl { - [MethodAlias(Name = "System.String System.Environment.GetResourceFromDefault(System.String)")] public static string GetResourceFromDefault(string aResource) { return aResource; } + + public static string GetResourceString(string aResource) { + return aResource; + } } } \ No newline at end of file diff --git a/source/Indy.IL2CPU/CustomImplementation/System/Globalization/CultureInfoImpl.cs b/source/Indy.IL2CPU/CustomImplementation/System/Globalization/CultureInfoImpl.cs new file mode 100644 index 000000000..b70c845b8 --- /dev/null +++ b/source/Indy.IL2CPU/CustomImplementation/System/Globalization/CultureInfoImpl.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Indy.IL2CPU.Plugs; +using System.Globalization; + +namespace Indy.IL2CPU.CustomImplementation.System.Globalization { + [Plug(Target = typeof(CultureInfo))] + public static class CultureInfoImpl { + public static CultureInfo get_CurrentCulture() { + return null; + } + } +} \ No newline at end of file diff --git a/source/Indy.IL2CPU/CustomImplementation/System/StringImpl.cs b/source/Indy.IL2CPU/CustomImplementation/System/StringImpl.cs index f5fe28262..0bbbc0a21 100644 --- a/source/Indy.IL2CPU/CustomImplementation/System/StringImpl.cs +++ b/source/Indy.IL2CPU/CustomImplementation/System/StringImpl.cs @@ -29,6 +29,25 @@ namespace Indy.IL2CPU.CustomImplementation.System { aStorage = aChars; } + public static string Format(object aFormatProvider, string aFormat, object[] aArgs) { + string[] xStrings = new string[1 + 2 + (aArgs.Length * 7) - 1]; + xStrings[0] = aFormat; + xStrings[1] = "("; + for (int i = 0; i < aArgs.Length; i++) { + xStrings[2 + (i *7)] = "Param"; + xStrings[3 + (i *7)] = i.ToString(); + xStrings[4 + (i *7)] = "="; + xStrings[5 + (i *7)] = "\""; + xStrings[6 + (i * 7)] = aArgs[i].ToString(); + xStrings[7 + (i * 7)] = "\""; + if (i < (aArgs.Length - 1)) { + xStrings[8 + (i * 7)] = ","; + } + } + xStrings[xStrings.Length - 1] = ")"; + return String.Concat(xStrings); + } + public static int IndexOf(string aThis, char c) { for (int i = 0; i < aThis.Length; i++) { if (aThis[i] == c) { @@ -38,43 +57,40 @@ namespace Indy.IL2CPU.CustomImplementation.System { return -1; } - public static string Substring(string aThis, int startpos) - { - char[] cs = new char[aThis.Length - startpos]; + public static string Substring(string aThis, int startpos) { + char[] cs = new char[aThis.Length - startpos]; - int j = 0; - for (int i = startpos; i < aThis.Length; i++) - cs[j++] = aThis[i]; + int j = 0; + for (int i = startpos; i < aThis.Length; i++) + cs[j++] = aThis[i]; - return new string(cs); - } + return new string(cs); + } - public static string Substring(string aThis, int startpos, int length) - { - if (startpos + length > aThis.Length) - length = aThis.Length - startpos; + public static string Substring(string aThis, int startpos, int length) { + if (startpos + length > aThis.Length) + length = aThis.Length - startpos; - char[] cs = new char[length]; + char[] cs = new char[length]; - int j = 0; - for (int i = startpos; i < startpos + length; i++) - cs[j++] = aThis[i]; + int j = 0; + for (int i = startpos; i < startpos + length; i++) + cs[j++] = aThis[i]; - return new string(cs); - } + return new string(cs); + } - // HACK: We need to redo this once char support is complete (only returns 0, -1). - public static int CompareTo(string aThis, string other) - { - if (aThis.Length != other.Length) - return -1; - for (int i = 0; i < aThis.Length; i++) - if (aThis[i] != other[i]) - return -1; - return 0; - } + // HACK: We need to redo this once char support is complete (only returns 0, -1). + public static int CompareTo(string aThis, string other) { + if (aThis.Length != other.Length) + return -1; + for (int i = 0; i < aThis.Length; i++) + if (aThis[i] != other[i]) + return -1; + return 0; + } - [PlugMethod(Enabled = false)] + [PlugMethod(Enabled = false)] public static uint GetStorage(string aString) { return 0; } diff --git a/source/Indy.IL2CPU/Indy.IL2CPU.csproj b/source/Indy.IL2CPU/Indy.IL2CPU.csproj index 3e89458b9..01ac46673 100644 --- a/source/Indy.IL2CPU/Indy.IL2CPU.csproj +++ b/source/Indy.IL2CPU/Indy.IL2CPU.csproj @@ -97,6 +97,7 @@ + diff --git a/source/Indy.IL2CPU/VTablesImpl.cs b/source/Indy.IL2CPU/VTablesImpl.cs index 6b60f2d49..a9b8239f8 100644 --- a/source/Indy.IL2CPU/VTablesImpl.cs +++ b/source/Indy.IL2CPU/VTablesImpl.cs @@ -24,7 +24,7 @@ namespace Indy.IL2CPU { //mTypes = new VTable[aTypeCount]; } - public static void SetTypeInfo(int aType, int aBaseType, ref int[] aMethodIndexes, ref int[] aMethodAddresses, int aName) { + public static void SetTypeInfo(int aType, int aBaseType, ref int[] aMethodIndexes, ref int[] aMethodAddresses, char[] aName) { mTypes[aType] = new VTable(); mTypes[aType].BaseTypeIdentifier = aBaseType; mTypes[aType].MethodIndexes = aMethodIndexes; @@ -32,6 +32,10 @@ namespace Indy.IL2CPU { mTypes[aType].Name = aName; } + public static string GetTypeName(int aType) { + return new String(mTypes[aType].Name); + } + public static void SetMethodInfo(int aType, int aMethodIndex, int aMethodIdentifier, int aMethodAddress, char[] aName) { mTypes[aType].MethodIndexes[aMethodIndex] = aMethodIdentifier; mTypes[aType].MethodAddresses[aMethodIndex] = aMethodAddress; @@ -50,7 +54,7 @@ namespace Indy.IL2CPU { public struct VTable { public int BaseTypeIdentifier; - public int Name; + public char[] Name; public int[] MethodIndexes; public int[] MethodAddresses; }