コード例 #1
0
        /// <summary>
        /// Handles the usage of phi variables.
        /// </summary>
        /// <param name="instructionOffset">The offset of the instruction, that pops the phi variable from the stack.</param>
        /// <param name="record">The VariableDefineUseRecord associated with the instruction.</param>
        /// <param name="variableNode">The node in the craph corresponding to the phi variable.</param>
        /// <param name="nodes"> The graph. </param>
        protected override void OnPhiVariableUsed(int instructionOffset, ClassHierarchyNode variableNode)
        {
            Instruction instr = offsetToInstruction[instructionOffset];

            if (instr.OpCode.Code == Code.Dup || instr.OpCode.Code == Code.Pop)
            {
                ///No information regarding the type of the phi variable can be extracted from pop/dup instructions
                return;
            }
            ///Get the use type of the phi variable.
            ClassHierarchyNode typeNode = GetUseExpressionTypeNode(instr, variableNode.Variable);

            if (instr.OpCode.Code == Code.Switch)
            {
                variableNode.AddSupertype(typeNode);
                resultingGraph.Add(typeNode);
                return;
            }

            ///It is possible, that a phi variable is being used with another one. This case needs special care.
            if (typeNode.NodeType.FullName == "System.Int32" && OnlyPhiVariablesUsed(offsetToExpression[instr.Offset]))
            {
                ///Only phi variables were part of the expression.
                List <ClassHierarchyNode> phiVariableNodes = GetUsedPhiVariableNodes(instr.Offset);
                for (int i = 0; i < phiVariableNodes.Count; i++)
                {
                    for (int j = i + 1; j < phiVariableNodes.Count; j++)
                    {
                        ///Add edge between the phi variables.
                        phiVariableNodes[i].AddSupertype(phiVariableNodes[j]);
                        phiVariableNodes[j].AddSupertype(phiVariableNodes[i]);
                    }
                }

                if (IsArithmeticOperation(instr.OpCode.Code))
                {
                    for (int i = 0; i < phiVariableNodes.Count; i++)
                    {
                        notPossibleBooleanNodes.Add(phiVariableNodes[i]);

                        ClassHierarchyNode integerTypeNode = GetTypeNode(typeSystem.Int32);
                        if (!integerTypeNode.CanAssignTo.Contains(phiVariableNodes[i]))
                        {
                            integerTypeNode.CanAssignTo.Add(phiVariableNodes[i]);
                            phiVariableNodes[i].SubTypes.Add(integerTypeNode);
                        }
                    }
                }

                return;
            }

            variableNode.AddSupertype(typeNode);
            resultingGraph.Add(typeNode);
        }
コード例 #2
0
 protected override void OnPhiVariableUsed(int instructionOffset, ClassHierarchyNode variableNode)
 {
     V_0 = this.offsetToInstruction.get_Item(instructionOffset);
     if (V_0.get_OpCode().get_Code() == 36 || V_0.get_OpCode().get_Code() == 37)
     {
         return;
     }
     V_1 = this.GetUseExpressionTypeNode(V_0, variableNode.get_Variable());
     if (V_0.get_OpCode().get_Code() == 68)
     {
         variableNode.AddSupertype(V_1);
         dummyVar0 = this.resultingGraph.Add(V_1);
         return;
     }
     if (!String.op_Equality(V_1.get_NodeType().get_FullName(), "System.Int32") || !this.OnlyPhiVariablesUsed(this.offsetToExpression.get_Item(V_0.get_Offset())))
     {
         variableNode.AddSupertype(V_1);
         dummyVar2 = this.resultingGraph.Add(V_1);
         return;
     }
     V_3 = this.GetUsedPhiVariableNodes(V_0.get_Offset());
     V_4 = 0;
     while (V_4 < V_3.get_Count())
     {
         V_5 = V_4 + 1;
         while (V_5 < V_3.get_Count())
         {
             V_3.get_Item(V_4).AddSupertype(V_3.get_Item(V_5));
             V_3.get_Item(V_5).AddSupertype(V_3.get_Item(V_4));
             V_5 = V_5 + 1;
         }
         V_4 = V_4 + 1;
     }
     if (this.IsArithmeticOperation(V_0.get_OpCode().get_Code()))
     {
         V_6 = 0;
         while (V_6 < V_3.get_Count())
         {
             dummyVar1 = this.notPossibleBooleanNodes.Add(V_3.get_Item(V_6));
             V_7       = this.GetTypeNode(this.typeSystem.get_Int32());
             if (!V_7.get_CanAssignTo().Contains(V_3.get_Item(V_6)))
             {
                 V_7.get_CanAssignTo().Add(V_3.get_Item(V_6));
                 V_3.get_Item(V_6).get_SubTypes().Add(V_7);
             }
             V_6 = V_6 + 1;
         }
     }
     return;
 }
コード例 #3
0
        /// <summary>
        /// Handles the assignment of phi variables.
        /// </summary>
        /// <param name="instructionOffset">The offset of the instruction, that put the value on the stack.</param>
        /// <param name="variableNode">The graph node corresponding to the phi variable.</param>
        /// <param name="nodes">The graph.</param>
        protected override void OnPhiVariableAssigned(int instructionOffset, ClassHierarchyNode variableNode)
        {
            /// This key should allways be present.
            Expression instructionExpression = offsetToExpression[instructionOffset];
            /// Determine the type of the assigned value.
            TypeReference assignedType = instructionExpression.ExpressionType;

            if (instructionExpression is LiteralExpression)
            {
                int literal = (int)((instructionExpression as LiteralExpression).Value);
                if (literal == 0 || literal == 1)
                {
                    assignedType = typeSystem.Boolean;
                }
                else if (literal <= byte.MaxValue && literal >= byte.MinValue)
                {
                    assignedType = typeSystem.Byte;
                }
                else if (literal < char.MaxValue && literal >= char.MinValue)
                {
                    /// Both char and short can be used here.
                    assignedType = typeSystem.Char;
                }
            }
            /// Add the edge in the graph.
            ClassHierarchyNode supertypeNode = GetTypeNode(assignedType);

            supertypeNode.AddSupertype(variableNode);
            resultingGraph.Add(supertypeNode);
        }
コード例 #4
0
 /// <summary>
 /// Adds an edge from <paramref name="smallerType"/> to <paramref name="biggerType"/>.
 /// </summary>
 /// <param name="biggerTypeNode">The type the edge points to.</param>
 /// <param name="smallerTypeNode">The type the edge comes from.</param>
 private void AddEdge(ClassHierarchyNode biggerTypeNode, ClassHierarchyNode smallerTypeNode)
 {
     // smallerTypeNode can assign to BiggerTypeNode
     smallerTypeNode.AddSupertype(biggerTypeNode);
     resultingGraph.Add(smallerTypeNode);
     resultingGraph.Add(biggerTypeNode);
 }
コード例 #5
0
 private void AddEdge(ClassHierarchyNode biggerTypeNode, ClassHierarchyNode smallerTypeNode)
 {
     smallerTypeNode.AddSupertype(biggerTypeNode);
     dummyVar0 = this.resultingGraph.Add(smallerTypeNode);
     dummyVar1 = this.resultingGraph.Add(biggerTypeNode);
     return;
 }
コード例 #6
0
        /// <summary>
        /// Builds the hierarchy between the hard nodes.
        /// </summary>
        /// <param name="hardNodes">Collection of the hard nodes.</param>
        protected virtual void BuildUpHardNodesHierarchy(IEnumerable <ClassHierarchyNode> hardNodes)
        {
            Queue <ClassHierarchyNode>   queuedNodes    = new Queue <ClassHierarchyNode>(hardNodes);
            HashSet <ClassHierarchyNode> processedNodes = new HashSet <ClassHierarchyNode>();

            while (queuedNodes.Count > 0)
            {
                ClassHierarchyNode currentType = queuedNodes.Dequeue();
                processedNodes.Add(currentType);
                resultingGraph.Add(currentType);
                TypeDefinition currentNodeType = currentType.NodeType.Resolve();
                TypeReference  baseTypeRef     = null;
                if (currentNodeType == null)
                {
                    continue;
                }
                baseTypeRef = currentNodeType.BaseType;
                if (baseTypeRef != null)
                {
                    ClassHierarchyNode baseType = GetTypeNode(baseTypeRef);
                    currentType.AddSupertype(baseType);
                    if (!processedNodes.Contains(baseType))
                    {
                        queuedNodes.Enqueue(baseType);
                    }
                }

                if (currentNodeType.IsInterface)
                {
                    ClassHierarchyNode objectNode = GetTypeNode(typeSystem.Object);
                    currentType.AddSupertype(objectNode);
                }

                IEnumerable <TypeReference> interfaces = currentType.NodeType.Resolve().Interfaces;
                foreach (TypeReference interfaceRef in interfaces)
                {
                    ClassHierarchyNode implementedInterface = GetTypeNode(interfaceRef);
                    currentType.AddSupertype(implementedInterface);
                    if (!processedNodes.Contains(implementedInterface))
                    {
                        queuedNodes.Enqueue(implementedInterface);
                    }
                }
            }

            AddObjectClassNodeIfMIssing();
        }
        /// <summary>
        /// Handles the usage of phi variables.
        /// </summary>
        /// <param name="instructionOffset">The offset of the instruction, that pops the phi variable from the stack.</param>
        /// <param name="record">The VariableDefineUseRecord associated with the instruction.</param>
        /// <param name="variableNode">The node in the craph corresponding to the phi variable.</param>
        /// <param name="nodes"> The graph. </param>
        protected override void OnPhiVariableUsed(int instructionOffset, ClassHierarchyNode variableNode)
        {
            Instruction instr = offsetToInstruction[instructionOffset];
            if (instr.OpCode.Code == Code.Dup || instr.OpCode.Code == Code.Pop)
            {
                ///No information regarding the type of the phi variable can be extracted from pop/dup instructions
                return;
            }
            ///Get the use type of the phi variable.
            ClassHierarchyNode typeNode = GetUseExpressionTypeNode(instr, variableNode.Variable);

            if (instr.OpCode.Code == Code.Switch)
            {
                variableNode.AddSupertype(typeNode);
                resultingGraph.Add(typeNode);
                return;
            }

            ///It is possible, that a phi variable is being used with another one. This case needs special care.
            if (typeNode.NodeType.FullName == "System.Int32" && OnlyPhiVariablesUsed(offsetToExpression[instr.Offset]))
            {
                ///Only phi variables were part of the expression.
                List<ClassHierarchyNode> phiVariableNodes = GetUsedPhiVariableNodes(instr.Offset);
                for (int i = 0; i < phiVariableNodes.Count; i++)
                {
                    for (int j = i + 1; j < phiVariableNodes.Count; j++)
                    {
                        ///Add edge between the phi variables.
                        phiVariableNodes[i].AddSupertype(phiVariableNodes[j]);
                        phiVariableNodes[j].AddSupertype(phiVariableNodes[i]);
                    }
                }

                if (IsArithmeticOperation(instr.OpCode.Code))
                {
                    for (int i = 0; i < phiVariableNodes.Count; i++)
                    {
                        notPossibleBooleanNodes.Add(phiVariableNodes[i]);

                        ClassHierarchyNode integerTypeNode = GetTypeNode(typeSystem.Int32);
                        if (!integerTypeNode.CanAssignTo.Contains(phiVariableNodes[i]))
                        {
                            integerTypeNode.CanAssignTo.Add(phiVariableNodes[i]);
                            phiVariableNodes[i].SubTypes.Add(integerTypeNode);
                        }
                    }
                }

                return;
            }

            variableNode.AddSupertype(typeNode);
            resultingGraph.Add(typeNode);
        }
 /// <summary>
 /// Adds an edge from <paramref name="smallerType"/> to <paramref name="biggerType"/>.
 /// </summary>
 /// <param name="biggerTypeNode">The type the edge points to.</param>
 /// <param name="smallerTypeNode">The type the edge comes from.</param>
 private void AddEdge(ClassHierarchyNode biggerTypeNode, ClassHierarchyNode smallerTypeNode)
 {
     // smallerTypeNode can assign to BiggerTypeNode
     smallerTypeNode.AddSupertype(biggerTypeNode);
     resultingGraph.Add(smallerTypeNode);
     resultingGraph.Add(biggerTypeNode);
 }