示例#1
0
        public void Graph_StartDFSInTheMiddle_ReturnCycleOfTwo()
        {
            // Arrange
            var graph = new DirectGraph <GraphNode>();

            var node1 = new GraphNode();
            var node2 = new GraphNode();
            var node3 = new GraphNode();

            node1.LinkNext(node2);
            node2.LinkNext(node3);

            graph.Add("node1", node1);
            graph.Add("node2", node2);
            graph.Add("node3", node2);

            // Act
            var cycles = new List <Cycle <GraphNode> >();

            foreach (var cycle in graph.DepthFirstCycle(node2))
            {
                cycles.Add(cycle);
            }

            // Assert
            Assert.AreEqual(1, cycles.Count);

            var cycle1 = cycles[0];

            Assert.AreEqual(2, cycle1.Count);
            Assert.AreEqual(node2, cycle1[0]);
            Assert.AreEqual(node3, cycle1[1]);
        }
示例#2
0
文件: Board.cs 项目: Nkmol/Circuit
        public Board()
        {
            Components = new DirectGraph <Component>();

            // Default board name
            Name = "RootBoard";
        }
示例#3
0
 private static void ResetExprentTypes(DirectGraph graph)
 {
     graph.IterateExprents((Exprent exprent) => {
         List <Exprent> lst = exprent.GetAllExprents(true);
         lst.Add(exprent);
         foreach (Exprent expr in lst)
         {
             if (expr.type == Exprent.Exprent_Var)
             {
                 ((VarExprent)expr).SetVarType(VarType.Vartype_Unknown);
             }
             else if (expr.type == Exprent.Exprent_Const)
             {
                 ConstExprent constExpr = (ConstExprent)expr;
                 if (constExpr.GetConstType().typeFamily == ICodeConstants.Type_Family_Integer)
                 {
                     constExpr.SetConstType(new ConstExprent(constExpr.GetIntValue(), constExpr.IsBoolPermitted
                                                                 (), null).GetConstType());
                 }
             }
         }
         return(0);
     }
                           );
 }
示例#4
0
        public void Graph_AddInfiniteRelation_ReturnNoCycles()
        {
            // Arrange
            var graph = new DirectGraph <GraphNode>();

            var node1 = new GraphNode();
            var node2 = new GraphNode();

            node1.LinkNext(node2);
            node2.LinkNext(node1);

            graph.Add("node1", node1);
            graph.Add("node2", node2);

            // Act
            var cycles = new List <Cycle <GraphNode> >();

            foreach (var cycle in graph.DepthFirstCycle(node1))
            {
                cycles.Add(cycle);
            }

            // Assert
            Assert.IsTrue(graph.IsCyclic);
            Assert.AreEqual(0, cycles.Count);
        }
示例#5
0
 public virtual DirectGraph GetOrBuildGraph()
 {
     if (graph == null && root != null)
     {
         graph = new FlattenStatementsHelper().BuildDirectGraph(root);
     }
     return(graph);
 }
示例#6
0
 public virtual void CalculateVarTypes(RootStatement root, DirectGraph graph)
 {
     SetInitVars(root);
     ResetExprentTypes(graph);
     //noinspection StatementWithEmptyBody
     while (!ProcessVarTypes(graph))
     {
     }
 }
        private static void ProcessClassRec(ClassesProcessor.ClassNode node, IDictionary
                                            <ClassWrapper, MethodWrapper> mapClassMeths, HashSet <ClassWrapper> setFound)
        {
            ClassWrapper wrapper = node.GetWrapper();

            // search code
            foreach (MethodWrapper meth in wrapper.GetMethods())
            {
                RootStatement root = meth.root;
                if (root != null)
                {
                    DirectGraph graph = meth.GetOrBuildGraph();
                    graph.IterateExprents((Exprent exprent) => {
                        foreach (KeyValuePair <ClassWrapper, MethodWrapper> ent in mapClassMeths)
                        {
                            if (ReplaceInvocations(exprent, ent.Key, ent.Value))
                            {
                                setFound.Add(ent.Key);
                            }
                        }
                        return(0);
                    }
                                          );
                }
            }
            // search initializers
            for (int j = 0; j < 2; j++)
            {
                VBStyleCollection <Exprent, string> initializers = j == 0 ? wrapper.GetStaticFieldInitializers
                                                                       () : wrapper.GetDynamicFieldInitializers();
                for (int i = 0; i < initializers.Count; i++)
                {
                    foreach (KeyValuePair <ClassWrapper, MethodWrapper> ent in mapClassMeths)
                    {
                        Exprent exprent = initializers[i];
                        if (ReplaceInvocations(exprent, ent.Key, ent.Value))
                        {
                            setFound.Add(ent.Key);
                        }
                        string cl = IsClass14Invocation(exprent, ent.Key, ent.Value);
                        if (cl != null)
                        {
                            initializers[i] = new ConstExprent(VarType.Vartype_Class, cl.Replace('.', '/'), exprent
                                                               .bytecode);
                            setFound.Add(ent.Key);
                        }
                    }
                }
            }
            // iterate nested classes
            foreach (ClassesProcessor.ClassNode nd in node.nested)
            {
                ProcessClassRec(nd, mapClassMeths, setFound);
            }
        }
示例#8
0
        public void Graph_AddBackEdge_BypassInfiniteLoop_ReturnOneCycle()
        {
            // Arrange
            var graph = new DirectGraph <GraphNode>();

            var node1 = new GraphNode {
                Name = "node1"
            };
            var node2 = new GraphNode {
                Name = "node2"
            };
            var node3 = new GraphNode {
                Name = "node3"
            };
            var node4 = new GraphNode {
                Name = "node4"
            };
            var node5 = new GraphNode {
                Name = "node5"
            };

            // Arrange - setup relations
            node1.LinkNext(node2);
            node2.LinkNext(node5);

            node1.LinkNext(node3);
            node3.LinkNext(node4);
            node4.LinkNext(node1);

            graph.Add("node1", node1);
            graph.Add("node2", node2);
            graph.Add("node3", node3);
            graph.Add("node4", node4);
            graph.Add("node5", node5);

            // Act
            var cycles = new List <Cycle <GraphNode> >();

            foreach (var cycle in graph.DepthFirstCycle(node1))
            {
                cycles.Add(cycle);
            }

            // Assert
            Assert.IsTrue(graph.IsCyclic);
            Assert.AreEqual(1, cycles.Count);

            var cycle1 = cycles[0];

            Assert.AreEqual(3, cycle1.Count);
            Assert.AreEqual(1, cycle1.Number);
            Assert.AreEqual(node1, cycle1[0], "node1");
            Assert.AreEqual(node2, cycle1[1], "node2");
            Assert.AreEqual(node5, cycle1[2], "node5");
        }
 private void EliminateStaticAccess(ClassesProcessor.ClassNode node)
 {
     if (node.type == ClassesProcessor.ClassNode.Class_Lambda)
     {
         return;
     }
     foreach (MethodWrapper meth in node.GetWrapper().GetMethods())
     {
         if (meth.root != null)
         {
             bool                    replaced   = false;
             DirectGraph             graph      = meth.GetOrBuildGraph();
             HashSet <DirectNode>    setVisited = new HashSet <DirectNode>();
             LinkedList <DirectNode> stack      = new LinkedList <DirectNode>();
             stack.AddLast(graph.first);
             while (!(stack.Count == 0))
             {
                 // TODO: replace with interface iterator?
                 DirectNode nd = Sharpen.Collections.RemoveFirst(stack);
                 if (setVisited.Contains(nd))
                 {
                     continue;
                 }
                 setVisited.Add(nd);
                 for (int i = 0; i < nd.exprents.Count; i++)
                 {
                     Exprent exprent = nd.exprents[i];
                     replaced |= ReplaceInvocations(node, meth, exprent);
                     if (exprent.type == Exprent.Exprent_Invocation)
                     {
                         Exprent ret = ReplaceAccessExprent(node, meth, (InvocationExprent)exprent);
                         if (ret != null)
                         {
                             nd.exprents[i] = ret;
                             replaced       = true;
                         }
                     }
                 }
                 Sharpen.Collections.AddAll(stack, nd.succs);
             }
             if (replaced)
             {
                 ComputeMethodType(node, meth);
             }
         }
     }
     foreach (ClassesProcessor.ClassNode child in node.nested)
     {
         EliminateStaticAccess(child);
     }
 }
示例#10
0
        private static void MergePhiVersions(SSAConstructorSparseEx ssa, DirectGraph graph
                                             )
        {
            // collect phi versions
            List <HashSet <VarVersionPair> > lst = new List <HashSet <VarVersionPair> >();

            foreach (KeyValuePair <VarVersionPair, FastSparseSetFactory <int> .FastSparseSet <int> > ent
                     in ssa.GetPhi())
            {
                HashSet <VarVersionPair> set = new HashSet <VarVersionPair>();
                set.Add(ent.Key);
                foreach (int version in ent.Value)
                {
                    set.Add(new VarVersionPair(ent.Key.var, version));
                }
                for (int i = lst.Count - 1; i >= 0; i--)
                {
                    HashSet <VarVersionPair> tset         = lst[i];
                    HashSet <VarVersionPair> intersection = new HashSet <VarVersionPair>(set);
                    intersection.IntersectWith(tset);
                    if (!(intersection.Count == 0))
                    {
                        Sharpen.Collections.AddAll(set, tset);
                        lst.RemoveAtReturningValue(i);
                    }
                }
                lst.Add(set);
            }
            Dictionary <VarVersionPair, int> phiVersions = new Dictionary <VarVersionPair, int
                                                                           >();

            foreach (HashSet <VarVersionPair> set in lst)
            {
                int min = int.MaxValue;
                foreach (VarVersionPair paar in set)
                {
                    if (paar.version < min)
                    {
                        min = paar.version;
                    }
                }
                foreach (VarVersionPair paar in set)
                {
                    Sharpen.Collections.Put(phiVersions, new VarVersionPair(paar.var, paar.version),
                                            min);
                }
            }
            UpdateVersions(graph, phiVersions);
        }
示例#11
0
        private int M;         //状态数量,即正则表达式长度

        /// <summary>
        /// 根据给定的正则表达式构造NFA
        /// </summary>
        public NFA(string regexp)
        {
            Stack <int> ops = new Stack <int>();//用来保存左括号、或符号

            re = regexp.ToCharArray();
            M  = re.Length;
            G  = new DirectGraph(M + 1);//有向图,保存每个点出发可以到达的点

            for (int i = 0; i < M; i++)
            {
                int lp = i;
                if (re[i] == '(' || re[i] == '|')//|的索引也要压入栈中,这样因为(的索引也压入了,可以遇到右括号时,(和|的索引都能知道,就能实现或跳转了
                {
                    ops.Push(i);
                }
                else if (re[i] == ')')
                {
                    List <int> orList = new List <int>();
                    while (ops.Count > 0)
                    {
                        int or = ops.Pop();
                        if (re[or] == '(')//找到|符号的上一个左括号的位置
                        {
                            lp = or;
                            break;
                        }
                        if (re[or] == '|')
                        {
                            orList.Add(or);
                        }
                    }
                    foreach (var or in orList)
                    {
                        G.AddAdj(lp, or + 1); //把(和|后面的第一个字符相连
                        G.AddAdj(or, i);      //把|和)相连
                    }
                }
                if (i < M - 1 && re[i + 1] == '*')                //当前字符下一字符为闭包
                {
                    G.AddAdj(lp, i + 1);                          //即B->*
                    G.AddAdj(i + 1, lp);                          //即*->B
                }
                if (re[i] == '(' || re[i] == '*' || re[i] == ')') //这些符号也都可以进入下一状态,但|不能直接进入下一状态。普通字符之间不需要进行连接,因为不是epsilon转换
                {
                    G.AddAdj(i, i + 1);
                }
            }
        }
示例#12
0
        public virtual void SetVarVersions(RootStatement root, VarVersionsProcessor previousVersionsProcessor
                                           )
        {
            SSAConstructorSparseEx ssa = new SSAConstructorSparseEx();

            ssa.SplitVariables(root, method);
            FlattenStatementsHelper flattenHelper = new FlattenStatementsHelper();
            DirectGraph             graph         = flattenHelper.BuildDirectGraph(root);

            MergePhiVersions(ssa, graph);
            typeProcessor.CalculateVarTypes(root, graph);
            SimpleMerge(typeProcessor, graph, method);
            // FIXME: advanced merging
            EliminateNonJavaTypes(typeProcessor);
            SetNewVarIndices(typeProcessor, graph, previousVersionsProcessor);
        }
示例#13
0
        public void Graph_CreateTwoCycleValidGraph_ReturnTwoCycles()
        {
            // Arrange
            var graph = new DirectGraph <GraphNode>();

            var node1 = new GraphNode();
            var node2 = new GraphNode();
            var node3 = new GraphNode();
            var node4 = new GraphNode();

            // Arrange - setup relations
            node1.LinkNext(node2);
            node1.LinkNext(node3);
            node2.LinkNext(node4);
            node3.LinkNext(node4);

            graph.Add("node1", node1);
            graph.Add("node2", node2);
            graph.Add("node3", node3);
            graph.Add("node4", node4);

            // Act
            var cycles = new List <Cycle <GraphNode> >();

            foreach (var cycle in graph.DepthFirstCycle(node1))
            {
                cycles.Add(cycle);
            }

            // Assert
            Assert.AreEqual(2, cycles.Count);

            var cycle1 = cycles[0];

            Assert.AreEqual(1, cycle1.Number);
            Assert.AreEqual(node1, cycle1[0]);
            Assert.AreEqual(node3, cycle1[1]);
            Assert.AreEqual(node4, cycle1[2]);

            var cycle2 = cycles[1];

            Assert.AreEqual(2, cycle2.Number);
            Assert.AreEqual(node1, cycle2[0]);
            Assert.AreEqual(node2, cycle2[1]);
            Assert.AreEqual(node4, cycle2[2]);
        }
示例#14
0
 private static void UpdateVersions(DirectGraph graph, Dictionary <VarVersionPair,
                                                                   int> versions)
 {
     graph.IterateExprents((Exprent exprent) => {
         List <Exprent> lst = exprent.GetAllExprents(true);
         lst.Add(exprent);
         foreach (Exprent expr in lst)
         {
             if (expr.type == Exprent.Exprent_Var)
             {
                 VarExprent var = (VarExprent)expr;
                 int?version    = versions.GetOrNullable(new VarVersionPair(var));
                 if (version != null)
                 {
                     var.SetVersion(version.Value);
                 }
             }
         }
         return(0);
     }
                           );
 }
示例#15
0
        public virtual bool FindPPandMM(RootStatement root)
        {
            FlattenStatementsHelper flatthelper = new FlattenStatementsHelper();
            DirectGraph             dgraph      = flatthelper.BuildDirectGraph(root);
            LinkedList <DirectNode> stack       = new LinkedList <DirectNode>();

            stack.AddLast(dgraph.first);
            HashSet <DirectNode> setVisited = new HashSet <DirectNode>();
            bool res = false;

            while (!(stack.Count == 0))
            {
                DirectNode node = Sharpen.Collections.RemoveFirst(stack);
                if (setVisited.Contains(node))
                {
                    continue;
                }
                setVisited.Add(node);
                res |= ProcessExprentList(node.exprents);
                Sharpen.Collections.AddAll(stack, node.succs);
            }
            return(res);
        }
示例#16
0
        private bool IterateStatements(RootStatement root, SSAUConstructorSparseEx ssa)
        {
            FlattenStatementsHelper flatthelper = new FlattenStatementsHelper();
            DirectGraph             dgraph      = flatthelper.BuildDirectGraph(root);
            bool res = false;
            HashSet <DirectNode>    setVisited = new HashSet <DirectNode>();
            LinkedList <DirectNode> stack      = new LinkedList <DirectNode>();
            LinkedList <Dictionary <VarVersionPair, Exprent> > stackMaps = new LinkedList <Dictionary <VarVersionPair, Exprent> >();

            stack.AddLast(dgraph.first);
            stackMaps.AddLast(new Dictionary <VarVersionPair, Exprent>());
            while (!(stack.Count == 0))
            {
                DirectNode nd = Sharpen.Collections.RemoveFirst(stack);
                Dictionary <VarVersionPair, Exprent> mapVarValues = Sharpen.Collections.RemoveFirst
                                                                        (stackMaps);
                if (setVisited.Contains(nd))
                {
                    continue;
                }
                setVisited.Add(nd);
                List <List <Exprent> > lstLists = new List <List <Exprent> >();
                if (!(nd.exprents.Count == 0))
                {
                    lstLists.Add(nd.exprents);
                }
                if (nd.succs.Count == 1)
                {
                    DirectNode ndsucc = nd.succs[0];
                    if (ndsucc.type == DirectNode.Node_Tail && !(ndsucc.exprents.Count == 0))
                    {
                        lstLists.Add(nd.succs[0].exprents);
                        nd = ndsucc;
                    }
                }
                for (int i = 0; i < lstLists.Count; i++)
                {
                    List <Exprent> lst   = lstLists[i];
                    int            index = 0;
                    while (index < lst.Count)
                    {
                        Exprent next = null;
                        if (index == lst.Count - 1)
                        {
                            if (i < lstLists.Count - 1)
                            {
                                next = lstLists[i + 1][0];
                            }
                        }
                        else
                        {
                            next = lst[index + 1];
                        }
                        int[] ret = IterateExprent(lst, index, next, mapVarValues, ssa);
                        if (ret[0] >= 0)
                        {
                            index = ret[0];
                        }
                        else
                        {
                            index++;
                        }
                        res |= (ret[1] == 1);
                    }
                }
                foreach (DirectNode ndx in nd.succs)
                {
                    stack.AddLast(ndx);
                    stackMaps.AddLast(new Dictionary <VarVersionPair, Exprent>(mapVarValues));
                }
                // make sure the 3 special exprent lists in a loop (init, condition, increment) are not empty
                // change loop type if necessary
                if ((nd.exprents.Count == 0) && (nd.type == DirectNode.Node_Init || nd.type == DirectNode
                                                 .Node_Condition || nd.type == DirectNode.Node_Increment))
                {
                    nd.exprents.Add(null);
                    if (nd.statement.type == Statement.Type_Do)
                    {
                        DoStatement loop = (DoStatement)nd.statement;
                        if (loop.GetLooptype() == DoStatement.Loop_For && loop.GetInitExprent() == null &&
                            loop.GetIncExprent() == null)
                        {
                            // "downgrade" loop to 'while'
                            loop.SetLooptype(DoStatement.Loop_While);
                        }
                    }
                }
            }
            return(res);
        }
示例#17
0
文件: Board.cs 项目: Nkmol/Circuit
 public Board(DirectGraph <Component> nodes) : this()
 {
     Components = nodes;
 }
示例#18
0
        private Exprent ReplaceAccessExprent(ClassesProcessor.ClassNode caller, MethodWrapper
                                             methdest, InvocationExprent invexpr)
        {
            ClassesProcessor.ClassNode node = DecompilerContext.GetClassProcessor().GetMapRootClasses
                                                  ().GetOrNull(invexpr.GetClassname());
            MethodWrapper methsource = null;

            if (node != null && node.GetWrapper() != null)
            {
                methsource = node.GetWrapper().GetMethodWrapper(invexpr.GetName(), invexpr.GetStringDescriptor
                                                                    ());
            }
            if (methsource == null || !mapMethodType.ContainsKey(methsource))
            {
                return(null);
            }
            // if same method, return
            if (node.classStruct.qualifiedName.Equals(caller.classStruct.qualifiedName) && methsource
                .methodStruct.GetName().Equals(methdest.methodStruct.GetName()) && methsource.methodStruct
                .GetDescriptor().Equals(methdest.methodStruct.GetDescriptor()))
            {
                // no recursive invocations permitted!
                return(null);
            }
            NestedMemberAccess.MethodAccess type = mapMethodType.GetOrNull(methsource);
            //		// FIXME: impossible case. MethodAccess.NORMAL is not saved in the map
            //		if(type == MethodAccess.NORMAL) {
            //			return null;
            //		}
            if (!SameTree(caller, node))
            {
                return(null);
            }
            DirectGraph graph      = methsource.GetOrBuildGraph();
            Exprent     source     = graph.first.exprents[0];
            Exprent     retexprent = null;

            switch (type.ordinal())
            {
            case 1:
            {
                ExitExprent exsource = (ExitExprent)source;
                if (exsource.GetValue().type == Exprent.Exprent_Var)
                {
                    // qualified this
                    VarExprent var     = (VarExprent)exsource.GetValue();
                    string     varname = methsource.varproc.GetVarName(new VarVersionPair(var));
                    if (!methdest.setOuterVarNames.Contains(varname))
                    {
                        VarNamesCollector vnc = new VarNamesCollector();
                        vnc.AddName(varname);
                        methdest.varproc.RefreshVarNames(vnc);
                        methdest.setOuterVarNames.Add(varname);
                    }
                    int        index = methdest.counter.GetCounterAndIncrement(CounterContainer.Var_Counter);
                    VarExprent ret   = new VarExprent(index, var.GetVarType(), methdest.varproc);
                    methdest.varproc.SetVarName(new VarVersionPair(index, 0), varname);
                    retexprent = ret;
                }
                else
                {
                    // field
                    FieldExprent ret = (FieldExprent)exsource.GetValue().Copy();
                    if (!ret.IsStatic())
                    {
                        ret.ReplaceExprent(ret.GetInstance(), invexpr.GetLstParameters()[0]);
                    }
                    retexprent = ret;
                }
                break;
            }

            case 2:
            {
                AssignmentExprent ret_1;
                if (source.type == Exprent.Exprent_Exit)
                {
                    ExitExprent extex = (ExitExprent)source;
                    ret_1 = (AssignmentExprent)extex.GetValue().Copy();
                }
                else
                {
                    ret_1 = (AssignmentExprent)source.Copy();
                }
                FieldExprent fexpr = (FieldExprent)ret_1.GetLeft();
                if (fexpr.IsStatic())
                {
                    ret_1.ReplaceExprent(ret_1.GetRight(), invexpr.GetLstParameters()[0]);
                }
                else
                {
                    ret_1.ReplaceExprent(ret_1.GetRight(), invexpr.GetLstParameters()[1]);
                    fexpr.ReplaceExprent(fexpr.GetInstance(), invexpr.GetLstParameters()[0]);
                }
                // do not use copied bytecodes
                ret_1.GetLeft().bytecode  = null;
                ret_1.GetRight().bytecode = null;
                retexprent = ret_1;
                break;
            }

            case 4:
            {
                retexprent = ReplaceFunction(invexpr, source);
                break;
            }

            case 3:
            {
                if (source.type == Exprent.Exprent_Exit)
                {
                    source = ((ExitExprent)source).GetValue();
                }
                InvocationExprent invret = (InvocationExprent)source.Copy();
                int index_1 = 0;
                if (!invret.IsStatic())
                {
                    invret.ReplaceExprent(invret.GetInstance(), invexpr.GetLstParameters()[0]);
                    index_1 = 1;
                }
                for (int i = 0; i < invret.GetLstParameters().Count; i++)
                {
                    invret.ReplaceExprent(invret.GetLstParameters()[i], invexpr.GetLstParameters()[i
                                                                                                   + index_1]);
                }
                retexprent = invret;
                break;
            }
            }
            if (retexprent != null)
            {
                // preserve original bytecodes
                retexprent.bytecode = null;
                retexprent.AddBytecodeOffsets(invexpr.bytecode);
                // hide synthetic access method
                bool hide = true;
                if (node.type == ClassesProcessor.ClassNode.Class_Root || (node.access & ICodeConstants
                                                                           .Acc_Static) != 0)
                {
                    StructMethod mt = methsource.methodStruct;
                    if (!mt.IsSynthetic())
                    {
                        hide = false;
                    }
                }
                if (hide)
                {
                    node.GetWrapper().GetHiddenMembers().Add(InterpreterUtil.MakeUniqueKey(invexpr.GetName
                                                                                               (), invexpr.GetStringDescriptor()));
                }
            }
            return(retexprent);
        }
 public void GraphTest()
 {
     DirectGraph <string, object> graph = new DirectGraph <string, object>();
 }
示例#20
0
        private void ComputeMethodType(ClassesProcessor.ClassNode node, MethodWrapper method
                                       )
        {
            NestedMemberAccess.MethodAccess type = NestedMemberAccess.MethodAccess.Normal;
            if (method.root != null)
            {
                DirectGraph  graph = method.GetOrBuildGraph();
                StructMethod mt    = method.methodStruct;
                if ((noSynthFlag || mt.IsSynthetic()) && mt.HasModifier(ICodeConstants.Acc_Static
                                                                        ))
                {
                    if (graph.nodes.Count == 2)
                    {
                        // incl. dummy exit node
                        if (graph.first.exprents.Count == 1)
                        {
                            Exprent          exprent = graph.first.exprents[0];
                            MethodDescriptor mtdesc  = MethodDescriptor.ParseDescriptor(mt.GetDescriptor());
                            int     parcount         = [email protected];
                            Exprent exprCore         = exprent;
                            if (exprent.type == Exprent.Exprent_Exit)
                            {
                                ExitExprent exexpr = (ExitExprent)exprent;
                                if (exexpr.GetExitType() == ExitExprent.Exit_Return && exexpr.GetValue() != null)
                                {
                                    exprCore = exexpr.GetValue();
                                }
                            }
                            switch (exprCore.type)
                            {
                            case Exprent.Exprent_Field:
                            {
                                FieldExprent fexpr = (FieldExprent)exprCore;
                                if ((parcount == 1 && !fexpr.IsStatic()) || (parcount == 0 && fexpr.IsStatic()))
                                {
                                    if (fexpr.GetClassname().Equals(node.classStruct.qualifiedName))
                                    {
                                        // FIXME: check for private flag of the field
                                        if (fexpr.IsStatic() || (fexpr.GetInstance().type == Exprent.Exprent_Var && ((VarExprent
                                                                                                                      )fexpr.GetInstance()).GetIndex() == 0))
                                        {
                                            type = NestedMemberAccess.MethodAccess.Field_Get;
                                        }
                                    }
                                }
                                break;
                            }

                            case Exprent.Exprent_Var:
                            {
                                // qualified this
                                if (parcount == 1)
                                {
                                    // this or final variable
                                    if (((VarExprent)exprCore).GetIndex() != 0)
                                    {
                                        type = NestedMemberAccess.MethodAccess.Field_Get;
                                    }
                                }
                                break;
                            }

                            case Exprent.Exprent_Function:
                            {
                                // for now detect only increment/decrement
                                FunctionExprent functionExprent = (FunctionExprent)exprCore;
                                if (functionExprent.GetFuncType() >= FunctionExprent.Function_Imm && functionExprent
                                    .GetFuncType() <= FunctionExprent.Function_Ppi)
                                {
                                    if (functionExprent.GetLstOperands()[0].type == Exprent.Exprent_Field)
                                    {
                                        type = NestedMemberAccess.MethodAccess.Function;
                                    }
                                }
                                break;
                            }

                            case Exprent.Exprent_Invocation:
                            {
                                type = NestedMemberAccess.MethodAccess.Method;
                                break;
                            }

                            case Exprent.Exprent_Assignment:
                            {
                                AssignmentExprent asexpr = (AssignmentExprent)exprCore;
                                if (asexpr.GetLeft().type == Exprent.Exprent_Field && asexpr.GetRight().type == Exprent
                                    .Exprent_Var)
                                {
                                    FieldExprent fexpras = (FieldExprent)asexpr.GetLeft();
                                    if ((parcount == 2 && !fexpras.IsStatic()) || (parcount == 1 && fexpras.IsStatic(
                                                                                       )))
                                    {
                                        if (fexpras.GetClassname().Equals(node.classStruct.qualifiedName))
                                        {
                                            // FIXME: check for private flag of the field
                                            if (fexpras.IsStatic() || (fexpras.GetInstance().type == Exprent.Exprent_Var && (
                                                                           (VarExprent)fexpras.GetInstance()).GetIndex() == 0))
                                            {
                                                if (((VarExprent)asexpr.GetRight()).GetIndex() == parcount - 1)
                                                {
                                                    type = NestedMemberAccess.MethodAccess.Field_Set;
                                                }
                                            }
                                        }
                                    }
                                }
                                break;
                            }
                            }
                            if (type == NestedMemberAccess.MethodAccess.Method)
                            {
                                // FIXME: check for private flag of the method
                                type = NestedMemberAccess.MethodAccess.Normal;
                                InvocationExprent invexpr = (InvocationExprent)exprCore;
                                bool isStatic             = invexpr.IsStatic();
                                if ((isStatic && invexpr.GetLstParameters().Count == parcount) || (!isStatic && invexpr
                                                                                                   .GetInstance().type == Exprent.Exprent_Var && ((VarExprent)invexpr.GetInstance()
                                                                                                                                                  ).GetIndex() == 0 && invexpr.GetLstParameters().Count == parcount - 1))
                                {
                                    bool equalpars = true;
                                    int  index     = isStatic ? 0 : 1;
                                    for (int i = 0; i < invexpr.GetLstParameters().Count; i++)
                                    {
                                        Exprent parexpr = invexpr.GetLstParameters()[i];
                                        if (parexpr.type != Exprent.Exprent_Var || ((VarExprent)parexpr).GetIndex() != index)
                                        {
                                            equalpars = false;
                                            break;
                                        }
                                        index += mtdesc.@params[i + (isStatic ? 0 : 1)].stackSize;
                                    }
                                    if (equalpars)
                                    {
                                        type = NestedMemberAccess.MethodAccess.Method;
                                    }
                                }
                            }
                        }
                        else if (graph.first.exprents.Count == 2)
                        {
                            Exprent exprentFirst  = graph.first.exprents[0];
                            Exprent exprentSecond = graph.first.exprents[1];
                            if (exprentFirst.type == Exprent.Exprent_Assignment && exprentSecond.type == Exprent
                                .Exprent_Exit)
                            {
                                MethodDescriptor mtdesc  = MethodDescriptor.ParseDescriptor(mt.GetDescriptor());
                                int parcount             = [email protected];
                                AssignmentExprent asexpr = (AssignmentExprent)exprentFirst;
                                if (asexpr.GetLeft().type == Exprent.Exprent_Field && asexpr.GetRight().type == Exprent
                                    .Exprent_Var)
                                {
                                    FieldExprent fexpras = (FieldExprent)asexpr.GetLeft();
                                    if ((parcount == 2 && !fexpras.IsStatic()) || (parcount == 1 && fexpras.IsStatic(
                                                                                       )))
                                    {
                                        if (fexpras.GetClassname().Equals(node.classStruct.qualifiedName))
                                        {
                                            // FIXME: check for private flag of the field
                                            if (fexpras.IsStatic() || (fexpras.GetInstance().type == Exprent.Exprent_Var && (
                                                                           (VarExprent)fexpras.GetInstance()).GetIndex() == 0))
                                            {
                                                if (((VarExprent)asexpr.GetRight()).GetIndex() == parcount - 1)
                                                {
                                                    ExitExprent exexpr = (ExitExprent)exprentSecond;
                                                    if (exexpr.GetExitType() == ExitExprent.Exit_Return && exexpr.GetValue() != null)
                                                    {
                                                        if (exexpr.GetValue().type == Exprent.Exprent_Var && ((VarExprent)asexpr.GetRight
                                                                                                                  ()).GetIndex() == parcount - 1)
                                                        {
                                                            type = NestedMemberAccess.MethodAccess.Field_Set;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (type != NestedMemberAccess.MethodAccess.Normal)
            {
                Sharpen.Collections.Put(mapMethodType, method, type);
            }
            else
            {
                Sharpen.Collections.Remove(mapMethodType, method);
            }
        }
示例#21
0
        private FinallyProcessor.Record GetFinallyInformation(StructMethod mt, RootStatement
                                                              root, CatchAllStatement fstat)
        {
            Dictionary <BasicBlock, bool> mapLast             = new Dictionary <BasicBlock, bool>();
            BasicBlockStatement           firstBlockStatement = fstat.GetHandler().GetBasichead();
            BasicBlock  firstBasicBlock = firstBlockStatement.GetBlock();
            Instruction instrFirst      = firstBasicBlock.GetInstruction(0);
            int         firstcode       = 0;

            switch (instrFirst.opcode)
            {
            case ICodeConstants.opc_pop:
            {
                firstcode = 1;
                break;
            }

            case ICodeConstants.opc_astore:
            {
                firstcode = 2;
                break;
            }
            }
            ExprProcessor proc = new ExprProcessor(methodDescriptor, varProcessor);

            proc.ProcessStatement(root, mt.GetClassStruct());
            SSAConstructorSparseEx ssa = new SSAConstructorSparseEx();

            ssa.SplitVariables(root, mt);
            List <Exprent> lstExprents = firstBlockStatement.GetExprents();
            VarVersionPair varpaar     = new VarVersionPair((VarExprent)((AssignmentExprent)lstExprents
                                                                         [firstcode == 2 ? 1 : 0]).GetLeft());
            FlattenStatementsHelper flatthelper = new FlattenStatementsHelper();
            DirectGraph             dgraph      = flatthelper.BuildDirectGraph(root);
            LinkedList <DirectNode> stack       = new LinkedList <DirectNode>();

            stack.AddLast(dgraph.first);
            HashSet <DirectNode> setVisited = new HashSet <DirectNode>();

            while (!(stack.Count == 0))
            {
                DirectNode node = Sharpen.Collections.RemoveFirst(stack);
                if (setVisited.Contains(node))
                {
                    continue;
                }
                setVisited.Add(node);
                BasicBlockStatement blockStatement = null;
                if (node.block != null)
                {
                    blockStatement = node.block;
                }
                else if (node.preds.Count == 1)
                {
                    blockStatement = node.preds[0].block;
                }
                bool isTrueExit = true;
                if (firstcode != 1)
                {
                    isTrueExit = false;
                    for (int i = 0; i < node.exprents.Count; i++)
                    {
                        Exprent exprent = node.exprents[i];
                        if (firstcode == 0)
                        {
                            List <Exprent> lst = exprent.GetAllExprents();
                            lst.Add(exprent);
                            bool found = false;
                            foreach (Exprent expr in lst)
                            {
                                if (expr.type == Exprent.Exprent_Var && new VarVersionPair((VarExprent)expr).Equals
                                        (varpaar))
                                {
                                    found = true;
                                    break;
                                }
                            }
                            if (found)
                            {
                                found = false;
                                if (exprent.type == Exprent.Exprent_Exit)
                                {
                                    ExitExprent exexpr = (ExitExprent)exprent;
                                    if (exexpr.GetExitType() == ExitExprent.Exit_Throw && exexpr.GetValue().type == Exprent
                                        .Exprent_Var)
                                    {
                                        found = true;
                                    }
                                }
                                if (!found)
                                {
                                    return(null);
                                }
                                else
                                {
                                    isTrueExit = true;
                                }
                            }
                        }
                        else if (firstcode == 2)
                        {
                            // search for a load instruction
                            if (exprent.type == Exprent.Exprent_Assignment)
                            {
                                AssignmentExprent assexpr = (AssignmentExprent)exprent;
                                if (assexpr.GetRight().type == Exprent.Exprent_Var && new VarVersionPair((VarExprent
                                                                                                          )assexpr.GetRight()).Equals(varpaar))
                                {
                                    Exprent next = null;
                                    if (i == node.exprents.Count - 1)
                                    {
                                        if (node.succs.Count == 1)
                                        {
                                            DirectNode nd = node.succs[0];
                                            if (!(nd.exprents.Count == 0))
                                            {
                                                next = nd.exprents[0];
                                            }
                                        }
                                    }
                                    else
                                    {
                                        next = node.exprents[i + 1];
                                    }
                                    bool found = false;
                                    if (next != null && next.type == Exprent.Exprent_Exit)
                                    {
                                        ExitExprent exexpr = (ExitExprent)next;
                                        if (exexpr.GetExitType() == ExitExprent.Exit_Throw && exexpr.GetValue().type == Exprent
                                            .Exprent_Var && assexpr.GetLeft().Equals(exexpr.GetValue()))
                                        {
                                            found = true;
                                        }
                                    }
                                    if (!found)
                                    {
                                        return(null);
                                    }
                                    else
                                    {
                                        isTrueExit = true;
                                    }
                                }
                            }
                        }
                    }
                }
                // find finally exits
                if (blockStatement != null && blockStatement.GetBlock() != null)
                {
                    Statement handler = fstat.GetHandler();
                    foreach (StatEdge edge in blockStatement.GetSuccessorEdges(Statement.Statedge_Direct_All
                                                                               ))
                    {
                        if (edge.GetType() != StatEdge.Type_Regular && handler.ContainsStatement(blockStatement
                                                                                                 ) && !handler.ContainsStatement(edge.GetDestination()))
                        {
                            bool?existingFlag = mapLast.GetOrNullable(blockStatement.GetBlock());
                            // note: the dummy node is also processed!
                            if (existingFlag == null || !existingFlag.Value)
                            {
                                Sharpen.Collections.Put(mapLast, blockStatement.GetBlock(), isTrueExit);
                                break;
                            }
                        }
                    }
                }
                Sharpen.Collections.AddAll(stack, node.succs);
            }
            // empty finally block?
            if (fstat.GetHandler().type == Statement.Type_Basicblock)
            {
                bool isEmpty            = false;
                bool isFirstLast        = mapLast.ContainsKey(firstBasicBlock);
                InstructionSequence seq = firstBasicBlock.GetSeq();
                switch (firstcode)
                {
                case 0:
                {
                    isEmpty = isFirstLast && seq.Length() == 1;
                    break;
                }

                case 1:
                {
                    isEmpty = seq.Length() == 1;
                    break;
                }

                case 2:
                {
                    isEmpty = isFirstLast ? seq.Length() == 3 : seq.Length() == 1;
                    break;
                }
                }
                if (isEmpty)
                {
                    firstcode = 3;
                }
            }
            return(new FinallyProcessor.Record(firstcode, mapLast));
        }
示例#22
0
 private bool ProcessVarTypes(DirectGraph graph)
 {
     return(graph.IterateExprents((Exprent exprent) => CheckTypeExprent(exprent) ? 0 :
                                  1));
 }
示例#23
0
        private static void SimpleMerge(VarTypeProcessor typeProcessor, DirectGraph graph
                                        , StructMethod mt)
        {
            Dictionary <VarVersionPair, VarType> mapExprentMaxTypes = typeProcessor.GetMapExprentMaxTypes
                                                                          ();
            Dictionary <VarVersionPair, VarType> mapExprentMinTypes = typeProcessor.GetMapExprentMinTypes
                                                                          ();
            Dictionary <int, HashSet <int> > mapVarVersions = new Dictionary <int, HashSet <int> >
                                                                  ();

            foreach (VarVersionPair pair in mapExprentMinTypes.Keys)
            {
                if (pair.version >= 0)
                {
                    // don't merge constants
                    mapVarVersions.ComputeIfAbsent(pair.var, (int k) => new HashSet <int>()).Add(pair.
                                                                                                 version);
                }
            }
            bool is_method_static = mt.HasModifier(ICodeConstants.Acc_Static);
            Dictionary <VarVersionPair, int> mapMergedVersions = new Dictionary <VarVersionPair
                                                                                 , int>();

            foreach (KeyValuePair <int, HashSet <int> > ent in mapVarVersions)
            {
                if (ent.Value.Count > 1)
                {
                    List <int> lstVersions = new List <int>(ent.Value);
                    lstVersions.Sort();
                    for (int i = 0; i < lstVersions.Count; i++)
                    {
                        VarVersionPair firstPair = new VarVersionPair(ent.Key, lstVersions[i]);
                        VarType        firstType = mapExprentMinTypes.GetOrNull(firstPair);
                        if (firstPair.var == 0 && firstPair.version == 1 && !is_method_static)
                        {
                            continue;
                        }
                        // don't merge 'this' variable
                        for (int j = i + 1; j < lstVersions.Count; j++)
                        {
                            VarVersionPair secondPair = new VarVersionPair(ent.Key, lstVersions[j]);
                            VarType        secondType = mapExprentMinTypes.GetOrNull(secondPair);
                            if (firstType.Equals(secondType) || (firstType.Equals(VarType.Vartype_Null) && secondType
                                                                 .type == ICodeConstants.Type_Object) || (secondType.Equals(VarType.Vartype_Null) &&
                                                                                                          firstType.type == ICodeConstants.Type_Object))
                            {
                                VarType firstMaxType  = mapExprentMaxTypes.GetOrNull(firstPair);
                                VarType secondMaxType = mapExprentMaxTypes.GetOrNull(secondPair);
                                VarType type          = firstMaxType == null ? secondMaxType : secondMaxType == null ? firstMaxType
                                                                         : VarType.GetCommonMinType(firstMaxType, secondMaxType);
                                Sharpen.Collections.Put(mapExprentMaxTypes, firstPair, type);
                                Sharpen.Collections.Put(mapMergedVersions, secondPair, firstPair.version);
                                Sharpen.Collections.Remove(mapExprentMaxTypes, secondPair);
                                Sharpen.Collections.Remove(mapExprentMinTypes, secondPair);
                                if (firstType.Equals(VarType.Vartype_Null))
                                {
                                    Sharpen.Collections.Put(mapExprentMinTypes, firstPair, secondType);
                                    firstType = secondType;
                                }
                                Sharpen.Collections.Put(typeProcessor.GetMapFinalVars(), firstPair, VarTypeProcessor
                                                        .Var_Non_Final);
                                lstVersions.RemoveAtReturningValue(j);
                                //noinspection AssignmentToForLoopParameter
                                j--;
                            }
                        }
                    }
                }
            }
            if (!(mapMergedVersions.Count == 0))
            {
                UpdateVersions(graph, mapMergedVersions);
            }
        }
示例#24
0
        private void SetNewVarIndices(VarTypeProcessor typeProcessor, DirectGraph graph,
                                      VarVersionsProcessor previousVersionsProcessor)
        {
            Dictionary <VarVersionPair, VarType> mapExprentMaxTypes = typeProcessor.GetMapExprentMaxTypes
                                                                          ();
            Dictionary <VarVersionPair, VarType> mapExprentMinTypes = typeProcessor.GetMapExprentMinTypes
                                                                          ();
            Dictionary <VarVersionPair, int> mapFinalVars = typeProcessor.GetMapFinalVars();
            CounterContainer counters = DecompilerContext.GetCounterContainer();
            Dictionary <VarVersionPair, int> mapVarPaar = new Dictionary <VarVersionPair, int>
                                                              ();
            Dictionary <int, int> mapOriginalVarIndices = new Dictionary <int, int>();

            // map var-version pairs on new var indexes
            foreach (VarVersionPair pair in new List <VarVersionPair>(mapExprentMinTypes.Keys))
            {
                if (pair.version >= 0)
                {
                    int newIndex = pair.version == 1 ? pair.var : counters.GetCounterAndIncrement(CounterContainer
                                                                                                  .Var_Counter);
                    VarVersionPair newVar = new VarVersionPair(newIndex, 0);
                    Sharpen.Collections.Put(mapExprentMinTypes, newVar, mapExprentMinTypes.GetOrNull(
                                                pair));
                    Sharpen.Collections.Put(mapExprentMaxTypes, newVar, mapExprentMaxTypes.GetOrNull(
                                                pair));
                    if (mapFinalVars.ContainsKey(pair))
                    {
                        Sharpen.Collections.Put(mapFinalVars, newVar, Sharpen.Collections.Remove(mapFinalVars
                                                                                                 , pair));
                    }
                    Sharpen.Collections.Put(mapVarPaar, pair, newIndex);
                    Sharpen.Collections.Put(mapOriginalVarIndices, newIndex, pair.var);
                }
            }
            // set new vars
            graph.IterateExprents((Exprent exprent) => {
                List <Exprent> lst = exprent.GetAllExprents(true);
                lst.Add(exprent);
                foreach (Exprent expr in lst)
                {
                    if (expr.type == Exprent.Exprent_Var)
                    {
                        VarExprent newVar = (VarExprent)expr;
                        int?newVarIndex   = mapVarPaar.GetOrNullable(new VarVersionPair(newVar));
                        if (newVarIndex != null)
                        {
                            newVar.SetIndex(newVarIndex.Value);
                            newVar.SetVersion(0);
                        }
                    }
                    else if (expr.type == Exprent.Exprent_Const)
                    {
                        VarType maxType = mapExprentMaxTypes.GetOrNull(new VarVersionPair(expr.id, -1));
                        if (maxType != null && maxType.Equals(VarType.Vartype_Char))
                        {
                            ((ConstExprent)expr).SetConstType(maxType);
                        }
                    }
                }
                return(0);
            }
                                  );
            if (previousVersionsProcessor != null)
            {
                Dictionary <int, int> oldIndices = previousVersionsProcessor.GetMapOriginalVarIndices
                                                       ();
                this.mapOriginalVarIndices = new Dictionary <int, int>(mapOriginalVarIndices.Count
                                                                       );
                foreach (KeyValuePair <int, int> entry in mapOriginalVarIndices)
                {
                    int value    = entry.Value;
                    int?oldValue = oldIndices.GetOrNullable(value);
                    value = oldValue != null ? oldValue.Value : value;
                    Sharpen.Collections.Put(this.mapOriginalVarIndices, entry.Key, value);
                }
            }
            else
            {
                this.mapOriginalVarIndices = mapOriginalVarIndices;
            }
        }