diff --git a/source/Indy.IL2CPU.Assembler/DataMember.cs b/source/Indy.IL2CPU.Assembler/DataMember.cs index 0fdf9284a..77f4399cf 100644 --- a/source/Indy.IL2CPU.Assembler/DataMember.cs +++ b/source/Indy.IL2CPU.Assembler/DataMember.cs @@ -7,13 +7,14 @@ using Mono.Cecil; namespace Indy.IL2CPU.Assembler { public class DataMember { + public const string IllegalIdentifierChars = "&.,+$<>{}-`\'/\\ ()[]*!"; public static string GetStaticFieldName(FieldDefinition aField) { return FilterStringForIncorrectChars("static_field__" + aField.DeclaringType.FullName + "_" + aField.Name); } public static string FilterStringForIncorrectChars(string aName) { string xTempResult = aName; - foreach (char c in new char[] { '&', '.', ',', '+', '$', '<', '>', '{', '}', '-', '`', '\'', '/', '\\', ' ', '(', ')', '[', ']', '*' }) { + foreach (char c in IllegalIdentifierChars) { xTempResult = xTempResult.Replace(c, '_'); } return xTempResult; diff --git a/source/Indy.IL2CPU.Assembler/Label.cs b/source/Indy.IL2CPU.Assembler/Label.cs index b227d1f86..74d83e772 100644 --- a/source/Indy.IL2CPU.Assembler/Label.cs +++ b/source/Indy.IL2CPU.Assembler/Label.cs @@ -62,12 +62,7 @@ namespace Indy.IL2CPU.Assembler { xSB.Append("_"); } xSB.Append("__"); - string xResult = xSB.ToString().Replace('.', '_').Replace('+', '_').Replace('*', '_').Replace('[', '_').Replace(']', '_').Replace('&', '_'); - if (xResult.StartsWith(".")) { - xResult = "." + DataMember.FilterStringForIncorrectChars(xResult.Substring(1)); - } else { - xResult = DataMember.FilterStringForIncorrectChars(xResult); - } + string xResult = DataMember.FilterStringForIncorrectChars(xSB.ToString()); if (xResult.Length > 245) { xResult = mHash.ComputeHash(Encoding.Default.GetBytes(xResult)).Aggregate("_", (r, x) => r + x.ToString("X2")); } diff --git a/source/Indy.IL2CPU.IL.X86/Blt_Un.cs b/source/Indy.IL2CPU.IL.X86/Blt_Un.cs index ecae8bfe5..640b8ab7f 100644 --- a/source/Indy.IL2CPU.IL.X86/Blt_Un.cs +++ b/source/Indy.IL2CPU.IL.X86/Blt_Un.cs @@ -19,7 +19,9 @@ namespace Indy.IL2CPU.IL.X86 { string BaseLabel = CurInstructionLabel + "__"; string LabelTrue = BaseLabel + "True"; string LabelFalse = BaseLabel + "False"; + new CPUx86.Pop(CPUx86.Registers.ECX); new CPUx86.Pop(CPUx86.Registers.EAX); + new CPUx86.Pushd(CPUx86.Registers.ECX); new CPUx86.Compare(CPUx86.Registers.EAX, CPUx86.Registers.AtESP); new CPUx86.JumpIfLess(LabelTrue); new CPUx86.JumpAlways(LabelFalse); diff --git a/source/Indy.IL2CPU.IL.X86/Callvirt.cs b/source/Indy.IL2CPU.IL.X86/Callvirt.cs index a9621e194..34bd184c3 100644 --- a/source/Indy.IL2CPU.IL.X86/Callvirt.cs +++ b/source/Indy.IL2CPU.IL.X86/Callvirt.cs @@ -22,10 +22,14 @@ namespace Indy.IL2CPU.IL.X86 { if (xMethod == null) { throw new Exception("Unable to determine Method!"); } + if(xMethod.ToString() == "!0 System.Collections.Generic.List`1::get_Item(System.Int32)") { + System.Diagnostics.Debugger.Break(); + } MethodDefinition xMethodDef = Engine.GetDefinitionFromMethodReference(xMethod); mMethodDescription = CPU.Label.GenerateLabelName(xMethodDef); if (xMethodDef.IsStatic || !xMethodDef.IsVirtual) { - mNormalAddress = CPU.Label.GenerateLabelName(xMethod); + Engine.QueueMethod(xMethodDef); + mNormalAddress = CPU.Label.GenerateLabelName(xMethodDef); mHasReturn = !xMethod.ReturnType.ReturnType.FullName.StartsWith("System.Void"); return; } diff --git a/source/Indy.IL2CPU.IL.X86/Ldfld.cs b/source/Indy.IL2CPU.IL.X86/Ldfld.cs index 1eb9364d2..7a078afcf 100644 --- a/source/Indy.IL2CPU.IL.X86/Ldfld.cs +++ b/source/Indy.IL2CPU.IL.X86/Ldfld.cs @@ -8,7 +8,9 @@ namespace Indy.IL2CPU.IL.X86 { [OpCode(Code.Ldfld)] public class Ldfld: Op { private readonly TypeInformation.Field mField; - public Ldfld(TypeInformation.Field aField):base(null, null) { + private readonly TypeInformation mType; + public Ldfld(TypeInformation.Field aField) + : base(null, null) { mField = aField; } public Ldfld(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo) @@ -23,12 +25,12 @@ namespace Indy.IL2CPU.IL.X86 { xField = Engine.GetDefinitionFromFieldReference(xFieldRef); } string xFieldId = xField.ToString(); - int xStorageSize; - mField = Engine.GetTypeFieldInfo(Engine.GetDefinitionFromTypeReference(xField.DeclaringType), out xStorageSize)[xFieldId]; + mType = Engine.GetTypeInfo(Engine.GetDefinitionFromTypeReference(xField.DeclaringType)); + mField = mType.Fields[xFieldId]; } public override void DoAssemble() { - Ldfld(Assembler, mField); + Ldfld(Assembler, mType, mField); } } } \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL.X86/Ldflda.cs b/source/Indy.IL2CPU.IL.X86/Ldflda.cs index bf6d461a6..a7c72ad64 100644 --- a/source/Indy.IL2CPU.IL.X86/Ldflda.cs +++ b/source/Indy.IL2CPU.IL.X86/Ldflda.cs @@ -7,7 +7,9 @@ using CPUx86 = Indy.IL2CPU.Assembler.X86; namespace Indy.IL2CPU.IL.X86 { [OpCode(Code.Ldflda)] public class Ldflda: Op { - private readonly string mRelativeAddress; + private TypeInformation mType; + private TypeInformation.Field mField; + public Ldflda(Mono.Cecil.Cil.Instruction aInstruction, MethodInformation aMethodInfo) : base(aInstruction, aMethodInfo) { FieldDefinition xField = aInstruction.Operand as FieldDefinition; @@ -20,21 +22,13 @@ namespace Indy.IL2CPU.IL.X86 { xField = Engine.GetDefinitionFromFieldReference(xFieldRef); } string xFieldId = xField.ToString(); - TypeInformation.Field xTheField; int xStorageSize; - xTheField = Engine.GetTypeFieldInfo(Engine.GetDefinitionFromTypeReference(xField.DeclaringType), out xStorageSize)[xFieldId]; - mRelativeAddress = xTheField.RelativeAddress; - } - - public Ldflda(string aRelativeAddress):base(null, null) { - mRelativeAddress = aRelativeAddress; + mType = Engine.GetTypeInfo(Engine.GetDefinitionFromTypeReference(xField.DeclaringType)); + mField = mType.Fields[xFieldId]; } public override void DoAssemble() { - new CPUx86.Pop(CPUx86.Registers.EAX); - new CPUx86.Add(CPUx86.Registers.EAX, mRelativeAddress.Trim().Substring(1)); - new CPUx86.Pushd(CPUx86.Registers.EAX); - Assembler.StackSizes.Push(4); + Ldflda(Assembler, mType, mField); } } } \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL.X86/Op.cs b/source/Indy.IL2CPU.IL.X86/Op.cs index 3862f4d0e..26d61ed9e 100644 --- a/source/Indy.IL2CPU.IL.X86/Op.cs +++ b/source/Indy.IL2CPU.IL.X86/Op.cs @@ -28,9 +28,9 @@ namespace Indy.IL2CPU.IL.X86 { } } - public static void Ldflda(Assembler.Assembler aAssembler, TypeInformation.Field aField) { + public static void Ldflda(Assembler.Assembler aAssembler, TypeInformation aType, TypeInformation.Field aField) { int aExtraOffset = 0; - if (aField.NeedsGC && !aAssembler.InMetalMode) { + if (aType.NeedsGC && !aAssembler.InMetalMode) { aExtraOffset = 12; } new Popd(CPUx86.Registers.EAX); @@ -47,14 +47,14 @@ namespace Indy.IL2CPU.IL.X86 { new Pushd("eax"); } - public static void Ldfld(Assembler.Assembler aAssembler, TypeInformation.Field aField) { - Ldfld(aAssembler, aField, true); + public static void Ldfld(Assembler.Assembler aAssembler, TypeInformation aType, TypeInformation.Field aField) { + Ldfld(aAssembler, aType, aField, true); } - public static void Ldfld(Assembler.Assembler aAssembler, TypeInformation.Field aField, bool aAddGCCode) { + public static void Ldfld(Assembler.Assembler aAssembler, TypeInformation aType, TypeInformation.Field aField, bool aAddGCCode) { aAssembler.StackSizes.Pop(); int aExtraOffset = 0; - if (aField.NeedsGC && !aAssembler.InMetalMode) { + if (aType.NeedsGC && !aAssembler.InMetalMode) { aExtraOffset = 12; } new CPUx86.Pop("ecx"); @@ -112,17 +112,17 @@ namespace Indy.IL2CPU.IL.X86 { aAssembler.StackSizes.Push(aField.Size); } - public static void Stfld(Assembler.Assembler aAssembler, TypeInformation.Field aField) { + public static void Stfld(Assembler.Assembler aAssembler, TypeInformation aType, TypeInformation.Field aField) { aAssembler.StackSizes.Pop(); int xRoundedSize = aField.Size; if (xRoundedSize % 4 != 0) { xRoundedSize += 4 - (xRoundedSize % 4); } int aExtraOffset = 0; - if (aField.NeedsGC && !aAssembler.InMetalMode) { + if (aType.NeedsGC && !aAssembler.InMetalMode) { aExtraOffset = 12; new CPUx86.Pushd("[esp + 4]"); - Ldfld(aAssembler, aField, false); + Ldfld(aAssembler, aType, aField, false); Engine.QueueMethod(GCImplementationRefs.DecRefCountRef); new CPUx86.Call(Label.GenerateLabelName(GCImplementationRefs.DecRefCountRef)); } diff --git a/source/Indy.IL2CPU.IL.X86/Stfld.cs b/source/Indy.IL2CPU.IL.X86/Stfld.cs index 496b57dee..9b8780eb9 100644 --- a/source/Indy.IL2CPU.IL.X86/Stfld.cs +++ b/source/Indy.IL2CPU.IL.X86/Stfld.cs @@ -10,6 +10,7 @@ namespace Indy.IL2CPU.IL.X86 { [OpCode(Code.Stfld)] public class Stfld: Op { private readonly TypeInformation.Field mField; + private readonly TypeInformation mType; public Stfld(Instruction aInstruction, MethodInformation aMethodInfo) : base(aInstruction, aMethodInfo) { if (aInstruction == null) { @@ -28,16 +29,12 @@ namespace Indy.IL2CPU.IL.X86 { xField = Engine.GetDefinitionFromFieldReference(xFieldRef); } string xFieldId = xField.ToString(); - int xStorageSize; - SortedList xFieldInfo = Engine.GetTypeFieldInfo(Engine.GetDefinitionFromTypeReference(xField.DeclaringType), out xStorageSize); - if (!xFieldInfo.ContainsKey(xFieldId)) { - throw new Exception("Field not found!"); - } - mField = xFieldInfo[xFieldId]; + mType = Engine.GetTypeInfo(Engine.GetDefinitionFromTypeReference(xField.DeclaringType)); + mField = mType.Fields[xFieldId]; } public override void DoAssemble() { - Stfld(Assembler, mField); + Stfld(Assembler, mType, mField); } } } \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL.X86/X86CustomMethodImplementationProxyOp.cs b/source/Indy.IL2CPU.IL.X86/X86CustomMethodImplementationProxyOp.cs index 538f2446e..6a10e69a5 100644 --- a/source/Indy.IL2CPU.IL.X86/X86CustomMethodImplementationProxyOp.cs +++ b/source/Indy.IL2CPU.IL.X86/X86CustomMethodImplementationProxyOp.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using Indy.IL2CPU.Assembler; using CPUx86 = Indy.IL2CPU.Assembler.X86; -using Instruction=Mono.Cecil.Cil.Instruction; +using Instruction = Mono.Cecil.Cil.Instruction; namespace Indy.IL2CPU.IL.X86 { public class X86CustomMethodImplementationProxyOp: CustomMethodImplementationProxyOp { @@ -16,8 +16,8 @@ namespace Indy.IL2CPU.IL.X86 { Op.Ldarg(Assembler, MethodInfo.Arguments[aIndex]); } - protected override void Ldflda(TypeInformation.Field aField) { - Op.Ldflda(Assembler, aField); + protected override void Ldflda(TypeInformation aType, TypeInformation.Field aField) { + Op.Ldflda(Assembler, aType, aField); } protected override void CallProxiedMethod() { diff --git a/source/Indy.IL2CPU.IL/CustomMethodImplementationProxyOp.cs b/source/Indy.IL2CPU.IL/CustomMethodImplementationProxyOp.cs index 7fa335121..2eedd0b0e 100644 --- a/source/Indy.IL2CPU.IL/CustomMethodImplementationProxyOp.cs +++ b/source/Indy.IL2CPU.IL/CustomMethodImplementationProxyOp.cs @@ -16,7 +16,7 @@ namespace Indy.IL2CPU.IL { public MethodDefinition ProxiedMethod; protected abstract void Ldarg(int aIndex); - protected abstract void Ldflda(TypeInformation.Field aField); + protected abstract void Ldflda(TypeInformation aType, TypeInformation.Field aField); protected abstract void CallProxiedMethod(); protected abstract void Ldloc(int index); @@ -37,7 +37,7 @@ namespace Indy.IL2CPU.IL { } if (xFieldName != null) { Ldarg(0); - Ldflda(MethodInfo.TypeInfo.Fields[xFieldName]); + Ldflda(MethodInfo.TypeInfo, MethodInfo.TypeInfo.Fields[xFieldName]); } else { Ldarg(curIndex++); } diff --git a/source/Indy.IL2CPU.IL/TypeInformation.cs b/source/Indy.IL2CPU.IL/TypeInformation.cs index 644771f38..a5fc932d7 100644 --- a/source/Indy.IL2CPU.IL/TypeInformation.cs +++ b/source/Indy.IL2CPU.IL/TypeInformation.cs @@ -36,10 +36,12 @@ namespace Indy.IL2CPU.IL { public readonly SortedList Fields; public readonly int StorageSize; public readonly TypeDefinition TypeDef; - public TypeInformation(int aStorageSize, SortedList aFields, TypeDefinition aTypeDef) { + public readonly bool NeedsGC; + public TypeInformation(int aStorageSize, SortedList aFields, TypeDefinition aTypeDef, bool aNeedsGC) { Fields = aFields; StorageSize = aStorageSize; TypeDef = aTypeDef; + NeedsGC = aNeedsGC; } } } \ No newline at end of file diff --git a/source/Indy.IL2CPU/Engine.cs b/source/Indy.IL2CPU/Engine.cs index 3c53454bf..e53f21ea5 100644 --- a/source/Indy.IL2CPU/Engine.cs +++ b/source/Indy.IL2CPU/Engine.cs @@ -398,7 +398,9 @@ namespace Indy.IL2CPU { continue; } if (xFoundMethod.ReturnType.ReturnType.FullName != aRef.ReturnType.ReturnType.FullName) { - continue; + if (!(xFoundMethod.ReturnType.ReturnType is GenericParameter && aRef.ReturnType.ReturnType is GenericParameter)) { + continue; + } } if (xFoundMethod.Parameters.Count != aRef.Parameters.Count) { continue; @@ -406,7 +408,7 @@ namespace Indy.IL2CPU { bool xMismatch = false; for (int i = 0; i < xFoundMethod.Parameters.Count; i++) { if (xFoundMethod.Parameters[i].ParameterType.FullName != aRef.Parameters[i].ParameterType.FullName) { - if(xFoundMethod.Parameters[i].ParameterType is GenericParameter && aRef.Parameters[i].ParameterType is GenericParameter) { + if (xFoundMethod.Parameters[i].ParameterType is GenericParameter && aRef.Parameters[i].ParameterType is GenericParameter) { continue; } xMismatch = true; @@ -681,18 +683,10 @@ namespace Indy.IL2CPU { continue; } string xMethodName = Label.GenerateLabelName(xCurrentMethod); - foreach (CustomAttribute xAttrib in xCurrentMethod.CustomAttributes) { - if (xAttrib.Constructor.DeclaringType.FullName == typeof(MethodAliasAttribute).FullName) { - //xMethodName = (string)xAttrib.Fields["Name"]; - break; - } - } TypeInformation xTypeInfo = null; { if (!xCurrentMethod.IsStatic) { - int xObjectStorageSize; - SortedList xTypeFields = GetTypeFieldInfo(xCurrentMethod, out xObjectStorageSize); - xTypeInfo = new TypeInformation(xObjectStorageSize, xTypeFields, GetDefinitionFromTypeReference(xCurrentMethod.DeclaringType)); + xTypeInfo = GetTypeInfo(Engine.GetDefinitionFromTypeReference(xCurrentMethod.DeclaringType)); } } MethodInformation xMethodInfo = GetMethodInfo(xCurrentMethod, xCurrentMethod, xMethodName, xTypeInfo); @@ -762,7 +756,7 @@ namespace Indy.IL2CPU { // todo: add support for types which need different stack size mInstructionsToSkip = 0; foreach (Instruction xInstruction in xCurrentMethod.Body.Instructions) { - if(mInstructionsToSkip > 0) { + if (mInstructionsToSkip > 0) { mInstructionsToSkip--; continue; } @@ -796,6 +790,14 @@ namespace Indy.IL2CPU { } } + public static TypeInformation GetTypeInfo(TypeDefinition aType) { + TypeInformation xTypeInfo; + int xObjectStorageSize; + SortedList xTypeFields = GetTypeFieldInfo(aType, out xObjectStorageSize); + xTypeInfo = new TypeInformation(xObjectStorageSize, xTypeFields, aType, !aType.IsValueType); + return xTypeInfo; + } + public static MethodInformation GetMethodInfo(MethodDefinition aCurrentMethodForArguments, MethodDefinition aCurrentMethodForLocals, string aMethodName, TypeInformation aTypeInfo) { MethodInformation xMethodInfo; { @@ -874,7 +876,6 @@ namespace Indy.IL2CPU { private static void GetTypeFieldInfoImpl(SortedList aTypeFields, TypeDefinition aType, ref int aObjectStorageSize, bool aGCObjects) { TypeDefinition xActualType = aType; - aObjectStorageSize = 0; do { foreach (FieldDefinition xField in aType.Fields) { if (xField.IsStatic) { @@ -883,6 +884,9 @@ namespace Indy.IL2CPU { if (xField.HasConstant) { Console.WriteLine("Field is constant: " + xField.GetFullName()); } + if (xField.DeclaringType.FullName.StartsWith("System.Collections.Generic") && aGCObjects) { + //System.Diagnostics.Debugger.Break(); + } if (xField.FieldType.IsValueType && aGCObjects) { continue; }