示例#1
0
        private static StackSlot MergeStackElement(StackSlot a, StackSlot b)
        {
            StackSlot mergedSlot;

            if (b.Value == null)
            {
                mergedSlot = a;
            }
            else if (a.Value == null)
            {
                mergedSlot = b;
            }
            else
            {
                mergedSlot = new StackSlot(MergePointValue.MergeValues(a.Value, b.Value));
            }

            return(mergedSlot);
        }
示例#2
0
        private StackSlot PopUnknown(Stack <StackSlot> stack, int count, MethodIL method, int ilOffset)
        {
            if (count < 1)
            {
                throw new InvalidOperationException();
            }

            StackSlot topOfStack = default;

            CheckForInvalidStack(stack, count, method, ilOffset);

            for (int i = 0; i < count; ++i)
            {
                StackSlot slot = stack.Pop();
                if (i == 0)
                {
                    topOfStack = slot;
                }
            }
            return(topOfStack);
        }
示例#3
0
        public void Scan(MethodIL methodBody)
        {
            MethodDesc thisMethod = methodBody.OwningMethod;

            ValueBasicBlockPair[] locals = new ValueBasicBlockPair[methodBody.GetLocals().Length];

            Dictionary <int, Stack <StackSlot> > knownStacks = new Dictionary <int, Stack <StackSlot> >();
            Stack <StackSlot> currentStack = new Stack <StackSlot>(methodBody.MaxStack);

            ScanExceptionInformation(knownStacks, methodBody);

            BasicBlockIterator blockIterator = new BasicBlockIterator(methodBody);

            MethodReturnValue = null;
            ILReader reader = new ILReader(methodBody.GetILBytes());

            while (reader.HasNext)
            {
                int curBasicBlock = blockIterator.MoveNext(reader.Offset);

                if (knownStacks.ContainsKey(reader.Offset))
                {
                    if (currentStack == null)
                    {
                        // The stack copy constructor reverses the stack
                        currentStack = new Stack <StackSlot>(knownStacks[reader.Offset].Reverse());
                    }
                    else
                    {
                        currentStack = MergeStack(currentStack, knownStacks[reader.Offset]);
                    }
                }

                if (currentStack == null)
                {
                    currentStack = new Stack <StackSlot>(methodBody.MaxStack);
                }

                int      offset = reader.Offset;
                ILOpcode opcode = reader.ReadILOpcode();

                switch (opcode)
                {
                case ILOpcode.add:
                case ILOpcode.add_ovf:
                case ILOpcode.add_ovf_un:
                case ILOpcode.and:
                case ILOpcode.div:
                case ILOpcode.div_un:
                case ILOpcode.mul:
                case ILOpcode.mul_ovf:
                case ILOpcode.mul_ovf_un:
                case ILOpcode.or:
                case ILOpcode.rem:
                case ILOpcode.rem_un:
                case ILOpcode.sub:
                case ILOpcode.sub_ovf:
                case ILOpcode.sub_ovf_un:
                case ILOpcode.xor:
                case ILOpcode.cgt:
                case ILOpcode.cgt_un:
                case ILOpcode.clt:
                case ILOpcode.clt_un:
                case ILOpcode.shl:
                case ILOpcode.shr:
                case ILOpcode.shr_un:
                case ILOpcode.ceq:
                    PopUnknown(currentStack, 2, methodBody, offset);
                    PushUnknown(currentStack);
                    reader.Skip(opcode);
                    break;

                case ILOpcode.dup:
                    currentStack.Push(currentStack.Peek());
                    break;

                case ILOpcode.ldnull:
                    currentStack.Push(new StackSlot(NullValue.Instance));
                    break;


                case ILOpcode.ldc_i4_0:
                case ILOpcode.ldc_i4_1:
                case ILOpcode.ldc_i4_2:
                case ILOpcode.ldc_i4_3:
                case ILOpcode.ldc_i4_4:
                case ILOpcode.ldc_i4_5:
                case ILOpcode.ldc_i4_6:
                case ILOpcode.ldc_i4_7:
                case ILOpcode.ldc_i4_8:
                {
                    int           value = opcode - ILOpcode.ldc_i4_0;
                    ConstIntValue civ   = new ConstIntValue(value);
                    StackSlot     slot  = new StackSlot(civ);
                    currentStack.Push(slot);
                }
                break;

                case ILOpcode.ldc_i4_m1:
                {
                    ConstIntValue civ  = new ConstIntValue(-1);
                    StackSlot     slot = new StackSlot(civ);
                    currentStack.Push(slot);
                }
                break;

                case ILOpcode.ldc_i4:
                {
                    int           value = (int)reader.ReadILUInt32();
                    ConstIntValue civ   = new ConstIntValue(value);
                    StackSlot     slot  = new StackSlot(civ);
                    currentStack.Push(slot);
                }
                break;

                case ILOpcode.ldc_i4_s:
                {
                    int           value = (sbyte)reader.ReadILByte();
                    ConstIntValue civ   = new ConstIntValue(value);
                    StackSlot     slot  = new StackSlot(civ);
                    currentStack.Push(slot);
                }
                break;

                case ILOpcode.arglist:
                case ILOpcode.ldftn:
                case ILOpcode.sizeof_:
                case ILOpcode.ldc_i8:
                case ILOpcode.ldc_r4:
                case ILOpcode.ldc_r8:
                    PushUnknown(currentStack);
                    reader.Skip(opcode);
                    break;

                case ILOpcode.ldarg:
                case ILOpcode.ldarg_0:
                case ILOpcode.ldarg_1:
                case ILOpcode.ldarg_2:
                case ILOpcode.ldarg_3:
                case ILOpcode.ldarg_s:
                case ILOpcode.ldarga:
                case ILOpcode.ldarga_s:
                    ScanLdarg(opcode, opcode switch
                    {
                        ILOpcode.ldarg => reader.ReadILUInt16(),
                        ILOpcode.ldarga => reader.ReadILUInt16(),
                        ILOpcode.ldarg_s => reader.ReadILByte(),
                        ILOpcode.ldarga_s => reader.ReadILByte(),
                        _ => opcode - ILOpcode.ldarg_0
                    }, currentStack, thisMethod);
                    break;
示例#4
0
 private static StackSlot MergeStackElement(StackSlot a, StackSlot b)
 {
     return(new StackSlot(MultiValueLattice.Meet(a.Value, b.Value)));
 }