diff --git a/source/Indy.IL2CPU.Assembler.X86/CmpXchg.cs b/source/Indy.IL2CPU.Assembler.X86/CmpXchg.cs new file mode 100644 index 000000000..cdbf354a2 --- /dev/null +++ b/source/Indy.IL2CPU.Assembler.X86/CmpXchg.cs @@ -0,0 +1,18 @@ +using System; +using System.Linq; + +namespace Indy.IL2CPU.Assembler.X86 { + [OpCode(0xFFFFFFFF, "cmpxchg")] + public class CmpXchg: Instruction { + public readonly string Destination; + public readonly string Source; + public CmpXchg(string aDestination, string aSource) { + Destination = aDestination; + Source = aSource; + } + + public override string ToString() { + return "cmpxchg " + Destination + ", " + Source; + } + } +} 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 57a385cf2..a926558bb 100644 --- a/source/Indy.IL2CPU.Assembler.X86/Indy.IL2CPU.Assembler.X86.csproj +++ b/source/Indy.IL2CPU.Assembler.X86/Indy.IL2CPU.Assembler.X86.csproj @@ -53,6 +53,7 @@ + diff --git a/source/Indy.IL2CPU.Assembler/DataMember.cs b/source/Indy.IL2CPU.Assembler/DataMember.cs index ab0b6f118..b35312640 100644 --- a/source/Indy.IL2CPU.Assembler/DataMember.cs +++ b/source/Indy.IL2CPU.Assembler/DataMember.cs @@ -12,7 +12,7 @@ namespace Indy.IL2CPU.Assembler { public static string FilterStringForIncorrectChars(string aName) { string xTempResult = aName; - foreach (char c in new char[] { '.', ',', '+', '$', '<', '>', '{', '}', '-', '`', '\'', '/', '\\', ' ', '(', ')', '[', ']' }) { + foreach (char c in new char[] { '.', ',', '+', '$', '<', '>', '{', '}', '-', '`', '\'', '/', '\\', ' ', '(', ')', '[', ']', '*' }) { xTempResult = xTempResult.Replace(c, '_'); } return xTempResult; diff --git a/source/Indy.IL2CPU.IL.X86.Win32/CustomImplementations/System/ConsoleImpl.cs b/source/Indy.IL2CPU.IL.X86.Win32/CustomImplementations/System/ConsoleImpl.cs new file mode 100644 index 000000000..74da438c0 --- /dev/null +++ b/source/Indy.IL2CPU.IL.X86.Win32/CustomImplementations/System/ConsoleImpl.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; + +namespace Indy.IL2CPU.IL.X86.Win32.CustomImplementations.System { + public static class ConsoleImpl { + [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] + static extern unsafe bool WriteConsole(IntPtr hConsoleOutput, uint* lpBuffer, + uint nNumberOfCharsToWrite, out uint lpNumberOfCharsWritten, + IntPtr lpReserved); + [DllImport("kernel32.dll")] + static extern IntPtr GetStdHandle(int nStdHandle); + + [DllImport("kernel32.dll")] + private static extern bool CloseHandle(IntPtr aHandle); + + private const int ConsoleOutHandle = -11; + private static int mInitialized = 0; + private static IntPtr mConsoleOutHandler; + + private static void DoInitialize() { + if(mInitialized== 0){ + mInitialized = 1; + mConsoleOutHandler = GetStdHandle(ConsoleOutHandle); + } + } + + public unsafe static void Write(uint* aData) { + DoInitialize(); + uint xCharsWritten; + uint xCharsToWrite = (uint)X86.CustomImplementations.System.StringImpl.get_Length_Normal(aData); + WriteConsole(mConsoleOutHandler, CustomImplementation.System.StringImpl.GetStorageNormal(aData), xCharsToWrite, out xCharsWritten, IntPtr.Zero); + } + + public static void WriteLine(string aData) { + Console.Write(aData); + Console.Write(Environment.NewLine); + } + } +} \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL.X86.Win32/CustomImplementations/System/ConsoleImplRefs.cs b/source/Indy.IL2CPU.IL.X86.Win32/CustomImplementations/System/ConsoleImplRefs.cs new file mode 100644 index 000000000..133d430a6 --- /dev/null +++ b/source/Indy.IL2CPU.IL.X86.Win32/CustomImplementations/System/ConsoleImplRefs.cs @@ -0,0 +1,35 @@ +using System; +using System.Linq; +using System.Reflection; +using Mono.Cecil; + +namespace Indy.IL2CPU.IL.X86.Win32.CustomImplementations.System { + public static class ConsoleImplRefs { + public static readonly MethodDefinition WriteRef; + public static readonly MethodDefinition WriteLineRef; + public static readonly AssemblyDefinition RuntimeAssemblyDef; + + static ConsoleImplRefs() { + RuntimeAssemblyDef = AssemblyFactory.GetAssembly(typeof (ConsoleImpl).Assembly.Location); + TypeDefinition xType = null; + foreach (ModuleDefinition xMod in RuntimeAssemblyDef.Modules) { + if (xMod.Types.Contains(typeof (ConsoleImpl).FullName)) { + xType = xMod.Types[typeof (ConsoleImpl).FullName]; + break; + } + } + if (xType == null) { + throw new Exception("ConsoleImpl type not found!"); + } + foreach (FieldInfo xField in typeof (ConsoleImplRefs).GetFields()) { + if (xField.Name.EndsWith("Ref")) { + MethodDefinition xTempMethod = xType.Methods.GetMethod(xField.Name.Substring(0, xField.Name.Length - "Ref".Length)).FirstOrDefault(); + if (xTempMethod == null) { + throw new Exception("Method '" + xField.Name.Substring(0, xField.Name.Length - "Ref".Length) + "' not found on RuntimeEngine!"); + } + xField.SetValue(null, xTempMethod); + } + } + } + } +} \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL.X86.Win32/Indy.IL2CPU.IL.X86.Win32.csproj b/source/Indy.IL2CPU.IL.X86.Win32/Indy.IL2CPU.IL.X86.Win32.csproj index 3ffc0cccf..daae54df7 100644 --- a/source/Indy.IL2CPU.IL.X86.Win32/Indy.IL2CPU.IL.X86.Win32.csproj +++ b/source/Indy.IL2CPU.IL.X86.Win32/Indy.IL2CPU.IL.X86.Win32.csproj @@ -25,6 +25,7 @@ DEBUG;TRACE prompt 4 + true pdbonly @@ -47,6 +48,8 @@ + + diff --git a/source/Indy.IL2CPU.IL.X86.Win32/Win32OpCodeMap.cs b/source/Indy.IL2CPU.IL.X86.Win32/Win32OpCodeMap.cs index 8d72c85c4..21add2102 100644 --- a/source/Indy.IL2CPU.IL.X86.Win32/Win32OpCodeMap.cs +++ b/source/Indy.IL2CPU.IL.X86.Win32/Win32OpCodeMap.cs @@ -9,5 +9,18 @@ namespace Indy.IL2CPU.IL.X86.Win32 { protected override Type GetCustomMethodImplementationOp() { return typeof(Win32CustomMethodImplementationOp); } + + public override Mono.Cecil.MethodReference GetCustomMethodImplementation(string aOrigMethodName, bool aInMetalMode) { + switch (aOrigMethodName) { + case "System_Void___System_Console_Write___System_String___": { + return CustomImplementations.System.ConsoleImplRefs.WriteRef; + } + case "System_Void___System_Console_WriteLine___System_String___": { + return CustomImplementations.System.ConsoleImplRefs.WriteLineRef; + } + default: + return base.GetCustomMethodImplementation(aOrigMethodName, aInMetalMode); + } + } } } diff --git a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/ObjectImpl.cs b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/ObjectImpl.cs new file mode 100644 index 000000000..6406008c6 --- /dev/null +++ b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/ObjectImpl.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Indy.IL2CPU.IL.X86.CustomImplementations.System { + public static class ObjectImpl { + + } +} diff --git a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/ObjectImplRefs.cs b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/ObjectImplRefs.cs new file mode 100644 index 000000000..e64f4dc3b --- /dev/null +++ b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/ObjectImplRefs.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using Mono.Cecil; + +namespace Indy.IL2CPU.IL.X86.CustomImplementations.System { + public static class ObjectImplRefs { + public static readonly AssemblyDefinition RuntimeAssemblyDef; + + static ObjectImplRefs() { + RuntimeAssemblyDef = AssemblyFactory.GetAssembly(typeof(ObjectImpl).Assembly.Location); + TypeDefinition xType = null; + foreach (ModuleDefinition xMod in RuntimeAssemblyDef.Modules) { + if (xMod.Types.Contains(typeof(ObjectImpl).FullName)) { + xType = xMod.Types[typeof(ObjectImpl).FullName]; + break; + } + } + if (xType == null) { + throw new Exception("ObjectImpl type not found!"); + } + foreach (FieldInfo xField in typeof(ObjectImplRefs).GetFields()) { + if (xField.Name.EndsWith("Ref")) { + MethodDefinition xTempMethod = xType.Methods.GetMethod(xField.Name.Substring(0, xField.Name.Length - "Ref".Length)).FirstOrDefault(); + if (xTempMethod == null) { + throw new Exception("Method '" + xField.Name.Substring(0, xField.Name.Length - "Ref".Length) + "' not found on RuntimeEngine!"); + } + xField.SetValue(null, xTempMethod); + } + } + } + } +} diff --git a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/StringImpl.cs b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/StringImpl.cs index 31fde95ad..95a6e2330 100644 --- a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/StringImpl.cs +++ b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/StringImpl.cs @@ -5,14 +5,14 @@ using System.Text; namespace Indy.IL2CPU.IL.X86.CustomImplementations.System { public static class StringImpl { - public static unsafe int get_Length_Normal(int* aThis) { - int xArrayPtrNumber = *(aThis + 3); + public static unsafe int get_Length_Normal(uint* aThis) { + int xArrayPtrNumber = (int)*(aThis + 3); int* xArrayPtr = (int*)xArrayPtrNumber; return *(xArrayPtr + 2); } - public static unsafe int get_Length_Metal(int* aThis) { - return *aThis; + public static unsafe int get_Length_Metal(uint* aThis) { + return (int)*aThis; } public static byte GetByteFromChar(char aChar) { 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 adbe06cd6..1148e1995 100644 --- a/source/Indy.IL2CPU.IL.X86/Indy.IL2CPU.IL.X86.csproj +++ b/source/Indy.IL2CPU.IL.X86/Indy.IL2CPU.IL.X86.csproj @@ -127,6 +127,8 @@ + + diff --git a/source/Indy.IL2CPU.IL.X86/LdStr.cs b/source/Indy.IL2CPU.IL.X86/LdStr.cs index 464862959..1b7b05eb2 100644 --- a/source/Indy.IL2CPU.IL.X86/LdStr.cs +++ b/source/Indy.IL2CPU.IL.X86/LdStr.cs @@ -34,15 +34,21 @@ namespace Indy.IL2CPU.IL.X86 { Move(Assembler, "eax", xDataName); Pushd(4, "eax"); } else { - string xDataName = Assembler.GetIdentifier("StringLiteral"); var xDataByteArray = new StringBuilder(); // todo: see if we need to output trailing bytes 00 00 or 00 01 depending on whether there are bytes >7F - xDataByteArray.Append(BitConverter.GetBytes(Engine.RegisterType(Engine.GetTypeDefinition("mscorlib", "System.String"))).Aggregate("", (r, b) => r + b + ",")); + xDataByteArray.Append(BitConverter.GetBytes(Engine.RegisterType(Engine.GetTypeDefinition("mscorlib", "System.Array"))).Aggregate("", (r, b) => r + b + ",")); xDataByteArray.Append(BitConverter.GetBytes((int)InstanceTypeEnum.Array).Aggregate("", (r, b) => r + b + ",")); xDataByteArray.Append(BitConverter.GetBytes(LiteralStr.Length).Aggregate("", (r, b) => r + b + ",")); - xDataByteArray.Append(Encoding.ASCII.GetBytes(LiteralStr).Aggregate("", (r, b) => r + b + ",")); + xDataByteArray.Append(Encoding.Unicode.GetBytes(LiteralStr).Aggregate("", (r, b) => r + b + ",")); xDataByteArray.Append("0,"); - Assembler.DataMembers.Add(new DataMember(xDataName, "db", xDataByteArray.ToString().TrimEnd(','))); + string xDataVal = xDataByteArray.ToString().TrimEnd(','); + string xDataName = (from item in Assembler.DataMembers + where item.DefaultValue == xDataVal + select item.Name).FirstOrDefault(); + if (String.IsNullOrEmpty(xDataName)) { + xDataName = Assembler.GetIdentifier("StringLiteral"); + Assembler.DataMembers.Add(new DataMember(xDataName, "db", xDataByteArray.ToString().TrimEnd(','))); + } Pushd(4, xDataName); new Newobj() { Assembler = Assembler, diff --git a/source/Indy.IL2CPU.IL.X86/Ldelem_Any.cs b/source/Indy.IL2CPU.IL.X86/Ldelem_Any.cs index 899020ec0..19908e3a7 100644 --- a/source/Indy.IL2CPU.IL.X86/Ldelem_Any.cs +++ b/source/Indy.IL2CPU.IL.X86/Ldelem_Any.cs @@ -19,9 +19,6 @@ namespace Indy.IL2CPU.IL.X86 { // todo: refactor all Ldelem variants to use this method for emitting public static void Assemble(CPU.Assembler aAssembler, int aElementSize) { - if(aElementSize % 4 != 0) { - throw new ArgumentException("ElementSize should be divisible by 4", "aElementSize"); - } aAssembler.Add(new CPUx86.Pop("eax")); aAssembler.Add(new CPUx86.Move("edx", "0" + aElementSize.ToString("X") + "h")); aAssembler.Add(new CPUx86.Multiply("edx")); @@ -29,11 +26,26 @@ namespace Indy.IL2CPU.IL.X86 { aAssembler.Add(new CPUx86.Pop("edx")); aAssembler.Add(new CPUx86.Add("edx", "eax")); aAssembler.Add(new CPUx86.Move("eax", "edx")); - for (int i = 0; i < (aElementSize / 4); i++) { - aAssembler.Add(new CPUx86.Pushd("[eax]")); - if (i != 0) { + int xSizeLeft = aElementSize; + while(xSizeLeft > 0) { + if(xSizeLeft >= 4) { + aAssembler.Add(new CPUx86.Push("dword [eax]")); aAssembler.Add(new CPUx86.Add("eax", "4")); - aAssembler.Add(new CPUx86.Pushd("eax")); + xSizeLeft -= 4; + }else { + if(xSizeLeft >= 2) { + aAssembler.Add(new CPUx86.Push("word [eax]")); + aAssembler.Add(new CPUx86.Add("eax", "2")); + xSizeLeft -= 2; + }else { + if(xSizeLeft >= 1) { + aAssembler.Add(new CPUx86.Push("byte [eax]")); + aAssembler.Add(new CPUx86.Add("eax", "1")); + xSizeLeft -= 1; + }else { + throw new Exception("Size left: " + xSizeLeft); + } + } } } aAssembler.StackSizes.Pop(); diff --git a/source/Indy.IL2CPU.IL.X86/Ldind_U2.cs b/source/Indy.IL2CPU.IL.X86/Ldind_U2.cs index 13158d1fb..d567bbb93 100644 --- a/source/Indy.IL2CPU.IL.X86/Ldind_U2.cs +++ b/source/Indy.IL2CPU.IL.X86/Ldind_U2.cs @@ -12,7 +12,7 @@ namespace Indy.IL2CPU.IL.X86 { } public override void DoAssemble() { Pop("eax"); - Pushd(2, "word [eax]"); + Push(Assembler, 2, "word [eax]"); } } } \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL.X86/Newobj.cs b/source/Indy.IL2CPU.IL.X86/Newobj.cs index 9a255b98f..ed18fa418 100644 --- a/source/Indy.IL2CPU.IL.X86/Newobj.cs +++ b/source/Indy.IL2CPU.IL.X86/Newobj.cs @@ -33,7 +33,7 @@ namespace Indy.IL2CPU.IL.X86 { Move(Assembler, "dword [eax + 4]", "0" + InstanceTypeEnum.NormalObject.ToString("X") + "h"); //Pushd("ecx"); for (int i = 0; i < CtorDef.Parameters.Count; i++) { - Assembler.Add(new CPUx86.Pushd("[ebp - 010h]")); + Assembler.Add(new CPUx86.Pushd("[esp + 0x8]")); } Call(new CPU.Label(CtorDef).Name); Pop("eax"); diff --git a/source/Indy.IL2CPU.IL.X86/Ret.cs b/source/Indy.IL2CPU.IL.X86/Ret.cs index 907c68340..4bac923c7 100644 --- a/source/Indy.IL2CPU.IL.X86/Ret.cs +++ b/source/Indy.IL2CPU.IL.X86/Ret.cs @@ -11,6 +11,7 @@ namespace Indy.IL2CPU.IL.X86 { : base(aInstruction, aMethodInfo) { } public override void DoAssemble() { + JumpAlways(".END__OF__METHOD"); } } } \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL.X86/X86MethodFooterOp.cs b/source/Indy.IL2CPU.IL.X86/X86MethodFooterOp.cs index 1d4709f1f..748b9e996 100644 --- a/source/Indy.IL2CPU.IL.X86/X86MethodFooterOp.cs +++ b/source/Indy.IL2CPU.IL.X86/X86MethodFooterOp.cs @@ -2,8 +2,9 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text; -using Mono.Cecil.Cil; +using Indy.IL2CPU.Assembler; using CPU = Indy.IL2CPU.Assembler.X86; +using Instruction=Mono.Cecil.Cil.Instruction; namespace Indy.IL2CPU.IL.X86 { public class X86MethodFooterOp: MethodFooterOp { @@ -45,16 +46,15 @@ namespace Indy.IL2CPU.IL.X86 { } public static void AssembleFooter(int aReturnSize, Assembler.Assembler aAssembler, int[] aLocalsSizes, int aTotalArgsSize) { + aAssembler.Add(new Label(".END__OF__METHOD")); if (aReturnSize > 0) { if (aReturnSize > 4) { throw new Exception("ReturnValue sizes larger than 4 not supported yet"); } aAssembler.Add(new Assembler.X86.Pop("eax")); - aAssembler.StackSizes.Pop(); } for (int j = (aLocalsSizes.Length - 1); j >= 0; j--) { int xLocalSize = aLocalsSizes[j]; - aAssembler.StackSizes.Pop(); aAssembler.Add(new CPU.Add("esp", "0x" + xLocalSize.ToString("X"))); } aAssembler.Add(new CPU.Pop("ebp")); diff --git a/source/Indy.IL2CPU.IL.X86/X86OpCodeMap.cs b/source/Indy.IL2CPU.IL.X86/X86OpCodeMap.cs index cdd9e451c..01922c090 100644 --- a/source/Indy.IL2CPU.IL.X86/X86OpCodeMap.cs +++ b/source/Indy.IL2CPU.IL.X86/X86OpCodeMap.cs @@ -2,7 +2,8 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; -using System.Text; +using CPU = Indy.IL2CPU.Assembler; +using CPUx86 = Indy.IL2CPU.Assembler.X86; namespace Indy.IL2CPU.IL.X86 { public abstract class X86OpCodeMap: OpCodeMap { @@ -41,7 +42,7 @@ namespace Indy.IL2CPU.IL.X86 { case "System_Int32___System_String_get_Length____": { if (aInMetalMode) { return CustomImplementations.System.StringImplRefs.get_Length_MetalRef; - }else { + } else { return CustomImplementations.System.StringImplRefs.get_Length_NormalRef; } } @@ -55,5 +56,57 @@ namespace Indy.IL2CPU.IL.X86 { return base.GetCustomMethodImplementation(aOrigMethodName, aInMetalMode); } } + + public override bool HasCustomAssembleImplementation(string aMethodName, bool aInMetalMode) { + switch (aMethodName) { + case "System_Object___System_Threading_Interlocked_CompareExchange___System_Object___System_Object__System_Object___": { + return true; + } + case "System_Int32___System_Threading_Interlocked_CompareExchange___System_Int32___System_Int32__System_Int32___": { + return true; + } + case "System_String___System_String_FastAllocateString___System_Int32___": { + return true; + } + default: + return base.HasCustomAssembleImplementation(aMethodName, aInMetalMode); + } + } + + public override void DoCustomAssembleImplementation(string aMethodName, bool aInMetalMode, Indy.IL2CPU.Assembler.Assembler aAssembler, MethodInformation aMethodInfo) { + switch (aMethodName) { + case "System_Object___System_Threading_Interlocked_CompareExchange___System_Object___System_Object__System_Object___": { + Assemble_System_Threading_Interlocked_CompareExchange__Object(aAssembler, aMethodInfo); + break; + } + case "System_Int32___System_Threading_Interlocked_CompareExchange___System_Int32___System_Int32__System_Int32___": { + Assemble_System_Threading_Interlocked_CompareExchange__Object(aAssembler, aMethodInfo); + break; + } + default: + base.DoCustomAssembleImplementation(aMethodName, aInMetalMode, aAssembler, aMethodInfo); + break; + } + } + + private static void Assemble_System_Threading_Interlocked_CompareExchange__Object(Assembler.Assembler aAssembler, MethodInformation aMethodInfo) { + //arguments: + // 0: location + // 1: value + // 2: comparand + Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[2].VirtualAddresses, aMethodInfo.Arguments[2].Size); + aAssembler.Add(new CPUx86.Pop("eax")); + Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[1].VirtualAddresses, aMethodInfo.Arguments[1].Size); + aAssembler.Add(new CPUx86.Pop("edx")); + Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0].VirtualAddresses, aMethodInfo.Arguments[0].Size); + aAssembler.Add(new CPUx86.Pop("ecx")); + aAssembler.Add(new CPUx86.Pushd("[ecx]")); + aAssembler.Add(new CPUx86.Pop("ecx")); + aAssembler.Add(new CPUx86.CmpXchg("ecx", "edx")); + Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0].VirtualAddresses, aMethodInfo.Arguments[0].Size); + aAssembler.Add(new CPUx86.Pop("eax")); + aAssembler.Add(new CPUx86.Move("[eax]", "ecx")); + aAssembler.Add(new CPUx86.Pushd("eax")); + } } } diff --git a/source/Indy.IL2CPU.IL.X86/X86PInvokeMethodBodyOp.cs b/source/Indy.IL2CPU.IL.X86/X86PInvokeMethodBodyOp.cs index a354fd0f7..3e62dde23 100644 --- a/source/Indy.IL2CPU.IL.X86/X86PInvokeMethodBodyOp.cs +++ b/source/Indy.IL2CPU.IL.X86/X86PInvokeMethodBodyOp.cs @@ -49,15 +49,19 @@ namespace Indy.IL2CPU.IL.X86 { // } // } // if (xNeedsExtras) { + string xStringMethodSuffix = "W"; + if(Assembler.InMetalMode) { + xStringMethodSuffix = "A"; + } if (!TheMethod.PInvokeInfo.IsNoMangle) { if (TheMethod.PInvokeInfo.IsCharSetUnicode) { - xMethodName += "A";// for now, strings are ASCII + xMethodName += xStringMethodSuffix; } else { if (TheMethod.PInvokeInfo.IsCharSetAnsi) { - xMethodName += "A"; + xMethodName += xStringMethodSuffix; } else { if (TheMethod.PInvokeInfo.IsCharSetAuto) { - xMethodName += "A";// for now, strings are ASCII + xMethodName += xStringMethodSuffix; } } } diff --git a/source/Indy.IL2CPU/CustomImplementation/System/StringImpl.cs b/source/Indy.IL2CPU/CustomImplementation/System/StringImpl.cs index 031b2638b..2d17f01f6 100644 --- a/source/Indy.IL2CPU/CustomImplementation/System/StringImpl.cs +++ b/source/Indy.IL2CPU/CustomImplementation/System/StringImpl.cs @@ -18,13 +18,21 @@ namespace Indy.IL2CPU.CustomImplementation.System { aStorage = aChars; } - public static uint GetStorageMetal(uint aStringPtr) { + [MethodAlias(Name = "System.String System.String.FastAllocateString(System.Int32)")] + public static String FastAllocateString(int aLength) { + Char[] xItems = new Char[aLength]; + return new String(xItems); + } + + public static unsafe uint* GetStorageMetal(uint* aStringPtr) { return aStringPtr; } - public static uint GetStorageNormal(uint aStringPtr) { - uint xResult = aStringPtr; - xResult = xResult + 12; + public static unsafe uint* GetStorageNormal(uint* aStringPtr) { + uint* xResult = aStringPtr; + xResult = xResult + 3; + xResult = (uint*)(*xResult); + xResult += 3; return xResult; } } diff --git a/source/Indy.IL2CPU/Engine.cs b/source/Indy.IL2CPU/Engine.cs index f3ec0f8ca..091a6b15a 100644 --- a/source/Indy.IL2CPU/Engine.cs +++ b/source/Indy.IL2CPU/Engine.cs @@ -882,6 +882,9 @@ namespace Indy.IL2CPU { if (xField.IsStatic) { continue; } + if(xField.HasConstant) { + Console.WriteLine("Field is constant: " + xField.GetFullName()); + } int xFieldSize; TypeSpecification xTypeSpec = xField.FieldType as TypeSpecification; if (xTypeSpec != null) { diff --git a/source/Indy.IL2CPU/RuntimeEngine/Heap.cs b/source/Indy.IL2CPU/RuntimeEngine/Heap.cs index 26a33df22..d5a1a20b4 100644 --- a/source/Indy.IL2CPU/RuntimeEngine/Heap.cs +++ b/source/Indy.IL2CPU/RuntimeEngine/Heap.cs @@ -6,7 +6,7 @@ using System.Text; namespace Indy.IL2CPU { partial class RuntimeEngine { public static uint HeapHandle = 0; - public const uint InitialHeapSize = 1024; + public const uint InitialHeapSize = 4096; public const uint MaximumHeapSize = 10 * 1024 * InitialHeapSize; // 10 megabytes public static void Heap_Initialize() { //HeapHandle = PInvokes.Kernel32_HeapCreate(0, InitialHeapSize, MaximumHeapSize);