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); } }
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)); }