public virtual void SetVarVersions(RootStatement root) { VarVersionsProcessor oldProcessor = varVersions; varVersions = new VarVersionsProcessor(method, methodDescriptor); varVersions.SetVarVersions(root, oldProcessor); }
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); } } } } } }
public static void IdentifyLabels(RootStatement root) { SetExplicitEdges(root); HideDefaultSwitchEdges(root); ProcessStatementLabel(root); SetRetEdgesUnlabeled(root); }
// node id, var, version //private HashMap<String, HashMap<Integer, FastSet<Integer>>> inVarVersions = new HashMap<String, HashMap<Integer, FastSet<Integer>>>(); // node id, var, version (direct branch) //private HashMap<String, HashMap<Integer, FastSet<Integer>>> outVarVersions = new HashMap<String, HashMap<Integer, FastSet<Integer>>>(); // node id, var, version (negative branch) //private HashMap<String, HashMap<Integer, FastSet<Integer>>> outNegVarVersions = new HashMap<String, HashMap<Integer, FastSet<Integer>>>(); // node id, var, version //private HashMap<String, HashMap<Integer, FastSet<Integer>>> extraVarVersions = new HashMap<String, HashMap<Integer, FastSet<Integer>>>(); // var, version // version, protected ranges (catch, finally) // version, version // ++ and -- // node.id, version, version // finally exits // versions memory dependencies // field access vars (exprent id, var id) // field access counter // set factory public virtual void SplitVariables(RootStatement root, StructMethod mt) { FlattenStatementsHelper flatthelper = new FlattenStatementsHelper(); DirectGraph dgraph = flatthelper.BuildDirectGraph(root); HashSet <int> setInit = new HashSet <int>(); for (int i = 0; i < 64; i++) { setInit.Add(i); } factory = new FastSparseSetFactory <int>(setInit); Sharpen.Collections.Put(extraVarVersions, dgraph.first.id, CreateFirstMap(mt, root )); SetCatchMaps(root, dgraph, flatthelper); // try { // DotExporter.toDotFile(dgraph, new File("c:\\Temp\\gr12_my.dot")); // } catch(Exception ex) {ex.printStackTrace();} HashSet <string> updated = new HashSet <string>(); do { // System.out.println("~~~~~~~~~~~~~ \r\n"+root.toJava()); SsaStatements(dgraph, updated, false); }while (!(updated.Count == 0)); // System.out.println("~~~~~~~~~~~~~ \r\n"+root.toJava()); SsaStatements(dgraph, updated, true); ssuversions.InitDominators(); }
public static void BuildAssertions(ClassesProcessor.ClassNode node) { ClassWrapper wrapper = node.GetWrapper(); StructField field = FindAssertionField(node); if (field != null) { string key = InterpreterUtil.MakeUniqueKey(field.GetName(), field.GetDescriptor() ); bool res = false; foreach (MethodWrapper meth in wrapper.GetMethods()) { RootStatement root = meth.root; if (root != null) { res |= ReplaceAssertions(root, wrapper.GetClassStruct().qualifiedName, key); } } if (res) { // hide the helper field wrapper.GetHiddenMembers().Add(key); } } }
private SFormsFastMapDirect CreateFirstMap(StructMethod mt, RootStatement root) { bool thisvar = !mt.HasModifier(ICodeConstants.Acc_Static); MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); int paramcount = [email protected] + (thisvar ? 1 : 0); int varindex = 0; SFormsFastMapDirect map = new SFormsFastMapDirect(); for (int i = 0; i < paramcount; i++) { int version = GetNextFreeVersion(varindex, root); // == 1 FastSparseSetFactory <int> .FastSparseSet <int> set = factory.SpawnEmptySet(); set.Add(version); map.Put(varindex, set); ssuversions.CreateNode(new VarVersionPair(varindex, version)); if (thisvar) { if (i == 0) { varindex++; } else { varindex += md.@params[i - 1].stackSize; } } else { varindex += md.@params[i].stackSize; } } return(map); }
public MethodWrapper(RootStatement root, VarProcessor varproc, StructMethod methodStruct , CounterContainer counter) { this.root = root; this.varproc = varproc; this.methodStruct = methodStruct; this.counter = counter; }
public static void CleanUpEdges(RootStatement root) { ResetAllEdges(root); RemoveNonImmediateEdges(root); LiftClosures(root); LowContinueLabels(root, new HashSet <StatEdge>()); LowClosures(root); }
public virtual void CalculateVarTypes(RootStatement root, DirectGraph graph) { SetInitVars(root); ResetExprentTypes(graph); //noinspection StatementWithEmptyBody while (!ProcessVarTypes(graph)) { } }
/* * public static Registry<TokenEnum, Type> TypeTokens = new Registry<TokenEnum, Type>() * { * {TokenEnum.DECL_BOOL, typeof(bool)}, * {TokenEnum.DECL_INT, typeof(int)}, * {TokenEnum.DECL_FLOAT, typeof(float)}, * {TokenEnum.DECL_FLOAT2, typeof(float2)}, * {TokenEnum.DECL_FLOAT3, typeof(float3)}, * {TokenEnum.DECL_FLOAT4, typeof(float4)}, * {TokenEnum.DECL_STRING, typeof(string)}, * {TokenEnum.DECL_BOOL_ARRAY, typeof(bool[])}, * {TokenEnum.DECL_INT_ARRAY, typeof(int[])}, * {TokenEnum.DECL_FLOAT_ARRAY, typeof(float[])}, * {TokenEnum.DECL_STRING_ARRAY, typeof(string[])} * }; */ public static void Parse(ContextScope scope, string text, out RootStatement result, string srcname, ref int linenumber, out List <LintElement> linter) { using (StringReader reader = new StringReader(text)) { Lexer lex = new Lexer(reader, Definitions, srcname, linenumber); result = new RootStatement(scope, lex); linenumber = lex.LineNumber; linter = lex.Linter; } }
public static bool MergeAllIfs(RootStatement root) { bool res = MergeAllIfsRec(root, new HashSet <int>()); if (res) { SequenceHelper.CondenseSequences(root); } return(res); }
public static bool InlineSingleBlocks(RootStatement root) { bool res = InlineSingleBlocksRec(root); if (res) { SequenceHelper.CondenseSequences(root); } return(res); }
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 static bool CondenseExits(RootStatement root) { int changed = IntegrateExits(root); if (changed > 0) { CleanUpUnreachableBlocks(root); SequenceHelper.CondenseSequences(root); } return(changed > 0); }
public List <Figure> Execute() { Dictionary <string, object> variableScope = new Dictionary <string, object>(); Dictionary <string, Function> functionScope = new Dictionary <string, Function>(); Function constructPoint = new ConstructPointFunction(); Function constructPlane = new ConstructPlaneFunction(); Function constructSphere = new ConstructSphereFunction(); Function intersection = new IntersectionFunction(); Function pointOn = new PointOnFunction(); Function binormal = new BinormalFunction(); Function constructLine = new ConstructLineFunction(); Function center = new CenterFunction(); Function nullFunc = new NullFunction(); Function space = new SpaceFunction(); functionScope.Add("point", constructPoint); functionScope.Add("plane", constructPlane); functionScope.Add("sphere", constructSphere); functionScope.Add("intersection", intersection); functionScope.Add("point_on", pointOn); functionScope.Add("binormal", binormal); functionScope.Add("line", constructLine); functionScope.Add("center", center); functionScope.Add("null", nullFunc); functionScope.Add("space", space); string[] files = Directory.GetFiles("Assets/Custom/Scripts/Euclid/Lib", "*.euclid"); foreach (string f in files) { RootStatement libRoot = ConstructAbstractSyntaxTree(Tokenize(ReadFromFile(f))); libRoot.Run(variableScope, functionScope); } root.Run(variableScope, functionScope); List <Figure> render = new List <Figure>(); foreach (string variable in variableScope.Keys) { if (variableScope[variable] is Figure) { Figure fig = variableScope[variable] as Figure; if (fig.properties.ContainsKey("render")) { if (Mathf.Approximately((float)fig.properties["render"], 1)) { render.Add(fig); Debug.Log(fig); fig.properties["name"] = variable; } } } } return(render); }
public static void ClearStatements(RootStatement root) { LinkedList <Statement> stack = new LinkedList <Statement>(); stack.AddLast(root); while (!(stack.Count == 0)) { Statement stat = Sharpen.Collections.RemoveFirst(stack); stat.ClearTempInformation(); Sharpen.Collections.AddAll(stack, stat.GetStats()); } }
private void SetInitVars(RootStatement root) { bool thisVar = !method.HasModifier(ICodeConstants.Acc_Static); MethodDescriptor md = methodDescriptor; if (thisVar) { StructClass cl = (StructClass)DecompilerContext.GetProperty(DecompilerContext.Current_Class ); VarType clType = new VarType(ICodeConstants.Type_Object, 0, cl.qualifiedName); Sharpen.Collections.Put(mapExprentMinTypes, new VarVersionPair(0, 1), clType); Sharpen.Collections.Put(mapExprentMaxTypes, new VarVersionPair(0, 1), clType); } int varIndex = 0; for (int i = 0; i < [email protected]; i++) { Sharpen.Collections.Put(mapExprentMinTypes, new VarVersionPair(varIndex + (thisVar ? 1 : 0), 1), md.@params[i]); Sharpen.Collections.Put(mapExprentMaxTypes, new VarVersionPair(varIndex + (thisVar ? 1 : 0), 1), md.@params[i]); varIndex += md.@params[i].stackSize; } // catch variables LinkedList <Statement> stack = new LinkedList <Statement>(); stack.AddLast(root); while (!(stack.Count == 0)) { Statement stat = Sharpen.Collections.RemoveFirst(stack); List <VarExprent> lstVars = null; if (stat.type == Statement.Type_Catchall) { lstVars = ((CatchAllStatement)stat).GetVars(); } else if (stat.type == Statement.Type_Trycatch) { lstVars = ((CatchStatement)stat).GetVars(); } if (lstVars != null) { foreach (VarExprent var in lstVars) { Sharpen.Collections.Put(mapExprentMinTypes, new VarVersionPair(var.GetIndex(), 1) , var.GetVarType()); Sharpen.Collections.Put(mapExprentMaxTypes, new VarVersionPair(var.GetIndex(), 1) , var.GetVarType()); } } Sharpen.Collections.AddAll(stack, stat.GetStats()); } }
private static void SetRetEdgesUnlabeled(RootStatement root) { Statement exit = root.GetDummyExit(); foreach (StatEdge edge in exit.GetAllPredecessorEdges()) { List <Exprent> lst = edge.GetSource().GetExprents(); if (edge.GetType() == StatEdge.Type_Finallyexit || (lst != null && !(lst.Count == 0) && lst[lst.Count - 1].type == Exprent.Exprent_Exit)) { edge.labeled = false; } } }
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); }
private static void ExtractStaticInitializers(ClassWrapper wrapper, MethodWrapper method) { RootStatement root = method.root; StructClass cl = wrapper.GetClassStruct(); Statement firstData = Statements.FindFirstData(root); if (firstData != null) { bool inlineInitializers = cl.HasModifier(ICodeConstants.Acc_Interface) || cl.HasModifier (ICodeConstants.Acc_Enum); while (!(firstData.GetExprents().Count == 0)) { Exprent exprent = firstData.GetExprents()[0]; bool found = false; if (exprent.type == Exprent.Exprent_Assignment) { AssignmentExprent assignExpr = (AssignmentExprent)exprent; if (assignExpr.GetLeft().type == Exprent.Exprent_Field) { FieldExprent fExpr = (FieldExprent)assignExpr.GetLeft(); if (fExpr.IsStatic() && fExpr.GetClassname().Equals(cl.qualifiedName) && cl.HasField (fExpr.GetName(), fExpr.GetDescriptor().descriptorString)) { // interfaces fields should always be initialized inline if (inlineInitializers || IsExprentIndependent(assignExpr.GetRight(), method)) { string keyField = InterpreterUtil.MakeUniqueKey(fExpr.GetName(), fExpr.GetDescriptor ().descriptorString); if (!wrapper.GetStaticFieldInitializers().ContainsKey(keyField)) { wrapper.GetStaticFieldInitializers().AddWithKey(assignExpr.GetRight(), keyField); firstData.GetExprents().RemoveAtReturningValue(0); found = true; } } } } } if (!found) { break; } } } }
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); } }
// statement.id, node.id(direct), node.id(continue) // node.id(source), statement.id(destination), edge type // node.id(exit), [node.id(source), statement.id(destination)] // node.id(exit), [node.id(source), statement.id(destination)] // positive if branches public virtual DirectGraph BuildDirectGraph(RootStatement root) { this.root = root; graph = new DirectGraph(); FlattenStatement(); // dummy exit node Statement dummyexit = root.GetDummyExit(); DirectNode node = new DirectNode(DirectNode.Node_Direct, dummyexit, dummyexit.id. ToString()); node.exprents = new List <Exprent>(); graph.nodes.AddWithKey(node, node.id); Sharpen.Collections.Put(mapDestinationNodes, dummyexit.id, new string[] { node.id , null }); SetEdges(); graph.first = graph.nodes.GetWithKey(mapDestinationNodes.GetOrNull(root.id)[0]); graph.SortReversePostOrder(); return(graph); }
public static RootStatement ParseGraph(ControlFlowGraph graph) { RootStatement root = GraphToStatement(graph); if (!ProcessStatement(root, new Dictionary <int, HashSet <int> >())) { // try { // DotExporter.toDotFile(root.getFirst().getStats().get(13), new File("c:\\Temp\\stat1.dot")); // } catch (Exception ex) { // ex.printStackTrace(); // } throw new Exception("parsing failure!"); } LabelHelper.LowContinueLabels(root, new HashSet <StatEdge>()); SequenceHelper.CondenseSequences(root); root.BuildMonitorFlags(); // build synchronized statements BuildSynchronized(root); return(root); }
public virtual void Run() { error = null; root = null; try { DecompilerContext.SetCurrentContext(parentContext); root = CodeToJava(method, methodDescriptor, varProc); } catch (Exception t) { error = t; } finally { DecompilerContext.SetCurrentContext(null); } finished = true; lock (Lock) { Monitor.PulseAll(Lock); } }
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); }
public virtual void SimplifyStackVars(RootStatement root, StructMethod mt, StructClass cl) { HashSet <int> setReorderedIfs = new HashSet <int>(); SSAUConstructorSparseEx ssau = null; while (true) { bool found = false; SSAConstructorSparseEx ssa = new SSAConstructorSparseEx(); ssa.SplitVariables(root, mt); SimplifyExprentsHelper sehelper = new SimplifyExprentsHelper(ssau == null); while (sehelper.SimplifyStackVarsStatement(root, setReorderedIfs, ssa, cl)) { found = true; } SetVersionsToNull(root); SequenceHelper.CondenseSequences(root); ssau = new SSAUConstructorSparseEx(); ssau.SplitVariables(root, mt); if (IterateStatements(root, ssau)) { found = true; } SetVersionsToNull(root); if (!found) { break; } } // remove unused assignments ssau = new SSAUConstructorSparseEx(); ssau.SplitVariables(root, mt); IterateStatements(root, ssau); SetVersionsToNull(root); }
private bool ProcessStatementEx(StructMethod mt, RootStatement root, ControlFlowGraph graph) { int bytecode_version = mt.GetClassStruct().GetBytecodeVersion(); LinkedList <Statement> stack = new LinkedList <Statement>(); stack.AddLast(root); while (!(stack.Count == 0)) { Statement stat = Sharpen.Collections.RemoveLast(stack); Statement parent = stat.GetParent(); if (parent != null && parent.type == Statement.Type_Catchall && stat == parent.GetFirst () && !parent.IsCopied()) { CatchAllStatement fin = (CatchAllStatement)parent; BasicBlock head = fin.GetBasichead().GetBlock(); BasicBlock handler = fin.GetHandler().GetBasichead().GetBlock(); if (catchallBlockIDs.ContainsKey(handler.id)) { } else if (finallyBlockIDs.ContainsKey(handler.id)) { // do nothing fin.SetFinally(true); int?var = finallyBlockIDs.GetOrNullable(handler.id); fin.SetMonitor(var == null ? null : new VarExprent(var.Value, VarType.Vartype_Int , varProcessor)); } else { FinallyProcessor.Record inf = GetFinallyInformation(mt, root, fin); if (inf == null) { // inconsistent finally Sharpen.Collections.Put(catchallBlockIDs, handler.id, null); } else { if (DecompilerContext.GetOption(IFernflowerPreferences.Finally_Deinline) && VerifyFinallyEx (graph, fin, inf)) { Sharpen.Collections.Put(finallyBlockIDs, handler.id, null); } else { int varindex = DecompilerContext.GetCounterContainer().GetCounterAndIncrement(CounterContainer .Var_Counter); InsertSemaphore(graph, GetAllBasicBlocks(fin.GetFirst()), head, handler, varindex , inf, bytecode_version); Sharpen.Collections.Put(finallyBlockIDs, handler.id, varindex); } DeadCodeHelper.RemoveDeadBlocks(graph); // e.g. multiple return blocks after a nested finally DeadCodeHelper.RemoveEmptyBlocks(graph); DeadCodeHelper.MergeBasicBlocks(graph); } return(true); } } Sharpen.Collections.AddAll(stack, stat.GetStats()); } return(false); }
private static RootStatement GraphToStatement(ControlFlowGraph graph) { VBStyleCollection <Statement, int> stats = new VBStyleCollection <Statement, int>(); VBStyleCollection <BasicBlock, int> blocks = graph.GetBlocks(); foreach (BasicBlock block in blocks) { stats.AddWithKey(new BasicBlockStatement(block), block.id); } BasicBlock firstblock = graph.GetFirst(); // head statement Statement firstst = stats.GetWithKey(firstblock.id); // dummy exit statement DummyExitStatement dummyexit = new DummyExitStatement(); Statement general; if (stats.Count > 1 || firstblock.IsSuccessor(firstblock)) { // multiple basic blocks or an infinite loop of one block general = new GeneralStatement(firstst, stats, null); } else { // one straightforward basic block RootStatement root = new RootStatement(firstst, dummyexit); firstst.AddSuccessor(new StatEdge(StatEdge.Type_Break, firstst, dummyexit, root)); return(root); } foreach (BasicBlock block in blocks) { Statement stat = stats.GetWithKey(block.id); foreach (BasicBlock succ in block.GetSuccs()) { Statement stsucc = stats.GetWithKey(succ.id); int type; if (stsucc == firstst) { type = StatEdge.Type_Continue; } else if (graph.GetFinallyExits().Contains(block)) { type = StatEdge.Type_Finallyexit; stsucc = dummyexit; } else if (succ.id == graph.GetLast().id) { type = StatEdge.Type_Break; stsucc = dummyexit; } else { type = StatEdge.Type_Regular; } stat.AddSuccessor(new StatEdge(type, stat, (type == StatEdge.Type_Continue) ? general : stsucc, (type == StatEdge.Type_Regular) ? null : general)); } // exceptions edges foreach (BasicBlock succex in block.GetSuccExceptions()) { Statement stsuccex = stats.GetWithKey(succex.id); ExceptionRangeCFG range = graph.GetExceptionRange(succex, block); if (!range.IsCircular()) { stat.AddSuccessor(new StatEdge(stat, stsuccex, range.GetExceptionTypes())); } } } general.BuildContinueSet(); general.BuildMonitorFlags(); return(new RootStatement(general, dummyexit)); }
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 virtual void Init() { DecompilerContext.SetProperty(DecompilerContext.Current_Class, classStruct); DecompilerContext.SetProperty(DecompilerContext.Current_Class_Wrapper, this); DecompilerContext.GetLogger().StartClass(classStruct.qualifiedName); int maxSec = System.Convert.ToInt32(DecompilerContext.GetProperty(IFernflowerPreferences .Max_Processing_Method).ToString()); bool testMode = DecompilerContext.GetOption(IFernflowerPreferences.Unit_Test_Mode ); foreach (StructMethod mt in classStruct.GetMethods()) { DecompilerContext.GetLogger().StartMethod(mt.GetName() + " " + mt.GetDescriptor() ); MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); VarProcessor varProc = new VarProcessor(mt, md); DecompilerContext.StartMethod(varProc); VarNamesCollector vc = varProc.GetVarNamesCollector(); CounterContainer counter = DecompilerContext.GetCounterContainer(); RootStatement root = null; bool isError = false; try { if (mt.ContainsCode()) { if (maxSec == 0 || testMode) { root = MethodProcessorRunnable.CodeToJava(mt, md, varProc); } else { MethodProcessorRunnable mtProc = new MethodProcessorRunnable(mt, md, varProc, DecompilerContext .GetCurrentContext()); Thread mtThread = new Thread(o => mtProc.Run()) { Name = "Java decompiler" }; long stopAt = Runtime.CurrentTimeMillis() + maxSec * 1000L; mtThread.Start(); while (!mtProc.IsFinished()) { try { lock (mtProc.Lock) { Thread.Sleep(200); } } catch (Exception e) { KillThread(mtThread); throw; } if (Runtime.CurrentTimeMillis() >= stopAt) { string message = "Processing time limit exceeded for method " + mt.GetName() + ", execution interrupted."; DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Error ); KillThread(mtThread); isError = true; break; } } if (!isError) { root = mtProc.GetResult(); } } } else { bool thisVar = !mt.HasModifier(ICodeConstants.Acc_Static); int paramCount = 0; if (thisVar) { Sharpen.Collections.Put(varProc.GetThisVars(), new VarVersionPair(0, 0), classStruct .qualifiedName); paramCount = 1; } paramCount += [email protected]; int varIndex = 0; for (int i = 0; i < paramCount; i++) { varProc.SetVarName(new VarVersionPair(varIndex, 0), vc.GetFreeName(varIndex)); if (thisVar) { if (i == 0) { varIndex++; } else { varIndex += md.@params[i - 1].stackSize; } } else { varIndex += md.@params[i].stackSize; } } } } catch (Exception t) { string message = "Method " + mt.GetName() + " " + mt.GetDescriptor() + " couldn't be decompiled."; DecompilerContext.GetLogger().WriteMessage(message, IFernflowerLogger.Severity.Warn , t); isError = true; } MethodWrapper methodWrapper = new MethodWrapper(root, varProc, mt, counter); methodWrapper.decompiledWithErrors = isError; methods.AddWithKey(methodWrapper, InterpreterUtil.MakeUniqueKey(mt.GetName(), mt. GetDescriptor())); if (!isError) { // rename vars so that no one has the same name as a field VarNamesCollector namesCollector = new VarNamesCollector(); classStruct.GetFields().ForEach((StructField f) => namesCollector.AddName(f.GetName ())); varProc.RefreshVarNames(namesCollector); // if debug information present and should be used if (DecompilerContext.GetOption(IFernflowerPreferences.Use_Debug_Var_Names)) { StructLocalVariableTableAttribute attr = mt.GetLocalVariableAttr(); if (attr != null) { // only param names here varProc.SetDebugVarNames(attr.GetMapParamNames()); // the rest is here methodWrapper.GetOrBuildGraph().IterateExprents((Exprent exprent) => { List <Exprent> lst = exprent.GetAllExprents(true); lst.Add(exprent); lst.Where(e => e.type == Exprent.Exprent_Var).ToList().ForEach((Exprent e) => { VarExprent varExprent = (VarExprent)e; string name = varExprent.GetDebugName(mt); if (name != null) { varProc.SetVarName(varExprent.GetVarVersionPair(), name); } } ); return(0); } ); } } } DecompilerContext.GetLogger().EndMethod(); } DecompilerContext.GetLogger().EndClass(); }