Exemple #1
0
        public void DoStackAnalysis(Stack <Type> aStack, ref uint aStackOffset)
        {
            StackOffsetBeforeExecution = aStackOffset;

            // if current instruction is the first instruction of a filter or catch statement, "push" the exception type now
            if (CurrentExceptionRegion != null && (CurrentExceptionRegion.HandlerOffset == Position ||
                                                   (CurrentExceptionRegion.FilterOffset == Position && CurrentExceptionRegion.FilterOffset != 0)))
            {
                if (CurrentExceptionRegion.Kind != ExceptionRegionKind.Finally)
                {
                    aStack.Push(typeof(object));
                    aStackOffset += ILOp.Align(ILOp.SizeOfType(typeof(object)), 4);
                }
            }


            if (StackPopTypes.Length > aStack.Count)
            {
                throw new Exception(String.Format("OpCode {0} tries to pop more stuff from analytical stack than there is!", this));
            }

            var pos = 0;

            foreach (var xPopItem in StackPopTypes)
            {
                var popped = aStack.Pop();

                if (xPopItem is null)
                {
                    StackPopTypes[pos] = popped;
                }
                else if (xPopItem != popped && xPopItem.IsAssignableTo(popped))
                {
                    throw new Exception($"Tried to pop a {xPopItem} from the stack but found a {popped}");
                }

                aStackOffset -= ILOp.Align(ILOp.SizeOfType(popped), 4);

                pos++;
            }

            DoInterpretStackTypes();

            foreach (var xPushItem in StackPushTypes)
            {
                aStack.Push(xPushItem);
                aStackOffset += ILOp.Align(ILOp.SizeOfType(xPushItem), 4);
            }
        }
Exemple #2
0
        public void InterpretStackTypes(IDictionary <int, ILOpCode> aOpCodes, Stack <Type> aStack, ref bool aSituationChanged, int aMaxRecursionDepth)
        {
            if (Processed)
            {
                ILInterpretationDebugLine(() => String.Format("{0} skipped for reinterpretation", this));
                return;
            }
            Processed = true;
            ILInterpretationDebugLine(() =>
            {
                var sb = new StringBuilder();
                sb.AppendFormat("Interpreting {0}. StackCount = {1}. Contents: ", this, aStack.Count);
                foreach (var item in aStack)
                {
                    if (item == null)
                    {
                        sb.Append("**NULL**, ");
                    }
                    else
                    {
                        sb.AppendFormat("{0}, ", item.FullName);
                    }
                }
                return(sb.ToString().Trim(',', ' '));
            });
            if (aMaxRecursionDepth == 0)
            {
                throw new Exception("Safety Error: MaxRecursionDepth reached!");
            }

            if (StackOffsetBeforeExecution == null)
            {
                StackOffsetBeforeExecution = 0;
                foreach (var item in aStack)
                {
                    if (item == null)
                    {
                        StackOffsetBeforeExecution = null;
                        break;
                    }
                    StackOffsetBeforeExecution += ILOp.Align(ILOp.SizeOfType(item), 4);
                }
            }

            // if current instruction is the first instruction of a catch statement, "push" the exception type now
            if (CurrentExceptionHandler != null &&
                CurrentExceptionHandler.HandlerOffset == Position)
            {
                if (CurrentExceptionHandler.Flags != SR.ExceptionHandlingClauseOptions.Finally)
                {
                    aStack.Push(CurrentExceptionHandler.CatchType);
                }
            }

            if (StackPopTypes.Length > aStack.Count)
            {
                throw new Exception(String.Format("OpCode {0} tries to pop more stuff from analytical stack than there is!", this));
            }

            for (int i = 0; i < StackPopTypes.Length; i++)
            {
                var xActualStackItem = aStack.ElementAt(i);
                if (xActualStackItem == null)
                {
                    continue;
                }
                if (StackPopTypes[i] == null)
                {
                    StackPopTypes[i]  = xActualStackItem;
                    aSituationChanged = true;
                }
                if (StackPopTypes[i] != xActualStackItem &&
                    !StackPopTypes[i].IsAssignableFrom(xActualStackItem) &&
                    !((StackPopTypes[i].IsPointer || StackPopTypes[i].IsByRef) && (xActualStackItem.IsPointer || xActualStackItem.IsByRef)))
                {
                    throw new Exception(String.Format("OpCode {0} tries to pop item at stack position {1} with type {2}, but actual type is {3}",
                                                      this, i, StackPopTypes[i], xActualStackItem));
                }
            }

            foreach (var xPopItem in StackPopTypes)
            {
                aStack.Pop();
            }
            try
            {
                DoInterpretStackTypes(ref aSituationChanged);
            }
            catch (Exception E)
            {
                throw new Exception("Error interpreting stacktypes for " + this, E);
            }
            foreach (var xPushItem in StackPushTypes)
            {
                aStack.Push(xPushItem);
            }
            DoInterpretNextInstructionStackTypes(aOpCodes, aStack, ref aSituationChanged, aMaxRecursionDepth);
        }