public static void RemoveRedundantReturns(RootStatement root) { DummyExitStatement dummyExit = root.GetDummyExit(); foreach (StatEdge edge in dummyExit.GetAllPredecessorEdges()) { if (!edge.@explicit) { Statement source = edge.GetSource(); List <Exprent> lstExpr = source.GetExprents(); if (lstExpr != null && !(lstExpr.Count == 0)) { Exprent expr = lstExpr[lstExpr.Count - 1]; if (expr.type == Exprent.Exprent_Exit) { ExitExprent ex = (ExitExprent)expr; if (ex.GetExitType() == ExitExprent.Exit_Return && ex.GetValue() == null) { // remove redundant return dummyExit.AddBytecodeOffsets(ex.bytecode); lstExpr.RemoveAtReturningValue(lstExpr.Count - 1); } } } } } }
private static InvocationExprent IsAssertionError(Statement stat) { if (stat == null || stat.GetExprents() == null || stat.GetExprents().Count != 1) { return(null); } Exprent expr = stat.GetExprents()[0]; if (expr.type == Exprent.Exprent_Exit) { ExitExprent exexpr = (ExitExprent)expr; if (exexpr.GetExitType() == ExitExprent.Exit_Throw && exexpr.GetValue().type == Exprent .Exprent_New) { NewExprent nexpr = (NewExprent)exexpr.GetValue(); if (Class_Assertion_Error.Equals(nexpr.GetNewType()) && nexpr.GetConstructor() != null) { return(nexpr.GetConstructor()); } } } return(null); }
private static bool BuildIff(Statement stat, SSAConstructorSparseEx ssa) { if (stat.type == Statement.Type_If && stat.GetExprents() == null) { IfStatement statement = (IfStatement)stat; Exprent ifHeadExpr = statement.GetHeadexprent(); HashSet <int> ifHeadExprBytecode = (ifHeadExpr == null ? null : ifHeadExpr.bytecode ); if (statement.iftype == IfStatement.Iftype_Ifelse) { Statement ifStatement = statement.GetIfstat(); Statement elseStatement = statement.GetElsestat(); if (ifStatement.GetExprents() != null && ifStatement.GetExprents().Count == 1 && elseStatement.GetExprents() != null && elseStatement.GetExprents().Count == 1 && ifStatement.GetAllSuccessorEdges().Count == 1 && elseStatement.GetAllSuccessorEdges ().Count == 1 && ifStatement.GetAllSuccessorEdges()[0].GetDestination() == elseStatement .GetAllSuccessorEdges()[0].GetDestination()) { Exprent ifExpr = ifStatement.GetExprents()[0]; Exprent elseExpr = elseStatement.GetExprents()[0]; if (ifExpr.type == Exprent.Exprent_Assignment && elseExpr.type == Exprent.Exprent_Assignment) { AssignmentExprent ifAssign = (AssignmentExprent)ifExpr; AssignmentExprent elseAssign = (AssignmentExprent)elseExpr; if (ifAssign.GetLeft().type == Exprent.Exprent_Var && elseAssign.GetLeft().type == Exprent.Exprent_Var) { VarExprent ifVar = (VarExprent)ifAssign.GetLeft(); VarExprent elseVar = (VarExprent)elseAssign.GetLeft(); if (ifVar.GetIndex() == elseVar.GetIndex() && ifVar.IsStack()) { // ifVar.getIndex() >= VarExprent.STACK_BASE) { bool found = false; foreach (KeyValuePair <VarVersionPair, FastSparseSetFactory <int> .FastSparseSet <int> > ent in ssa.GetPhi()) { if (ent.Key.var == ifVar.GetIndex()) { if (ent.Value.Contains(ifVar.GetVersion()) && ent.Value.Contains(elseVar.GetVersion ())) { found = true; break; } } } if (found) { List <Exprent> data = new List <Exprent>(statement.GetFirst().GetExprents()); List <Exprent> operands = Sharpen.Arrays.AsList(statement.GetHeadexprent().GetCondition (), ifAssign.GetRight(), elseAssign.GetRight()); data.Add(new AssignmentExprent(ifVar, new FunctionExprent(FunctionExprent.Function_Iif , operands, ifHeadExprBytecode), ifHeadExprBytecode)); statement.SetExprents(data); if ((statement.GetAllSuccessorEdges().Count == 0)) { StatEdge ifEdge = ifStatement.GetAllSuccessorEdges()[0]; StatEdge edge = new StatEdge(ifEdge.GetType(), statement, ifEdge.GetDestination() ); statement.AddSuccessor(edge); if (ifEdge.closure != null) { ifEdge.closure.AddLabeledEdge(edge); } } SequenceHelper.DestroyAndFlattenStatement(statement); return(true); } } } } else if (ifExpr.type == Exprent.Exprent_Exit && elseExpr.type == Exprent.Exprent_Exit) { ExitExprent ifExit = (ExitExprent)ifExpr; ExitExprent elseExit = (ExitExprent)elseExpr; if (ifExit.GetExitType() == elseExit.GetExitType() && ifExit.GetValue() != null && elseExit.GetValue() != null && ifExit.GetExitType() == ExitExprent.Exit_Return) { // throw is dangerous, because of implicit casting to a common superclass // e.g. throws IOException and throw true?new RuntimeException():new IOException(); won't work if (ifExit.GetExitType() == ExitExprent.Exit_Throw && !ifExit.GetValue().GetExprType ().Equals(elseExit.GetValue().GetExprType())) { // note: getExprType unreliable at this point! return(false); } // avoid flattening to 'iff' if any of the branches is an 'iff' already if (IsIff(ifExit.GetValue()) || IsIff(elseExit.GetValue())) { return(false); } List <Exprent> data = new List <Exprent>(statement.GetFirst().GetExprents()); data.Add(new ExitExprent(ifExit.GetExitType(), new FunctionExprent(FunctionExprent .Function_Iif, Sharpen.Arrays.AsList(statement.GetHeadexprent().GetCondition(), ifExit.GetValue(), elseExit.GetValue()), ifHeadExprBytecode), ifExit.GetRetType( ), ifHeadExprBytecode)); statement.SetExprents(data); StatEdge retEdge = ifStatement.GetAllSuccessorEdges()[0]; Statement closure = retEdge.closure == statement?statement.GetParent() : retEdge .closure; statement.AddSuccessor(new StatEdge(StatEdge.Type_Break, statement, retEdge.GetDestination (), closure)); SequenceHelper.DestroyAndFlattenStatement(statement); return(true); } } } } } return(false); }
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)); }
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); } }
private static bool RemoveReturnCheck(Statement stat, StructMethod mt) { Statement parent = stat.GetParent(); if (parent != null && parent.type == Statement.Type_If && stat.type == Statement. Type_Basicblock && stat.GetExprents().Count == 1) { Exprent exprent = stat.GetExprents()[0]; if (exprent.type == Exprent.Exprent_Exit) { ExitExprent exit_exprent = (ExitExprent)exprent; if (exit_exprent.GetExitType() == ExitExprent.Exit_Return) { Exprent exprent_value = exit_exprent.GetValue(); //if(exprent_value.type == Exprent.EXPRENT_VAR) { // VarExprent var_value = (VarExprent)exprent_value; IfStatement ifparent = (IfStatement)parent; Exprent if_condition = ifparent.GetHeadexprent().GetCondition(); if (ifparent.GetElsestat() == stat && if_condition.type == Exprent.Exprent_Function && ((FunctionExprent)if_condition).GetFuncType() == FunctionExprent.Function_Eq) { // TODO: reversed order possible (in theory) FunctionExprent func = (FunctionExprent)if_condition; Exprent first_param = func.GetLstOperands()[0]; Exprent second_param = func.GetLstOperands()[1]; StatEdge ifedge = ifparent.GetIfEdge(); StatEdge elseedge = ifparent.GetElseEdge(); Statement ifbranch = ifparent.GetIfstat(); Statement elsebranch = ifparent.GetElsestat(); if (second_param.type == Exprent.Exprent_Const && second_param.GetExprType().type == ICodeConstants.Type_Null) { // TODO: reversed parameter order //if(first_param.type == Exprent.EXPRENT_VAR && ((VarExprent)first_param).getIndex() == var_value.getIndex()) { if (first_param.Equals(exprent_value)) { // TODO: check for absence of side effects like method invocations etc. if (ifbranch.type == Statement.Type_Basicblock && ifbranch.GetExprents().Count == 1 && ifbranch.GetExprents()[0].type == Exprent.Exprent_Exit) { // TODO: special check for IllegalStateException ifparent.GetFirst().RemoveSuccessor(ifedge); ifparent.GetFirst().RemoveSuccessor(elseedge); ifparent.GetStats().RemoveWithKey(ifbranch.id); ifparent.GetStats().RemoveWithKey(elsebranch.id); if (!(ifbranch.GetAllSuccessorEdges().Count == 0)) { ifbranch.RemoveSuccessor(ifbranch.GetAllSuccessorEdges()[0]); } if (!(ifparent.GetFirst().GetExprents().Count == 0)) { elsebranch.GetExprents().InsertRange(0, ifparent.GetFirst().GetExprents()); } ifparent.GetParent().ReplaceStatement(ifparent, elsebranch); ifparent.GetParent().SetAllParent(); return(true); } } } } } } } else if (parent != null && parent.type == Statement.Type_Sequence && stat.type == Statement.Type_Basicblock && stat.GetExprents().Count == 1) { //} Exprent exprent = stat.GetExprents()[0]; if (exprent.type == Exprent.Exprent_Exit) { ExitExprent exit_exprent = (ExitExprent)exprent; if (exit_exprent.GetExitType() == ExitExprent.Exit_Return) { Exprent exprent_value = exit_exprent.GetValue(); SequenceStatement sequence = (SequenceStatement)parent; int sequence_stats_number = sequence.GetStats().Count; if (sequence_stats_number > 1 && sequence.GetStats().GetLast() == stat && sequence .GetStats()[sequence_stats_number - 2].type == Statement.Type_If) { IfStatement ifstat = (IfStatement)sequence.GetStats()[sequence_stats_number - 2]; Exprent if_condition = ifstat.GetHeadexprent().GetCondition(); if (ifstat.iftype == IfStatement.Iftype_If && if_condition.type == Exprent.Exprent_Function && ((FunctionExprent)if_condition).GetFuncType() == FunctionExprent.Function_Eq) { // TODO: reversed order possible (in theory) FunctionExprent func = (FunctionExprent)if_condition; Exprent first_param = func.GetLstOperands()[0]; Exprent second_param = func.GetLstOperands()[1]; Statement ifbranch = ifstat.GetIfstat(); if (second_param.type == Exprent.Exprent_Const && second_param.GetExprType().type == ICodeConstants.Type_Null) { // TODO: reversed parameter order if (first_param.Equals(exprent_value)) { // TODO: check for absence of side effects like method invocations etc. if (ifbranch.type == Statement.Type_Basicblock && ifbranch.GetExprents().Count == 1 && ifbranch.GetExprents()[0].type == Exprent.Exprent_Exit) { // TODO: special check for IllegalStateException ifstat.RemoveSuccessor(ifstat.GetAllSuccessorEdges()[0]); // remove 'else' edge if (!(ifstat.GetFirst().GetExprents().Count == 0)) { stat.GetExprents().InsertRange(0, ifstat.GetFirst().GetExprents()); } foreach (StatEdge edge in ifstat.GetAllPredecessorEdges()) { ifstat.RemovePredecessor(edge); edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, stat); stat.AddPredecessor(edge); } sequence.GetStats().RemoveWithKey(ifstat.id); sequence.SetFirst(sequence.GetStats()[0]); return(true); } } } } } } } } foreach (Statement st in stat.GetStats()) { if (RemoveReturnCheck(st, mt)) { return(true); } } return(false); }