Example #1
0
        protected override void NotePreStateBeforeInterpretingInstruction(LocalsAndOperands <V> preState, Instruction instruction)
        {
            if (instruction.Operation.OperationCode == OperationCode.Callvirt)
            {
                // This copy is CRUCIAL: the preState is mutable and the analysis
                // WILL change it behind our back.

                LocalsAndOperands <V> preStateCopy = preState.Copy();

                preStatesByOperation[instruction.Operation] = preStateCopy;
            }
        }
Example #2
0
        // Interpret the instruction in the given abstract state and return the resulting abstract state
        private LocalsAndOperands <V> InterpretInstructionInState(Instruction instruction, LocalsAndOperands <V> preState, IMethodDefinition method)
        {
            LocalsAndOperands <V> currentState = preState.Copy();

            // Switch cases copied directly from Cci's DataFlowInferencer

            NotePreStateBeforeInterpretingInstruction(currentState, instruction);

            switch (instruction.Operation.OperationCode)
            {
            case OperationCode.Add:
            case OperationCode.Add_Ovf:
            case OperationCode.Add_Ovf_Un:
            case OperationCode.And:
            case OperationCode.Ceq:
            case OperationCode.Cgt:
            case OperationCode.Cgt_Un:
            case OperationCode.Clt:
            case OperationCode.Clt_Un:
            case OperationCode.Div:
            case OperationCode.Div_Un:
            case OperationCode.Ldelema:
            case OperationCode.Ldelem:
            case OperationCode.Ldelem_I:
            case OperationCode.Ldelem_I1:
            case OperationCode.Ldelem_I2:
            case OperationCode.Ldelem_I4:
            case OperationCode.Ldelem_I8:
            case OperationCode.Ldelem_R4:
            case OperationCode.Ldelem_R8:
            case OperationCode.Ldelem_Ref:
            case OperationCode.Ldelem_U1:
            case OperationCode.Ldelem_U2:
            case OperationCode.Ldelem_U4:
            case OperationCode.Mul:
            case OperationCode.Mul_Ovf:
            case OperationCode.Mul_Ovf_Un:
            case OperationCode.Or:
            case OperationCode.Rem:
            case OperationCode.Rem_Un:
            case OperationCode.Shl:
            case OperationCode.Shr:
            case OperationCode.Shr_Un:
            case OperationCode.Sub:
            case OperationCode.Sub_Ovf:
            case OperationCode.Sub_Ovf_Un:
            case OperationCode.Xor:
                //instruction.Operand2 = stack.Pop();
                //instruction.Operand1 = stack.Pop();
                //stack.Push(instruction);
                currentState.Pop();
                currentState.Pop();
                //currentState.Push(ValueAbstraction.Top); // Not right
                currentState.Push(ValueAbstraction.GetAbstractValueForType(FixupTypeForFlow(instruction.Type.ResolvedType))); // still not right
                break;


            case OperationCode.Ldarg:
            case OperationCode.Ldarg_0:
            case OperationCode.Ldarg_1:
            case OperationCode.Ldarg_2:
            case OperationCode.Ldarg_3:
            case OperationCode.Ldarg_S:
            {
                int argumentIndex = GetArgumentIndexFromParameterOperation(instruction.Operation, method);
                V   argumentValue = currentState.Arguments.ElementAt(argumentIndex);

                currentState.Push(argumentValue);
            }
            break;

            case OperationCode.Ldloc:
            case OperationCode.Ldloc_0:
            case OperationCode.Ldloc_1:
            case OperationCode.Ldloc_2:
            case OperationCode.Ldloc_3:
            case OperationCode.Ldloc_S: {
                Contract.Assume(instruction.Operation.Value is ILocalDefinition);

                ILocalDefinition local = instruction.Operation.Value as ILocalDefinition;

                int localIndex = GetLocalIndexFromLocalOperation(instruction.Operation, method);

                V localValue = currentState.Locals.ElementAt(localIndex);

                currentState.Push(localValue);
            }

            break;

            case OperationCode.Ldsfld:
            case OperationCode.Ldarga:
            case OperationCode.Ldarga_S:
            case OperationCode.Ldsflda:
            case OperationCode.Ldloca:
            case OperationCode.Ldloca_S:
            case OperationCode.Ldftn:
            case OperationCode.Ldc_I4:
            case OperationCode.Ldc_I4_0:
            case OperationCode.Ldc_I4_1:
            case OperationCode.Ldc_I4_2:
            case OperationCode.Ldc_I4_3:
            case OperationCode.Ldc_I4_4:
            case OperationCode.Ldc_I4_5:
            case OperationCode.Ldc_I4_6:
            case OperationCode.Ldc_I4_7:
            case OperationCode.Ldc_I4_8:
            case OperationCode.Ldc_I4_M1:
            case OperationCode.Ldc_I4_S:
            case OperationCode.Ldc_I8:
            case OperationCode.Ldc_R4:
            case OperationCode.Ldc_R8:
            case OperationCode.Ldnull:
            case OperationCode.Ldstr:
            case OperationCode.Ldtoken:
            case OperationCode.Sizeof:
            case OperationCode.Arglist:
                //stack.Push(instruction);
                //currentState.Push(ValueAbstraction.Top); // not right
                currentState.Push(ValueAbstraction.GetAbstractValueForType(FixupTypeForFlow(instruction.Type.ResolvedType))); // Still not right
                break;

            case OperationCode.Array_Addr:
            case OperationCode.Array_Get:
                Contract.Assume(instruction.Operation.Value is IArrayTypeReference); //This is an informally specified property of the Metadata model.
                //InitializeArrayIndexerInstruction(instruction, stack, (IArrayTypeReference)instruction.Operation.Value);
                InitializeArrayIndexerInstruction(instruction, currentState, (IArrayTypeReference)instruction.Operation.Value);
                break;

            case OperationCode.Array_Create:
            case OperationCode.Array_Create_WithLowerBound:
            case OperationCode.Newarr:
                InitializeArrayCreateInstruction(instruction, currentState, instruction.Operation);
                break;

            case OperationCode.Array_Set:
                /*stack.Pop();
                 * Contract.Assume(instruction.Operation.Value is IArrayTypeReference); //This is an informally specified property of the Metadata model.
                 * InitializeArrayIndexerInstruction(instruction, stack, (IArrayTypeReference)instruction.Operation.Value);
                 */
                currentState.Pop();
                Contract.Assume(instruction.Operation.Value is IArrayTypeReference); //This is an informally specified property of the Metadata model.
                InitializeArrayIndexerInstruction(instruction, currentState, (IArrayTypeReference)instruction.Operation.Value);

                break;

            case OperationCode.Beq:
            case OperationCode.Beq_S:
            case OperationCode.Bge:
            case OperationCode.Bge_S:
            case OperationCode.Bge_Un:
            case OperationCode.Bge_Un_S:
            case OperationCode.Bgt:
            case OperationCode.Bgt_S:
            case OperationCode.Bgt_Un:
            case OperationCode.Bgt_Un_S:
            case OperationCode.Ble:
            case OperationCode.Ble_S:
            case OperationCode.Ble_Un:
            case OperationCode.Ble_Un_S:
            case OperationCode.Blt:
            case OperationCode.Blt_S:
            case OperationCode.Blt_Un:
            case OperationCode.Blt_Un_S:
            case OperationCode.Bne_Un:
            case OperationCode.Bne_Un_S:
                /*instruction.Operand2 = stack.Pop();
                 * instruction.Operand1 = stack.Pop();
                 */
                currentState.Pop();
                currentState.Pop();
                break;

            case OperationCode.Box:
            case OperationCode.Castclass:
            case OperationCode.Ckfinite:
            case OperationCode.Conv_I:
            case OperationCode.Conv_I1:
            case OperationCode.Conv_I2:
            case OperationCode.Conv_I4:
            case OperationCode.Conv_I8:
            case OperationCode.Conv_Ovf_I:
            case OperationCode.Conv_Ovf_I_Un:
            case OperationCode.Conv_Ovf_I1:
            case OperationCode.Conv_Ovf_I1_Un:
            case OperationCode.Conv_Ovf_I2:
            case OperationCode.Conv_Ovf_I2_Un:
            case OperationCode.Conv_Ovf_I4:
            case OperationCode.Conv_Ovf_I4_Un:
            case OperationCode.Conv_Ovf_I8:
            case OperationCode.Conv_Ovf_I8_Un:
            case OperationCode.Conv_Ovf_U:
            case OperationCode.Conv_Ovf_U_Un:
            case OperationCode.Conv_Ovf_U1:
            case OperationCode.Conv_Ovf_U1_Un:
            case OperationCode.Conv_Ovf_U2:
            case OperationCode.Conv_Ovf_U2_Un:
            case OperationCode.Conv_Ovf_U4:
            case OperationCode.Conv_Ovf_U4_Un:
            case OperationCode.Conv_Ovf_U8:
            case OperationCode.Conv_Ovf_U8_Un:
            case OperationCode.Conv_R_Un:
            case OperationCode.Conv_R4:
            case OperationCode.Conv_R8:
            case OperationCode.Conv_U:
            case OperationCode.Conv_U1:
            case OperationCode.Conv_U2:
            case OperationCode.Conv_U4:
            case OperationCode.Conv_U8:
            case OperationCode.Isinst:
            case OperationCode.Ldind_I:
            case OperationCode.Ldind_I1:
            case OperationCode.Ldind_I2:
            case OperationCode.Ldind_I4:
            case OperationCode.Ldind_I8:
            case OperationCode.Ldind_R4:
            case OperationCode.Ldind_R8:
            case OperationCode.Ldind_Ref:
            case OperationCode.Ldind_U1:
            case OperationCode.Ldind_U2:
            case OperationCode.Ldind_U4:
            case OperationCode.Ldobj:
            case OperationCode.Ldflda:
            case OperationCode.Ldfld:
            case OperationCode.Ldlen:
            case OperationCode.Ldvirtftn:
            case OperationCode.Localloc:
            case OperationCode.Mkrefany:
            case OperationCode.Neg:
            case OperationCode.Not:
            case OperationCode.Refanytype:
            case OperationCode.Refanyval:
            case OperationCode.Unbox:
            case OperationCode.Unbox_Any:
                /*instruction.Operand1 = stack.Pop();
                 * stack.Push(instruction);
                 */
                currentState.Pop();
                //currentState.Push(ValueAbstraction.Top); // Could be smarter than Top
                currentState.Push(ValueAbstraction.GetAbstractValueForType(FixupTypeForFlow(instruction.Type.ResolvedType))); // Still not right
                break;

            case OperationCode.Brfalse:
            case OperationCode.Brfalse_S:
            case OperationCode.Brtrue:
            case OperationCode.Brtrue_S:
                //instruction.Operand1 = stack.Pop();
                currentState.Pop();
                break;

            case OperationCode.Call:
                /*var signature = instruction.Operation.Value as ISignature;
                 * Contract.Assume(signature != null); //This is an informally specified property of the Metadata model.
                 * if (!signature.IsStatic) instruction.Operand1 = stack.Pop();
                 * InitializeArgumentsAndPushReturnResult(instruction, stack, signature);
                 */
                var signature = instruction.Operation.Value as ISignature;
                Contract.Assume(signature != null); //This is an informally specified property of the Metadata model.

                InterpretCallWithSignature(currentState, signature, !signature.IsStatic);
                break;

            case OperationCode.Callvirt:
                /*
                 * instruction.Operand1 = stack.Pop();
                 * Contract.Assume(instruction.Operation.Value is ISignature); //This is an informally specified property of the Metadata model.
                 * InitializeArgumentsAndPushReturnResult(instruction, stack, (ISignature)instruction.Operation.Value);
                 */


                Contract.Assume(instruction.Operation.Value is ISignature); //This is an informally specified property of the Metadata model.
                InterpretCallWithSignature(currentState, (ISignature)instruction.Operation.Value, true);
                break;

            case OperationCode.Calli:
                /*
                 * Contract.Assume(instruction.Operation.Value is ISignature); //This is an informally specified property of the Metadata model.
                 * InitializeArgumentsAndPushReturnResult(instruction, stack, (ISignature)instruction.Operation.Value);
                 * instruction.Operand1 = stack.Pop();
                 */


                currentState.Pop(); // the method pointer

                signature = instruction.Operation.Value as ISignature;
                Contract.Assume(signature != null); //This is an informally specified property of the Metadata model.
                InterpretCallWithSignature(currentState, (ISignature)instruction.Operation.Value, !signature.IsStatic);

                break;

            case OperationCode.Cpobj:
            case OperationCode.Stfld:
            case OperationCode.Stind_I:
            case OperationCode.Stind_I1:
            case OperationCode.Stind_I2:
            case OperationCode.Stind_I4:
            case OperationCode.Stind_I8:
            case OperationCode.Stind_R4:
            case OperationCode.Stind_R8:
            case OperationCode.Stind_Ref:
            case OperationCode.Stobj:
                /*
                 * instruction.Operand2 = stack.Pop();
                 * instruction.Operand1 = stack.Pop();
                 */
                currentState.Pop();
                currentState.Pop();

                break;

            case OperationCode.Cpblk:
            case OperationCode.Initblk:
            case OperationCode.Stelem:
            case OperationCode.Stelem_I:
            case OperationCode.Stelem_I1:
            case OperationCode.Stelem_I2:
            case OperationCode.Stelem_I4:
            case OperationCode.Stelem_I8:
            case OperationCode.Stelem_R4:
            case OperationCode.Stelem_R8:
            case OperationCode.Stelem_Ref:
                /*var indexAndValue = new Instruction[2];
                 * indexAndValue[1] = stack.Pop();
                 * indexAndValue[0] = stack.Pop();
                 * instruction.Operand2 = indexAndValue;
                 * instruction.Operand1 = stack.Pop();
                 */


                currentState.Pop();
                currentState.Pop();
                currentState.Pop();
                break;

            case OperationCode.Dup:
                /*
                 * var dupop = stack.Pop();
                 * instruction.Operand1 = dupop;
                 * stack.Push(dupop);
                 * stack.Push(instruction);
                 */
                // Pop the top and push it twice
                var dupValue = currentState.Pop();
                currentState.Push(dupValue);
                currentState.Push(dupValue);
                break;



            case OperationCode.Starg:
            case OperationCode.Starg_S:
            {
                int argumentIndex = GetArgumentIndexFromParameterOperation(instruction.Operation, method);

                V newArgumentValue = currentState.Pop();

                currentState.Arguments[argumentIndex] = newArgumentValue;
            }
            break;

            case OperationCode.Stloc:
            case OperationCode.Stloc_0:
            case OperationCode.Stloc_1:
            case OperationCode.Stloc_2:
            case OperationCode.Stloc_3:
            case OperationCode.Stloc_S: {
                Contract.Assume(instruction.Operation.Value is ILocalDefinition);

                ILocalDefinition local = instruction.Operation.Value as ILocalDefinition;

                int localIndex = GetLocalIndexFromLocalOperation(instruction.Operation, method);

                V newLocalValue = currentState.Pop();

                currentState.Locals[localIndex] = newLocalValue;
            }
            break;


            case OperationCode.Endfilter:
            case OperationCode.Initobj:
            case OperationCode.Pop:

            case OperationCode.Stsfld:
            case OperationCode.Throw:
            case OperationCode.Switch:
                //instruction.Operand1 = stack.Pop();

                currentState.Pop();
                break;

            case OperationCode.Newobj:
                /*
                 * Contract.Assume(instruction.Operation.Value is ISignature); //This is an informally specified property of the Metadata model.
                 * InitializeArgumentsAndPushReturnResult(instruction, stack, (ISignature)instruction.Operation.Value); //won't push anything
                 * stack.Push(instruction);
                 */

                Contract.Assume(instruction.Operation.Value is IMethodReference);                         //This is an informally specified property of the Metadata model.
                InterpretCallWithSignature(currentState, (ISignature)instruction.Operation.Value, false); //won't push anything, since return type is void


                currentState.Push(ValueAbstraction.GetAbstractValueForType(FixupTypeForFlow(((IMethodReference)instruction.Operation.Value).ResolvedMethod.ContainingTypeDefinition)));

                break;

            case OperationCode.Ret:
                /*if (this.cdfg.MethodBody.MethodDefinition.Type.TypeCode != PrimitiveTypeCode.Void)
                 * instruction.Operand1 = stack.Pop();
                 */
                if (method.Type.TypeCode != PrimitiveTypeCode.Void)
                {
                    currentState.Pop();
                }
                break;
            }

            return(currentState);
        }