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 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(); }
public VarDefinitionHelper(Statement root, StructMethod mt, VarProcessor varproc) { // statement.id, defined vars mapVarDefStatements = new Dictionary <int, Statement>(); mapStatementVars = new Dictionary <int, HashSet <int> >(); implDefVars = new HashSet <int>(); this.varproc = varproc; VarNamesCollector vc = varproc.GetVarNamesCollector(); bool thisvar = !mt.HasModifier(ICodeConstants.Acc_Static); MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); int paramcount = 0; if (thisvar) { paramcount = 1; } paramcount += [email protected]; // method parameters are implicitly defined int varindex = 0; for (int i = 0; i < paramcount; i++) { implDefVars.Add(varindex); 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; } } if (thisvar) { StructClass current_class = (StructClass)DecompilerContext.GetProperty(DecompilerContext .Current_Class); Sharpen.Collections.Put(varproc.GetThisVars(), new VarVersionPair(0, 0), current_class .qualifiedName); varproc.SetVarName(new VarVersionPair(0, 0), "this"); vc.AddName("this"); } // catch variables are implicitly defined LinkedList <Statement> stack = new LinkedList <Statement>(); stack.AddLast(root); while (!(stack.Count == 0)) { Statement st = Sharpen.Collections.RemoveFirst(stack); List <VarExprent> lstVars = null; if (st.type == Statement.Type_Catchall) { lstVars = ((CatchAllStatement)st).GetVars(); } else if (st.type == Statement.Type_Trycatch) { lstVars = ((CatchStatement)st).GetVars(); } if (lstVars != null) { foreach (VarExprent var in lstVars) { implDefVars.Add(var.GetIndex()); varproc.SetVarName(new VarVersionPair(var), vc.GetFreeName(var.GetIndex())); var.SetDefinition(true); } } Sharpen.Collections.AddAll(stack, st.GetStats()); } InitStatement(root); }