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]); }
public Board() { Components = new DirectGraph <Component>(); // Default board name Name = "RootBoard"; }
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); } ); }
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); }
public virtual DirectGraph GetOrBuildGraph() { if (graph == null && root != null) { graph = new FlattenStatementsHelper().BuildDirectGraph(root); } return(graph); }
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); } }
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); } }
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); }
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); } } }
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); }
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]); }
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); } ); }
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); }
public Board(DirectGraph <Component> nodes) : this() { Components = nodes; }
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>(); }
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 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 bool ProcessVarTypes(DirectGraph graph) { return(graph.IterateExprents((Exprent exprent) => CheckTypeExprent(exprent) ? 0 : 1)); }
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); } }
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; } }