예제 #1
0
        private void CreateExceptionHandlers(CilCompilationUnit unit, CilInstructionCollection result)
        {
            foreach (var subGraph in unit.ControlFlowGraph.SubGraphs)
            {
                var ehFrame = (EHFrame)subGraph.UserData[EHFrame.EHFrameProperty];

                CilExceptionHandlerType type;
                switch (ehFrame.Type)
                {
                case EHType.CATCH:
                    type = CilExceptionHandlerType.Exception;
                    break;

                case EHType.FILTER:
                    type = CilExceptionHandlerType.Filter;
                    break;

                case EHType.FAULT:
                    type = CilExceptionHandlerType.Fault;
                    break;

                case EHType.FINALLY:
                    type = CilExceptionHandlerType.Finally;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                // Find first and last nodes of try block.
                var tryBody = (ICollection <Node>)subGraph.UserData[ControlFlowGraph.TryBlockProperty];
                var(tryStartNode, tryEndNode) = FindMinMaxNodes(tryBody);

                // Find first and last nodes of handler block.
                var handlerBody = (ICollection <Node>)subGraph.UserData[ControlFlowGraph.HandlerBlockProperty];
                var(handlerStartNode, handlerEndNode) = FindMinMaxNodes(handlerBody);

                // Create handler.
                var handler = new CilExceptionHandler();
                handler.HandlerType = type;

                handler.TryStart = new CilInstructionLabel(_blockEntries[tryStartNode]);
                handler.TryEnd   = GetHandlerEndLabel(result, tryEndNode, "try");

                handler.HandlerStart = new CilInstructionLabel(_blockEntries[handlerStartNode]);
                handler.HandlerEnd   = GetHandlerEndLabel(result, handlerEndNode, "handler");

                handler.ExceptionType = ehFrame.CatchType;

                if (ehFrame.Type == EHType.FILTER)
                {
                    var filterStartNode = (Node)subGraph.UserData[ControlFlowGraph.FilterStartProperty];
                    handler.FilterStart = new CilInstructionLabel(_blockEntries[filterStartNode]);
                }

                _context.ExceptionHandlers.Add(ehFrame, handler);
            }
        }
예제 #2
0
 public static void RemoveInstructionRange(CilInstructionCollection instr, IEnumerable <int> removalIndexes,
                                           ref int index)
 {
     foreach (int removalIndex in removalIndexes)
     {
         instr.RemoveAt(index + removalIndex);
         index--;
     }
 }
예제 #3
0
        private void CreateExceptionHandlers(CilCompilationUnit unit, CilInstructionCollection result)
        {
            foreach (var subGraph in unit.ControlFlowGraph.SubGraphs)
            {
                var ehFrame = (EHFrame)subGraph.UserData[EHFrame.EHFrameProperty];

                ExceptionHandlerType type;
                switch (ehFrame.Type)
                {
                case EHType.CATCH:
                    type = ExceptionHandlerType.Exception;
                    break;

                case EHType.FILTER:
                    type = ExceptionHandlerType.Filter;
                    break;

                case EHType.FAULT:
                    type = ExceptionHandlerType.Fault;
                    break;

                case EHType.FINALLY:
                    type = ExceptionHandlerType.Finally;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                // Find first and last nodes of try block.
                var tryBody = (ICollection <Node>)subGraph.UserData[ControlFlowGraph.TryBlockProperty];
                var(tryStartNode, tryEndNode) = FindMinMaxNodes(tryBody);

                // Find first and last nodes of handler block.
                var handlerBody = (ICollection <Node>)subGraph.UserData[ControlFlowGraph.HandlerBlockProperty];
                var(handlerStartNode, handlerEndNode) = FindMinMaxNodes(handlerBody);

                // Create handler.
                var handler = new ExceptionHandler(type)
                {
                    TryStart = _blockEntries[tryStartNode],
                    TryEnd   = result.GetByOffset(_blockExits[tryEndNode].Offset + _blockExits[tryEndNode].Size)
                               ?? throw new CilCodeGeneratorException(
                                         $"Could not infer end of try block in {_context.MethodBody.Method.Name}."),
                                     HandlerStart = _blockEntries[handlerStartNode],
                                     HandlerEnd   = result.GetByOffset(_blockExits[handlerEndNode].Offset + _blockExits[handlerEndNode].Size)
                                                    ?? throw new CilCodeGeneratorException(
                                                              $"Could not infer end of handler block in {_context.MethodBody.Method.Name}."),
                                                          CatchType = ehFrame.CatchType
                };

                _context.ExceptionHandlers.Add(ehFrame, handler);
            }
        }
예제 #4
0
        private ICilLabel GetHandlerEndLabel(CilInstructionCollection result, Node endNode, string type)
        {
            var instruction = result.GetByOffset(_blockExits[endNode].Offset + _blockExits[endNode].Size);

            if (instruction is null)
            {
                throw new CilCodeGeneratorException(
                          $"Could not infer end of {type} block in {_context.MethodBody.Owner.Name}.");
            }

            return(new CilInstructionLabel(instruction));
        }
예제 #5
0
        public IList <CilInstruction> VisitCompilationUnit(CilCompilationUnit unit)
        {
            // Add variable signatures to the end result.
            BindVariablesToSignatures(unit);

            var result = GenerateInstructions(unit);

            var instructions = new CilInstructionCollection(_context.MethodBody);

            instructions.AddRange(result);
            instructions.CalculateOffsets();

            CreateExceptionHandlers(unit, instructions);

            return(instructions);
        }
예제 #6
0
        public object[] ParamsParser(MethodDefinition DecMethod, int Index, CilInstructionCollection IL, Module Module)
        {
            var C = DecMethod.Parameters.Count; int ParsedIndex = -0; object[] ParsedParams = new object[C]; var Temp = 0;

            for (int x = -C + Index; x < Index; x++)
            {
                if (IL[x].OpCode == CilOpCodes.Ldsfld)          // Yes Sorry for Pseudo code here :)
                {
                    ParsedParams[ParsedIndex++] = Convert.ChangeType(GetFieldValue(Module, ((IFieldDescriptor)IL[x].Operand).MetadataToken.ToInt32()), System.Type.GetType(DecMethod.Parameters[Temp++].ParameterType.GetTypeFullName())); GetJunk.Add(IL[x]);
                }
                else
                {
                    ParsedParams[ParsedIndex++] = Convert.ChangeType(IL[x].Operand, System.Type.GetType(DecMethod.Parameters[Temp++].ParameterType.GetTypeFullName()));
                    GetJunk.Add(IL[x]);
                }
            }
            return(ParsedParams);
        }
예제 #7
0
        private static object[] GetArguments(MethodBase methodBase, CilInstructionCollection instr, int i)
        {
            var arguments = new object[methodBase.GetParameters().Length];

            for (int j = 0; j < arguments.Length; j++)
            {
                switch (instr[i - j - 1].OpCode.OperandType)
                {
                case CilOperandType.InlineMethod:
                case CilOperandType.InlineI:
                case CilOperandType.InlineString:
                    arguments[arguments.Length - j - 1] = instr[i - j - 1].Operand;
                    InstructionsToRemove.Add(instr[i - j - 1]);
                    break;

                default:
                    arguments[arguments.Length - j - 1] = null;
                    break;
                }
            }

            return(arguments);
        }
 public CilEndLabel(CilInstructionCollection collection)
 {
     _collection = collection ?? throw new ArgumentNullException(nameof(collection));
 }
 /// <summary>
 /// Creates a new instance of the <see cref="Enumerator"/> structure.
 /// </summary>
 /// <param name="collection">The collection to enumerate.</param>
 public Enumerator(CilInstructionCollection collection)
 {
     _enumerator = collection._items.GetEnumerator();
 }
예제 #10
0
        public object[] ParamsParser(MethodDefinition DecMethod, int Index, CilInstructionCollection IL, Module Module)
        {
            var pi = 0;

            var pp = 0;

            var rMethod = Module.ResolveMethod(DecMethod.MetadataToken.ToInt32());

            var rMethodParams = rMethod.GetParameters();

            var C = rMethodParams.Length;

            var Parsed = new object[C];

            for (int x = (-C + Index); x < Index; x++)
            {
                object Result = null;

                if (IL[x].OpCode == CilOpCodes.Stsfld)
                {
                    Result = Module.ResolveField(((IFieldDescriptor)IL[x].Operand).MetadataToken.ToInt32()).GetValue(null);
                }

                var CurrentT = rMethodParams[pi++].ParameterType;



                if (CurrentT == typeof(String) || CurrentT == typeof(string))
                {
                    Result = (string)IL[x].Operand;
                }
                else if (CurrentT == typeof(Int16) || CurrentT == typeof(short))
                {
                    Result = Result == null ? (short)IL[x].GetLdcI4Constant() : (short)Result;
                }
                else if (CurrentT == typeof(Int32) || CurrentT == typeof(int))
                {
                    Result = Result == null ? (int)IL[x].GetLdcI4Constant() : (int)Result;
                }
                else if (CurrentT == typeof(Int64) || CurrentT == typeof(long))
                {
                    Result = Result == null ? (long)IL[x].GetLdcI4Constant() : (long)Result;
                }
                else if (CurrentT == typeof(SByte) || CurrentT == typeof(sbyte))
                {
                    Result = Result == null ? (sbyte)IL[x].Operand : (sbyte)Result;
                }
                else if (CurrentT == typeof(Byte) || CurrentT == typeof(byte))
                {
                    Result = Result == null ? (byte)IL[x].Operand : (byte)Result;
                }
                else if (CurrentT == typeof(UInt16) || CurrentT == typeof(ushort))
                {
                    Result = Result == null ? (ushort)unchecked (IL[x].GetLdcI4Constant()) : (ushort)Result;
                }
                else if (CurrentT == typeof(UInt32) || CurrentT == typeof(uint))
                {
                    Result = Result == null ? (uint)unchecked (IL[x].GetLdcI4Constant()) : (uint)Result;
                }
                else if (CurrentT == typeof(UInt64) || CurrentT == typeof(ulong))
                {
                    Result = Result == null ? (ulong)unchecked (IL[x].GetLdcI4Constant()) : (ulong)Result;
                }
                else if (CurrentT == typeof(Boolean) || CurrentT == typeof(bool))
                {
                    Result = Result == null ? (IL[x].GetLdcI4Constant() == 1 ? true : false) : Convert.ToBoolean(Result);
                }
                else if (CurrentT == typeof(Char) || CurrentT == typeof(char))
                {
                    Result = Result == null?Convert.ToChar(IL[x].GetLdcI4Constant()) : (char)Result;
                }
                else
                {
                    Result = Result == null?Convert.ChangeType(IL[x].Operand, CurrentT) : Convert.ChangeType(Result, CurrentT);
                }

                Parsed[pp++] = Result;

                GetJunk.Add(IL[x]);
            }

            return(Parsed);
        }