From 8cab5bc18c59a3e10fd4c39e9febb83bfbcdd883 Mon Sep 17 00:00:00 2001 From: mterwoord_cp <7cd3fd84a0151ea055c2f79e4d2eef9576fe9afesxUZAwxD> Date: Fri, 9 May 2008 14:48:15 +0000 Subject: [PATCH] Enumerations for now. on arrays they work, List not yet --- source/Indy.IL2CPU.Assembler.X86/Assembler.cs | 4 +- .../CustomImplementations/System/ArrayImpl.cs | 16 +- .../Indy.IL2CPU.IL/InitVmtImplementationOp.cs | 51 ++++-- source/Indy.IL2CPU.IL/OpCodeMap.cs | 9 +- source/Indy.IL2CPU/Engine.cs | 162 ++++++++++++------ source/Indy.IL2CPU/GCImplementation.cs | 2 + source/MatthijsTest/Program.cs | 23 ++- 7 files changed, 180 insertions(+), 87 deletions(-) diff --git a/source/Indy.IL2CPU.Assembler.X86/Assembler.cs b/source/Indy.IL2CPU.Assembler.X86/Assembler.cs index 4a6c2cc8d..60ccfd9d0 100644 --- a/source/Indy.IL2CPU.Assembler.X86/Assembler.cs +++ b/source/Indy.IL2CPU.Assembler.X86/Assembler.cs @@ -7,7 +7,7 @@ using System.Text; namespace Indy.IL2CPU.Assembler.X86 { public class Assembler : Indy.IL2CPU.Assembler.Assembler { - public const string BreakMethodName = "_CODE_REQUESTED_BREAK_"; + public const string BreakMethodName = "DebugStub_Break"; protected byte mComNumber = 0; protected UInt16[] mComPortAddresses = { 0x3F8, 0x2F8, 0x3E8, 0x2E8 }; @@ -79,8 +79,6 @@ namespace Indy.IL2CPU.Assembler.X86 { aOutputWriter.WriteLine(" hlt"); aOutputWriter.WriteLine(" jmp .loop"); aOutputWriter.WriteLine(" "); - aOutputWriter.WriteLine(" " + BreakMethodName + ":"); - aOutputWriter.WriteLine(" ret"); if (mComNumber > 0) { var xStub = new DebugStub(); xStub.Main(mComPortAddresses[mComNumber - 1]); diff --git a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/ArrayImpl.cs b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/ArrayImpl.cs index 50e3936df..8502c927f 100644 --- a/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/ArrayImpl.cs +++ b/source/Indy.IL2CPU.IL.X86/CustomImplementations/System/ArrayImpl.cs @@ -18,6 +18,16 @@ namespace Indy.IL2CPU.IL.X86.CustomImplementations.System { } } + public static int GetUpperBound(Array aThis, int aDimension) { + return GetLength(aThis, aDimension) - 1; + } + + public static int GetLength(Array aThis, int aDimension) + { + if (aDimension != 0) { throw new NotSupportedException("Multidimensional array's are not yet supported!"); } + return aThis.Length; + } + [PlugMethod(Signature = "System_Boolean__System_Array_TrySZBinarySearch_System_Array__System_Int32__System_Int32__System_Object__System_Int32__")] public static unsafe bool TrySZBinarySearch(uint* aArray, uint sourceIndex, uint count, uint value, out uint retVal) { @@ -68,10 +78,10 @@ namespace Indy.IL2CPU.IL.X86.CustomImplementations.System { if (aDimension != 0) { throw new NotSupportedException("Multidimensional arrays not supported yet!"); } - return get_Length(aThis); + return 0; } - [PlugMethod(Signature = "System_Object__System_Array_GetValue_System_Int32_")] + [PlugMethod(Signature = "System_Object__System_Array_GetValue_System_Int32_")] public static unsafe uint GetValue(uint* aThis, int aIndex) { aThis += 3; uint xElementSize = *aThis; @@ -90,6 +100,8 @@ namespace Indy.IL2CPU.IL.X86.CustomImplementations.System { throw new NotSupportedException("GetValue not supported in this situation!"); } + public static unsafe object GetValue(Array aThis, params int[] aIndices) { throw new NotImplementedException("Multidimensional arrays not supported yet!"); } + [PlugMethod(Signature = "System_Void__System_Array_SetValue_System_Object__System_Int32_")] public static unsafe void SetValue(uint* aThis, uint aValue, int aIndex) { aThis += 3; diff --git a/source/Indy.IL2CPU.IL/InitVmtImplementationOp.cs b/source/Indy.IL2CPU.IL/InitVmtImplementationOp.cs index 12ecf6fbe..9e9c64a44 100644 --- a/source/Indy.IL2CPU.IL/InitVmtImplementationOp.cs +++ b/source/Indy.IL2CPU.IL/InitVmtImplementationOp.cs @@ -1,4 +1,4 @@ -//#define MTW_DEBUG +#define MTW_DEBUG using System; using System.Collections.Generic; using System.Linq; @@ -8,6 +8,15 @@ using System.Xml; using System.Reflection; namespace Indy.IL2CPU.IL { + public class MethodBaseComparer : IComparer + { + #region IComparer Members + public int Compare(MethodBase x, MethodBase y) + { + return x.GetFullName().CompareTo(y.GetFullName()); + } + #endregion + } public abstract class InitVmtImplementationOp: Op { public delegate int GetMethodIdentifierEventHandler(MethodBase aMethod); public InitVmtImplementationOp(ILReader aReader, MethodInformation aMethodInfo) @@ -80,17 +89,27 @@ namespace Indy.IL2CPU.IL { xDebug.WriteAttributeString("Id", i.ToString("X")); #endif Type xType = mTypes[i]; - List xEmittedMethods = new List(); + if (xType.IsInterface) { continue; } + // value contains true if the method is an interface method definition + SortedList xEmittedMethods = new SortedList(new MethodBaseComparer()); foreach (MethodBase xMethod in xType.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { if (Methods.Contains(xMethod) && !xMethod.IsAbstract) { - xEmittedMethods.Add(xMethod); + xEmittedMethods.Add(xMethod, false); } } foreach (MethodBase xCtor in xType.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { if (Methods.Contains(xCtor) && !xCtor.IsAbstract) { - xEmittedMethods.Add(xCtor); + xEmittedMethods.Add(xCtor, false); } } + foreach (var xIntf in xType.GetInterfaces()) { + var xIntfMap = xType.GetInterfaceMap(xIntf); + for (int xI = 0; xI < xIntfMap.InterfaceMethods.Length; xI++) { + if (Methods.Contains(xIntfMap.InterfaceMethods[xI])) { + xEmittedMethods.Add(xIntfMap.InterfaceMethods[xI], true); + } + } + } Pushd("0" + i.ToString("X") + "h"); int? xBaseIndex = null; if (xType.BaseType == null) { @@ -103,7 +122,7 @@ namespace Indy.IL2CPU.IL { } } } - if (xBaseIndex == null) { + if (xBaseIndex == null) { throw new Exception("Base type not found!"); } #if MTW_DEBUG @@ -139,26 +158,22 @@ namespace Indy.IL2CPU.IL { //Pushd("0"); Call(SetTypeInfoRef); for (int j = 0; j < xEmittedMethods.Count; j++) { - - - MethodBase xMethod = xEmittedMethods[j]; + MethodBase xMethod = xEmittedMethods.Keys[j]; + var xMethodId =GetMethodIdentifier(xMethod); + if (xEmittedMethods.Values[j]) { + var xIntfMap = xType.GetInterfaceMap(xMethod.DeclaringType); + xMethod = xIntfMap.TargetMethods[Array.IndexOf(xIntfMap.InterfaceMethods, xMethod)]; + } #if MTW_DEBUG xDebug.WriteStartElement("Method"); - xDebug.WriteAttributeString("Id", GetMethodIdentifier(xMethod).ToString("X")); + xDebug.WriteAttributeString("Id", xMethodId.ToString("X")); xDebug.WriteAttributeString("Name", xMethod.GetFullName()); xDebug.WriteEndElement(); #endif - if (xMethod.DeclaringType.FullName == "System.Object" && xMethod.Name == "Equals" && xMethod.GetParameters().Length == 1 && xMethod.GetParameters()[0].ParameterType.FullName == "System.Object") { - System.Diagnostics.Debugger.Break(); - } Pushd("0" + i.ToString("X") + "h"); Pushd("0" + j.ToString("X") + "h"); - ParameterInfo[] xParams = xMethod.GetParameters(); - Type[] xMethodParams = new Type[xParams.Length]; - for (int k = 0; k < xParams.Length; k++) { - xMethodParams[k] = xParams[k].ParameterType; - } - Pushd("0" + GetMethodIdentifier(xMethod).ToString("X") + "h"); + + Pushd("0" + xMethodId.ToString("X") + "h"); Pushd(Label.GenerateLabelName(xMethod)); //xDataValue = Encoding.ASCII.GetBytes(GetFullName(xMethod)).Aggregate("", (b, x) => b + x + ",") + "0"; //xDataName = "____SYSTEM____METHOD___" + DataMember.FilterStringForIncorrectChars(GetFullName(xMethod)); diff --git a/source/Indy.IL2CPU.IL/OpCodeMap.cs b/source/Indy.IL2CPU.IL/OpCodeMap.cs index fa96b24f2..78034be71 100644 --- a/source/Indy.IL2CPU.IL/OpCodeMap.cs +++ b/source/Indy.IL2CPU.IL/OpCodeMap.cs @@ -70,10 +70,11 @@ namespace Indy.IL2CPU.IL { } public virtual IList GetPlugAssemblies() { - List xResult = new List(); - xResult.Add(typeof(OpCodeMap).Assembly); - xResult.Add(Assembly.Load("Indy.IL2CPU")); - return xResult; + var xResult = new List { + typeof(OpCodeMap).Assembly, + Assembly.Load("Indy.IL2CPU") + }; + return xResult; } public MethodBase GetCustomMethodImplementation(string aOrigMethodName, bool aInMetalMode) { diff --git a/source/Indy.IL2CPU/Engine.cs b/source/Indy.IL2CPU/Engine.cs index 71476dbd0..fae020ead 100644 --- a/source/Indy.IL2CPU/Engine.cs +++ b/source/Indy.IL2CPU/Engine.cs @@ -473,61 +473,102 @@ namespace Indy.IL2CPU { xOp.Assemble(); } - private void ScanForMethodsToIncludeForVMT() { - List xCheckedTypes = new List(); - foreach (MethodBase xMethod in mMethods.Keys) { - if (xMethod.IsStatic) { - continue; - } - Type xCurrentType = xMethod.DeclaringType; - if (!xCheckedTypes.Contains(xCurrentType, mTypesEqualityComparer)) { - xCheckedTypes.Add(xCurrentType); - } - } - foreach (Type xType in mTypes) { - if (!xCheckedTypes.Contains(xType, mTypesEqualityComparer)) { - xCheckedTypes.Add(xType); - } - } - for (int i = 0; i < xCheckedTypes.Count; i++) { - Type xCurrentType = xCheckedTypes[i]; - while (xCurrentType != null) { - if (!xCheckedTypes.Contains(xCurrentType, mTypesEqualityComparer)) { - xCheckedTypes.Add(xCurrentType); - } - if (xCurrentType.FullName == "System.Object") { - break; - } - if (xCurrentType.BaseType == null) { - break; - } - xCurrentType = xCurrentType.BaseType; - } - } - foreach (Type xTD in xCheckedTypes) { - foreach (MethodBase xMethod in xTD.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)) { - if (!xMethod.IsStatic) { - if (xTD.BaseType == null) { - continue; - } - if (xMethod.IsVirtual && !xMethod.IsConstructor && !xMethod.IsFinal) { - Type xCurrentInspectedType = xTD.BaseType; - ParameterInfo[] xParams = xMethod.GetParameters(); - Type[] xMethodParams = new Type[xParams.Length]; - for (int i = 0; i < xParams.Length; i++) { - xMethodParams[i] = xParams[i].ParameterType; - } - MethodBase xBaseMethod = GetUltimateBaseMethod(xMethod, xMethodParams, xTD); - if (xBaseMethod != null && xBaseMethod != xMethod) { - if (mMethods.ContainsKey(xBaseMethod)) { - QueueMethod(xMethod); - } - } - } - } - } - } - } + private void ScanForMethodsToIncludeForVMT() + { + List xCheckedTypes = new List(); + foreach (MethodBase xMethod in mMethods.Keys) + { + if (xMethod.IsStatic) + { + continue; + } + Type xCurrentType = xMethod.DeclaringType; + if (!xCheckedTypes.Contains(xCurrentType, mTypesEqualityComparer)) + { + xCheckedTypes.Add(xCurrentType); + } + } + foreach (Type xType in mTypes) + { + if (!xCheckedTypes.Contains(xType, mTypesEqualityComparer)) + { + xCheckedTypes.Add(xType); + } + } + for (int i = 0; i < xCheckedTypes.Count; i++) + { + Type xCurrentType = xCheckedTypes[i]; + while (xCurrentType != null) + { + if (!xCheckedTypes.Contains(xCurrentType, mTypesEqualityComparer)) + { + xCheckedTypes.Add(xCurrentType); + } + if (xCurrentType.FullName == "System.Object") + { + break; + } + if (xCurrentType.BaseType == null) + { + break; + } + xCurrentType = xCurrentType.BaseType; + } + } + foreach (Type xTD in xCheckedTypes) + { + foreach (MethodBase xMethod in xTD.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)) + { + if (!xMethod.IsStatic) + { + if (xTD.BaseType == null) + { + continue; + } + if (xMethod.IsVirtual && !xMethod.IsConstructor && !xMethod.IsFinal) + { + Type xCurrentInspectedType = xTD.BaseType; + ParameterInfo[] xParams = xMethod.GetParameters(); + Type[] xMethodParams = new Type[xParams.Length]; + for (int i = 0; i < xParams.Length; i++) + { + xMethodParams[i] = xParams[i].ParameterType; + } + MethodBase xBaseMethod = GetUltimateBaseMethod(xMethod, xMethodParams, xTD); + if (xBaseMethod != null && xBaseMethod != xMethod) + { + if (mMethods.ContainsKey(xBaseMethod)) + { + QueueMethod(xMethod); + } + } + } + } + } + } + for(int j = 0; j < mMethods.Count;j++){ + var xMethod = mMethods.Skip(j).First(); + if (xMethod.Key.DeclaringType.IsInterface) + { + var xInterface = xMethod.Key.DeclaringType; + foreach (var xImplType in mTypes) + { + if (xImplType.IsInterface) { continue; } + if (xImplType.GetInterfaces().Contains(xInterface)) + { + var xIntfMap = xImplType.GetInterfaceMap(xInterface); + for (int i = 0; i < xIntfMap.InterfaceMethods.Length; i++) + { + if (mMethods.ContainsKey(xIntfMap.InterfaceMethods[i])) + { + QueueMethod(xIntfMap.TargetMethods[i]); + } + } + } + } + } + } + } private static MethodBase GetUltimateBaseMethod(MethodBase aMethod, Type[] aMethodParams, Type aCurrentInspectedType) { MethodBase xBaseMethod = null; @@ -780,7 +821,7 @@ namespace Indy.IL2CPU { continue; } string xMethodName = Label.GenerateLabelName(xCurrentMethod); - TypeInformation xTypeInfo = null; + TypeInformation xTypeInfo = null; { if (!xCurrentMethod.IsStatic) { xTypeInfo = GetTypeInfo(xCurrentMethod.DeclaringType); @@ -1161,13 +1202,20 @@ MethodInformation xMethodInfo = GetMethodInfo(xCurrentMethod, xCurrentMethod, xM foreach (MethodBase xOrigMethodDef in xTypeRef.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic)) { string xOrigStrippedSignature = GetStrippedMethodBaseFullName(xOrigMethodDef); if (xOrigStrippedSignature == xStrippedSignature) { + if (mPlugMethods.ContainsKey(Label.GenerateLabelName(xOrigMethodDef))) + { + System.Diagnostics.Debugger.Break(); + } mPlugMethods.Add(Label.GenerateLabelName(xOrigMethodDef), xMethod); } } foreach (MethodBase xOrigMethodDef in xTypeRef.GetConstructors(BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic)) { string xOrigStrippedSignature = GetStrippedMethodBaseFullName(xOrigMethodDef); if (xOrigStrippedSignature == xStrippedSignature) { - mPlugMethods.Add(Label.GenerateLabelName(xOrigMethodDef), xMethod); + if (mPlugMethods.ContainsKey(Label.GenerateLabelName(xOrigMethodDef))) + { + System.Diagnostics.Debugger.Break(); + } mPlugMethods.Add(Label.GenerateLabelName(xOrigMethodDef), xMethod); } } } diff --git a/source/Indy.IL2CPU/GCImplementation.cs b/source/Indy.IL2CPU/GCImplementation.cs index 823ce043b..81fa852e4 100644 --- a/source/Indy.IL2CPU/GCImplementation.cs +++ b/source/Indy.IL2CPU/GCImplementation.cs @@ -7,8 +7,10 @@ using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; +using System.Diagnostics; namespace Indy.IL2CPU { + [DebuggerStepThrough] public static class GCImplementation { private static int mLock = 0; private static void AcquireLock() { diff --git a/source/MatthijsTest/Program.cs b/source/MatthijsTest/Program.cs index a3f04b41f..6ba58b008 100644 --- a/source/MatthijsTest/Program.cs +++ b/source/MatthijsTest/Program.cs @@ -2,9 +2,10 @@ using System.Collections.Generic; using System.Text; using Cosmos.Build.Windows; +using System.Collections; namespace MatthijsTest { - public class Program { + public class Program { #region Cosmos Builder logic // Most users wont touch this. This will call the Cosmos Build tool @@ -15,6 +16,20 @@ namespace MatthijsTest { #endregion + public class MessageContainer : IEnumerable + { + public IEnumerator GetEnumerator() { + yield return "String1"; + yield return "String2"; + yield return "String3"; + yield return "String4"; + yield return "String5"; + + } + } + + + public static void GetResumeAndResume(ref uint aSuspend) { aSuspend = 0; @@ -22,8 +37,10 @@ namespace MatthijsTest { } public static void Init() { - //Cosmos.Kernel.Boot.Default(); - var xTest = new Object(); + var xTest = (IEnumerable)new string[] { "String1", "String2", "String3" }; + foreach(string xItem in xTest){ + Console.WriteLine(xItem); + } } } } \ No newline at end of file