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);
            }
        }
示例#2
0
        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();
        }
        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);
        }