/// <summary> /// Scans the specified type's non-static fields. /// </summary> /// <param name="TheLibrary">The library currently being compiled.</param> /// <param name="TheTypeInfo">The type to scan the non-static fields of.</param> /// <param name="FieldTablesBlock">The ASM block for the fields table for the library currently being compiled.</param> private static void ScanFields(ILLibrary TheLibrary, Types.TypeInfo TheTypeInfo, ASM.ASMBlock FieldTablesBlock) { string currentTypeId = TheTypeInfo.ID; string currentTypeName = TheTypeInfo.UnderlyingType.FullName; List <Tuple <string, string, string> > AllFieldInfo = new List <Tuple <string, string, string> >(); if (TheTypeInfo.UnderlyingType.BaseType == null || (TheTypeInfo.UnderlyingType.BaseType.FullName != "System.Array" && TheTypeInfo.UnderlyingType.BaseType.FullName != "System.MulticastDelegate")) { foreach (Types.FieldInfo anOwnField in TheTypeInfo.FieldInfos) { if (!anOwnField.IsStatic) { Types.TypeInfo FieldTypeInfo = TheLibrary.GetTypeInfo(anOwnField.FieldType); string fieldOffsetVal = anOwnField.OffsetInBytes.ToString(); string fieldSizeVal = (FieldTypeInfo.IsValueType ? FieldTypeInfo.SizeOnHeapInBytes : FieldTypeInfo.SizeOnStackInBytes).ToString(); string fieldTypeIdVal = FieldTypeInfo.ID; FieldTablesBlock.AddExternalLabel(fieldTypeIdVal); AllFieldInfo.Add(new Tuple <string, string, string>(fieldOffsetVal, fieldSizeVal, fieldTypeIdVal)); } } } string parentTypeFieldTablePtr = "0"; bool parentPtrIsExternal = false; if (TheTypeInfo.UnderlyingType.BaseType != null) { if (!TheTypeInfo.UnderlyingType.BaseType.AssemblyQualifiedName.Contains("mscorlib")) { Types.TypeInfo baseTypeInfo = TheLibrary.GetTypeInfo(TheTypeInfo.UnderlyingType.BaseType); parentPtrIsExternal = (ScannedTypes.ContainsKey(baseTypeInfo.ID) && ScannedTypes[baseTypeInfo.ID] != TheLibrary) || !TheLibrary.TypeInfos.Contains(baseTypeInfo); parentTypeFieldTablePtr = baseTypeInfo.ID + "_FieldTable"; } } { string fieldOffsetVal = "0"; string fieldSizeVal = "0"; string fieldTypeIdVal = parentTypeFieldTablePtr; if (parentPtrIsExternal) { FieldTablesBlock.AddExternalLabel(fieldTypeIdVal); } AllFieldInfo.Add(new Tuple <string, string, string>(fieldOffsetVal, fieldSizeVal, fieldTypeIdVal)); } List <Tuple <string, int> > TableEntryFieldInfos = GetSpecialClassFieldInfo(TheLibrary, typeof(Attributes.FieldInfoStructAttribute)); ASM.ASMOp newFieldTableOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.FieldTable, currentTypeId, currentTypeName, AllFieldInfo, TableEntryFieldInfos); FieldTablesBlock.Append(newFieldTableOp); }
/// <summary> /// Scans the specified type's methods. /// </summary> /// <param name="TheLibrary">The library currently being compiled.</param> /// <param name="TheTypeInfo">The type to scan the methods of.</param> /// <param name="MethodTablesBlock">The ASM block for the methods table for the library currently being compiled.</param> private static void ScanMethods(ILLibrary TheLibrary, Types.TypeInfo TheTypeInfo, ASM.ASMBlock MethodTablesBlock) { string currentTypeId = TheTypeInfo.ID; string currentTypeName = TheTypeInfo.UnderlyingType.FullName; List <Tuple <string, string> > AllMethodInfo = new List <Tuple <string, string> >(); if (TheTypeInfo.UnderlyingType.BaseType == null || TheTypeInfo.UnderlyingType.BaseType.FullName != "System.Array") { foreach (Types.MethodInfo aMethodInfo in TheTypeInfo.MethodInfos) { if (!aMethodInfo.IsStatic && !aMethodInfo.UnderlyingInfo.IsAbstract) { string methodID = aMethodInfo.ID; string methodIDValue = aMethodInfo.IDValue.ToString(); MethodTablesBlock.AddExternalLabel(methodID); AllMethodInfo.Add(new Tuple <string, string>(methodID, methodIDValue)); } } } string parentTypeMethodTablePtr = "0"; bool parentPtrIsExternal = false; if (TheTypeInfo.UnderlyingType.BaseType != null) { if (!TheTypeInfo.UnderlyingType.BaseType.AssemblyQualifiedName.Contains("mscorlib")) { Types.TypeInfo baseTypeInfo = TheLibrary.GetTypeInfo(TheTypeInfo.UnderlyingType.BaseType); parentPtrIsExternal = (ScannedTypes.ContainsKey(baseTypeInfo.ID) && ScannedTypes[baseTypeInfo.ID] != TheLibrary) || !TheLibrary.TypeInfos.Contains(baseTypeInfo); parentTypeMethodTablePtr = baseTypeInfo.ID + "_MethodTable"; } } { string methodID = parentTypeMethodTablePtr; string methodIDValue = "0"; if (parentPtrIsExternal) { MethodTablesBlock.AddExternalLabel(methodID); } AllMethodInfo.Add(new Tuple <string, string>(methodID, methodIDValue)); } List <Tuple <string, int> > TableEntryFieldInfos = GetSpecialClassFieldInfo(TheLibrary, typeof(Attributes.MethodInfoStructAttribute)); ASM.ASMOp newMethodTableOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.MethodTable, currentTypeId, currentTypeName, AllMethodInfo, TableEntryFieldInfos); MethodTablesBlock.Append(newMethodTableOp); }
/// <summary> /// Scans the specified type (excludes fields and methods). /// </summary> /// <param name="TheLibrary">The library currently being compiled.</param> /// <param name="TheTypeInfo">The type to scan.</param> /// <param name="TypesTableBlock">The ASM block for the types table for the library currently being compiled.</param> private static void ScanType(ILLibrary TheLibrary, Types.TypeInfo TheTypeInfo, ASM.ASMBlock TypesTableBlock) { string TypeId = TheTypeInfo.ID; string SizeVal = TheTypeInfo.SizeOnHeapInBytes.ToString(); string IdVal = (TypesScanned++).ToString(); string StackSizeVal = TheTypeInfo.SizeOnStackInBytes.ToString(); string IsValueTypeVal = (TheTypeInfo.IsValueType ? "1" : "0"); string MethodTablePointer = TypeId + "_MethodTable"; string IsPointerTypeVal = (TheTypeInfo.IsPointer ? "1" : "0"); string BaseTypeIdVal = "0"; if (TheTypeInfo.UnderlyingType.BaseType != null) { if (!TheTypeInfo.UnderlyingType.BaseType.AssemblyQualifiedName.Contains("mscorlib")) { Types.TypeInfo baseTypeInfo = TheLibrary.GetTypeInfo(TheTypeInfo.UnderlyingType.BaseType); BaseTypeIdVal = baseTypeInfo.ID; //Declared external to this library, so won't appear in this library's type tables if ((ScannedTypes.ContainsKey(baseTypeInfo.ID) && ScannedTypes[baseTypeInfo.ID] != TheLibrary) || !TheLibrary.TypeInfos.Contains(baseTypeInfo)) { TypesTableBlock.AddExternalLabel(BaseTypeIdVal); } } } string FieldTablePointer = TypeId + "_FieldTable"; string TypeSignatureLiteralLabel = TheLibrary.AddStringLiteral(TheTypeInfo.UnderlyingType.FullName); // Legacy string TypeIdLiteralLabel = TheLibrary.AddStringLiteral(TheTypeInfo.ID); Types.TypeInfo typeTypeInfo = ILLibrary.SpecialClasses[typeof(Attributes.TypeClassAttribute)].First(); List <Types.FieldInfo> OrderedFields = typeTypeInfo.FieldInfos.Where(x => !x.IsStatic).OrderBy(x => x.OffsetInBytes).ToList(); List <Tuple <string, Types.TypeInfo> > FieldInformation = new List <Tuple <string, Types.TypeInfo> >(); foreach (Types.FieldInfo aTypeField in OrderedFields) { Types.TypeInfo FieldTypeInfo = TheLibrary.GetTypeInfo(aTypeField.FieldType); FieldInformation.Add(new Tuple <string, Types.TypeInfo>(aTypeField.Name, FieldTypeInfo)); } ASM.ASMOp newTypeTableOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.TypeTable, TypeId, SizeVal, IdVal, StackSizeVal, IsValueTypeVal, MethodTablePointer, IsPointerTypeVal, BaseTypeIdVal, FieldTablePointer, TypeSignatureLiteralLabel, TypeIdLiteralLabel, FieldInformation); TypesTableBlock.Append(newTypeTableOp); TypesTableBlock.AddExternalLabel(MethodTablePointer); TypesTableBlock.AddExternalLabel(FieldTablePointer); TypesTableBlock.AddExternalLabel(TypeSignatureLiteralLabel); TypesTableBlock.AddExternalLabel(TypeIdLiteralLabel); }
/// <summary> /// Scans the specified library and any dependencies. /// </summary> /// <param name="TheLibrary">The library to scan.</param> /// <returns> /// CompileResult.OK if completed successfully. /// Otherwise CompileResult.PartialFail or CompileResult.Error depending on /// the extent of the problem. /// </returns> public static CompileResult Scan(ILLibrary TheLibrary) { CompileResult result = CompileResult.OK; if (TheLibrary.ILScanned) { return(result); } TheLibrary.ILScanned = true; foreach (ILLibrary depLib in TheLibrary.Dependencies) { Scan(depLib); } // Create / Add Static Fields ASM Block ASM.ASMBlock StaticFieldsBlock = new ASM.ASMBlock() { Priority = (long.MinValue / 2) - 9 }; TheLibrary.TheASMLibrary.ASMBlocks.Add(StaticFieldsBlock); // Create / Add Types Table ASM Block ASM.ASMBlock TypesTableBlock = new ASM.ASMBlock() { Priority = (long.MinValue / 2) - 8 }; TheLibrary.TheASMLibrary.ASMBlocks.Add(TypesTableBlock); // Create / Add Method Tables ASM Block ASM.ASMBlock MethodTablesBlock = new ASM.ASMBlock() { Priority = (long.MinValue / 2) + 0 }; TheLibrary.TheASMLibrary.ASMBlocks.Add(MethodTablesBlock); // Create / Add Field Tables ASM Block ASM.ASMBlock FieldTablesBlock = new ASM.ASMBlock() { Priority = (long.MinValue / 2) + 1 }; TheLibrary.TheASMLibrary.ASMBlocks.Add(FieldTablesBlock); // Don't use foreach or you get collection modified exceptions for (int i = 0; i < TheLibrary.TypeInfos.Count; i++) { Types.TypeInfo aTypeInfo = TheLibrary.TypeInfos[i]; if (!ScannedTypes.ContainsKey(aTypeInfo.ID)) { ScannedTypes.Add(aTypeInfo.ID, TheLibrary); ScanStaticFields(TheLibrary, aTypeInfo, StaticFieldsBlock); ScanType(TheLibrary, aTypeInfo, TypesTableBlock); ScanMethods(TheLibrary, aTypeInfo, MethodTablesBlock); ScanFields(TheLibrary, aTypeInfo, FieldTablesBlock); } } foreach (Types.MethodInfo aMethodInfo in TheLibrary.ILBlocks.Keys) { ILBlock anILBlock = TheLibrary.ILBlocks[aMethodInfo]; CompileResult singleResult = CompileResult.OK; if (anILBlock.Plugged) { singleResult = ScanPluggedILBlock(TheLibrary, aMethodInfo, anILBlock); } else { singleResult = ScanNonpluggedILBlock(TheLibrary, aMethodInfo, anILBlock); } if (result != CompileResult.OK) { result = singleResult; } } // Create / Add String Literals ASM Block #region String Literals Block ASM.ASMBlock StringLiteralsBlock = new ASM.ASMBlock() { Priority = (long.MinValue / 2) - 10 }; TheLibrary.TheASMLibrary.ASMBlocks.Add(StringLiteralsBlock); string StringTypeId = ILLibrary.SpecialClasses[typeof(Attributes.StringClassAttribute)].First().ID; StringLiteralsBlock.AddExternalLabel(StringTypeId); foreach (KeyValuePair <string, string> aStringLiteral in TheLibrary.StringLiterals) { string value = aStringLiteral.Value; byte[] lengthBytes = BitConverter.GetBytes(value.Length); ASM.ASMOp newLiteralOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.StringLiteral, aStringLiteral.Key, StringTypeId, lengthBytes, value.ToCharArray()); StringLiteralsBlock.Append(newLiteralOp); } #endregion return(result); }
/// <summary> /// Scans the specified library and any dependencies. /// </summary> /// <param name="TheLibrary">The library to scan.</param> /// <returns> /// CompileResult.OK if completed successfully. /// Otherwise CompileResult.PartialFail or CompileResult.Error depending on /// the extent of the problem. /// </returns> public static CompileResult Scan(ILLibrary TheLibrary) { CompileResult result = CompileResult.OK; if (TheLibrary.ILScanned) { return result; } TheLibrary.ILScanned = true; foreach (ILLibrary depLib in TheLibrary.Dependencies) { Scan(depLib); } // Create / Add Static Fields ASM Block ASM.ASMBlock StaticFieldsBlock = new ASM.ASMBlock() { Priority = (long.MinValue / 2) - 9 }; TheLibrary.TheASMLibrary.ASMBlocks.Add(StaticFieldsBlock); // Create / Add Types Table ASM Block ASM.ASMBlock TypesTableBlock = new ASM.ASMBlock() { Priority = (long.MinValue / 2) - 8 }; TheLibrary.TheASMLibrary.ASMBlocks.Add(TypesTableBlock); // Create / Add Method Tables ASM Block ASM.ASMBlock MethodTablesBlock = new ASM.ASMBlock() { Priority = (long.MinValue / 2) + 0 }; TheLibrary.TheASMLibrary.ASMBlocks.Add(MethodTablesBlock); // Create / Add Field Tables ASM Block ASM.ASMBlock FieldTablesBlock = new ASM.ASMBlock() { Priority = (long.MinValue / 2) + 1 }; TheLibrary.TheASMLibrary.ASMBlocks.Add(FieldTablesBlock); // Don't use foreach or you get collection modified exceptions for (int i = 0; i < TheLibrary.TypeInfos.Count; i++) { Types.TypeInfo aTypeInfo = TheLibrary.TypeInfos[i]; if (!ScannedTypes.ContainsKey(aTypeInfo.ID)) { ScannedTypes.Add(aTypeInfo.ID, TheLibrary); ScanStaticFields(TheLibrary, aTypeInfo, StaticFieldsBlock); ScanType(TheLibrary, aTypeInfo, TypesTableBlock); ScanMethods(TheLibrary, aTypeInfo, MethodTablesBlock); ScanFields(TheLibrary, aTypeInfo, FieldTablesBlock); } } foreach (Types.MethodInfo aMethodInfo in TheLibrary.ILBlocks.Keys) { ILBlock anILBlock = TheLibrary.ILBlocks[aMethodInfo]; CompileResult singleResult = CompileResult.OK; if (anILBlock.Plugged) { singleResult = ScanPluggedILBlock(TheLibrary, aMethodInfo, anILBlock); } else { singleResult = ScanNonpluggedILBlock(TheLibrary, aMethodInfo, anILBlock); } if (result != CompileResult.OK) { result = singleResult; } } // Create / Add String Literals ASM Block #region String Literals Block ASM.ASMBlock StringLiteralsBlock = new ASM.ASMBlock() { Priority = (long.MinValue / 2) - 10 }; TheLibrary.TheASMLibrary.ASMBlocks.Add(StringLiteralsBlock); string StringTypeId = ILLibrary.SpecialClasses[typeof(Attributes.StringClassAttribute)].First().ID; StringLiteralsBlock.AddExternalLabel(StringTypeId); foreach (KeyValuePair<string, string> aStringLiteral in TheLibrary.StringLiterals) { string value = aStringLiteral.Value; byte[] lengthBytes = BitConverter.GetBytes(value.Length); ASM.ASMOp newLiteralOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.StringLiteral, aStringLiteral.Key, StringTypeId, lengthBytes, value.ToCharArray()); StringLiteralsBlock.Append(newLiteralOp); } #endregion return result; }
/// <summary> /// Adds the specified label as an external dependency. /// </summary> /// <param name="label">The label to add.</param> public void AddExternalLabel(string label) { Result.AddExternalLabel(label); }