diff --git a/source/Indy.IL2CPU.Assembler.X86/RepeatMovsb.cs b/source/Indy.IL2CPU.Assembler.X86/RepeatMovsb.cs index 6fae12752..a3d94fa7f 100644 --- a/source/Indy.IL2CPU.Assembler.X86/RepeatMovsb.cs +++ b/source/Indy.IL2CPU.Assembler.X86/RepeatMovsb.cs @@ -5,9 +5,9 @@ using System.Text; namespace Indy.IL2CPU.Assembler.X86 { [OpCode(0xFFFFFFFF, "rep movsb")] - public class RepeatMovsd: Instruction { + public class RepeatMovsb: Instruction { //public readonly string Destination; - public RepeatMovsd() { + public RepeatMovsb() { // Destination = aDestination; } //public override string ToString() { diff --git a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/Array_InternalCopy.cs b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/Array_InternalCopy.cs index ab75fccb8..84871fecc 100644 --- a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/Array_InternalCopy.cs +++ b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/Array_InternalCopy.cs @@ -43,7 +43,7 @@ namespace Indy.IL2CPU.IL.X86.CustomImplementations.System.Assemblers { new CPUx86.Move("edx", "[ebp + 0xC]"); new CPUx86.Multiply("edx"); new CPUx86.Move("ecx", "eax"); - new RepeatMovsd(); + new RepeatMovsb(); } } } diff --git a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/Buffer_BlockCopy.cs b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/Buffer_BlockCopy.cs index 045bcf757..abfa2d01c 100644 --- a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/Buffer_BlockCopy.cs +++ b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/Buffer_BlockCopy.cs @@ -29,7 +29,7 @@ namespace Indy.IL2CPU.IL.X86.CustomImplementations.System.Assemblers { new CPUx86.Add("edi", "eax"); new CPUx86.Move("ecx", "[ebp + 8]"); - new CPUx86.RepeatMovsd(); + new CPUx86.RepeatMovsb(); } } } \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/MulticastDelegate_Invoke.cs b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/MulticastDelegate_Invoke.cs new file mode 100644 index 000000000..b2e9b2e81 --- /dev/null +++ b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/Assemblers/MulticastDelegate_Invoke.cs @@ -0,0 +1,93 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Indy.IL2CPU.Plugs; +using CPUx86 = Indy.IL2CPU.Assembler.X86; +using CPU = Indy.IL2CPU.Assembler; + +namespace Indy.IL2CPU.IL.X86.CustomImplementations.System.Assemblers { + public class MulticastDelegate_Invoke : AssemblerMethod, INeedsMethodInfo { + /// + /// This method implements Multicast Invoke. This means that it should call all delegates + /// in the current multicast delegate. + /// The argument size is available in the $$ArgSize$$ field. This value is already rounded to 4byte boundaries + /// + /// + public override void Assemble(Assembler.Assembler aAssembler) { + if (MethodInfo == null) { + throw new Exception("This AssemblerMethod needs MethodInfo!"); + } + /* + * EAX contains the GetInvocationList() array at the index at which it was last used + * EDX contains the index at which the EAX is + * EBX contains the number of items in the array + * ECX contains the argument size + */ + new CPU.Label("____DEBUG_FOR_MULTICAST___"); + new CPUx86.Move("eax", "[" + MethodInfo.Arguments[0].VirtualAddresses[0] + "]"); + var xGetInvocationListMethod = typeof(MulticastDelegate).GetMethod("GetInvocationList"); + new CPUx86.Push("eax"); + new CPUx86.Call(CPU.Label.GenerateLabelName(xGetInvocationListMethod)); + new CPUx86.Pop("eax"); + new CPUx86.Add("eax", "8"); + new CPUx86.Move("ebx", "[eax]"); + new CPUx86.Add("eax", "8"); + new CPUx86.Move("edi", "0"); + new CPUx86.Move("ecx", "[" + MethodInfo.Arguments[0].VirtualAddresses[0] + "]"); + new CPUx86.Move("ecx", "[ecx + " + (MethodInfo.Arguments[0].TypeInfo.Fields["$$ArgSize$$"].Offset + 12) + "]"); + + new CPU.Label(".BEGIN_OF_LOOP"); + new CPUx86.Compare("edx", "ebx"); + new CPUx86.JumpIfEqual(".END_OF_INVOKE_"); + new CPUx86.Pushad(); + new CPUx86.Move("edi", "[eax]"); + new CPUx86.Move("edi", "[edi + " + (MethodInfo.Arguments[0].TypeInfo.Fields["System.Object System.Delegate._target"].Offset+12) + "]"); + new CPUx86.Compare("edi", "0"); + new CPUx86.JumpIfZero(".NO_THIS"); + new CPUx86.Push("edi"); + + new CPU.Label(".NO_THIS"); + new CPUx86.Sub("esp", "ecx"); + new CPUx86.Move("esi", + "esp"); + new CPUx86.Compare("edi", "0"); + new CPUx86.JumpIfZero(".NO_THIS2"); + new CPUx86.Add("esi", "4"); + + new CPU.Label(".NO_THIS2"); + new CPUx86.Move("edi", "[eax]"); + new CPUx86.Move("edi", "[edi + " + (MethodInfo.Arguments[0].TypeInfo.Fields["System.IntPtr System.Delegate._methodPtr"].Offset + 12) + "]"); + new CPUx86.Push("edi"); + new CPUx86.Move("edi", "esp"); + new CPUx86.Add("edi", "4"); + // substract twice + new CPUx86.Add("esi", + "ecx"); + new CPUx86.Add("esi", + "ecx"); + new CPUx86.Add("esi", + "40"); // 32 for the Pushad, 16 for the method header + new CPUx86.RepeatMovsb(); + new CPUx86.Pop("edi"); + new CPUx86.Call("edi"); + new CPUx86.Popad(); + new CPUx86.Add("edx", + "1"); + new CPUx86.Add("eax", "4"); + new CPUx86.Jump(".BEGIN_OF_LOOP"); + + new CPU.Label(".END_OF_INVOKE_"); + //MethodInfo.Arguments[0]. +// new CPUx86.Move("ebx", "[eax + " + (MethodInfo.Arguments[0].TypeInfo.Fields["$$ArgSize$$"].Offset + 12) + "]"); + + //new CPUx86.Move("eax", CPUx86.Registers. + } + + public MethodInformation MethodInfo + { + get; + set; + } + } +} \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/DelegateImpl.cs b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/DelegateImpl.cs index 916338f3c..48c25556d 100644 --- a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/DelegateImpl.cs +++ b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/DelegateImpl.cs @@ -9,17 +9,21 @@ namespace Indy.IL2CPU.IL.X86.CustomImplementations.System { //[PlugField(FieldId = "$$Method$$", FieldType = typeof(object))] //[PlugField(FieldId = "$$Object$$", FieldType = typeof(object))] public static class DelegateImpl { - //[PlugMethod(Signature = "System_IntPtr___System_Delegate_GetInvokeMethod____")] - //public static unsafe uint GetInvokeMethod(uint* aThis, [FieldAccess(Name = "$$Method$$")]uint aInvokeMethod) { - // //return *(aThis + 2); - // return aInvokeMethod; - //} - //public static void DoSomethingWithDelegate(Delegate aDelegate) { - // // fake method to have the type Delegate referenced by the assembly - // object o = aDelegate.Target; - // object o2 = o; + [PlugMethod(Signature = "System_MulticastDelegate__System_Delegate_InternalAllocLike_System_Delegate_")] + public unsafe static uint InternalAllocLike(uint* aDelegate) { + uint xNeededSize = 1024; // 24 is needed fields for Multicast Delegate + xNeededSize += 12; + uint xResultAddr = GCImplementation.AllocNewObject(xNeededSize); + byte* xResult = (byte*)xResultAddr; + byte* xDelegateAsByte = (byte*)aDelegate; + for (int i = 0; i < 1024; i++) + { + xResult[i] = xDelegateAsByte[i]; + } + return xResultAddr; + } - //} + public static IntPtr GetInvokeMethod() { return IntPtr.Zero; } } } \ No newline at end of file diff --git a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/MulticastDelegateImpl.cs b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/MulticastDelegateImpl.cs index 9c2645823..2b8567e33 100644 --- a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/MulticastDelegateImpl.cs +++ b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/MulticastDelegateImpl.cs @@ -2,9 +2,16 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using Indy.IL2CPU.Plugs; namespace Indy.IL2CPU.IL.X86.CustomImplementations.System { - public static unsafe class MulticastDelegateImpl { - + [Plug(Target=typeof(MulticastDelegate))] + [PlugField(FieldType=typeof(int), FieldId="$$ArgSize$$")] + public class MulticastDelegateImpl { + [PlugMethod(MethodAssembler=typeof(Assemblers.MulticastDelegate_Invoke))] + public static void InvokeMulticast(MulticastDelegate aThis) + { + throw new Exception("This method should be implemented using a MethodAssembler"); + } } } 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 5c3621351..7086df128 100644 --- a/source/Indy.IL2CPU.IL.X86/Indy.IL2CPU.IL.X86.csproj +++ b/source/Indy.IL2CPU.IL.X86/Indy.IL2CPU.IL.X86.csproj @@ -121,6 +121,7 @@ + diff --git a/source/Indy.IL2CPU.IL.X86/Isinst.cs b/source/Indy.IL2CPU.IL.X86/Isinst.cs index 914070b5e..64b7743e5 100644 --- a/source/Indy.IL2CPU.IL.X86/Isinst.cs +++ b/source/Indy.IL2CPU.IL.X86/Isinst.cs @@ -31,11 +31,11 @@ namespace Indy.IL2CPU.IL.X86 { public override void DoAssemble() { string mReturnNullLabel = mThisLabel + "_ReturnNull"; - new CPUx86.Move(CPUx86.Registers.EAX, CPUx86.Registers.AtESP); + new CPUx86.Move(CPUx86.Registers.EAX, "[esp]"); new CPUx86.Compare(CPUx86.Registers.EAX, "0"); new CPUx86.JumpIfZero(mReturnNullLabel); new CPUx86.Pushd(CPUx86.Registers.AtEAX); - new CPUx86.Pushd("0" + mTypeId ); + new CPUx86.Pushd("0x" + mTypeId.ToString("X")); Assembler.StackContents.Push(new StackContent(4, typeof(object))); Assembler.StackContents.Push(new StackContent(4, typeof(object))); MethodBase xMethodIsInstance = Engine.GetMethodBase(typeof(VTablesImpl), "IsInstance", "System.Int32", "System.Int32"); diff --git a/source/Indy.IL2CPU.IL.X86/X86OpCodeMap.cs b/source/Indy.IL2CPU.IL.X86/X86OpCodeMap.cs index b06ef0215..3fa75cf83 100644 --- a/source/Indy.IL2CPU.IL.X86/X86OpCodeMap.cs +++ b/source/Indy.IL2CPU.IL.X86/X86OpCodeMap.cs @@ -6,6 +6,7 @@ using System.Reflection; using CPU = Indy.IL2CPU.Assembler; using CPUx86 = Indy.IL2CPU.Assembler.X86; using Indy.IL2CPU.Assembler; +using Indy.IL2CPU.IL.X86.CustomImplementations.System; namespace Indy.IL2CPU.IL.X86 { public class X86OpCodeMap: OpCodeMap { @@ -51,10 +52,11 @@ namespace Indy.IL2CPU.IL.X86 { public override bool HasCustomAssembleImplementation(MethodInformation aMethodInfo, bool aInMetalMode) { switch (aMethodInfo.LabelName) { - case "System_Object___System_Threading_Interlocked_CompareExchange___System_Object___System_Object__System_Object___": { + 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___": { + case "System_Int32__System_Threading_Interlocked_CompareExchange_System_Int32___System_Int32__System_Int32_": { return true; } case "System_String___System_String_FastAllocateString___System_Int32___": { @@ -66,9 +68,10 @@ namespace Indy.IL2CPU.IL.X86 { case "System_IntPtr___System_Delegate_GetInvokeMethod____": { return true; } - //case "System_IntPtr___System_Delegate_GetMulticastInvoke____": { - // return true; - // } + case "System_IntPtr__System_Delegate_GetMulticastInvoke__": + { + return true; + } case "System_MulticastDelegate___System_Delegate_InternalAllocLike___System_Delegate___": { return true; } @@ -87,21 +90,27 @@ namespace Indy.IL2CPU.IL.X86 { } } + private static readonly MethodBase InvokeMulticastRef = typeof(MulticastDelegateImpl).GetMethod("InvokeMulticast", BindingFlags.Public | BindingFlags.Static); + public override void DoCustomAssembleImplementation(bool aInMetalMode, Indy.IL2CPU.Assembler.Assembler aAssembler, MethodInformation aMethodInfo) { switch (aMethodInfo.LabelName) { - case "System_Object___System_Threading_Interlocked_CompareExchange___System_Object___System_Object__System_Object___": { + 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___": { + case "System_Int32__System_Threading_Interlocked_CompareExchange_System_Int32___System_Int32__System_Int32_": { Assemble_System_Threading_Interlocked_CompareExchange__Object(aAssembler, aMethodInfo); break; } - //case "System_IntPtr___System_Delegate_GetMulticastInvoke____": { - // Engine.QueueMethod(CustomImplementations.System.EventHandlerImplRefs.MulticastInvokeRef); - // new CPUx86.Push(CPU.Label.GenerateLabelName(CustomImplementations.System.EventHandlerImplRefs.MulticastInvokeRef)); - // break; - // } + case "System_IntPtr__System_Delegate_GetMulticastInvoke__": + { + //IL.X86.Op.Ldarg(aAssembler, aMethodInfo.Arguments[0]); + + Engine.QueueMethod(InvokeMulticastRef); + new CPUx86.Push(Label.GenerateLabelName(InvokeMulticastRef)); + break; + } case "System_MulticastDelegate___System_Delegate_InternalAllocLike___System_Delegate___": { break; } @@ -118,26 +127,45 @@ namespace Indy.IL2CPU.IL.X86 { xOp.Assembler = aAssembler; xOp.ProxiedMethod = CustomImplementations.System.EventHandlerImplRefs.CtorRef; xOp.Assemble(); + Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0]); + // + var xInvokeMethod = aMethodInfo.TypeInfo.TypeDef.GetMethod("Invoke"); + var xDelegateMethodInfo = Engine.GetMethodInfo(xInvokeMethod, xInvokeMethod, xInvokeMethod.Name, aMethodInfo.TypeInfo, aMethodInfo.DebugMode); + int xArgSize = (from item in xDelegateMethodInfo.Arguments + select item.Size + (item.Size % 4 == 0 + ? 0 + : (4 - (item.Size % 4)))).Take(xDelegateMethodInfo.Arguments.Length).Sum(); + new CPUx86.Push((xArgSize-4).ToString()); + new CPU.Label(".SetArgSize"); + aAssembler.StackContents.Push(new StackContent(4)); + Stfld.Stfld(aAssembler, aMethodInfo.TypeInfo, aMethodInfo.TypeInfo.Fields["$$ArgSize$$"]); break; } - if (aMethodInfo.Method.Name == "Invoke") { + if (aMethodInfo.Method.Name == "Invoke") { // param 0 is instance of eventhandler // param 1 is sender // param 2 is eventargs new Label(".LoadTargetObject"); Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0]); - Ldarg.Ldfld(aAssembler, aMethodInfo.TypeInfo, "System.Object System.Delegate._target"); - new Label(".LoadMethodParams"); - for (int i = 1; i < aMethodInfo.Arguments.Length; i++) { - Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[i]); - } - new Label(".LoadMethodPointer"); - Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0]); - Ldarg.Ldfld(aAssembler, aMethodInfo.TypeInfo, "System.IntPtr System.Delegate._methodPtr"); - new CPUx86.Pop("eax"); - new CPUx86.Call(CPUx86.Registers.EAX); - new CPUx86.Add("esp", - "4"); + //Ldarg.Ldfld(aAssembler, aMethodInfo.TypeInfo, "System.Object System.Delegate._target"); + //new Label(".LoadMethodParams"); + //for (int i = 1; i < aMethodInfo.Arguments.Length; i++) { + // Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[i]); + //} + //new Label(".LoadMethodPointer"); + //Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0]); + //Ldarg.Ldfld(aAssembler, aMethodInfo.TypeInfo, "System.IntPtr System.Delegate._methodPtr"); + //new CPUx86.Pop("eax"); + //new CPUx86.Call(CPUx86.Registers.EAX); + //new CPUx86.Add("esp", + // "4"); + Engine.QueueMethod(InvokeMulticastRef); + new CPUx86.Call(Label.GenerateLabelName(InvokeMulticastRef)); + var xGetInvocationListMethod = typeof(MulticastDelegate).GetMethod("GetInvocationList"); + Engine.QueueMethod(xGetInvocationListMethod); + xGetInvocationListMethod = typeof(Delegate).GetMethod("GetInvocationList"); + Engine.QueueMethod(xGetInvocationListMethod); + // new CPUx86.Pop(CPUx86.Registers.EAX); //new CPUx86.Move("esp", "ebp"); break; diff --git a/source/Indy.IL2CPU.IL/INeedsMethodInfo.cs b/source/Indy.IL2CPU.IL/INeedsMethodInfo.cs new file mode 100644 index 000000000..d4012fb2c --- /dev/null +++ b/source/Indy.IL2CPU.IL/INeedsMethodInfo.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Indy.IL2CPU.IL { + public interface INeedsMethodInfo { + MethodInformation MethodInfo { + set; + } + } +} \ 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 0c061605e..449218bda 100644 --- a/source/Indy.IL2CPU.IL/Indy.IL2CPU.IL.csproj +++ b/source/Indy.IL2CPU.IL/Indy.IL2CPU.IL.csproj @@ -64,6 +64,7 @@ + diff --git a/source/Indy.IL2CPU.IL/MethodInformation.cs b/source/Indy.IL2CPU.IL/MethodInformation.cs index 068cf8fa8..6b509dfd3 100644 --- a/source/Indy.IL2CPU.IL/MethodInformation.cs +++ b/source/Indy.IL2CPU.IL/MethodInformation.cs @@ -44,6 +44,7 @@ namespace Indy.IL2CPU.IL { int aOffset, KindEnum aKind, bool aIsReferenceType, + TypeInformation aTypeInfo, Type aArgumentType) { mSize = aSize; mVirtualAddresses = new string[mSize / 4]; @@ -51,6 +52,7 @@ namespace Indy.IL2CPU.IL { mArgumentType = aArgumentType; mIsReferenceType = aIsReferenceType; mOffset = -1; + TypeInfo = aTypeInfo; Offset = aOffset; } @@ -124,6 +126,8 @@ namespace Indy.IL2CPU.IL { mArgumentType = value; } } + + public readonly TypeInformation TypeInfo; } public MethodInformation(string aLabelName, diff --git a/source/Indy.IL2CPU.IL/OpCodeMap.cs b/source/Indy.IL2CPU.IL/OpCodeMap.cs index 78034be71..cba8ac29a 100644 --- a/source/Indy.IL2CPU.IL/OpCodeMap.cs +++ b/source/Indy.IL2CPU.IL/OpCodeMap.cs @@ -90,27 +90,18 @@ namespace Indy.IL2CPU.IL { } public virtual void DoCustomAssembleImplementation(bool aInMetalMode, Assembler.Assembler aAssembler, MethodInformation aMethodInfo) { - PlugMethodAttribute xAttrib = (PlugMethodAttribute)aMethodInfo.Method.GetCustomAttributes(typeof(PlugMethodAttribute), true).Cast().FirstOrDefault(); + PlugMethodAttribute xAttrib = aMethodInfo.Method.GetCustomAttributes(typeof(PlugMethodAttribute), true).Cast().FirstOrDefault(); if (xAttrib != null) { Type xAssemblerType = xAttrib.MethodAssembler; if (xAssemblerType != null) { - AssemblerMethod xAssembler = (AssemblerMethod)Activator.CreateInstance(xAssemblerType); + var xAssembler = (AssemblerMethod)Activator.CreateInstance(xAssemblerType); + var xNeedsMethodInfo = xAssembler as INeedsMethodInfo; + if (xNeedsMethodInfo != null) { + xNeedsMethodInfo.MethodInfo = aMethodInfo; } xAssembler.Assemble(aAssembler); } } - } - - private static Type GetType(Assembly aAssembly, string aType) { - string xActualTypeName = aType; - if (xActualTypeName.Contains("<") && xActualTypeName.Contains(">")) { - xActualTypeName = xActualTypeName.Substring(0, xActualTypeName.IndexOf("<")); - } - Type xResult = aAssembly.GetType(aType, false); - if (xResult != null) { - return xResult; - } - throw new Exception("Type '" + aType + "' not found in assembly '" + aAssembly + "'!"); - } + } public virtual void PostProcess(Assembler.Assembler aAssembler) { } diff --git a/source/Indy.IL2CPU/Engine.cs b/source/Indy.IL2CPU/Engine.cs index 995e82d49..2e2da9ede 100644 --- a/source/Indy.IL2CPU/Engine.cs +++ b/source/Indy.IL2CPU/Engine.cs @@ -578,8 +578,7 @@ namespace Indy.IL2CPU { if (xTD.BaseType == null) { continue; } - if (xMethod.IsVirtual && !xMethod.IsConstructor && - !xMethod.IsFinal) { + if (xMethod.IsVirtual && !xMethod.IsConstructor) { Type xCurrentInspectedType = xTD.BaseType; ParameterInfo[] xParams = xMethod.GetParameters(); Type[] xMethodParams = new Type[xParams.Length]; @@ -639,8 +638,7 @@ namespace Indy.IL2CPU { break; } aCurrentInspectedType = aCurrentInspectedType.BaseType; - MethodBase xFoundMethod = aCurrentInspectedType.GetMethod(aMethod.Name, - aMethodParams); + MethodBase xFoundMethod = aCurrentInspectedType.GetMethod(aMethod.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, Type.DefaultBinder, aMethodParams, new ParameterModifier[0]); ParameterInfo[] xParams = xFoundMethod.GetParameters(); bool xContinue = true; for (int i = 0; i < xParams.Length; i++) { @@ -654,7 +652,12 @@ namespace Indy.IL2CPU { continue; } if (xFoundMethod != null) { - if (xFoundMethod.IsVirtual == aMethod.IsVirtual && xFoundMethod.IsPrivate == false && xFoundMethod.IsPublic == aMethod.IsPublic && xFoundMethod.IsFamily == aMethod.IsFamily && xFoundMethod.IsFamilyAndAssembly == aMethod.IsFamilyAndAssembly && xFoundMethod.IsFamilyOrAssembly == aMethod.IsFamilyOrAssembly && + if (xFoundMethod.IsVirtual == aMethod.IsVirtual && + xFoundMethod.IsPrivate == false && + xFoundMethod.IsPublic == aMethod.IsPublic && + xFoundMethod.IsFamily == aMethod.IsFamily && + xFoundMethod.IsFamilyAndAssembly == aMethod.IsFamilyAndAssembly && + xFoundMethod.IsFamilyOrAssembly == aMethod.IsFamilyOrAssembly && xFoundMethod.IsFinal == false) { xBaseMethod = xFoundMethod; } @@ -1445,6 +1448,7 @@ namespace Indy.IL2CPU { xCurOffset, xKind, !xParamDef.ParameterType.IsValueType, + GetTypeInfo(xParamDef.ParameterType), xParamDef.ParameterType); xCurOffset += xArgSize; } @@ -1454,6 +1458,7 @@ namespace Indy.IL2CPU { xCurOffset, MethodInformation.Argument.KindEnum.In, !aCurrentMethodForArguments.DeclaringType.IsValueType, + GetTypeInfo(aCurrentMethodForArguments.DeclaringType), aCurrentMethodForArguments.DeclaringType); } else { ParameterInfo[] xParameters = aCurrentMethodForArguments.GetParameters(); @@ -1477,6 +1482,7 @@ namespace Indy.IL2CPU { xCurOffset, xKind, !xParamDef.ParameterType.IsValueType, + GetTypeInfo(xParamDef.ParameterType), xParamDef.ParameterType); xCurOffset += xArgSize; } @@ -1509,7 +1515,7 @@ namespace Indy.IL2CPU { out aObjectStorageSize); } - private static void GetTypeFieldInfoImpl(Dictionary aTypeFields, + private static void GetTypeFieldInfoImpl(List> aTypeFields, Type aType, ref int aObjectStorageSize) { Type xActualType = aType; @@ -1522,7 +1528,8 @@ namespace Indy.IL2CPU { item.Value); } } - foreach (FieldInfo xField in aType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { + foreach (FieldInfo xField in aType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)) + { if (xField.IsStatic) { continue; } @@ -1557,9 +1564,9 @@ namespace Indy.IL2CPU { xFieldSize = GetFieldStorageSize(xFieldType); } //} - if (aTypeFields.ContainsKey(xFieldId)) { - continue; - } + if ((from item in aTypeFields + where item.Key == xFieldId + select item).Count() > 0) { continue; } int xOffset = aObjectStorageSize; FieldOffsetAttribute xOffsetAttrib = xField.GetCustomAttributes(typeof(FieldOffsetAttribute), true).FirstOrDefault() as FieldOffsetAttribute; @@ -1569,13 +1576,13 @@ namespace Indy.IL2CPU { aObjectStorageSize += xFieldSize; xOffset = -1; } - aTypeFields.Add(xField.GetFullName(), + aTypeFields.Insert(0, new KeyValuePair(xField.GetFullName(), new TypeInformation.Field(xFieldSize, xFieldType.IsClass && !xFieldType.IsValueType, xFieldType, (xPlugFieldAttr != null && xPlugFieldAttr.IsExternalValue)) { Offset = xOffset - }); + })); } while (xCurrentPlugFieldList.Count > 0) { var xItem = xCurrentPlugFieldList.Values.First(); @@ -1594,11 +1601,11 @@ namespace Indy.IL2CPU { } int xOffset = aObjectStorageSize; aObjectStorageSize += xFieldSize; - aTypeFields.Add(xItem.FieldId, + aTypeFields.Insert(0, new KeyValuePair(xItem.FieldId, new TypeInformation.Field(xFieldSize, xFieldType.IsClass && !xFieldType.IsValueType, xFieldType, - xItem.IsExternalValue)); + xItem.IsExternalValue))); } if (aType.FullName != "System.Object" && aType.BaseType != null) { @@ -1611,7 +1618,7 @@ namespace Indy.IL2CPU { public static Dictionary GetTypeFieldInfo(Type aType, out int aObjectStorageSize) { - Dictionary xTypeFields = new Dictionary(); + var xTypeFields = new List>(); aObjectStorageSize = 0; GetTypeFieldInfoImpl(xTypeFields, aType, @@ -1619,8 +1626,8 @@ namespace Indy.IL2CPU { if (aType.IsExplicitLayout) { var xStructLayout = aType.StructLayoutAttribute; if (xStructLayout.Size == 0) { - aObjectStorageSize = (from item in xTypeFields.Values - let xSize = item.Offset + item.Size + aObjectStorageSize = (from item in xTypeFields + let xSize = item.Value.Offset + item.Value.Size orderby xSize select xSize).FirstOrDefault(); } else { @@ -1629,10 +1636,9 @@ namespace Indy.IL2CPU { } int xOffset = 0; Dictionary xResult = new Dictionary(); - foreach (var item in xTypeFields.Reverse()) { + foreach (var item in xTypeFields) { var xItem = item.Value; - if (item.Value.Offset == - -1) { + if (item.Value.Offset == -1) { xItem.Offset = xOffset; xOffset += xItem.Size; } @@ -1700,6 +1706,7 @@ namespace Indy.IL2CPU { if (mCurrent == null) { throw new Exception("ERROR: No Current Engine found!"); } + if (aMethod == null) { System.Diagnostics.Debugger.Break(); } if (!aMethod.IsStatic) { RegisterType(aMethod.DeclaringType); } @@ -1739,7 +1746,11 @@ namespace Indy.IL2CPU { aType.GetArrayRank() != 1) { throw new Exception("Multidimensional arrays are not yet supported!"); } - aType = aType.GetElementType(); + if (aType.IsArray) { aType = typeof(Array); } + else + { + aType = aType.GetElementType(); + } } Type xFoundItem = mCurrent.mTypes.FirstOrDefault(x => x.FullName.Equals(aType.FullName)); if (xFoundItem == null) { diff --git a/source/MatthijsTest/Program.cs b/source/MatthijsTest/Program.cs index 5642c0be2..47b4585db 100644 --- a/source/MatthijsTest/Program.cs +++ b/source/MatthijsTest/Program.cs @@ -20,33 +20,29 @@ namespace MatthijsTest #endregion - public static void GetResumeAndResume(ref uint aSuspend) - { - aSuspend = 0; - throw new NotImplementedException(); - } - public static int GetValue() { - return 5; } + public static void Init() { Console.Clear(); Console.WriteLine("Kernel started!"); - int xTest = 987; - IntPtr xPtr = (IntPtr)xTest; - xTest = (int)xPtr; - Console.Write("Value: "); - Console.Write(xTest.ToString()); - Console.WriteLine(); + Console.WriteLine("Starting doing tests"); + DoIt(); + Console.WriteLine("Done"); } - } - public interface ITest { - void DoMessage();} + public class TestType { public void DoIt(object sender, EventArgs e) { Console.WriteLine("Writeline from an instance method!"); } } - public class TestImpl : ITest { - public void DoMessage() { - Console.WriteLine("Message from interface member"); + public static void DoIt() + { + EventHandler xEvent = WriteMessage1; + var xType = new TestType(); + xEvent += xType.DoIt; + xEvent += WriteMessage2; + xEvent(null, null); } + + public static void WriteMessage1(object sender, EventArgs e) { Console.WriteLine("Message 1"); } + public static void WriteMessage2(object sender, EventArgs e) { Console.WriteLine("Message 2"); } } -} \ No newline at end of file +}