Exemple #1
0
        /// <summary>
        /// Executes the IL Reader for the specified library.
        /// </summary>
        /// <param name="TheLibrary">The library to read.</param>
        /// <returns>The return value from the IL Reader.</returns>
        private static CompileResult ExecuteILReader(ILLibrary TheLibrary)
        {
            CompileResult result = CompileResult.OK;

            if (TheLibrary.ILRead)
            {
                return(result);
            }
            TheLibrary.ILRead = true;

            foreach (ILLibrary depLib in TheLibrary.Dependencies)
            {
                result = result == CompileResult.OK ? ExecuteILReader(depLib) : result;
            }

            foreach (Types.TypeInfo aTypeInfo in TheLibrary.TypeInfos)
            {
                foreach (Types.MethodInfo aMethodInfo in aTypeInfo.MethodInfos)
                {
                    TheLibrary.ILBlocks.Add(aMethodInfo, ILReader.Read(aMethodInfo));
                }
            }

            return(result);
        }
Exemple #2
0
        /// <summary>
        /// Loads an IL Library from the specified file.
        /// </summary>
        /// <param name="FilePath">The path to the file to load as an IL Library.</param>
        /// <returns>The loaded IL Library.</returns>
        private static ILLibrary LoadILLibraryFromFile(string FilePath)
        {
            if (string.IsNullOrWhiteSpace(FilePath))
            {
                Logger.LogError(Errors.Loader_LibraryPathNullOrEmpty_ErrorCode, FilePath, 0,
                    Errors.ErrorMessages[Errors.Loader_LibraryPathNullOrEmpty_ErrorCode]);

                return null;
            }
            else if (!File.Exists(FilePath))
            {
                Logger.LogError(Errors.Loader_LibraryFileDoesntExist_ErrorCode, FilePath, 0,
                    Errors.ErrorMessages[Errors.Loader_LibraryFileDoesntExist_ErrorCode]);

                return null;
            }

            try
            {
                ILLibrary result = new ILLibrary();
                result.TheAssembly = Assembly.LoadFrom(FilePath);
                return result;
            }
            catch (Exception ex)
            {
                Logger.LogError(Errors.Loader_UnexpectedError_ErrorCode, FilePath, 0,
                    string.Format(
                        Errors.ErrorMessages[Errors.Loader_UnexpectedError_ErrorCode],
                        ex.Message, ex.StackTrace));
            }
            return null;
        }
Exemple #3
0
        /// <summary>
        /// Executes the IL Reader for the specified library.
        /// </summary>
        /// <param name="TheLibrary">The library to read.</param>
        /// <returns>The return value from the IL Reader.</returns>
        private static CompileResult ExecuteILReader(ILLibrary TheLibrary)
        {
            CompileResult result = CompileResult.OK;

            if (TheLibrary.ILRead)
            {
                return result;
            }
            TheLibrary.ILRead = true;

            foreach (ILLibrary depLib in TheLibrary.Dependencies)
            {
                result = result == CompileResult.OK ? ExecuteILReader(depLib) : result;
            }

            foreach (Types.TypeInfo aTypeInfo in TheLibrary.TypeInfos)
            {
                foreach (Types.MethodInfo aMethodInfo in aTypeInfo.MethodInfos)
                {
                    TheLibrary.ILBlocks.Add(aMethodInfo, ILReader.Read(aMethodInfo));
                }
            }

            return result;
        }
Exemple #4
0
        /// <summary>
        /// Executes the IL Scanner for the specified library.
        /// </summary>
        /// <param name="TheLibrary">The library to scan.</param>
        /// <returns>The return value from the IL Scanner.</returns>
        private static CompileResult ExecuteILScanner(ILLibrary TheLibrary)
        {
            CompileResult result = CompileResult.OK;

            result = ILScanner.Scan(TheLibrary);

            return(result);
        }
Exemple #5
0
        /// <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);
        }
Exemple #6
0
        /// <summary>
        /// Executes the IL Preprocessor for the specified library.
        /// </summary>
        /// <param name="TheLibrary">The library to preprocess.</param>
        /// <returns>The return value from the IL Preprocessor.</returns>
        private static CompileResult ExecuteILPreprocessor(ILLibrary TheLibrary)
        {
            CompileResult result = CompileResult.OK;

            ILPreprocessor.Preprocess(TheLibrary);

            ILPreprocessor.PreprocessSpecialClasses(TheLibrary);
            ILPreprocessor.PreprocessSpecialMethods(TheLibrary);

            return(result);
        }
Exemple #7
0
        /// <summary>
        /// Scans the specified plugged IL block.
        /// </summary>
        /// <param name="TheLibrary">The library currently being compiled.</param>
        /// <param name="theMethodInfo">The method which generated the IL block.</param>
        /// <param name="theILBlock">The IL block to scan.</param>
        /// <returns>CompileResult.OK.</returns>
        private static CompileResult ScanPluggedILBlock(ILLibrary TheLibrary, Types.MethodInfo theMethodInfo, ILBlock theILBlock)
        {
            TheLibrary.TheASMLibrary.ASMBlocks.Add(new ASM.ASMBlock()
            {
                PlugPath         = theILBlock.PlugPath,
                OriginMethodInfo = theMethodInfo,
                Priority         = theMethodInfo.Priority
            });

            return(CompileResult.OK);
        }
Exemple #8
0
        /// <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);
        }
Exemple #9
0
        /// <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);
        }
Exemple #10
0
        private static List <Tuple <string, int> > GetSpecialClassFieldInfo(ILLibrary TheLibrary, Type SpecialClassType)
        {
            Types.TypeInfo              InformationAboutInfoStruct         = ILLibrary.SpecialClasses[SpecialClassType].First();
            List <Types.FieldInfo>      InfoStruct_OrderedFields           = InformationAboutInfoStruct.FieldInfos.Where(x => !x.IsStatic).OrderBy(x => x.OffsetInBytes).ToList();
            List <Tuple <string, int> > InfoStruct_OrderedFieldInfo_Subset = new List <Tuple <string, int> >();

            foreach (Types.FieldInfo aField in InfoStruct_OrderedFields)
            {
                Types.TypeInfo FieldTypeInfo = TheLibrary.GetTypeInfo(aField.FieldType);
                InfoStruct_OrderedFieldInfo_Subset.Add(new Tuple <string, int>(aField.Name,
                                                                               FieldTypeInfo.IsValueType ? FieldTypeInfo.SizeOnHeapInBytes : FieldTypeInfo.SizeOnStackInBytes));
            }
            return(InfoStruct_OrderedFieldInfo_Subset);
        }
Exemple #11
0
        /// <summary>
        /// Compiles the specified IL library and any dependencies using the IL Reader, Il Preprocessor and IL Scanner.
        /// </summary>
        /// <remarks>
        /// The IL Compiler's steps read in the IL bytes for each block into IL ops and then preprocess and compile them
        /// into ASM ops.
        /// </remarks>
        /// <param name="TheLibrary">The library to compile.</param>
        /// <returns>CompileResult.OK if all steps complete successfully.</returns>
        public static CompileResult Compile(ILLibrary TheLibrary)
        {
            CompileResult Result = ExecuteILReader(TheLibrary);

            if (Result == CompileResult.OK)
            {
                Result = ExecuteILPreprocessor(TheLibrary);

                if (Result == CompileResult.OK)
                {
                    Result = ExecuteILScanner(TheLibrary);
                }
            }

            return Result;
        }
Exemple #12
0
        /// <summary>
        /// Compiles the specified IL library and any dependencies using the IL Reader, Il Preprocessor and IL Scanner.
        /// </summary>
        /// <remarks>
        /// The IL Compiler's steps read in the IL bytes for each block into IL ops and then preprocess and compile them
        /// into ASM ops.
        /// </remarks>
        /// <param name="TheLibrary">The library to compile.</param>
        /// <returns>CompileResult.OK if all steps complete successfully.</returns>
        public static CompileResult Compile(ILLibrary TheLibrary)
        {
            CompileResult Result = ExecuteILReader(TheLibrary);

            if (Result == CompileResult.OK)
            {
                Result = ExecuteILPreprocessor(TheLibrary);

                if (Result == CompileResult.OK)
                {
                    Result = ExecuteILScanner(TheLibrary);
                }
            }

            return(Result);
        }
Exemple #13
0
        /// <summary>
        /// Scans the specified type's static fields.
        /// </summary>
        /// <param name="TheLibrary">The library currently being compiled.</param>
        /// <param name="TheTypeInfo">The type to scan the static fields of.</param>
        /// <param name="StaticFieldsBlock">The ASM block for the static fields for the library currently being compiled.</param>
        private static void ScanStaticFields(ILLibrary TheLibrary, Types.TypeInfo TheTypeInfo, ASM.ASMBlock StaticFieldsBlock)
        {
            foreach (Types.FieldInfo aFieldInfo in TheTypeInfo.FieldInfos)
            {
                if (aFieldInfo.IsStatic)
                {
                    Types.TypeInfo fieldTypeInfo = TheLibrary.GetTypeInfo(aFieldInfo.FieldType);

                    string FieldID = aFieldInfo.ID;
                    string Size    = fieldTypeInfo.SizeOnStackInBytes.ToString();

                    ASM.ASMOp newStaticFieldOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.StaticField, FieldID, Size);
                    StaticFieldsBlock.Append(newStaticFieldOp);
                }
            }
        }
Exemple #14
0
        /* Tasks of the IL Preprocessor:
         *      - Pre-processing for special classes / methods:
         *              - Static constructors
         *      - Pre-scan IL ops to:
         *              - Type Scan any local variable which are of an unscanned types
         *      - Inject general ops (method start, method end, etc.)
         *      - Inject GC IL ops
         *      - Inject wrapping try-finally for GC
         *      - Inject IL ops for try-catch-finally
         */

        /// <summary>
        /// Preprocesses the specified IL library and any dependencies.
        /// </summary>
        /// <param name="TheLibrary">The library to preprocess.</param>
        public static void Preprocess(ILLibrary TheLibrary)
        {
            if (TheLibrary == null)
            {
                return;
            }

            if (TheLibrary.ILPreprocessed)
            {
                return;
            }
            TheLibrary.ILPreprocessed = true;

            foreach (IL.ILLibrary aDependency in TheLibrary.Dependencies)
            {
                Preprocess(aDependency);
            }
            
            foreach (Types.MethodInfo aMethodInfo in TheLibrary.ILBlocks.Keys)
            {
                PreprocessMethodInfo(TheLibrary, aMethodInfo);
            }

            foreach (Types.MethodInfo aMethodInfo in TheLibrary.ILBlocks.Keys)
            {
                if (!aMethodInfo.IsPlugged)
                {
                    DealWithCatchHandlers(aMethodInfo, TheLibrary.ILBlocks[aMethodInfo]);
                    InjectGeneral1(aMethodInfo, TheLibrary.ILBlocks[aMethodInfo]);
                    InjectGC(TheLibrary, aMethodInfo, TheLibrary.ILBlocks[aMethodInfo]);
                    InjectGeneral2(aMethodInfo, TheLibrary.ILBlocks[aMethodInfo]);
                    InjectTryCatchFinally(aMethodInfo, TheLibrary.ILBlocks[aMethodInfo]);

                    PreprocessILOps(TheLibrary, aMethodInfo, TheLibrary.ILBlocks[aMethodInfo]);
                }
            }
        }
Exemple #15
0
        /// <summary>
        /// Injects the garbage collector related IL ops into the specified method.
        /// </summary>
        /// <param name="TheLibrary">The library being compiled.</param>
        /// <param name="theMethodInfo">The method to inject ops into.</param>
        /// <param name="theILBlock">The IL block for the method to inject ops into.</param>
        private static void InjectGC(ILLibrary TheLibrary, Types.MethodInfo theMethodInfo, ILBlock theILBlock)
        {
            if (theMethodInfo.ApplyGC)
            {
                // Find the index of the MethodStart op
                int MethodStartOpPos = theILBlock.PositionOf(theILBlock.ILOps.Where(x => x is ILOps.MethodStart).First());

                // Inject ops for incrementing ref. count of args at start of method
                int InjectIncArgsRefCountPos = MethodStartOpPos + 1;
                foreach (Types.VariableInfo argInfo in theMethodInfo.ArgumentInfos)
                {
                    if (argInfo.TheTypeInfo.IsGCManaged)
                    {
                        theILBlock.ILOps.Insert(InjectIncArgsRefCountPos, new ILOp()
                        {
                            opCode = System.Reflection.Emit.OpCodes.Ldarg,
                            ValueBytes = BitConverter.GetBytes(argInfo.Position)
                        });
                        theILBlock.ILOps.Insert(InjectIncArgsRefCountPos + 1, new ILOp()
                        {
                            opCode = System.Reflection.Emit.OpCodes.Call,
                            MethodToCall = ILLibrary.SpecialMethods[typeof(Attributes.IncrementRefCountMethodAttribute)].First().UnderlyingInfo
                        });
                    }
                }

                // The following two things can be done within the same loop:
                
                // Inject ops for inc./dec. ref. counts of objects when written to:
                //      - Arguments / Locals
                //      - Fields / Static Fields
                //      - Elements of Arrays

                // Add Cleanup Block and Inject finally-block ops for it
                //      - Also remember the op for storing return value (if any)

                ILPreprocessState preprocessState = new ILPreprocessState()
                {
                    TheILLibrary = TheLibrary,
                    Input = theILBlock,
                    CurrentStackFrame = new StackFrame()
                };

                ExceptionHandledBlock CleanupExBlock = new ExceptionHandledBlock();
                
                for (int opIndx = 0; opIndx < theILBlock.ILOps.Count; opIndx++)
                {
                    ILOp currOp = theILBlock.ILOps[opIndx];
                    bool IncRefCount = false;
                    int incOpIndexBy = 0;
                    
                    switch ((ILOp.OpCodes)currOp.opCode.Value)
                    {
                        case ILOp.OpCodes.Stsfld:
                            #region Stsfld
                            {
                                int metadataToken = Utilities.ReadInt32(currOp.ValueBytes, 0);
                                System.Reflection.FieldInfo theField = theMethodInfo.UnderlyingInfo.Module.ResolveField(metadataToken);
                                Types.TypeInfo theFieldTypeInfo = TheLibrary.GetTypeInfo(theField.FieldType);
                                if (theFieldTypeInfo.IsGCManaged)
                                {
                                    theILBlock.ILOps.Insert(opIndx, new ILOp()
                                    {
                                        opCode = System.Reflection.Emit.OpCodes.Ldsfld,
                                        ValueBytes = currOp.ValueBytes
                                    });
                                    theILBlock.ILOps.Insert(opIndx + 1, new ILOp()
                                    {
                                        opCode = System.Reflection.Emit.OpCodes.Call,
                                        MethodToCall = ILLibrary.SpecialMethods[typeof(Attributes.DecrementRefCountMethodAttribute)].First().UnderlyingInfo
                                    });
                                    
                                    IncRefCount = true;
                                    incOpIndexBy = 2;
                                }
                            }
                            #endregion
                            break;
                        case ILOp.OpCodes.Stloc:
                        case ILOp.OpCodes.Stloc_0:
                        case ILOp.OpCodes.Stloc_1:
                        case ILOp.OpCodes.Stloc_2:
                        case ILOp.OpCodes.Stloc_3:
                        case ILOp.OpCodes.Stloc_S:
                            #region Stloc
                            {
                                UInt16 localIndex = 0;
                                switch ((ILOp.OpCodes)currOp.opCode.Value)
                                {
                                    case ILOp.OpCodes.Stloc:
                                        localIndex = (UInt16)Utilities.ReadInt16(currOp.ValueBytes, 0);
                                        break;
                                    case ILOp.OpCodes.Stloc_0:
                                        localIndex = 0;
                                        break;
                                    case ILOp.OpCodes.Stloc_1:
                                        localIndex = 1;
                                        break;
                                    case ILOp.OpCodes.Stloc_2:
                                        localIndex = 2;
                                        break;
                                    case ILOp.OpCodes.Stloc_3:
                                        localIndex = 3;
                                        break;
                                    case ILOp.OpCodes.Stloc_S:
                                        localIndex = (UInt16)currOp.ValueBytes[0];
                                        break;
                                }
                                Types.TypeInfo LocalTypeInfo = theMethodInfo.LocalInfos[localIndex].TheTypeInfo;
                                if (LocalTypeInfo.IsGCManaged)
                                {
                                    theILBlock.ILOps.Insert(opIndx, new ILOp()
                                    {
                                        opCode = System.Reflection.Emit.OpCodes.Ldloc,
                                        ValueBytes = BitConverter.GetBytes(localIndex)
                                    });
                                    theILBlock.ILOps.Insert(opIndx + 1, new ILOp()
                                    {
                                        opCode = System.Reflection.Emit.OpCodes.Call,
                                        MethodToCall = ILLibrary.SpecialMethods[typeof(Attributes.DecrementRefCountMethodAttribute)].First().UnderlyingInfo
                                    });
                                    
                                    IncRefCount = true;
                                    incOpIndexBy = 2;
                                }
                            }
                            #endregion
                            break;
                        case ILOp.OpCodes.Stfld:
                            #region Stfld
                            {
                                int metadataToken = Utilities.ReadInt32(currOp.ValueBytes, 0);
                                System.Reflection.FieldInfo theField = theMethodInfo.UnderlyingInfo.Module.ResolveField(metadataToken);
                                Types.TypeInfo theFieldTypeInfo = TheLibrary.GetTypeInfo(theField.FieldType);
                                if (theFieldTypeInfo.IsGCManaged)
                                {
                                    // Items on stack:
                                    //  - Object reference
                                    //  - (New) Value to store
                                    //
                                    // We want to load the current value of the field
                                    //  for which we must duplicate the object ref
                                    // But first, we must remove the (new) value to store
                                    //  off the stack, while also storing it to put back
                                    //  on the stack after so the store can continue
                                    //
                                    // So:
                                    //      1. Switch value to store and object ref on stack
                                    //      3. Duplicate the object ref
                                    //      4. Load the field value
                                    //      5. Call dec ref count
                                    //      6. Switch value to store and object ref back again

                                    //USE A SWITCH STACK ITEMS OP!!

                                    theILBlock.ILOps.Insert(opIndx, new ILOps.StackSwitch()
                                    {
                                        StackSwitch_Items = 2
                                    });
                                    
                                    theILBlock.ILOps.Insert(opIndx + 1, new ILOp()
                                    {
                                        opCode = System.Reflection.Emit.OpCodes.Dup
                                    });
                                    theILBlock.ILOps.Insert(opIndx + 2, new ILOp()
                                    {
                                        opCode = System.Reflection.Emit.OpCodes.Ldfld,
                                        ValueBytes = currOp.ValueBytes
                                    });
                                    theILBlock.ILOps.Insert(opIndx + 3, new ILOp()
                                    {
                                        opCode = System.Reflection.Emit.OpCodes.Call,
                                        MethodToCall = ILLibrary.SpecialMethods[typeof(Attributes.DecrementRefCountMethodAttribute)].First().UnderlyingInfo
                                    });

                                    theILBlock.ILOps.Insert(opIndx + 4, new ILOps.StackSwitch()
                                    {
                                        StackSwitch_Items = 2
                                    });

                                    IncRefCount = true;
                                    incOpIndexBy = 5;
                                }
                            }
                            #endregion
                            break;
                        case ILOp.OpCodes.Stelem:
                        case ILOp.OpCodes.Stelem_Ref:
                            #region Stelem / Stelem_Ref
                            {
                                bool doDecrement = false;
                                bool isRefOp = false;
                                if ((ILOp.OpCodes)currOp.opCode.Value == ILOp.OpCodes.Stelem_Ref)
                                {
                                    doDecrement = preprocessState.CurrentStackFrame.Stack.Peek().isGCManaged;
                                    isRefOp = true;
                                }
                                else
                                {
                                    int metadataToken = Utilities.ReadInt32(currOp.ValueBytes, 0);
                                    Type elementType = theMethodInfo.UnderlyingInfo.Module.ResolveType(metadataToken);
                                    doDecrement = TheLibrary.GetTypeInfo(elementType).IsGCManaged;
                                }

                                if (doDecrement)
                                {
                                    // Items on stack:
                                    //  - Array reference
                                    //  - Index
                                    //  - (New) Value to store
                                    //
                                    // We want to load the current value of the element at Index in the array
                                    //  for which we must duplicate the array ref and index
                                    // But first, we must remove the (new) value to store
                                    //  off the stack, while also storing it to put back
                                    //  on the stack after so the store can continue
                                    //
                                    // So:
                                    //      1. Switch (rotate) 1 times the top 3 values so that index is on top
                                    //      2. Duplicate the index
                                    //      3. Switch (rotate) 2 times the top 4 values so that array ref is on top
                                    //      4. Duplicate the array ref
                                    //      5. Switch (rotate) 4 times the top 5 values so that duplicate array ref and index are on top
                                    //      6. Do LdElem op to load existing element value
                                    //      7. Call GC.DecrementRefCount
                                    //      8. Switch (rotate) 1 times the top 3 values so that the stack is in its original state
                                    //      (9. Continue to increment ref count as normal)
                                    //
                                    // The following is a diagram of the stack manipulation occurring here:
                                    //      Key: A=Array ref, I=Index, V=Value to store, E=Loaded element
                                    //      Top-most stack item appears last
                                    //  
                                    //     1) Rotate x 1    2) Duplicate       3)  Rot x 2         4)  Dup
                                    //  A,I,V ---------> V,A,I ---------> V,A,I,I ---------> I,I,V,A ---------> I,I,V,A,A
                                    //
                                    //
                                    //          5) Rot x 4           6) Ldelem        7) Call GC (Dec)
                                    //  I,I,V,A,A ---------> I,V,A,A,I ---------> I,V,A,E ---------> I,V,A
                                    //
                                    //
                                    //      8) Rot x 1       9)  Dup         10) Call GC (Inc)
                                    //  I,V,A ---------> A,I,V ---------> A,I,V,V ---------> A,I,V

                                    #region 1.
                                    theILBlock.ILOps.Insert(opIndx, new ILOps.StackSwitch()
                                    {
                                        ValueBytes = BitConverter.GetBytes(3),
                                        StackSwitch_Items = 3
                                    });
                                    incOpIndexBy++;
                                    #endregion
                                    #region 2.
                                    theILBlock.ILOps.Insert(opIndx + incOpIndexBy, new ILOp()
                                    {
                                        opCode = System.Reflection.Emit.OpCodes.Dup
                                    });
                                    incOpIndexBy++;
                                    #endregion
                                    #region 3.
                                    theILBlock.ILOps.Insert(opIndx + incOpIndexBy, new ILOps.StackSwitch()
                                    {
                                        ValueBytes = BitConverter.GetBytes(4),
                                        StackSwitch_Items = 4
                                    });
                                    incOpIndexBy++;

                                    theILBlock.ILOps.Insert(opIndx + incOpIndexBy, new ILOps.StackSwitch()
                                    {
                                        ValueBytes = BitConverter.GetBytes(4),
                                        StackSwitch_Items = 4
                                    });
                                    incOpIndexBy++;
                                    #endregion
                                    #region 4.
                                    theILBlock.ILOps.Insert(opIndx + incOpIndexBy, new ILOp()
                                    {
                                        opCode = System.Reflection.Emit.OpCodes.Dup
                                    });
                                    incOpIndexBy++;
                                    #endregion
                                    #region 5.
                                    theILBlock.ILOps.Insert(opIndx + incOpIndexBy, new ILOps.StackSwitch()
                                    {
                                        ValueBytes = BitConverter.GetBytes(5),
                                        StackSwitch_Items = 5
                                    });
                                    incOpIndexBy++;
                                    theILBlock.ILOps.Insert(opIndx + incOpIndexBy, new ILOps.StackSwitch()
                                    {
                                        ValueBytes = BitConverter.GetBytes(5),
                                        StackSwitch_Items = 5
                                    });
                                    incOpIndexBy++;
                                    theILBlock.ILOps.Insert(opIndx + incOpIndexBy, new ILOps.StackSwitch()
                                    {
                                        ValueBytes = BitConverter.GetBytes(5),
                                        StackSwitch_Items = 5
                                    });
                                    incOpIndexBy++;
                                    theILBlock.ILOps.Insert(opIndx + incOpIndexBy, new ILOps.StackSwitch()
                                    {
                                        ValueBytes = BitConverter.GetBytes(5),
                                        StackSwitch_Items = 5
                                    });
                                    incOpIndexBy++;
                                    #endregion
                                    #region 6.
                                    theILBlock.ILOps.Insert(opIndx + incOpIndexBy, new ILOp()
                                    {
                                        opCode = isRefOp ? System.Reflection.Emit.OpCodes.Ldelem_Ref : System.Reflection.Emit.OpCodes.Ldelem,
                                        ValueBytes = currOp.ValueBytes
                                    });
                                    incOpIndexBy++;
                                    #endregion
                                    #region 7.
                                    theILBlock.ILOps.Insert(opIndx + incOpIndexBy, new ILOp()
                                    {
                                        opCode = System.Reflection.Emit.OpCodes.Call,
                                        MethodToCall = ILLibrary.SpecialMethods[typeof(Attributes.DecrementRefCountMethodAttribute)].First().UnderlyingInfo
                                    });
                                    incOpIndexBy++;
                                    #endregion
                                    #region 8.
                                    theILBlock.ILOps.Insert(opIndx + incOpIndexBy, new ILOps.StackSwitch()
                                    {
                                        ValueBytes = BitConverter.GetBytes(3),
                                        StackSwitch_Items = 3
                                    });
                                    incOpIndexBy++;
                                    #endregion

                                    IncRefCount = true;
                                }
                            }
                            #endregion
                            break;
                        case ILOp.OpCodes.Starg:
                        case ILOp.OpCodes.Starg_S:
                            #region Starg
                            {
                                UInt16 index = (ILOp.OpCodes)currOp.opCode.Value == ILOp.OpCodes.Starg_S ? 
                                    (UInt16)currOp.ValueBytes[0] : (UInt16)Utilities.ReadInt16(currOp.ValueBytes, 0);
                                if (theMethodInfo.ArgumentInfos[index].TheTypeInfo.IsGCManaged)
                                {
                                    theILBlock.ILOps.Insert(opIndx, new ILOp()
                                    {
                                        opCode = System.Reflection.Emit.OpCodes.Ldarg,
                                        ValueBytes = BitConverter.GetBytes(index)
                                    });
                                    theILBlock.ILOps.Insert(opIndx + 1, new ILOp()
                                    {
                                        opCode = System.Reflection.Emit.OpCodes.Call,
                                        MethodToCall = ILLibrary.SpecialMethods[typeof(Attributes.DecrementRefCountMethodAttribute)].First().UnderlyingInfo
                                    });

                                    IncRefCount = true;
                                    incOpIndexBy = 2;
                                }
                            }
                            #endregion
                            break;
                    }

                    if (IncRefCount &&
                        !preprocessState.CurrentStackFrame.Stack.Peek().isNewGCObject)
                    {
                        theILBlock.ILOps.Insert(opIndx + incOpIndexBy, new ILOp()
                        {
                            opCode = System.Reflection.Emit.OpCodes.Dup
                        });
                        incOpIndexBy++;
                        theILBlock.ILOps.Insert(opIndx + incOpIndexBy, new ILOp()
                        {
                            opCode = System.Reflection.Emit.OpCodes.Call,
                            MethodToCall = ILLibrary.SpecialMethods[typeof(Attributes.IncrementRefCountMethodAttribute)].First().UnderlyingInfo
                        });
                        incOpIndexBy++;
                    }

                    // If op changed
                    if (theILBlock.ILOps[opIndx] != currOp)
                    {
                        theILBlock.ILOps[opIndx].Offset = currOp.Offset;
                        theILBlock.ILOps[opIndx].BytesSize = currOp.BytesSize;
                    }

                    // <= is correct. E.g. if 1 extra op added, incOpIndex=1 so <= results in currOp processed
                    //      + extra op processed
                    bool UseNextOpAsCleanupStart = false;
                    for (int i = 0; i <= incOpIndexBy; i++)
                    {
                        currOp = theILBlock.ILOps[opIndx];

                        if (UseNextOpAsCleanupStart)
                        {
                            UseNextOpAsCleanupStart = false;

                            CleanupExBlock.Offset = currOp.Offset;
                        }

                        if (currOp is ILOps.MethodStart)
                        {
                            TargetArchitecture.MethodStartOp.PerformStackOperations(preprocessState, theILBlock.ILOps[opIndx]);
                            UseNextOpAsCleanupStart = true;
                        }
                        else if (currOp is ILOps.MethodEnd)
                        {
                            TargetArchitecture.MethodEndOp.PerformStackOperations(preprocessState, theILBlock.ILOps[opIndx]);
                        }
                        else if (currOp is ILOps.StackSwitch)
                        {
                            TargetArchitecture.StackSwitchOp.PerformStackOperations(preprocessState, theILBlock.ILOps[opIndx]);
                        }
                        else
                        {
                            // Leave unsupported ops for the IL Scanner to deal with (or later code e.g. castclass op)
                            if (TargetArchitecture.TargetILOps.ContainsKey((ILOp.OpCodes)currOp.opCode.Value))
                            {
                                ILOp ConverterOp = TargetArchitecture.TargetILOps[(ILOp.OpCodes)currOp.opCode.Value];
                                ConverterOp.PerformStackOperations(preprocessState, currOp);
                            }
                        }

                        if (i > 0)
                        {
                            opIndx++;
                        }
                    }
                }

                if (theMethodInfo.ArgumentInfos.Count > 0 ||
                    theMethodInfo.LocalInfos.Count > 0)
                {
                    bool AddCleanupBlock = false;
                    foreach (Types.VariableInfo anArgInfo in theMethodInfo.ArgumentInfos)
                    {
                        if (anArgInfo.TheTypeInfo.IsGCManaged)
                        {
                            AddCleanupBlock = true;
                            break;
                        }
                    }
                    if (!AddCleanupBlock)
                    {
                        foreach (Types.VariableInfo aLocInfo in theMethodInfo.LocalInfos)
                        {
                            if (aLocInfo.TheTypeInfo.IsGCManaged)
                            {
                                AddCleanupBlock = true;
                                break;
                            }
                        }
                    }

                    if (AddCleanupBlock)
                    {
                        ILOp lastOp = theILBlock.ILOps.Last();
                        int lastOpOffset = lastOp.Offset;
                        int lastOpIndex = theILBlock.ILOps.Count - 1;
                        bool MethodHasReturnValue = false;

                        // If there is a return value, we will need to temp store it
                        if (theMethodInfo.UnderlyingInfo is System.Reflection.MethodInfo)
                        {
                            Type returnType = ((System.Reflection.MethodInfo)theMethodInfo.UnderlyingInfo).ReturnType;
                            //Void return type = no return value
                            if (returnType != typeof(void))
                            {
                                // Add local variable for storing return value
                                int lastLocalOffset = theMethodInfo.LocalInfos.Count > 0 ? theMethodInfo.LocalInfos.Last().Offset : 0;
                                int lastLocalSize = theMethodInfo.LocalInfos.Count > 0 ? theMethodInfo.LocalInfos.Last().TheTypeInfo.SizeOnStackInBytes : 0;
                                theMethodInfo.LocalInfos.Add(new Types.VariableInfo()
                                {
                                    UnderlyingType = returnType,
                                    TheTypeInfo = TheLibrary.GetTypeInfo(returnType),
                                    Position = theMethodInfo.LocalInfos.Count,
                                    Offset = lastLocalOffset + lastLocalSize
                                });

                                // Add op for storing return value, update op offsets
                                theILBlock.ILOps.Insert(lastOpIndex, new ILOp()
                                {
                                    opCode = System.Reflection.Emit.OpCodes.Stloc,
                                    Offset = lastOpOffset,
                                    BytesSize = lastOp.BytesSize,
                                    ValueBytes = BitConverter.GetBytes(theMethodInfo.LocalInfos.Count - 1)
                                });
                                lastOpIndex++;

                                MethodHasReturnValue = true;
                            }
                        }

                        ILOp leaveOp;
                        // Add the Leave op of the try-block
                        theILBlock.ILOps.Insert(lastOpIndex, leaveOp = new ILOp()
                        {
                            opCode = System.Reflection.Emit.OpCodes.Leave,
                            Offset = lastOpOffset,
                            BytesSize = lastOp.BytesSize,
                            ValueBytes = BitConverter.GetBytes(0)
                        });
                        lastOpIndex++;

                        FinallyBlock CleanupFinallyBlock = new FinallyBlock()
                        {
                            Offset = lastOpOffset + lastOp.BytesSize,
                            Length = 0
                        };
                        CleanupExBlock.Length = lastOpOffset - CleanupExBlock.Offset;
                        CleanupExBlock.FinallyBlocks.Add(CleanupFinallyBlock);

                        int cleanupOpsOffset = lastOpOffset + 1;

                        // Add cleanup code for local variables (including the return value local)
                        foreach (Types.VariableInfo aLocInfo in theMethodInfo.LocalInfos)
                        {
                            if (aLocInfo.TheTypeInfo.IsGCManaged)
                            {
                                theILBlock.ILOps.Insert(lastOpIndex, new ILOp()
                                {
                                    opCode = System.Reflection.Emit.OpCodes.Ldloc,
                                    Offset = cleanupOpsOffset,
                                    BytesSize = 1,
                                    ValueBytes = BitConverter.GetBytes(aLocInfo.Position)
                                });
                                cleanupOpsOffset++;
                                lastOpIndex++;

                                theILBlock.ILOps.Insert(lastOpIndex, new ILOp()
                                {
                                    opCode = System.Reflection.Emit.OpCodes.Call,
                                    Offset = cleanupOpsOffset,
                                    BytesSize = 1,
                                    MethodToCall = ILLibrary.SpecialMethods[typeof(Attributes.DecrementRefCountMethodAttribute)].First().UnderlyingInfo
                                });
                                cleanupOpsOffset++;
                                lastOpIndex++;

                                CleanupFinallyBlock.Length += 2;
                            }
                        }

                        // Add cleanup code for arguments
                        foreach (Types.VariableInfo anArgInfo in theMethodInfo.ArgumentInfos)
                        {
                            if (anArgInfo.TheTypeInfo.IsGCManaged)
                            {
                                theILBlock.ILOps.Insert(lastOpIndex, new ILOp()
                                {
                                    opCode = System.Reflection.Emit.OpCodes.Ldarg,
                                    Offset = cleanupOpsOffset,
                                    BytesSize = 1,
                                    ValueBytes = BitConverter.GetBytes(anArgInfo.Position)
                                });
                                cleanupOpsOffset++;
                                lastOpIndex++;

                                theILBlock.ILOps.Insert(lastOpIndex, new ILOp()
                                {
                                    opCode = System.Reflection.Emit.OpCodes.Call,
                                    Offset = cleanupOpsOffset,
                                    BytesSize = 1,
                                    MethodToCall = ILLibrary.SpecialMethods[typeof(Attributes.DecrementRefCountMethodAttribute)].First().UnderlyingInfo
                                });
                                cleanupOpsOffset++;
                                lastOpIndex++;

                                CleanupFinallyBlock.Length += 2;
                            }
                        }

                        // Add end finally op
                        theILBlock.ILOps.Insert(lastOpIndex, leaveOp.LoadAtILOpAfterOp = new ILOp()
                        {
                            opCode = System.Reflection.Emit.OpCodes.Endfinally,
                            Offset = cleanupOpsOffset,
                            BytesSize = 1
                        });
                        cleanupOpsOffset++;
                        lastOpIndex++;
                        
                        CleanupFinallyBlock.Length++;

                        // Add restore return value op
                        if (MethodHasReturnValue)
                        {
                            theILBlock.ILOps.Insert(lastOpIndex, new ILOp()
                            {
                                opCode = System.Reflection.Emit.OpCodes.Ldloc,
                                Offset = cleanupOpsOffset,
                                BytesSize = 1,
                                ValueBytes = BitConverter.GetBytes(theMethodInfo.LocalInfos.Count - 1)
                            });
                            cleanupOpsOffset++;
                            lastOpIndex++;
                        }

                        // Add ex block to the method
                        theILBlock.ExceptionHandledBlocks.Add(CleanupExBlock);

                        // Replace any Ret ops contained within Cleanup Block with:
                        //      - Op to store return value (if any)
                        //      - Leave op
                        bool Inside = false;
                        for(int opIndx = 0; opIndx < theILBlock.ILOps.Count; opIndx++)
                        {
                            if (theILBlock.ILOps[opIndx].Offset > CleanupExBlock.Offset + CleanupExBlock.Length)
                            {
                                break;
                            }
                            else if (theILBlock.ILOps[opIndx].Offset >= CleanupExBlock.Offset)
                            {
                                Inside = true;
                            }

                            if (Inside &&
                                (ILOp.OpCodes)theILBlock.ILOps[opIndx].opCode.Value == ILOp.OpCodes.Ret)
                            {
                                ILOp ARetOp = theILBlock.ILOps[opIndx];
                                theILBlock.ILOps.RemoveAt(opIndx);

                                if (MethodHasReturnValue)
                                {
                                    theILBlock.ILOps.Insert(opIndx, new ILOp()
                                    {
                                        opCode = System.Reflection.Emit.OpCodes.Stloc,
                                        Offset = ARetOp.Offset,
                                        ValueBytes = BitConverter.GetBytes(theMethodInfo.LocalInfos.Count - 1)
                                    });
                                    theILBlock.ILOps.Insert(opIndx + 1, new ILOp()
                                    {
                                        Offset = ARetOp.Offset,
                                        opCode = System.Reflection.Emit.OpCodes.Leave,
                                        ValueBytes = BitConverter.GetBytes(0),
                                        LoadAtILOpAfterOp = leaveOp.LoadAtILOpAfterOp
                                    });
                                }
                                else
                                {
                                    theILBlock.ILOps.Insert(opIndx, new ILOp()
                                    {
                                        Offset = ARetOp.Offset,
                                        opCode = System.Reflection.Emit.OpCodes.Leave,
                                        ValueBytes = BitConverter.GetBytes(0),
                                        LoadAtILOpAfterOp = leaveOp.LoadAtILOpAfterOp
                                    });
                                }
                            }
                        }
                    }
                }
            }
        }
Exemple #16
0
        /// <summary>
        /// Preprocesses the IL ops of the specified method/IL block.
        /// </summary>
        /// <param name="TheLibrary">The library being compiled.</param>
        /// <param name="theMethodInfo">The method to preprocess.</param>
        /// <param name="theILBlock">The IL block for the method to preprocess.</param>
        private static void PreprocessILOps(ILLibrary TheLibrary, Types.MethodInfo theMethodInfo, ILBlock theILBlock)
        {
            StaticConstructorDependency staticConstructorDependencyRoot = null;
            if (theMethodInfo.UnderlyingInfo is System.Reflection.ConstructorInfo &&
                        theMethodInfo.IsStatic)
            {
                System.Reflection.ConstructorInfo aConstructor = (System.Reflection.ConstructorInfo)theMethodInfo.UnderlyingInfo;
                staticConstructorDependencyRoot = ILLibrary.TheStaticConstructorDependencyTree[aConstructor];
                if (staticConstructorDependencyRoot == null)
                {
                    staticConstructorDependencyRoot = new StaticConstructorDependency()
                    {
                        TheConstructor = aConstructor
                    };
                    ILLibrary.TheStaticConstructorDependencyTree.Children.Add(staticConstructorDependencyRoot);
                }
            }

            ILPreprocessState preprosState = new ILPreprocessState()
            {
                TheILLibrary = TheLibrary,
                Input = theILBlock
            };

            for (int i = 0; i < theILBlock.ILOps.Count; i++)
            {
                ILOp theOp = theILBlock.ILOps[i];

                // Remove cast class ops
                if ((ILOp.OpCodes)theOp.opCode.Value == ILOp.OpCodes.Castclass)
                {
                    theILBlock.ILOps.RemoveAt(i);
                    i--;
                    continue;
                }
                else if ((ILOp.OpCodes)theOp.opCode.Value == ILOp.OpCodes.Call)
                {
                    if (theOp.MethodToCall != null && 
                        theOp.MethodToCall.DeclaringType.AssemblyQualifiedName.Contains("mscorlib"))
                    {
                        //We do not want to process ops which attempt to call methods in mscorlib!
                        theILBlock.ILOps.RemoveAt(i);
                        i--;

                        //We do not allow calls to methods declared in MSCorLib.
                        //Some of these calls can just be ignored (e.g. GetTypeFromHandle is
                        //  called by typeof operator).
                        //Ones which can't be ignored, will result in an error...by virtue of
                        //  the fact that they were ignored when they were required.

                        //But just to make sure we save ourselves a headache later when
                        //  runtime debugging, output a message saying we ignored the call.

                        // TODO - IL level comments
                        // result.ASM.AppendLine("; Call to method defined in MSCorLib ignored:"); // DEBUG INFO
                        // result.ASM.AppendLine("; " + anILOpInfo.MethodToCall.DeclaringType.FullName + "." + anILOpInfo.MethodToCall.Name); // DEBUG INFO

                        //If the method is a call to a constructor in MsCorLib:
                        if (theOp.MethodToCall is System.Reflection.ConstructorInfo)
                        {
                            //Then we can presume it was a call to a base-class constructor (e.g. the Object constructor)
                            //  and so we just need to remove any args that were loaded onto the stack.
                            // TODO: result.ASM.AppendLine("; Method to call was constructor so removing params"); // DEBUG INFO
                            
                            //Remove args from stack
                            //If the constructor was non-static, then the first arg is the instance reference.
                            if (!theOp.MethodToCall.IsStatic)
                            {
                                i++;
                                theILBlock.ILOps.Insert(i, new ILOp()
                                {
                                    opCode = System.Reflection.Emit.OpCodes.Pop
                                });
                            }
                            foreach (System.Reflection.ParameterInfo anInfo in theOp.MethodToCall.GetParameters())
                            {
                                i++;
                                theILBlock.ILOps.Insert(i, new ILOp()
                                {
                                    opCode = System.Reflection.Emit.OpCodes.Pop
                                });
                            }
                        }
                    }
                }

                try
                {
                    ILOp ConverterOp = TargetArchitecture.TargetILOps[(ILOp.OpCodes)theOp.opCode.Value];

                    ConverterOp.Preprocess(preprosState, theOp);

                    if (staticConstructorDependencyRoot != null)
                    {
                        //Create our static constructor dependency tree

                        //Each of these ops could try to access a static method or field
                        switch ((ILOp.OpCodes)theOp.opCode.Value)
                        {
                            case ILOp.OpCodes.Call:
                                //Check if the method to call is static and not a constructor itself
                                //If so, we must add the declaring type's static constructors to the tree
                                if(theOp.ValueBytes != null && theOp.ValueBytes.Length > 0)
                                {
                                    int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
                                    System.Reflection.MethodBase methodBaseInf = theMethodInfo.UnderlyingInfo.Module.ResolveMethod(metadataToken);
                                    if (!(methodBaseInf.IsConstructor || methodBaseInf is System.Reflection.ConstructorInfo))
                                    {
                                        System.Reflection.MethodInfo methodInf = (System.Reflection.MethodInfo)methodBaseInf;
                                        System.Reflection.ConstructorInfo[] staticConstructors = 
                                            methodInf.DeclaringType.GetConstructors(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)
                                                .Concat(methodInf.DeclaringType.GetConstructors(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic))
                                                .ToArray();
                                        if (staticConstructors.Length > 0)
                                        {
                                            System.Reflection.ConstructorInfo TheConstructor = staticConstructors[0];
                                            if (staticConstructorDependencyRoot[TheConstructor] == null)
                                            {
                                                staticConstructorDependencyRoot.Children.Add(new StaticConstructorDependency()
                                                {
                                                    TheConstructor = TheConstructor
                                                });
                                            }
                                        }
                                    }
                                }
                                break;
                            case ILOp.OpCodes.Ldsfld:
                            case ILOp.OpCodes.Ldsflda:
                            case ILOp.OpCodes.Stsfld:
                                {
                                    int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
                                    System.Reflection.FieldInfo fieldInf = theMethodInfo.UnderlyingInfo.Module.ResolveField(metadataToken);
                                    System.Reflection.ConstructorInfo[] staticConstructors = fieldInf.DeclaringType.GetConstructors(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public)
                                                                   .Concat(fieldInf.DeclaringType.GetConstructors(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic))
                                                                   .ToArray();
                                    if (staticConstructors.Length > 0)
                                    {
                                        System.Reflection.ConstructorInfo TheConstructor = staticConstructors[0];
                                        if (staticConstructorDependencyRoot[TheConstructor] == null)
                                        {
                                            staticConstructorDependencyRoot.Children.Add(new StaticConstructorDependency()
                                            {
                                                TheConstructor = TheConstructor
                                            });
                                        }
                                    }
                                }
                                break;
                        }
                    }                    
                }
                catch (KeyNotFoundException)
                {
                    //Ignore - will be caught by Il scanner
                }
                catch (Exception ex)
                {
                    Logger.LogError("ILPRE", theILBlock.TheMethodInfo.ToString(), 0,
                        "Il Preprocessor error: PreprocessILOps: " + ex.Message);
                }
            }
        }
Exemple #17
0
 /// <summary>
 /// Gets the next unique ID for a method of the specified type.
 /// </summary>
 /// <remarks>
 /// Used for generatign IDs to go in the method tables for use in virtual calls (callvirt Il ops).
 /// </remarks>
 /// <param name="TheLibrary">The IL library being compiled.</param>
 /// <param name="aTypeInfo">The type to get the next method ID from.</param>
 /// <returns>The next unique method ID.</returns>
 private static int GetMethodIDGenerator(ILLibrary TheLibrary, Types.TypeInfo aTypeInfo)
 {
     int totalGen = aTypeInfo.MethodIDGenerator;
     if (aTypeInfo.UnderlyingType.BaseType != null)
     {
         if (!aTypeInfo.UnderlyingType.BaseType.AssemblyQualifiedName.Contains("mscorlib"))
         {
             totalGen += GetMethodIDGenerator(TheLibrary, aTypeInfo.UnderlyingType.BaseType);
         }
     }
     return totalGen;
 }
Exemple #18
0
 /// <summary>
 /// Gets the next unique ID for a method of the specified type.
 /// </summary>
 /// <remarks>
 /// Used for generatign IDs to go in the method tables for use in virtual calls (callvirt Il ops).
 /// </remarks>
 /// <param name="TheLibrary">The IL library being compiled.</param>
 /// <param name="aType">The type to get the next method ID from.</param>
 /// <returns>The next unique method ID.</returns>
 private static int GetMethodIDGenerator(ILLibrary TheLibrary, Type aType)
 {
     Types.TypeInfo aTypeInfo = TheLibrary.GetTypeInfo(aType);
     return GetMethodIDGenerator(TheLibrary, aTypeInfo);
 }
Exemple #19
0
        /// <summary>
        /// Preprocesses the specified method.
        /// </summary>
        /// <param name="TheLibrary">The library being compiled.</param>
        /// <param name="theMethodInfo">The method to preprocess.</param>
        private static void PreprocessMethodInfo(ILLibrary TheLibrary, Types.MethodInfo theMethodInfo)
        {
            if (theMethodInfo.Preprocessed)
            {
                return;
            }
            theMethodInfo.Preprocessed = true;

            string sig = theMethodInfo.Signature;
            bool SetMethodID = true;
            if (!theMethodInfo.IsConstructor)
            {
                System.Reflection.MethodInfo methodInf = (System.Reflection.MethodInfo)theMethodInfo.UnderlyingInfo;
                if (methodInf.GetBaseDefinition() != methodInf)
                {
                    Types.MethodInfo baseMethodInfo = TheLibrary.GetMethodInfo(methodInf.GetBaseDefinition());
                    PreprocessMethodInfo(TheLibrary, baseMethodInfo);
                    theMethodInfo.IDValue = baseMethodInfo.IDValue;
                    SetMethodID = false;
                }
            }
            if (SetMethodID)
            {
                Types.TypeInfo declarerTypeInfo = TheLibrary.GetTypeInfo(theMethodInfo.UnderlyingInfo.DeclaringType);
                int ID = GetMethodIDGenerator(TheLibrary, declarerTypeInfo);
                theMethodInfo.IDValue = ID + 1;
                declarerTypeInfo.MethodIDGenerator++;
            }

            int totalLocalsOffset = 0;
            foreach (Types.VariableInfo aVarInfo in theMethodInfo.LocalInfos)
            {
                //Causes processing of the type - in case it hasn't already been processed
                Types.TypeInfo aTypeInfo = TheLibrary.GetTypeInfo(aVarInfo.UnderlyingType);
                aVarInfo.TheTypeInfo = aTypeInfo;
                aVarInfo.Offset = totalLocalsOffset;
                totalLocalsOffset += aTypeInfo.SizeOnStackInBytes;
            }

            int totalArgsSize = 0;
            if (!theMethodInfo.IsStatic)
            {
                Types.VariableInfo newVarInfo = new Types.VariableInfo()
                {
                    UnderlyingType = theMethodInfo.UnderlyingInfo.DeclaringType,
                    Position = 0,
                    TheTypeInfo = TheLibrary.GetTypeInfo(theMethodInfo.UnderlyingInfo.DeclaringType)
                };

                theMethodInfo.ArgumentInfos.Add(newVarInfo);

                totalArgsSize += newVarInfo.TheTypeInfo.SizeOnStackInBytes;
            }
            System.Reflection.ParameterInfo[] args = theMethodInfo.UnderlyingInfo.GetParameters();
            foreach (System.Reflection.ParameterInfo argItem in args)
            {
                Types.VariableInfo newVarInfo = new Types.VariableInfo()
                {
                    UnderlyingType = argItem.ParameterType,
                    Position = theMethodInfo.ArgumentInfos.Count,
                    TheTypeInfo = TheLibrary.GetTypeInfo(argItem.ParameterType)
                };

                theMethodInfo.ArgumentInfos.Add(newVarInfo);
                totalArgsSize += newVarInfo.TheTypeInfo.SizeOnStackInBytes;
            }

            //System.Reflection.ParameterInfo returnArgItem = (theMethodInfo.IsConstructor ? null : ((System.Reflection.MethodInfo)theMethodInfo.UnderlyingInfo).ReturnParameter);
            //if (returnArgItem != null)
            //{
            //    Types.VariableInfo newVarInfo = new Types.VariableInfo()
            //    {
            //        UnderlyingType = returnArgItem.ParameterType,
            //        Position = theMethodInfo.ArgumentInfos.Count,
            //        TheTypeInfo = TheLibrary.GetTypeInfo(returnArgItem.ParameterType)
            //    };

            //    theMethodInfo.ArgumentInfos.Add(newVarInfo);
            //    totalArgsSize += newVarInfo.TheTypeInfo.SizeOnStackInBytes;
            //}

            int offset = totalArgsSize;
            for (int i = 0; i < theMethodInfo.ArgumentInfos.Count; i++)
            {
                offset -= theMethodInfo.ArgumentInfos[i].TheTypeInfo.SizeOnStackInBytes;
                theMethodInfo.ArgumentInfos[i].Offset = offset;
            }
        }
Exemple #20
0
 /// <summary>
 /// Preprocesses any special methods within the specified library.
 /// </summary>
 /// <param name="RootLibrary">The root library being compiled.</param>
 public static void PreprocessSpecialMethods(ILLibrary RootLibrary)
 {
     // Setup calls to Static Constructors
     Types.MethodInfo CallStaticConstructorsInfo = ILLibrary.SpecialMethods[typeof(Attributes.CallStaticConstructorsMethodAttribute)].First();
     ILBlock CallStaticConstructorsBlock = RootLibrary.GetILBlock(CallStaticConstructorsInfo);
     List<System.Reflection.ConstructorInfo> staticConstructorsToCall = ILLibrary.TheStaticConstructorDependencyTree.Flatten();
     foreach (System.Reflection.ConstructorInfo anInfo in staticConstructorsToCall)
     {
         CallStaticConstructorsBlock.ILOps.Insert(CallStaticConstructorsBlock.ILOps.Count - 1,
             new ILOp()
             {
                 opCode = System.Reflection.Emit.OpCodes.Call,
                 ValueBytes = null,
                 MethodToCall = anInfo
             }
         );
     }
 }
Exemple #21
0
        /// <summary>
        /// Scans the specified type's static fields.
        /// </summary>
        /// <param name="TheLibrary">The library currently being compiled.</param>
        /// <param name="TheTypeInfo">The type to scan the static fields of.</param>
        /// <param name="StaticFieldsBlock">The ASM block for the static fields for the library currently being compiled.</param>
        private static void ScanStaticFields(ILLibrary TheLibrary, Types.TypeInfo TheTypeInfo, ASM.ASMBlock StaticFieldsBlock)
        {
            foreach (Types.FieldInfo aFieldInfo in TheTypeInfo.FieldInfos)
            {
                if (aFieldInfo.IsStatic)
                {
                    Types.TypeInfo fieldTypeInfo = TheLibrary.GetTypeInfo(aFieldInfo.FieldType);

                    string FieldID = aFieldInfo.ID;
                    string Size = fieldTypeInfo.SizeOnStackInBytes.ToString();

                    ASM.ASMOp newStaticFieldOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.StaticField, FieldID, Size);
                    StaticFieldsBlock.Append(newStaticFieldOp);
                }
            }
        }
Exemple #22
0
        /// <summary>
        /// Executes the IL Scanner for the specified library.
        /// </summary>
        /// <param name="TheLibrary">The library to scan.</param>
        /// <returns>The return value from the IL Scanner.</returns>
        private static CompileResult ExecuteILScanner(ILLibrary TheLibrary)
        {
            CompileResult result = CompileResult.OK;

            result = ILScanner.Scan(TheLibrary);

            return result;
        }
Exemple #23
0
        public static void SaveLibraryInfo(string FolderPath, IL.ILLibrary TheLibrary)
        {
            string RootAssemblyName = Utilities.CleanFileName(TheLibrary.TheAssembly.GetName().Name);

            using (StreamWriter Str = new StreamWriter(Path.Combine(FolderPath, RootAssemblyName + "_Dependencies.txt"), false))
            {
                foreach (IL.ILLibrary DependencyLibrary in TheLibrary.Dependencies)
                {
                    Str.WriteLine(Utilities.CleanFileName(DependencyLibrary.TheAssembly.GetName().Name));
                }
            }

            using (StreamWriter Str = new StreamWriter(Path.Combine(FolderPath, RootAssemblyName + "_Library.txt"), false))
            {
                foreach (Types.TypeInfo ATypeInfo in TheLibrary.TypeInfos)
                {
                    //TypeID
                    //¬BaseTypeID:[ID]
                    //¬IsGCManaged:[Boolean]
                    //¬IsPointer:[Boolean]
                    //¬IsValueType:[Boolean]
                    //¬SizeOnHeapInBytes:[Integer]
                    //¬SizeOnStackInBytes:[Integer]
                    //|Field:[ID]
                    //~Type:[TypeID]
                    //~IsStatic:[Boolean]
                    //~Name:[String]
                    //~OffsetInBytes:[Integer]
                    //|Method:[ID]
                    //~ApplyDebug:[Boolean]
                    //~ApplyGC:[Boolean]
                    //~IDValue:[Integer]
                    //~IsConstructor:[Boolean]
                    //~IsPlugged:[Boolean]
                    //~IsStatic:[Boolean]
                    //~Signature:[String]
                    //~Argument:Offset|Position|TypeID
                    //~Local:Offset|Position|TypeID

                    Str.WriteLine(ATypeInfo.ID);
                    if (ATypeInfo.UnderlyingType.BaseType != null &&
                        !ATypeInfo.UnderlyingType.BaseType.AssemblyQualifiedName.Contains("mscorlib"))
                    {
                        Str.WriteLine("¬BaseTypeID:" + TheLibrary.GetTypeInfo(ATypeInfo.UnderlyingType.BaseType).ID);
                    }
                    Str.WriteLine("¬IsGCManaged:" + ATypeInfo.IsGCManaged.ToString());
                    Str.WriteLine("¬IsPointer:" + ATypeInfo.IsPointer.ToString());
                    Str.WriteLine("¬IsValueType:" + ATypeInfo.IsValueType.ToString());
                    Str.WriteLine("¬SizeOnHeapInBytes:" + ATypeInfo.SizeOnHeapInBytes.ToString());
                    Str.WriteLine("¬SizeOnStackInBytes:" + ATypeInfo.SizeOnStackInBytes.ToString());

                    foreach (Types.FieldInfo AFieldInfo in ATypeInfo.FieldInfos)
                    {
                        Str.WriteLine("|Field:" + AFieldInfo.ID);
                        Str.WriteLine("~Type:" + TheLibrary.GetTypeInfo(AFieldInfo.FieldType).ID);
                        Str.WriteLine("~IsStatic:" + AFieldInfo.IsStatic.ToString());
                        Str.WriteLine("~Name:" + AFieldInfo.Name);
                        Str.WriteLine("~OffsetInBytes:" + AFieldInfo.OffsetInBytes.ToString());
                    }

                    foreach (Types.MethodInfo AMethodInfo in ATypeInfo.MethodInfos)
                    {
                        Str.WriteLine("|Method:" + AMethodInfo.ID);
                        Str.WriteLine("~ApplyDebug:" + AMethodInfo.ApplyDebug.ToString());
                        Str.WriteLine("~ApplyGC:" + AMethodInfo.ApplyGC.ToString());
                        Str.WriteLine("~IDValue:" + AMethodInfo.IDValue.ToString());
                        Str.WriteLine("~IsConstructor:" + AMethodInfo.IsConstructor.ToString());
                        Str.WriteLine("~IsPlugged:" + AMethodInfo.IsPlugged.ToString());
                        Str.WriteLine("~IsStatic:" + AMethodInfo.IsStatic.ToString());
                        Str.WriteLine("~Signature:" + AMethodInfo.Signature);

                        Type RetType = (AMethodInfo.IsConstructor ?
                                        typeof(void) : ((System.Reflection.MethodInfo)AMethodInfo.UnderlyingInfo).ReturnType);
                        Str.WriteLine("~ReturnSize:" + Types.TypeScanner.GetSizeOnStackInBytes(RetType));

                        foreach (Types.VariableInfo AnArgumentInfo in AMethodInfo.ArgumentInfos)
                        {
                            Str.WriteLine("~Argument:" + AnArgumentInfo.Offset.ToString() + "|" + AnArgumentInfo.Position.ToString() + "|" + AnArgumentInfo.TheTypeInfo.ID);
                        }
                        foreach (Types.VariableInfo ALocalInfo in AMethodInfo.LocalInfos)
                        {
                            Str.WriteLine("~Local:" + ALocalInfo.Offset.ToString() + "|" + ALocalInfo.Position.ToString() + "|" + ALocalInfo.TheTypeInfo.ID);
                        }
                    }
                }
            }
        }
Exemple #24
0
        /// <summary>
        /// Performs the link.
        /// </summary>
        /// <param name="TheLibrary">The root library to link.</param>
        /// <returns>CompileResult.OK if the link succeeded. Otherwise, CompileResult.Fail.</returns>
        public static CompileResult Link(IL.ILLibrary TheLibrary, bool dependency = false, string Name = null)
        {
            bool OK = true;

            // If: Link to ELF and Libraries
            //      - Link sub-libs to .a files
            //      - Link main lib to .elf file (if present)
            // If: Link to ISO
            //      - Generate basic link-script
            //      - Generate full link-script by inserting necessary file location instructions for all object files
            //      - Execute ld to build bin file
            //      - Execute ISO9660Generator to build .ISO file

            if (Options.LinkMode == Options.LinkModes.ELF)
            {
                // Check for main method. If found, that library gets linked to Executable not Shared Lib

                List <string> depLibNames = new List <string>();
                foreach (IL.ILLibrary depLib in TheLibrary.Dependencies)
                {
                    string depLibName = Utilities.CleanFileName(depLib.TheAssembly.GetName().Name);
                    if (Options.ShortenDependencyNames)
                    {
                        if (!DependencyNameMapping.ContainsKey(depLibName))
                        {
                            DependencyNameMapping.Add(depLibName, (NameGenerator++).ToString());
                        }

                        depLibName = DependencyNameMapping[depLibName];
                    }
                    depLibNames.Add(depLibName);

                    OK = OK && (Link(depLib, true, depLibName) == CompileResult.OK);
                    if (!OK)
                    {
                        break;
                    }
                }

                if (!OK)
                {
                    return(CompileResult.Fail);
                }

                List <ASM.ASMBlock> SequencedASMBlocks = new List <ASM.ASMBlock>();
                SequencedASMBlocks.AddRange(TheLibrary.TheASMLibrary.ASMBlocks);
                SequencedASMBlocks.Sort(GetOrder);
                SequencedASMBlocks.ForEach(delegate(ASM.ASMBlock block)
                {
                    if (block != null && block.OriginMethodInfo != null)
                    {
                        DebugDataWriter.AddMethodMapping(block.OriginMethodInfo.ID, block.ASMOutputFilePath);
                    }
                });

                // Find start method if any, use as ENTRY point
                bool   ExecutableOutput = false;
                string EntryPoint       = null;
                if (IL.ILLibrary.SpecialMethods.ContainsKey(typeof(Attributes.MainMethodAttribute)))
                {
                    Types.MethodInfo mainMethodInfo  = IL.ILLibrary.SpecialMethods[typeof(Attributes.MainMethodAttribute)].First();
                    IL.ILBlock       mainMethodBlock = TheLibrary.GetILBlock(mainMethodInfo, false);
                    if (mainMethodBlock != null)
                    {
                        ExecutableOutput = true;
                        EntryPoint       = mainMethodInfo.ID;
                    }
                }

                if (Options.ShortenDependencyNames && string.IsNullOrWhiteSpace(Name))
                {
                    Name = "Driver";
                }

                string AssemblyName = string.IsNullOrWhiteSpace(Name) ? Utilities.CleanFileName(TheLibrary.TheAssembly.GetName().Name) : Name;

                DebugDataWriter.SaveDataFiles(Options.OutputPath, AssemblyName);
                DebugDataWriter.SaveLibraryInfo(Options.OutputPath, TheLibrary);

                LinkInformation LinkInfo = new LinkInformation()
                {
                    ToolsPath          = Options.ToolsPath,
                    LinkScriptCmdPath  = Path.Combine(Options.OutputPath, @"DriversCompiler\" + AssemblyName + "_linker_command.txt"),
                    LinkScriptPath     = Path.Combine(Options.OutputPath, @"DriversCompiler\" + AssemblyName + "_linker.ld"),
                    BinPath            = Path.Combine(Options.OutputPath, "Output\\" + (ExecutableOutput ? AssemblyName + ".elf" : "Lib" + AssemblyName + ".a")),
                    MapPath            = Path.Combine(Options.OutputPath, AssemblyName + ".map"),
                    ASMPath            = Path.Combine(Options.OutputPath, AssemblyName + ".new.asm"),
                    LdWorkingDir       = Path.Combine(Options.OutputPath, "") + "\\",
                    ExecutableOutput   = ExecutableOutput,
                    EntryPoint         = EntryPoint,
                    SequencedASMBlocks = SequencedASMBlocks,
                    depLibNames        = depLibNames
                };

                if (!Directory.Exists(Path.GetDirectoryName(LinkInfo.BinPath)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(LinkInfo.BinPath));
                }

                OK = TargetArchitecture.TargetFunctions.LinkELF(TheLibrary, LinkInfo);

                if (OK)
                {
                    DebugDataWriter.ProcessMapFile(LinkInfo.MapPath);
                }
            }
            else if (Options.LinkMode == Options.LinkModes.ISO)
            {
                List <ASM.ASMBlock> SequencedASMBlocks = new List <ASM.ASMBlock>();
                List <IL.ILLibrary> FlattenedLibs      = TheLibrary.Flatten();
                foreach (IL.ILLibrary depLib in FlattenedLibs)
                {
                    SequencedASMBlocks.AddRange(depLib.TheASMLibrary.ASMBlocks);
                    DebugDataWriter.SaveLibraryInfo(Options.OutputPath, depLib);
                }
                SequencedASMBlocks.Sort(GetOrder);
                SequencedASMBlocks.ForEach(delegate(ASM.ASMBlock block)
                {
                    if (block != null && block.OriginMethodInfo != null)
                    {
                        DebugDataWriter.AddMethodMapping(block.OriginMethodInfo.ID, block.ASMOutputFilePath);
                    }
                });

                string AssemblyName = Utilities.CleanFileName(TheLibrary.TheAssembly.GetName().Name);

                DebugDataWriter.SaveDataFiles(Options.OutputPath, AssemblyName);
                DebugDataWriter.SaveLibraryInfo(Options.OutputPath, TheLibrary);

                LinkInformation LinkInfo = new LinkInformation()
                {
                    ToolsPath          = Options.ToolsPath,
                    ISOGenPath         = Path.Combine(Options.ToolsPath, @"ISO9660Generator.exe"),
                    ISOToolsDirPath    = Path.Combine(Options.ToolsPath, @"ISO"),
                    ISODirPath         = Path.Combine(Options.OutputPath, @"DriversCompiler\ISO"),
                    LinkScriptPath     = Path.Combine(Options.OutputPath, @"DriversCompiler\linker.ld"),
                    BinPath            = Path.Combine(Options.OutputPath, @"DriversCompiler\ISO\Kernel.bin"),
                    ISOLinuxPath       = Path.Combine(Options.OutputPath, @"DriversCompiler\ISO\" + (Options.BuildMode == Options.BuildModes.Debug ? "isolinux-debug.bin" : "isolinux.bin")),
                    ISOPath            = Path.Combine(Options.OutputPath, AssemblyName + ".iso"),
                    MapPath            = Path.Combine(Options.OutputPath, AssemblyName + ".map"),
                    ASMPath            = Path.Combine(Options.OutputPath, AssemblyName + ".new.asm"),
                    LdWorkingDir       = Path.Combine(Options.OutputPath, "DriversCompiler") + "\\",
                    SequencedASMBlocks = SequencedASMBlocks
                };

                if (Directory.Exists(LinkInfo.ISODirPath))
                {
                    Directory.Delete(LinkInfo.ISODirPath, true);
                }
                CopyDirectory(LinkInfo.ISOToolsDirPath, LinkInfo.ISODirPath, true);

                OK = TargetArchitecture.TargetFunctions.LinkISO(TheLibrary, LinkInfo);

                if (OK)
                {
                    DebugDataWriter.ProcessMapFile(LinkInfo.MapPath);
                }
            }

            return(OK ? CompileResult.OK : CompileResult.Fail);
        }
Exemple #25
0
        /// <summary>
        /// Scans the specified non-plugged IL block.
        /// </summary>
        /// <param name="TheLibrary">The library currently being compiled.</param>
        /// <param name="theMethodInfo">The method which generated the IL block.</param>
        /// <param name="theILBlock">The IL block to scan.</param>
        /// <returns>CompileResult.OK.</returns>
        private static CompileResult ScanNonpluggedILBlock(ILLibrary TheLibrary, Types.MethodInfo theMethodInfo, ILBlock theILBlock)
        {
            CompileResult result = CompileResult.OK;

            ASM.ASMBlock TheASMBlock = new ASM.ASMBlock()
            {
                OriginMethodInfo = theMethodInfo,
                Priority         = theMethodInfo.Priority
            };

            ILConversionState convState = new ILConversionState()
            {
                TheILLibrary      = TheLibrary,
                CurrentStackFrame = new StackFrame(),
                Input             = theILBlock,
                Result            = TheASMBlock
            };

            foreach (ILOp anOp in theILBlock.ILOps)
            {
                try
                {
                    string commentText = TheASMBlock.GenerateILOpLabel(convState.PositionOf(anOp), "") + "  --  " + anOp.opCode.ToString() + " -- Offset: " + anOp.Offset.ToString("X2");

                    ASM.ASMOp newCommentOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.Comment, commentText);
                    TheASMBlock.ASMOps.Add(newCommentOp);

                    int currCount = TheASMBlock.ASMOps.Count;
                    if (anOp is ILOps.MethodStart)
                    {
                        TargetArchitecture.MethodStartOp.Convert(convState, anOp);
                    }
                    else if (anOp is ILOps.MethodEnd)
                    {
                        TargetArchitecture.MethodEndOp.Convert(convState, anOp);
                    }
                    else if (anOp is ILOps.StackSwitch)
                    {
                        TargetArchitecture.StackSwitchOp.Convert(convState, anOp);
                    }
                    else
                    {
                        ILOp ConverterOp = TargetArchitecture.TargetILOps[(ILOp.OpCodes)anOp.opCode.Value];
                        ConverterOp.Convert(convState, anOp);
                    }

                    if (anOp.LabelRequired)
                    {
                        if (currCount < TheASMBlock.ASMOps.Count)
                        {
                            TheASMBlock.ASMOps[currCount].ILLabelPosition = convState.PositionOf(anOp);
                            TheASMBlock.ASMOps[currCount].RequiresILLabel = true;
                        }
                    }
                }
                catch (KeyNotFoundException)
                {
                    result = CompileResult.PartialFailure;

                    Logger.LogError(Errors.ILCompiler_ScanILOpFailure_ErrorCode, theMethodInfo.ToString(), anOp.Offset,
                                    string.Format(Errors.ErrorMessages[Errors.ILCompiler_ScanILOpFailure_ErrorCode], "Conversion IL op not found: " + Enum.GetName(typeof(ILOp.OpCodes), anOp.opCode.Value) + "."));
                }
                catch (InvalidOperationException)
                {
                    result = CompileResult.PartialFailure;

                    Logger.LogError(Errors.ILCompiler_ScanILOpFailure_ErrorCode, theMethodInfo.ToString(), anOp.Offset,
                                    string.Format(Errors.ErrorMessages[Errors.ILCompiler_ScanILOpFailure_ErrorCode], Enum.GetName(typeof(ILOp.OpCodes), anOp.opCode.Value)));
                }
                catch (NotSupportedException ex)
                {
                    result = CompileResult.PartialFailure;

                    Logger.LogError(Errors.ILCompiler_ScanILOpFailure_ErrorCode, theMethodInfo.ToString(), anOp.Offset,
                                    string.Format(Errors.ErrorMessages[Errors.ILCompiler_ScanILOpFailure_ErrorCode], "An IL op reported something as not supported. " + Enum.GetName(typeof(ILOp.OpCodes), anOp.opCode.Value) + ". " + ex.Message));
                }
                catch (Exception ex)
                {
                    result = CompileResult.Fail;

                    Logger.LogError(Errors.ILCompiler_ScanILOpFailure_ErrorCode, theMethodInfo.ToString(), anOp.Offset,
                                    string.Format(Errors.ErrorMessages[Errors.ILCompiler_ScanILOpFailure_ErrorCode], ex.Message));
                }
            }

            TheLibrary.TheASMLibrary.ASMBlocks.Add(TheASMBlock);

            return(result);
        }
Exemple #26
0
 public abstract bool LinkISO(IL.ILLibrary TheLibrary, LinkInformation LinkInfo);
Exemple #27
0
        /// <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);
        }
Exemple #28
0
        /// <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);
        }
Exemple #29
0
 /// <summary>
 /// Gets the next unique ID for a method of the specified type.
 /// </summary>
 /// <remarks>
 /// Used for generatign IDs to go in the method tables for use in virtual calls (callvirt Il ops).
 /// </remarks>
 /// <param name="TheLibrary">The IL library being compiled.</param>
 /// <param name="aTypeInfo">The type to get the next method ID from.</param>
 /// <returns>The next unique method ID.</returns>
 private static int GetMethodIDGenerator(ILLibrary TheLibrary, Types.TypeInfo aTypeInfo, bool useMethodCount = false)
 {
     int totalGen = 0;
     if (useMethodCount)
     {
         totalGen = aTypeInfo.MethodInfos.Count;
     }
     else
     {
         totalGen = aTypeInfo.MethodIDGenerator;
     }
     if (aTypeInfo.UnderlyingType.BaseType != null)
     {
         if (!aTypeInfo.UnderlyingType.BaseType.AssemblyQualifiedName.Contains("mscorlib"))
         {
             totalGen += GetMethodIDGenerator(TheLibrary, aTypeInfo.UnderlyingType.BaseType, true);
         }
     }
     return totalGen;
 }
Exemple #30
0
 /// <summary>
 /// Preprocesses any special classes within the specified library.
 /// </summary>
 /// <param name="RootLibrary">The root library being compiled.</param>
 public static void PreprocessSpecialClasses(ILLibrary RootLibrary)
 {
     //Is there anything to do here?
 }
Exemple #31
0
        /// <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);
        }
Exemple #32
0
        /// <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;
        }
Exemple #33
0
 /// <summary>
 /// Gets the next unique ID for a method of the specified type.
 /// </summary>
 /// <remarks>
 /// Used for generatign IDs to go in the method tables for use in virtual calls (callvirt Il ops).
 /// </remarks>
 /// <param name="TheLibrary">The IL library being compiled.</param>
 /// <param name="aType">The type to get the next method ID from.</param>
 /// <returns>The next unique method ID.</returns>
 private static int GetMethodIDGenerator(ILLibrary TheLibrary, Type aType, bool useMethodCount = false)
 {
     Types.TypeInfo aTypeInfo = TheLibrary.GetTypeInfo(aType);
     return GetMethodIDGenerator(TheLibrary, aTypeInfo, useMethodCount);
 }
Exemple #34
0
 private static List<Tuple<string, int>> GetSpecialClassFieldInfo(ILLibrary TheLibrary, Type SpecialClassType)
 {
     Types.TypeInfo InformationAboutInfoStruct = ILLibrary.SpecialClasses[SpecialClassType].First();
     List<Types.FieldInfo> InfoStruct_OrderedFields = InformationAboutInfoStruct.FieldInfos.Where(x => !x.IsStatic).OrderBy(x => x.OffsetInBytes).ToList();
     List<Tuple<string, int>> InfoStruct_OrderedFieldInfo_Subset = new List<Tuple<string, int>>();
     foreach (Types.FieldInfo aField in InfoStruct_OrderedFields)
     {
         Types.TypeInfo FieldTypeInfo = TheLibrary.GetTypeInfo(aField.FieldType);
         InfoStruct_OrderedFieldInfo_Subset.Add(new Tuple<string, int>(aField.Name,
             FieldTypeInfo.IsValueType ? FieldTypeInfo.SizeOnHeapInBytes : FieldTypeInfo.SizeOnStackInBytes));
     }
     return InfoStruct_OrderedFieldInfo_Subset;
 }
Exemple #35
0
        /// <summary>
        /// Executes the IL Preprocessor for the specified library.
        /// </summary>
        /// <param name="TheLibrary">The library to preprocess.</param>
        /// <returns>The return value from the IL Preprocessor.</returns>
        private static CompileResult ExecuteILPreprocessor(ILLibrary TheLibrary)
        {
            CompileResult result = CompileResult.OK;

            ILPreprocessor.Preprocess(TheLibrary);

            ILPreprocessor.PreprocessSpecialClasses(TheLibrary);
            ILPreprocessor.PreprocessSpecialMethods(TheLibrary);
    
            return result;
        }
Exemple #36
0
        /// <summary>
        /// Scans the specified plugged IL block.
        /// </summary>
        /// <param name="TheLibrary">The library currently being compiled.</param>
        /// <param name="theMethodInfo">The method which generated the IL block.</param>
        /// <param name="theILBlock">The IL block to scan.</param>
        /// <returns>CompileResult.OK.</returns>
        private static CompileResult ScanPluggedILBlock(ILLibrary TheLibrary, Types.MethodInfo theMethodInfo, ILBlock theILBlock)
        {
            TheLibrary.TheASMLibrary.ASMBlocks.Add(new ASM.ASMBlock()
            {
                PlugPath = theILBlock.PlugPath,
                OriginMethodInfo = theMethodInfo,
                Priority = theMethodInfo.Priority
            });

            return CompileResult.OK;
        }
Exemple #37
0
        /// <summary>
        /// Scans the specified non-plugged IL block.
        /// </summary>
        /// <param name="TheLibrary">The library currently being compiled.</param>
        /// <param name="theMethodInfo">The method which generated the IL block.</param>
        /// <param name="theILBlock">The IL block to scan.</param>
        /// <returns>CompileResult.OK.</returns>
        private static CompileResult ScanNonpluggedILBlock(ILLibrary TheLibrary, Types.MethodInfo theMethodInfo, ILBlock theILBlock)
        {
            CompileResult result = CompileResult.OK;

            ASM.ASMBlock TheASMBlock = new ASM.ASMBlock()
            {
                OriginMethodInfo = theMethodInfo,
                Priority = theMethodInfo.Priority
            };
            
            ILConversionState convState = new ILConversionState()
            {
                TheILLibrary = TheLibrary,
                CurrentStackFrame = new StackFrame(),
                Input = theILBlock,
                Result = TheASMBlock
            };
            foreach (ILOp anOp in theILBlock.ILOps)
            {
                try
                {
                    string commentText = TheASMBlock.GenerateILOpLabel(convState.PositionOf(anOp), "") + "  --  " + anOp.opCode.ToString() + " -- Offset: " + anOp.Offset.ToString("X2");
                    
                    ASM.ASMOp newCommentOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.Comment, commentText);
                    TheASMBlock.ASMOps.Add(newCommentOp);
                    
                    int currCount = TheASMBlock.ASMOps.Count;
                    if (anOp is ILOps.MethodStart)
                    {
                        TargetArchitecture.MethodStartOp.Convert(convState, anOp);
                    }
                    else if (anOp is ILOps.MethodEnd)
                    {
                        TargetArchitecture.MethodEndOp.Convert(convState, anOp);
                    }
                    else if (anOp is ILOps.StackSwitch)
                    {
                        TargetArchitecture.StackSwitchOp.Convert(convState, anOp);
                    }
                    else
                    {
                        ILOp ConverterOp = TargetArchitecture.TargetILOps[(ILOp.OpCodes)anOp.opCode.Value];
                        ConverterOp.Convert(convState, anOp);
                    }

                    if (anOp.LabelRequired)
                    {
                        if (currCount < TheASMBlock.ASMOps.Count)
                        {
                            TheASMBlock.ASMOps[currCount].ILLabelPosition = convState.PositionOf(anOp);
                            TheASMBlock.ASMOps[currCount].RequiresILLabel = true;
                        }
                    }
                }
                catch (KeyNotFoundException)
                {
                    result = CompileResult.PartialFailure;

                    Logger.LogError(Errors.ILCompiler_ScanILOpFailure_ErrorCode, theMethodInfo.ToString(), anOp.Offset,
                        string.Format(Errors.ErrorMessages[Errors.ILCompiler_ScanILOpFailure_ErrorCode], Enum.GetName(typeof(ILOp.OpCodes), anOp.opCode.Value), "Conversion for IL op not found."));
                }
                catch (InvalidOperationException ex)
                {
                    result = CompileResult.PartialFailure;

                    Logger.LogError(Errors.ILCompiler_ScanILOpFailure_ErrorCode, theMethodInfo.ToString(), anOp.Offset,
                        string.Format(Errors.ErrorMessages[Errors.ILCompiler_ScanILOpFailure_ErrorCode], Enum.GetName(typeof(ILOp.OpCodes), anOp.opCode.Value), ex.Message));
                }
                catch (NotSupportedException ex)
                {
                    result = CompileResult.PartialFailure;

                    Logger.LogError(Errors.ILCompiler_ScanILOpFailure_ErrorCode, theMethodInfo.ToString(), anOp.Offset,
                        string.Format(Errors.ErrorMessages[Errors.ILCompiler_ScanILOpFailure_ErrorCode], Enum.GetName(typeof(ILOp.OpCodes), anOp.opCode.Value), "An IL op reported something as not supported : " + ex.Message));
                }
                catch (Exception ex)
                {
                    result = CompileResult.Fail;

                    Logger.LogError(Errors.ILCompiler_ScanILOpFailure_ErrorCode, theMethodInfo.ToString(), anOp.Offset,
                        string.Format(Errors.ErrorMessages[Errors.ILCompiler_ScanILOpFailure_ErrorCode], Enum.GetName(typeof(ILOp.OpCodes), anOp.opCode.Value), ex.Message));
                }
            }

            TheLibrary.TheASMLibrary.ASMBlocks.Add(TheASMBlock);

            return result;
        }
Exemple #38
0
        /// <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);
        }
Exemple #39
0
        /// <summary>
        /// Loads all the dependencies of a library.
        /// </summary>
        /// <param name="aLibrary">The library to load dependencies of.</param>
        /// <returns>The number of dependencies loaded.</returns>
        public static int LoadDependencies(ILLibrary aLibrary)
        {
            if (aLibrary == null)
            {
                return 0;
            }

            int DependenciesLoaded = 0;

            Assembly RootAssembly = aLibrary.TheAssembly;
            AssemblyName[] refAssemblyNames = RootAssembly.GetReferencedAssemblies();
            foreach (AssemblyName aRefName in refAssemblyNames)
            {
                if (IsAssemblyFullNameIgnored(aRefName.FullName))
                {
                    continue;
                }

                string refFilePath = Path.Combine(Path.GetDirectoryName(RootAssembly.Location), aRefName.Name + ".dll");
                ILLibrary refLibrary = LoadILLibrary(refFilePath);
                if (refLibrary == null)
                {
                    throw new NullReferenceException("Loaded dependency library was null!");
                }
                else
                {
                    if (LibraryCache.ContainsKey(refLibrary.ToString()))
                    {
                        aLibrary.Dependencies.Add(LibraryCache[refLibrary.ToString()]);
                    }
                    else
                    {
                        aLibrary.Dependencies.Add(refLibrary);
                        LibraryCache.Add(refLibrary.ToString(), refLibrary);
                    }
                }
            }

            return DependenciesLoaded;
        }