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