コード例 #1
0
ファイル: ILMethod.cs プロジェクト: aura-systems/IL2CPU
 public ILMethod(List <ILOpCode> aOpCodes, DebugInfo.SequencePoint[] aSequences)
 {
     First = aOpCodes[0];
     Code  = new Dictionary <int, ILOpCode>();
     foreach (var opCode in aOpCodes)
     {
         Code[opCode.Position] = opCode;
     }
     Length         = aOpCodes.Count;
     StructuredCode = ILGroup.GenerateGroups(this, aSequences);
 }
コード例 #2
0
        public static List <ILGroup> GenerateGroups(ILMethod aMethod, DebugInfo.SequencePoint[] aSequences)
        {
            var analysed = 0;

            var groups = new Dictionary <int, ILGroup>();

            // Make lookup table from aSequences
            HashSet <int> sequenceLookup = null;

            if (aSequences.Length != 0)
            {
                sequenceLookup = new HashSet <int>();
                foreach (var seq in aSequences)
                {
                    if (seq.LineStart != 0xFEEFEE)
                    {
                        sequenceLookup.Add(seq.Offset);
                    }
                }
            }

            var first = new ILGroup(aMethod.First, new Stack <Type> {
            });

            groups.Add(aMethod.First.Position, first);

            _ExceptionRegionInfo exceptionRegion;

            // find all groups by finding all branches etc
            foreach (var position in aMethod.Code.Keys)
            {
                var op = aMethod.Code[position];
                exceptionRegion = op.CurrentExceptionRegion;

                if (exceptionRegion != null && exceptionRegion.HandlerOffset == position)
                {
                    if (!groups.ContainsKey(position))
                    {
                        var item = new ILGroup(op);
                        groups.Add(position, item);
                    }
                }

                foreach (var future in op.GetNextOpCodePositions())
                {
                    var(newGroup, Position) = future;

                    if (groups.ContainsKey(Position)) // branches sometimes force us to have more groups then expected
                    {
                        // this opcode should already be in the process of being analysed
                        continue;
                    }

                    if (!newGroup)
                    {
                        // if this is the first operation in a try block we also want a new group
                        newGroup = ((exceptionRegion?.TryOffset ?? -1) != (aMethod.Code[Position].CurrentExceptionRegion?.TryOffset ?? -1));
                        // we still have to check if we want this group to have a debug point at this position
                        newGroup |= (sequenceLookup != null && sequenceLookup.Contains(Position));
                        // also a new group if we reach the catch block
                        newGroup |= exceptionRegion != null && exceptionRegion.HandlerOffset == Position;
                    }


                    var aILOpCode = aMethod.Code[Position];
                    if (newGroup)
                    {
                        var item = new ILGroup(aILOpCode);
                        groups.Add(Position, item);
                    }
                }
            }

            // Initialse the datastructure with the first opcode

            // Analyse op codes
            foreach (var(_, opGroup) in groups)
            {
                while (true)
                {
                    var analysing = opGroup.OpCodes.Last();

                    analysed++;

                    var done = true;

                    if (analysing.CurrentExceptionRegion != null && analysing.CurrentExceptionRegion.TryOffset == analysing.Position)
                    {
                        opGroup.PossibleContinuations.Add(groups[analysing.CurrentExceptionRegion.HandlerOffset]);
                    }

                    foreach (var future in analysing.GetNextOpCodePositions())
                    {
                        var(newGroup, Position) = future;
                        if (!newGroup && !groups.ContainsKey(Position))
                        {
                            opGroup.OpCodes.Add(aMethod.Code[Position]);
                            done = false;
                        }
                        else
                        {
                            opGroup.PossibleContinuations.Add(groups[Position]);
                        }
                    }

                    if (done)
                    {
                        break;
                    }
                }
            }

            if (analysed != aMethod.Length)
            {
                throw new Exception("GenerateGroups --- Did not reach all instructions in method");
            }

            return(groups.Values.ToList());
        }