using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using Indy.IL2CPU.Assembler; using Indy.IL2CPU.IL; namespace Indy.IL2CPU.Compiler { partial class CompilerHelper//: IMetaDataInfoService { //#region Implementation of IMetaDataInfoService //public uint SizeOfType(Type aType) //{ // if (aType.FullName == "System.Void") // { // return 0; // } // if ((!aType.IsValueType && aType.IsClass) || aType.IsInterface) // { // return 4; // } // switch (aType.FullName) // { // case "System.Char": // return 2; // case "System.Byte": // case "System.SByte": // return 1; // case "System.UInt16": // case "System.Int16": // return 2; // case "System.UInt32": // case "System.Int32": // return 4; // case "System.UInt64": // case "System.Int64": // return 8; // // for now hardcode IntPtr and UIntPtr to be 32-bit // case "System.UIntPtr": // case "System.IntPtr": // return 4; // case "System.Boolean": // return 1; // case "System.Single": // return 4; // case "System.Double": // return 8; // case "System.Decimal": // return 16; // case "System.Guid": // return 16; // case "System.Enum": // return 4; // case "System.DateTime": // return 8; // } // if (aType.FullName != null && aType.FullName.EndsWith("*")) // { // // pointer // return 4; // } // // array // //TypeSpecification xTypeSpec = aType as TypeSpecification; // //if (xTypeSpec != null) { // // return 4; // //} // if (aType.IsEnum) // { // return SizeOfType(aType.GetField("value__").FieldType); // } // if (aType.IsValueType) // { // var xSla = aType.StructLayoutAttribute; // if (xSla != null) // { // if (xSla.Size > 0) // { // return (uint)xSla.Size; // } // } // } // uint xResult; // GetTypeFieldInfo(aType, // out xResult); // return xResult; //} //public IDictionary GetTypeFieldInfo(Type aType, // out uint aObjectStorageSize) //{ // var xTypeFields = new List>(); // aObjectStorageSize = 0; // GetTypeFieldInfoImpl(xTypeFields, // aType, // ref aObjectStorageSize); // if (aType.IsExplicitLayout) // { // var xStructLayout = aType.StructLayoutAttribute; // if (xStructLayout.Size == 0) // { // aObjectStorageSize = (uint)((from item in xTypeFields // let xSize = item.Value.Offset + item.Value.Size // orderby xSize descending // select xSize).FirstOrDefault()); // } // else // { // aObjectStorageSize = (uint)xStructLayout.Size; // } // } // int xOffset = 0; // var xResult = new Dictionary(); // foreach (var item in xTypeFields) // { // var xItem = item.Value; // if (item.Value.Offset == -1) // { // xItem.Offset = xOffset; // xOffset += xItem.Size; // } // xResult.Add(item.Key, // xItem); // } // return xResult; //} //public void GetTypeFieldInfoImpl(List> aTypeFields, // Type aType, // ref uint aObjectStorageSize) //{ // //if (aType == null) // //{ // // throw new ArgumentNullException("aType"); // //} // //Type xActualType = aType; // //Dictionary xCurrentPlugFieldList = new Dictionary(); // //do // //{ // // if (mPlugFields.ContainsKey(aType)) // // { // // var xOrigList = mPlugFields[aType]; // // foreach (var item in xOrigList) // // { // // xCurrentPlugFieldList.Add(item.Key, // // item.Value); // // } // // } // // foreach (FieldInfo xField in aType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) // // { // // if (xField.IsStatic) // // { // // continue; // // } // // if (xField.DeclaringType != aType) // // { // // // somehow this gives other results than including DeclaredOnly // // continue; // // } // // //if (xField.HasConstant) { // // // Console.WriteLine("Field is constant: " + xField.GetFullName()); // // //} // // // todo: add support for constants? // // PlugFieldAttribute xPlugFieldAttr = null; // // if (xCurrentPlugFieldList.ContainsKey(xField.GetFullName())) // // { // // xPlugFieldAttr = xCurrentPlugFieldList[xField.GetFullName()]; // // xCurrentPlugFieldList.Remove(xField.GetFullName()); // // } // // Type xFieldType = null; // // int xFieldSize; // // string xFieldId; // // if (xPlugFieldAttr != null) // // { // // xFieldType = xPlugFieldAttr.FieldType; // // xFieldId = xPlugFieldAttr.FieldId; // // } // // else // // { // // xFieldId = xField.GetFullName(); // // } // // if (xFieldType == null) // // { // // xFieldType = xField.FieldType; // // } // // //if ((!xFieldType.IsValueType && aGCObjects && xFieldType.IsClass) || (xPlugFieldAttr != null && xPlugFieldAttr.IsExternalValue && aGCObjects)) { // // // continue; // // //} // // if ((xFieldType.IsClass && !xFieldType.IsValueType) || (xPlugFieldAttr != null && xPlugFieldAttr.IsExternalValue)) // // { // // xFieldSize = 4; // // } // // else // // { // // xFieldSize = (int)SizeOfType(xFieldType); // // } // // //} // // if ((from item in aTypeFields // // where item.Key == xFieldId // // select item).Count() > 0) // // { // // continue; // // } // // int xOffset = (int)aObjectStorageSize; // // FieldOffsetAttribute xOffsetAttrib = xField.GetCustomAttributes(typeof(FieldOffsetAttribute), // // true).FirstOrDefault() as FieldOffsetAttribute; // // if (xOffsetAttrib != null) // // { // // xOffset = xOffsetAttrib.Value; // // } // // else // // { // // aObjectStorageSize += (uint)xFieldSize; // // xOffset = -1; // // } // // 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(); // // xCurrentPlugFieldList.Remove(xItem.FieldId); // // Type xFieldType = xItem.FieldType; // // int xFieldSize; // // string xFieldId = xItem.FieldId; // // if (xFieldType == null) // // { // // xFieldType = xItem.FieldType; // // } // // if (xFieldType == null) // // { // // LogMessage(LogSeverityEnum.Error, "Plugged field {0} not found! (On Type {1})", xItem.FieldId, aType.AssemblyQualifiedName); // // } // // if (xItem.IsExternalValue || (xFieldType.IsClass && !xFieldType.IsValueType)) // // { // // xFieldSize = 4; // // } // // else // // { // // xFieldSize = (int)SizeOfType(xFieldType); // // } // // int xOffset = (int)aObjectStorageSize; // // aObjectStorageSize += (uint)xFieldSize; // // aTypeFields.Insert(0, // // new KeyValuePair(xItem.FieldId, // // new TypeInformation.Field(xFieldSize, // // xFieldType.IsClass && !xFieldType.IsValueType, // // xFieldType, // // xItem.IsExternalValue))); // // } // // if (aType.FullName != "System.Object" && aType.BaseType != null) // // { // // aType = aType.BaseType; // // } // // else // // { // // break; // // } // //} while (true); // throw new NotImplementedException(); //} //public IDictionary GetTypeFieldInfo(MethodBase aCurrentMethod, // out uint aObjectStorageSize) //{ // Type xCurrentInspectedType = aCurrentMethod.DeclaringType; // return GetTypeFieldInfo(xCurrentInspectedType, // out aObjectStorageSize); //} //public TypeInformation GetTypeInfo(Type aType) //{ // TypeInformation xTypeInfo; // uint xObjectStorageSize; // IDictionary xTypeFields = GetTypeFieldInfo(aType, // out xObjectStorageSize); // xTypeInfo = new TypeInformation(xObjectStorageSize, // xTypeFields, // aType, // (!aType.IsValueType) && aType.IsClass); // return xTypeInfo; //} //public MethodInformation GetMethodInfo(MethodBase aCurrentMethodForArguments, // MethodBase aCurrentMethodForLocals, // string aMethodName, // TypeInformation aTypeInfo, // bool aDebugMode) //{ // return GetMethodInfo(aCurrentMethodForArguments, aCurrentMethodForLocals, aMethodName, aTypeInfo, aDebugMode, null); //} //public MethodInformation GetMethodInfo(MethodBase aMethod, bool aDebugMode) //{ // return GetMethodInfo(aMethod, aMethod, MethodInfoLabelGenerator.GenerateLabelName(aMethod), GetTypeInfo(aMethod.DeclaringType), aDebugMode); //} //public MethodInformation GetMethodInfo(MethodBase aCurrentMethodForArguments, // MethodBase aCurrentMethodForLocals, // string aMethodName, // TypeInformation aTypeInfo, // bool aDebugMode, // IDictionary aMethodData) //{ // if (aCurrentMethodForLocals.IsGenericMethod) // { // if (!(from item in mAllMethods // where item.GetFullName() == aMethodName // select item).Any()) // { // mAllMethods.Add(aCurrentMethodForLocals); // } // } // if(mCurrentAssemblyCompilationInfo==null){throw new Exception("No Current Assembly Info!");} // if(aCurrentMethodForArguments.DeclaringType.Assembly!=mCurrentAssemblyCompilationInfo.Assembly) // { // mCurrentAssemblyCompilationInfo.ReferenceMethod(aCurrentMethodForArguments); // } // MethodInformation xMethodInfo; // { // MethodInformation.Variable[] xVars = new MethodInformation.Variable[0]; // int xCurOffset = 0; // // todo:implement check for body // //if (aCurrentMethodForLocals.HasBody) { // MethodBody xBody = null; // try // { // xBody = aCurrentMethodForLocals.GetMethodBody(); // } // catch // { // } // if (xBody != null) // { // xVars = new MethodInformation.Variable[xBody.LocalVariables.Count]; // foreach (LocalVariableInfo xVarDef in xBody.LocalVariables) // { // int xVarSize = (int)SizeOfType(xVarDef.LocalType); // if ((xVarSize % 4) != 0) // { // xVarSize += 4 - (xVarSize % 4); // } // xVars[xVarDef.LocalIndex] = new MethodInformation.Variable(xCurOffset, // xVarSize, // !xVarDef.LocalType.IsValueType, // xVarDef.LocalType); // // todo: implement support for generic parameters? // //if (!(xVarDef.VariableType is GenericParameter)) { // //RegisterType(xVarDef.LocalType); // //} // xCurOffset += xVarSize; // } // } // MethodInformation.Argument[] xArgs; // if (!aCurrentMethodForArguments.IsStatic) // { // ParameterInfo[] xParameters = aCurrentMethodForArguments.GetParameters(); // xArgs = new MethodInformation.Argument[xParameters.Length + 1]; // xCurOffset = 0; // uint xArgSize; // for (int i = xArgs.Length - 1; i > 0; i--) // { // ParameterInfo xParamDef = xParameters[i - 1]; // xArgSize = SizeOfType(xParamDef.ParameterType); // if ((xArgSize % 4) != 0) // { // xArgSize += 4 - (xArgSize % 4); // } // MethodInformation.Argument.KindEnum xKind = MethodInformation.Argument.KindEnum.In; // if (xParamDef.IsOut) // { // if (xParamDef.IsIn) // { // xKind = MethodInformation.Argument.KindEnum.ByRef; // } // else // { // xKind = MethodInformation.Argument.KindEnum.Out; // } // } // xArgs[i] = new MethodInformation.Argument(xArgSize, // xCurOffset, // xKind, // !xParamDef.ParameterType.IsValueType, // GetTypeInfo(xParamDef.ParameterType), // xParamDef.ParameterType); // xCurOffset += (int)xArgSize; // } // xArgSize = 4; // // this // xArgs[0] = new MethodInformation.Argument(xArgSize, // xCurOffset, // MethodInformation.Argument.KindEnum.In, // !aCurrentMethodForArguments.DeclaringType.IsValueType, // GetTypeInfo(aCurrentMethodForArguments.DeclaringType), // aCurrentMethodForArguments.DeclaringType); // } // else // { // ParameterInfo[] xParameters = aCurrentMethodForArguments.GetParameters(); // xArgs = new MethodInformation.Argument[xParameters.Length]; // xCurOffset = 0; // for (int i = xArgs.Length - 1; i >= 0; i--) // { // ParameterInfo xParamDef = xParameters[i]; //xArgs.Length - i - 1]; // uint xArgSize = SizeOfType(xParamDef.ParameterType); // if ((xArgSize % 4) != 0) // { // xArgSize += 4 - (xArgSize % 4); // } // MethodInformation.Argument.KindEnum xKind = MethodInformation.Argument.KindEnum.In; // if (xParamDef.IsOut) // { // if (xParamDef.IsIn) // { // xKind = MethodInformation.Argument.KindEnum.ByRef; // } // else // { // xKind = MethodInformation.Argument.KindEnum.Out; // } // } // xArgs[i] = new MethodInformation.Argument(xArgSize, // xCurOffset, // xKind, // !xParamDef.ParameterType.IsValueType, // GetTypeInfo(xParamDef.ParameterType), // xParamDef.ParameterType); // xCurOffset += (int)xArgSize; // } // } // int xResultSize = 0;// SizeOfType(aCurrentMethodForArguments.ReturnType.ReturnType); // MethodInfo xMethInfo = aCurrentMethodForArguments as MethodInfo; // Type xReturnType = typeof(void); // if (xMethInfo != null) // { // xResultSize = (int)SizeOfType(xMethInfo.ReturnType); // xReturnType = xMethInfo.ReturnType; // } // xMethodInfo = new MethodInformation(aMethodName, // xVars, // xArgs, // (uint)xResultSize, // !aCurrentMethodForArguments.IsStatic, // aTypeInfo, // aCurrentMethodForArguments, // xReturnType, // aDebugMode, // aMethodData); // } // return xMethodInfo; //} //public uint GetObjectStorageSize(Type aType) //{ // if (aType == null) // { // throw new ArgumentNullException("aType"); // } // var xTypeInfo = GetTypeInfo(aType); // return xTypeInfo.NeedsGC // ? xTypeInfo.StorageSize + ObjectImpl.FieldDataOffset // : xTypeInfo.StorageSize; //} //public void LogMessage(LogSeverityEnum aSeverity, string aMessage, params object[] aArgs) //{ // if(DebugLog!=null) // { // DebugLog(aSeverity, String.Format(aMessage, aArgs)); // } //} //public string GetStaticFieldLabel(FieldInfo aField) //{ // var xLabel = DataMember.GetStaticFieldName(aField); // if (aField.DeclaringType.Assembly != mCurrentAssemblyCompilationInfo.Assembly) // { // mCurrentAssemblyCompilationInfo.ReferenceStaticField(aField); // } // return xLabel; //} //public string GetTypeIdLabel(Type aType) //{ // var xLabel = Label.FilterStringForIncorrectChars(aType.AssemblyQualifiedName + "__TYPE_ID"); // if (aType.Assembly != mCurrentAssemblyCompilationInfo.Assembly) // { // mCurrentAssemblyCompilationInfo.ReferenceID(xLabel); // } // else // { // if (!mCreatedIDLabels.Contains(xLabel)) // { // AssemblyCompilationInfo xAsmInfo; // if (!mAssemblyInfos.TryGetValue(aType.Assembly, out xAsmInfo)) // { // xAsmInfo = new AssemblyCompilationInfo {Assembly = aType.Assembly}; // mAssemblyInfos.Add(xAsmInfo.Assembly, xAsmInfo); // } // xAsmInfo.IDLabels.Add(xLabel); // mCreatedIDLabels.Add(xLabel); // } // } // return xLabel; //} //private HashSet mCreatedIDLabels = new HashSet(StringComparer.InvariantCulture); //public string GetMethodIdLabel(MethodBase aMethodDef) //{ // var xLabel = Label.FilterStringForIncorrectChars(aMethodDef.GetFullName()+ "__METHOD_ID"); // if (aMethodDef.DeclaringType.Assembly != mCurrentAssemblyCompilationInfo.Assembly) // { // mCurrentAssemblyCompilationInfo.ReferenceID(xLabel); // } // else // { // if (!mCreatedIDLabels.Contains(xLabel)) // { // AssemblyCompilationInfo xAsmInfo; // if (!mAssemblyInfos.TryGetValue(aMethodDef.DeclaringType.Assembly, out xAsmInfo)) // { // xAsmInfo = new AssemblyCompilationInfo {Assembly = aMethodDef.DeclaringType.Assembly}; // mAssemblyInfos.Add(xAsmInfo.Assembly, xAsmInfo); // } // xAsmInfo.IDLabels.Add(xLabel); // mCreatedIDLabels.Add(xLabel); // } // } // return xLabel; //} //#endregion } }