private static void MapClassMethods(ClassesProcessor.ClassNode node, Dictionary <
                                                ClassWrapper, MethodWrapper> map)
        {
            bool noSynthFlag = DecompilerContext.GetOption(IFernflowerPreferences.Synthetic_Not_Set
                                                           );
            ClassWrapper wrapper = node.GetWrapper();

            foreach (MethodWrapper method in wrapper.GetMethods())
            {
                StructMethod mt = method.methodStruct;
                if ((noSynthFlag || mt.IsSynthetic()) && mt.GetDescriptor().Equals("(Ljava/lang/String;)Ljava/lang/Class;"
                                                                                   ) && mt.HasModifier(ICodeConstants.Acc_Static))
                {
                    RootStatement root = method.root;
                    if (root != null && root.GetFirst().type == Statement.Type_Trycatch)
                    {
                        CatchStatement cst = (CatchStatement)root.GetFirst();
                        if (cst.GetStats().Count == 2 && cst.GetFirst().type == Statement.Type_Basicblock &&
                            cst.GetStats()[1].type == Statement.Type_Basicblock && cst.GetVars()[0].GetVarType
                                ().Equals(new VarType(ICodeConstants.Type_Object, 0, "java/lang/ClassNotFoundException"
                                                      )))
                        {
                            BasicBlockStatement body    = (BasicBlockStatement)cst.GetFirst();
                            BasicBlockStatement handler = (BasicBlockStatement)cst.GetStats()[1];
                            if (body.GetExprents().Count == 1 && handler.GetExprents().Count == 1)
                            {
                                if (Body_Expr.Equals(body.GetExprents()[0]) && Handler_Expr.Equals(handler.GetExprents
                                                                                                       ()[0]))
                                {
                                    Sharpen.Collections.Put(map, wrapper, method);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            // iterate nested classes
            foreach (ClassesProcessor.ClassNode nd in node.nested)
            {
                MapClassMethods(nd, map);
            }
        }
示例#2
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));
        }