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