Beispiel #1
0
        public static List <VarVersionPair> GetSyntheticParametersMask(ClassesProcessor.ClassNode
                                                                       node, string descriptor, int parameters)
        {
            List <VarVersionPair> mask    = null;
            ClassWrapper          wrapper = node.GetWrapper();

            if (wrapper != null)
            {
                // own class
                MethodWrapper methodWrapper = wrapper.GetMethodWrapper(ICodeConstants.Init_Name,
                                                                       descriptor);
                if (methodWrapper == null)
                {
                    if (DecompilerContext.GetOption(IFernflowerPreferences.Ignore_Invalid_Bytecode))
                    {
                        return(null);
                    }
                    throw new Exception("Constructor " + node.classStruct.qualifiedName + "." + ICodeConstants
                                        .Init_Name + descriptor + " not found");
                }
                mask = methodWrapper.synthParameters;
            }
            else if (parameters > 0 && node.type == ClassesProcessor.ClassNode.Class_Member &&
                     (node.access & ICodeConstants.Acc_Static) == 0)
            {
                // non-static member class
                mask    = new List <VarVersionPair>(Enumerable.Repeat <VarVersionPair>(null, parameters));
                mask[0] = new VarVersionPair(-1, 0);
            }
            return(mask);
        }
 public virtual void PropagateMemberAccess(ClassesProcessor.ClassNode root)
 {
     if ((root.nested.Count == 0))
     {
         return;
     }
     noSynthFlag = DecompilerContext.GetOption(IFernflowerPreferences.Synthetic_Not_Set
                                               );
     ComputeMethodTypes(root);
     EliminateStaticAccess(root);
 }
Beispiel #3
0
 private void AppendDefinitionType(TextBuffer buffer)
 {
     if (DecompilerContext.GetOption(IFernflowerPreferences.Use_Debug_Var_Names))
     {
         MethodWrapper method = (MethodWrapper)DecompilerContext.GetProperty(DecompilerContext
                                                                             .Current_Method_Wrapper);
         if (method != null)
         {
             int?originalIndex = null;
             if (processor != null)
             {
                 originalIndex = processor.GetVarOriginalIndex(index);
             }
             if (originalIndex != null)
             {
                 // first try from signature
                 if (DecompilerContext.GetOption(IFernflowerPreferences.Decompile_Generic_Signatures
                                                 ))
                 {
                     StructLocalVariableTypeTableAttribute attr = method.methodStruct.GetAttribute(StructGeneralAttribute
                                                                                                   .Attribute_Local_Variable_Type_Table);
                     if (attr != null)
                     {
                         string signature = attr.GetSignature(originalIndex, visibleOffset);
                         if (signature != null)
                         {
                             GenericFieldDescriptor descriptor = GenericMain.ParseFieldSignature(signature);
                             if (descriptor != null)
                             {
                                 buffer.Append(GenericMain.GetGenericCastTypeName(descriptor.type));
                                 return;
                             }
                         }
                     }
                 }
                 // then try from descriptor
                 StructLocalVariableTableAttribute attr_1 = method.methodStruct.GetLocalVariableAttr
                                                                ();
                 if (attr_1 != null)
                 {
                     string descriptor = attr_1.GetDescriptor(originalIndex, visibleOffset);
                     if (descriptor != null)
                     {
                         buffer.Append(ExprProcessor.GetCastTypeName(new VarType(descriptor)));
                         return;
                     }
                 }
             }
         }
     }
     buffer.Append(ExprProcessor.GetCastTypeName(GetVarType()));
 }
Beispiel #4
0
 public virtual bool HasBooleanValue()
 {
     switch (constType.type)
     {
     case ICodeConstants.Type_Boolean:
     case ICodeConstants.Type_Char:
     case ICodeConstants.Type_Byte:
     case ICodeConstants.Type_Bytechar:
     case ICodeConstants.Type_Short:
     case ICodeConstants.Type_Shortchar:
     case ICodeConstants.Type_Int:
     {
         int value = (int)this.value;
         return(value == 0 || (DecompilerContext.GetOption(IFernflowerPreferences.Boolean_True_One
                                                           ) && value == 1));
     }
     }
     return(false);
 }
Beispiel #5
0
        public virtual bool SimplifyStackVarsStatement(Statement stat, HashSet <int> setReorderedIfs
                                                       , SSAConstructorSparseEx ssa, StructClass cl)
        {
            bool           res         = false;
            List <Exprent> expressions = stat.GetExprents();

            if (expressions == null)
            {
                bool processClass14 = DecompilerContext.GetOption(IFernflowerPreferences.Decompile_Class_1_4
                                                                  );
                while (true)
                {
                    bool changed = false;
                    foreach (Statement st in stat.GetStats())
                    {
                        res    |= SimplifyStackVarsStatement(st, setReorderedIfs, ssa, cl);
                        changed = IfHelper.MergeIfs(st, setReorderedIfs) || BuildIff(st, ssa) || processClass14 &&
                                  CollapseInlinedClass14(st);
                        // collapse composed if's
                        // collapse iff ?: statement
                        // collapse inlined .class property in version 1.4 and before
                        if (changed)
                        {
                            break;
                        }
                    }
                    res |= changed;
                    if (!changed)
                    {
                        break;
                    }
                }
            }
            else
            {
                res = SimplifyStackVarsExprents(expressions, cl);
            }
            return(res);
        }
Beispiel #6
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();
        }
Beispiel #7
0
        private bool SimplifyStackVarsExprents(List <Exprent> list, StructClass cl)
        {
            bool res   = false;
            int  index = 0;

            while (index < list.Count)
            {
                Exprent current = list[index];
                Exprent ret     = IsSimpleConstructorInvocation(current);
                if (ret != null)
                {
                    list[index] = ret;
                    res         = true;
                    continue;
                }
                // lambda expression (Java 8)
                ret = IsLambda(current, cl);
                if (ret != null)
                {
                    list[index] = ret;
                    res         = true;
                    continue;
                }
                // remove monitor exit
                if (IsMonitorExit(current))
                {
                    list.RemoveAtReturningValue(index);
                    res = true;
                    continue;
                }
                // trivial assignment of a stack variable
                if (IsTrivialStackAssignment(current))
                {
                    list.RemoveAtReturningValue(index);
                    res = true;
                    continue;
                }
                if (index == list.Count - 1)
                {
                    break;
                }
                Exprent next = list[index + 1];
                // constructor invocation
                if (IsConstructorInvocationRemote(list, index))
                {
                    list.RemoveAtReturningValue(index);
                    res = true;
                    continue;
                }
                // remove getClass() invocation, which is part of a qualified new
                if (DecompilerContext.GetOption(IFernflowerPreferences.Remove_Get_Class_New))
                {
                    if (IsQualifiedNewGetClass(current, next))
                    {
                        list.RemoveAtReturningValue(index);
                        res = true;
                        continue;
                    }
                }
                // direct initialization of an array
                int arrCount = IsArrayInitializer(list, index);
                if (arrCount > 0)
                {
                    for (int i = 0; i < arrCount; i++)
                    {
                        list.RemoveAtReturningValue(index + 1);
                    }
                    res = true;
                    continue;
                }
                // add array initializer expression
                if (AddArrayInitializer(current, next))
                {
                    list.RemoveAtReturningValue(index + 1);
                    res = true;
                    continue;
                }
                // integer ++expr and --expr  (except for vars!)
                Exprent func = IsPPIorMMI(current);
                if (func != null)
                {
                    list[index] = func;
                    res         = true;
                    continue;
                }
                // expr++ and expr--
                if (IsIPPorIMM(current, next) || IsIPPorIMM2(current, next))
                {
                    list.RemoveAtReturningValue(index + 1);
                    res = true;
                    continue;
                }
                // assignment on stack
                if (IsStackAssignment(current, next))
                {
                    list.RemoveAtReturningValue(index + 1);
                    res = true;
                    continue;
                }
                if (!firstInvocation && IsStackAssignment2(current, next))
                {
                    list.RemoveAtReturningValue(index + 1);
                    res = true;
                    continue;
                }
                index++;
            }
            return(res);
        }
Beispiel #8
0
        private static bool RemoveEmptyBlock(ControlFlowGraph graph, BasicBlock block, bool
                                             merging)
        {
            bool deletedRanges = false;

            if (block.GetSeq().IsEmpty())
            {
                if (block.GetSuccs().Count > 1)
                {
                    if (block.GetPreds().Count > 1)
                    {
                        // ambiguous block
                        throw new Exception("ERROR: empty block with multiple predecessors and successors found"
                                            );
                    }
                    else if (!merging)
                    {
                        throw new Exception("ERROR: empty block with multiple successors found");
                    }
                }
                HashSet <BasicBlock> setExits = new HashSet <BasicBlock>(graph.GetLast().GetPreds()
                                                                         );
                if ((block.GetPredExceptions().Count == 0) && (!setExits.Contains(block) || block
                                                               .GetPreds().Count == 1))
                {
                    if (setExits.Contains(block))
                    {
                        BasicBlock pred = block.GetPreds()[0];
                        // FIXME: flag in the basic block
                        if (pred.GetSuccs().Count != 1 || (!pred.GetSeq().IsEmpty() && pred.GetSeq().GetLastInstr
                                                               ().group == ICodeConstants.Group_Switch))
                        {
                            return(false);
                        }
                    }
                    HashSet <BasicBlock> setPreds = new HashSet <BasicBlock>(block.GetPreds());
                    HashSet <BasicBlock> setSuccs = new HashSet <BasicBlock>(block.GetSuccs());
                    // collect common exception ranges of predecessors and successors
                    HashSet <BasicBlock> setCommonExceptionHandlers = null;
                    for (int i = 0; i < 2; ++i)
                    {
                        foreach (BasicBlock pred in i == 0 ? setPreds : setSuccs)
                        {
                            if (setCommonExceptionHandlers == null)
                            {
                                setCommonExceptionHandlers = new HashSet <BasicBlock>(pred.GetSuccExceptions());
                            }
                            else
                            {
                                setCommonExceptionHandlers.IntersectWith(pred.GetSuccExceptions());
                            }
                        }
                    }
                    // check the block to be in each of the common ranges
                    if (setCommonExceptionHandlers != null && !(setCommonExceptionHandlers.Count == 0))
                    {
                        foreach (BasicBlock handler in setCommonExceptionHandlers)
                        {
                            if (!block.GetSuccExceptions().Contains(handler))
                            {
                                return(false);
                            }
                        }
                    }
                    // remove ranges consisting of this one block
                    List <ExceptionRangeCFG> lstRanges = graph.GetExceptions();
                    for (int i = lstRanges.Count - 1; i >= 0; i--)
                    {
                        ExceptionRangeCFG range = lstRanges[i];
                        List <BasicBlock> lst   = range.GetProtectedRange();
                        if (lst.Count == 1 && lst[0] == block)
                        {
                            if (DecompilerContext.GetOption(IFernflowerPreferences.Remove_Empty_Ranges))
                            {
                                block.RemoveSuccessorException(range.GetHandler());
                                lstRanges.RemoveAtReturningValue(i);
                                deletedRanges = true;
                            }
                            else
                            {
                                return(false);
                            }
                        }
                    }
                    // connect remaining nodes
                    if (merging)
                    {
                        BasicBlock pred = block.GetPreds()[0];
                        pred.RemoveSuccessor(block);
                        List <BasicBlock> lstSuccs = new List <BasicBlock>(block.GetSuccs());
                        foreach (BasicBlock succ in lstSuccs)
                        {
                            block.RemoveSuccessor(succ);
                            pred.AddSuccessor(succ);
                        }
                    }
                    else
                    {
                        foreach (BasicBlock pred in setPreds)
                        {
                            foreach (BasicBlock succ in setSuccs)
                            {
                                pred.ReplaceSuccessor(block, succ);
                            }
                        }
                    }
                    // finally exit edges
                    HashSet <BasicBlock> setFinallyExits = graph.GetFinallyExits();
                    if (setFinallyExits.Contains(block))
                    {
                        setFinallyExits.Remove(block);
                        setFinallyExits.Add(new Sharpen.EnumeratorAdapter <BasicBlock>(setPreds.GetEnumerator()).Next());
                    }
                    // replace first if necessary
                    if (graph.GetFirst() == block)
                    {
                        if (setSuccs.Count != 1)
                        {
                            throw new Exception("multiple or no entry blocks!");
                        }
                        else
                        {
                            graph.SetFirst(new Sharpen.EnumeratorAdapter <BasicBlock>(setSuccs.GetEnumerator()).Next());
                        }
                    }
                    // remove this block
                    graph.RemoveBlock(block);
                    if (deletedRanges)
                    {
                        RemoveDeadBlocks(graph);
                    }
                }
            }
            return(deletedRanges);
        }
        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);
        }
Beispiel #10
0
        public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer)
        {
            bool literal = DecompilerContext.GetOption(IFernflowerPreferences.Literals_As_Is
                                                       );
            bool ascii = DecompilerContext.GetOption(IFernflowerPreferences.Ascii_String_Characters
                                                     );

            tracer.AddMapping(bytecode);
            if (constType.type != ICodeConstants.Type_Null && value == null)
            {
                return(new TextBuffer(ExprProcessor.GetCastTypeName(constType)));
            }
            switch (constType.type)
            {
            case ICodeConstants.Type_Boolean:
            {
                return(new TextBuffer(((int)value != 0).ToString()));
            }

            case ICodeConstants.Type_Char:
            {
                int    val = (int)value;
                string ret = Char_Escapes.GetOrNull(val);
                if (ret == null)
                {
                    char c = (char)val;
                    if (IsPrintableAscii(c) || !ascii && TextUtil.IsPrintableUnicode(c))
                    {
                        ret = c.ToString();
                    }
                    else
                    {
                        ret = TextUtil.CharToUnicodeLiteral(c);
                    }
                }
                return(new TextBuffer(ret).Enclose("'", "'"));
            }

            case ICodeConstants.Type_Byte:
            case ICodeConstants.Type_Bytechar:
            case ICodeConstants.Type_Short:
            case ICodeConstants.Type_Shortchar:
            case ICodeConstants.Type_Int:
            {
                int intVal = (int)value;
                if (!literal)
                {
                    if (intVal == int.MaxValue)
                    {
                        return(new FieldExprent("MAX_VALUE", "java/lang/Integer", true, null, FieldDescriptor
                                                .Integer_Descriptor, bytecode).ToJava(0, tracer));
                    }
                    else if (intVal == int.MinValue)
                    {
                        return(new FieldExprent("MIN_VALUE", "java/lang/Integer", true, null, FieldDescriptor
                                                .Integer_Descriptor, bytecode).ToJava(0, tracer));
                    }
                }
                return(new TextBuffer(value.ToString()));
            }

            case ICodeConstants.Type_Long:
            {
                long longVal = (long)value;
                if (!literal)
                {
                    if (longVal == long.MaxValue)
                    {
                        return(new FieldExprent("MAX_VALUE", "java/lang/Long", true, null, FieldDescriptor
                                                .Long_Descriptor, bytecode).ToJava(0, tracer));
                    }
                    else if (longVal == long.MinValue)
                    {
                        return(new FieldExprent("MIN_VALUE", "java/lang/Long", true, null, FieldDescriptor
                                                .Long_Descriptor, bytecode).ToJava(0, tracer));
                    }
                }
                return(new TextBuffer(value.ToString()).Append('L'));
            }

            case ICodeConstants.Type_Float:
            {
                float floatVal = (float)value;
                if (!literal)
                {
                    if (float.IsNaN(floatVal))
                    {
                        return(new FieldExprent("NaN", "java/lang/Float", true, null, FieldDescriptor.Float_Descriptor
                                                , bytecode).ToJava(0, tracer));
                    }
                    else if (floatVal == float.PositiveInfinity)
                    {
                        return(new FieldExprent("POSITIVE_INFINITY", "java/lang/Float", true, null, FieldDescriptor
                                                .Float_Descriptor, bytecode).ToJava(0, tracer));
                    }
                    else if (floatVal == float.NegativeInfinity)
                    {
                        return(new FieldExprent("NEGATIVE_INFINITY", "java/lang/Float", true, null, FieldDescriptor
                                                .Float_Descriptor, bytecode).ToJava(0, tracer));
                    }
                    else if (floatVal == float.MaxValue)
                    {
                        return(new FieldExprent("MAX_VALUE", "java/lang/Float", true, null, FieldDescriptor
                                                .Float_Descriptor, bytecode).ToJava(0, tracer));
                    }
                    else if (floatVal == float.MinValue)
                    {
                        return(new FieldExprent("MIN_VALUE", "java/lang/Float", true, null, FieldDescriptor
                                                .Float_Descriptor, bytecode).ToJava(0, tracer));
                    }
                }
                else if (float.IsNaN(floatVal))
                {
                    return(new TextBuffer("0.0F / 0.0"));
                }
                else if (floatVal == float.PositiveInfinity)
                {
                    return(new TextBuffer("1.0F / 0.0"));
                }
                else if (floatVal == float.NegativeInfinity)
                {
                    return(new TextBuffer("-1.0F / 0.0"));
                }
                return(new TextBuffer(value.ToString()).Append('F'));
            }

            case ICodeConstants.Type_Double:
            {
                double doubleVal = (double)value;
                if (!literal)
                {
                    if (double.IsNaN(doubleVal))
                    {
                        return(new FieldExprent("NaN", "java/lang/Double", true, null, FieldDescriptor.Double_Descriptor
                                                , bytecode).ToJava(0, tracer));
                    }
                    else if (doubleVal == double.PositiveInfinity)
                    {
                        return(new FieldExprent("POSITIVE_INFINITY", "java/lang/Double", true, null, FieldDescriptor
                                                .Double_Descriptor, bytecode).ToJava(0, tracer));
                    }
                    else if (doubleVal == double.NegativeInfinity)
                    {
                        return(new FieldExprent("NEGATIVE_INFINITY", "java/lang/Double", true, null, FieldDescriptor
                                                .Double_Descriptor, bytecode).ToJava(0, tracer));
                    }
                    else if (doubleVal == double.MaxValue)
                    {
                        return(new FieldExprent("MAX_VALUE", "java/lang/Double", true, null, FieldDescriptor
                                                .Double_Descriptor, bytecode).ToJava(0, tracer));
                    }
                    else if (doubleVal == double.MinValue)
                    {
                        return(new FieldExprent("MIN_VALUE", "java/lang/Double", true, null, FieldDescriptor
                                                .Double_Descriptor, bytecode).ToJava(0, tracer));
                    }
                }
                else if (double.IsNaN(doubleVal))
                {
                    return(new TextBuffer("0.0D / 0.0"));
                }
                else if (doubleVal == double.PositiveInfinity)
                {
                    return(new TextBuffer("1.0D / 0.0"));
                }
                else if (doubleVal == double.NegativeInfinity)
                {
                    return(new TextBuffer("-1.0D / 0.0"));
                }
                return(new TextBuffer(value.ToString()).Append('D'));
            }

            case ICodeConstants.Type_Null:
            {
                return(new TextBuffer("null"));
            }

            case ICodeConstants.Type_Object:
            {
                if (constType.Equals(VarType.Vartype_String))
                {
                    return(new TextBuffer(ConvertStringToJava(value.ToString(), ascii)).Enclose("\"",
                                                                                                "\""));
                }
                else if (constType.Equals(VarType.Vartype_Class))
                {
                    string  stringVal = value.ToString();
                    VarType type      = new VarType(stringVal, !stringVal.StartsWith("["));
                    return(new TextBuffer(ExprProcessor.GetCastTypeName(type)).Append(".class"));
                }
                break;
            }
            }
            throw new Exception("invalid constant type: " + constType);
        }
        public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer)
        {
            TextBuffer buf             = new TextBuffer();
            string     super_qualifier = null;
            bool       isInstanceThis  = false;

            tracer.AddMapping(bytecode);
            if (instance is InvocationExprent)
            {
                ((InvocationExprent)instance).MarkUsingBoxingResult();
            }
            if (isStatic__)
            {
                if (IsBoxingCall() && canIgnoreBoxing)
                {
                    // process general "boxing" calls, e.g. 'Object[] data = { true }' or 'Byte b = 123'
                    // here 'byte' and 'short' values do not need an explicit narrowing type cast
                    ExprProcessor.GetCastedExprent(lstParameters[0], descriptor.@params[0], buf, indent
                                                   , false, false, false, false, tracer);
                    return(buf);
                }
                ClassesProcessor.ClassNode node = (ClassesProcessor.ClassNode)DecompilerContext.GetProperty
                                                      (DecompilerContext.Current_Class_Node);
                if (node == null || !classname.Equals(node.classStruct.qualifiedName))
                {
                    buf.Append(DecompilerContext.GetImportCollector().GetShortNameInClassContext(ExprProcessor
                                                                                                 .BuildJavaClassName(classname)));
                }
            }
            else
            {
                if (instance != null && instance.type == Exprent.Exprent_Var)
                {
                    VarExprent     instVar = (VarExprent)instance;
                    VarVersionPair varPair = new VarVersionPair(instVar);
                    VarProcessor   varProc = instVar.GetProcessor();
                    if (varProc == null)
                    {
                        MethodWrapper currentMethod = (MethodWrapper)DecompilerContext.GetProperty(DecompilerContext
                                                                                                   .Current_Method_Wrapper);
                        if (currentMethod != null)
                        {
                            varProc = currentMethod.varproc;
                        }
                    }
                    string this_classname = null;
                    if (varProc != null)
                    {
                        this_classname = varProc.GetThisVars().GetOrNull(varPair);
                    }
                    if (this_classname != null)
                    {
                        isInstanceThis = true;
                        if (invocationTyp == Invoke_Special)
                        {
                            if (!classname.Equals(this_classname))
                            {
                                // TODO: direct comparison to the super class?
                                StructClass cl          = DecompilerContext.GetStructContext().GetClass(classname);
                                bool        isInterface = cl != null && cl.HasModifier(ICodeConstants.Acc_Interface);
                                super_qualifier = !isInterface ? this_classname : classname;
                            }
                        }
                    }
                }
                if (functype == Typ_General)
                {
                    if (super_qualifier != null)
                    {
                        TextUtil.WriteQualifiedSuper(buf, super_qualifier);
                    }
                    else if (instance != null)
                    {
                        TextBuffer res = instance.ToJava(indent, tracer);
                        if (IsUnboxingCall())
                        {
                            // we don't print the unboxing call - no need to bother with the instance wrapping / casting
                            buf.Append(res);
                            return(buf);
                        }
                        VarType rightType = instance.GetExprType();
                        VarType leftType  = new VarType(ICodeConstants.Type_Object, 0, classname);
                        if (rightType.Equals(VarType.Vartype_Object) && !leftType.Equals(rightType))
                        {
                            buf.Append("((").Append(ExprProcessor.GetCastTypeName(leftType)).Append(")");
                            if (instance.GetPrecedence() >= FunctionExprent.GetPrecedence(FunctionExprent.Function_Cast
                                                                                          ))
                            {
                                res.Enclose("(", ")");
                            }
                            buf.Append(res).Append(")");
                        }
                        else if (instance.GetPrecedence() > GetPrecedence())
                        {
                            buf.Append("(").Append(res).Append(")");
                        }
                        else
                        {
                            buf.Append(res);
                        }
                    }
                }
            }
            switch (functype)
            {
            case Typ_General:
            {
                if (VarExprent.Var_Nameless_Enclosure.Equals(buf.ToString()))
                {
                    buf = new TextBuffer();
                }
                if (buf.Length() > 0)
                {
                    buf.Append(".");
                }
                buf.Append(name);
                if (invocationTyp == Invoke_Dynamic)
                {
                    buf.Append("<invokedynamic>");
                }
                buf.Append("(");
                break;
            }

            case Typ_Clinit:
            {
                throw new Exception("Explicit invocation of " + ICodeConstants.Clinit_Name);
            }

            case Typ_Init:
            {
                if (super_qualifier != null)
                {
                    buf.Append("super(");
                }
                else if (isInstanceThis)
                {
                    buf.Append("this(");
                }
                else if (instance != null)
                {
                    buf.Append(instance.ToJava(indent, tracer)).Append(".<init>(");
                }
                else
                {
                    throw new Exception("Unrecognized invocation of " + ICodeConstants.Init_Name);
                }
                break;
            }
            }
            List <VarVersionPair> mask = null;
            bool isEnum = false;

            if (functype == Typ_Init)
            {
                ClassesProcessor.ClassNode newNode = DecompilerContext.GetClassProcessor().GetMapRootClasses
                                                         ().GetOrNull(classname);
                if (newNode != null)
                {
                    mask = ExprUtil.GetSyntheticParametersMask(newNode, stringDescriptor, lstParameters
                                                               .Count);
                    isEnum = newNode.classStruct.HasModifier(ICodeConstants.Acc_Enum) && DecompilerContext
                             .GetOption(IFernflowerPreferences.Decompile_Enum);
                }
            }
            BitSet setAmbiguousParameters = GetAmbiguousParameters();

            // omit 'new Type[] {}' for the last parameter of a vararg method call
            if (lstParameters.Count == [email protected] && IsVarArgCall())
            {
                Exprent lastParam = lstParameters[lstParameters.Count - 1];
                if (lastParam.type == Exprent_New && lastParam.GetExprType().arrayDim >= 1)
                {
                    ((NewExprent)lastParam).SetVarArgParam(true);
                }
            }
            bool firstParameter = true;
            int  start          = isEnum ? 2 : 0;

            for (int i = start; i < lstParameters.Count; i++)
            {
                if (mask == null || mask[i] == null)
                {
                    TextBuffer buff      = new TextBuffer();
                    bool       ambiguous = setAmbiguousParameters.Get(i);
                    // 'byte' and 'short' literals need an explicit narrowing type cast when used as a parameter
                    ExprProcessor.GetCastedExprent(lstParameters[i], descriptor.@params[i], buff, indent
                                                   , true, ambiguous, true, true, tracer);
                    // the last "new Object[0]" in the vararg call is not printed
                    if (buff.Length() > 0)
                    {
                        if (!firstParameter)
                        {
                            buf.Append(", ");
                        }
                        buf.Append(buff);
                    }
                    firstParameter = false;
                }
            }
            buf.Append(')');
            return(buf);
        }
Beispiel #12
0
        // precedence of new
        public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer)
        {
            TextBuffer buf = new TextBuffer();

            if (anonymous)
            {
                ClassesProcessor.ClassNode child = DecompilerContext.GetClassProcessor().GetMapRootClasses
                                                       ().GetOrNull(newType.value);
                // IDEA-204310 - avoid backtracking later on for lambdas (causes spurious imports)
                if (!enumConst && (!lambda || DecompilerContext.GetOption(IFernflowerPreferences
                                                                          .Lambda_To_Anonymous_Class)))
                {
                    string enclosing = null;
                    if (!lambda && constructor != null)
                    {
                        enclosing = GetQualifiedNewInstance(child.anonymousClassType.value, constructor.GetLstParameters
                                                                (), indent, tracer);
                        if (enclosing != null)
                        {
                            buf.Append(enclosing).Append('.');
                        }
                    }
                    buf.Append("new ");
                    string typename = ExprProcessor.GetCastTypeName(child.anonymousClassType);
                    if (enclosing != null)
                    {
                        ClassesProcessor.ClassNode anonymousNode = DecompilerContext.GetClassProcessor().
                                                                   GetMapRootClasses().GetOrNull(child.anonymousClassType.value);
                        if (anonymousNode != null)
                        {
                            typename = anonymousNode.simpleName;
                        }
                        else
                        {
                            typename = Sharpen.Runtime.Substring(typename, typename.LastIndexOf('.') + 1);
                        }
                    }
                    GenericClassDescriptor descriptor = ClassWriter.GetGenericClassDescriptor(child.classStruct
                                                                                              );
                    if (descriptor != null)
                    {
                        if ((descriptor.superinterfaces.Count == 0))
                        {
                            buf.Append(GenericMain.GetGenericCastTypeName(descriptor.superclass));
                        }
                        else
                        {
                            if (descriptor.superinterfaces.Count > 1 && !lambda)
                            {
                                DecompilerContext.GetLogger().WriteMessage("Inconsistent anonymous class signature: "
                                                                           + child.classStruct.qualifiedName, IFernflowerLogger.Severity.Warn);
                            }
                            buf.Append(GenericMain.GetGenericCastTypeName(descriptor.superinterfaces[0]));
                        }
                    }
                    else
                    {
                        buf.Append(typename);
                    }
                }
                buf.Append('(');
                if (!lambda && constructor != null)
                {
                    List <Exprent>        parameters = constructor.GetLstParameters();
                    List <VarVersionPair> mask       = child.GetWrapper().GetMethodWrapper(ICodeConstants.Init_Name
                                                                                           , constructor.GetStringDescriptor()).synthParameters;
                    if (mask == null)
                    {
                        InvocationExprent superCall = child.superInvocation;
                        mask = ExprUtil.GetSyntheticParametersMask(superCall.GetClassname(), superCall.GetStringDescriptor
                                                                       (), parameters.Count);
                    }
                    int  start      = enumConst ? 2 : 0;
                    bool firstParam = true;
                    for (int i = start; i < parameters.Count; i++)
                    {
                        if (mask == null || mask[i] == null)
                        {
                            if (!firstParam)
                            {
                                buf.Append(", ");
                            }
                            ExprProcessor.GetCastedExprent(parameters[i], constructor.GetDescriptor().@params
                                                           [i], buf, indent, true, tracer);
                            firstParam = false;
                        }
                    }
                }
                buf.Append(')');
                if (enumConst && buf.Length() == 2)
                {
                    buf.SetLength(0);
                }
                if (lambda)
                {
                    if (!DecompilerContext.GetOption(IFernflowerPreferences.Lambda_To_Anonymous_Class
                                                     ))
                    {
                        buf.SetLength(0);
                    }
                    // remove the usual 'new <class>()', it will be replaced with lambda style '() ->'
                    Exprent    methodObject = constructor == null ? null : constructor.GetInstance();
                    TextBuffer clsBuf       = new TextBuffer();
                    new ClassWriter().ClassLambdaToJava(child, clsBuf, methodObject, indent, tracer);
                    buf.Append(clsBuf);
                    tracer.IncrementCurrentSourceLine(clsBuf.CountLines());
                }
                else
                {
                    TextBuffer clsBuf = new TextBuffer();
                    new ClassWriter().ClassToJava(child, clsBuf, indent, tracer);
                    buf.Append(clsBuf);
                    tracer.IncrementCurrentSourceLine(clsBuf.CountLines());
                }
            }
            else if (directArrayInit)
            {
                VarType leftType = newType.DecreaseArrayDim();
                buf.Append('{');
                for (int i = 0; i < lstArrayElements.Count; i++)
                {
                    if (i > 0)
                    {
                        buf.Append(", ");
                    }
                    ExprProcessor.GetCastedExprent(lstArrayElements[i], leftType, buf, indent, false,
                                                   tracer);
                }
                buf.Append('}');
            }
            else if (newType.arrayDim == 0)
            {
                if (!enumConst)
                {
                    string enclosing = null;
                    if (constructor != null)
                    {
                        enclosing = GetQualifiedNewInstance(newType.value, constructor.GetLstParameters()
                                                            , indent, tracer);
                        if (enclosing != null)
                        {
                            buf.Append(enclosing).Append('.');
                        }
                    }
                    buf.Append("new ");
                    string typename = ExprProcessor.GetTypeName(newType);
                    if (enclosing != null)
                    {
                        ClassesProcessor.ClassNode newNode = DecompilerContext.GetClassProcessor().GetMapRootClasses
                                                                 ().GetOrNull(newType.value);
                        if (newNode != null)
                        {
                            typename = newNode.simpleName;
                        }
                        else
                        {
                            typename = Sharpen.Runtime.Substring(typename, typename.LastIndexOf('.') + 1);
                        }
                    }
                    buf.Append(typename);
                }
                if (constructor != null)
                {
                    List <Exprent>        parameters = constructor.GetLstParameters();
                    List <VarVersionPair> mask       = ExprUtil.GetSyntheticParametersMask(constructor.GetClassname
                                                                                               (), constructor.GetStringDescriptor(), parameters.Count);
                    int start = enumConst ? 2 : 0;
                    if (!enumConst || start < parameters.Count)
                    {
                        buf.Append('(');
                        bool firstParam = true;
                        for (int i = start; i < parameters.Count; i++)
                        {
                            if (mask == null || mask[i] == null)
                            {
                                Exprent expr     = parameters[i];
                                VarType leftType = constructor.GetDescriptor().@params[i];
                                if (i == parameters.Count - 1 && expr.GetExprType() == VarType.Vartype_Null && ProbablySyntheticParameter
                                        (leftType.value))
                                {
                                    break;
                                }
                                // skip last parameter of synthetic constructor call
                                if (!firstParam)
                                {
                                    buf.Append(", ");
                                }
                                ExprProcessor.GetCastedExprent(expr, leftType, buf, indent, true, false, true, true
                                                               , tracer);
                                firstParam = false;
                            }
                        }
                        buf.Append(')');
                    }
                }
            }
            else if (isVarArgParam)
            {
                // just print the array elements
                VarType leftType = newType.DecreaseArrayDim();
                for (int i = 0; i < lstArrayElements.Count; i++)
                {
                    if (i > 0)
                    {
                        buf.Append(", ");
                    }
                    // new String[][]{{"abc"}, {"DEF"}} => new String[]{"abc"}, new String[]{"DEF"}
                    Exprent element = lstArrayElements[i];
                    if (element.type == Exprent_New)
                    {
                        ((NewExprent)element).SetDirectArrayInit(false);
                    }
                    ExprProcessor.GetCastedExprent(element, leftType, buf, indent, false, tracer);
                }
                // if there is just one element of Object[] type it needs to be casted to resolve ambiguity
                if (lstArrayElements.Count == 1)
                {
                    VarType elementType = lstArrayElements[0].GetExprType();
                    if (elementType.type == ICodeConstants.Type_Object && elementType.value.Equals("java/lang/Object"
                                                                                                   ) && elementType.arrayDim >= 1)
                    {
                        buf.Prepend("(Object)");
                    }
                }
            }
            else
            {
                buf.Append("new ").Append(ExprProcessor.GetTypeName(newType));
                if ((lstArrayElements.Count == 0))
                {
                    for (int i = 0; i < newType.arrayDim; i++)
                    {
                        buf.Append('[');
                        if (i < lstDims.Count)
                        {
                            buf.Append(lstDims[i].ToJava(indent, tracer));
                        }
                        buf.Append(']');
                    }
                }
                else
                {
                    for (int i = 0; i < newType.arrayDim; i++)
                    {
                        buf.Append("[]");
                    }
                    VarType leftType = newType.DecreaseArrayDim();
                    buf.Append('{');
                    for (int i = 0; i < lstArrayElements.Count; i++)
                    {
                        if (i > 0)
                        {
                            buf.Append(", ");
                        }
                        ExprProcessor.GetCastedExprent(lstArrayElements[i], leftType, buf, indent, false,
                                                       tracer);
                    }
                    buf.Append('}');
                }
            }
            return(buf);
        }
Beispiel #13
0
        public virtual void Save()
        {
            switch (type)
            {
            case Type_Folder:
            {
                // create folder
                resultSaver.SaveFolder(filename);
                // non-class files
                foreach (string[] pair in otherEntries)
                {
                    resultSaver.CopyFile(pair[0], filename, pair[1]);
                }
                // classes
                for (int i = 0; i < classes.Count; i++)
                {
                    StructClass cl        = classes[i];
                    string      entryName = decompiledData.GetClassEntryName(cl, classEntries[i]);
                    if (entryName != null)
                    {
                        string content = decompiledData.GetClassContent(cl);
                        if (content != null)
                        {
                            int[] mapping = null;
                            if (DecompilerContext.GetOption(IFernflowerPreferences.Bytecode_Source_Mapping))
                            {
                                mapping = DecompilerContext.GetBytecodeSourceMapper().GetOriginalLinesMapping();
                            }
                            resultSaver.SaveClassFile(filename, cl.qualifiedName, entryName, content, mapping
                                                      );
                        }
                    }
                }
                break;
            }

            case Type_Jar:
            case Type_Zip:
            {
                // create archive file
                resultSaver.SaveFolder(archivePath);
                resultSaver.CreateArchive(archivePath, filename, manifest);
                // directory entries
                foreach (string dirEntry in dirEntries)
                {
                    resultSaver.SaveDirEntry(archivePath, filename, dirEntry + "\\");
                }
                // non-class entries
                foreach (string[] pair in otherEntries)
                {
                    if (type != Type_Jar || !Sharpen.Runtime.EqualsIgnoreCase(Manifest_Name,
                                                                              pair[1]))
                    {
                        resultSaver.CopyEntry(pair[0], archivePath, filename, pair[1]);
                    }
                }
                // classes
                for (int i = 0; i < classes.Count; i++)
                {
                    StructClass cl        = classes[i];
                    string      entryName = decompiledData.GetClassEntryName(cl, classEntries[i]);
                    if (entryName != null)
                    {
                        string content = decompiledData.GetClassContent(cl);
                        resultSaver.SaveClassEntry(archivePath, filename, cl.qualifiedName, entryName, content
                                                   );
                    }
                }
                resultSaver.CloseArchive(archivePath, filename);
                break;
            }
            }
        }
        /// <exception cref="System.IO.IOException"/>
        public static RootStatement CodeToJava(StructMethod mt, MethodDescriptor md, VarProcessor
                                               varProc)
        {
            StructClass cl            = mt.GetClassStruct();
            bool        isInitializer = ICodeConstants.Clinit_Name.Equals(mt.GetName());

            // for now static initializer only
            mt.ExpandData();
            InstructionSequence seq   = mt.GetInstructionSequence();
            ControlFlowGraph    graph = new ControlFlowGraph(seq);

            DeadCodeHelper.RemoveDeadBlocks(graph);
            graph.InlineJsr(mt);
            // TODO: move to the start, before jsr inlining
            DeadCodeHelper.ConnectDummyExitBlock(graph);
            DeadCodeHelper.RemoveGotos(graph);
            ExceptionDeobfuscator.RemoveCircularRanges(graph);
            ExceptionDeobfuscator.RestorePopRanges(graph);
            if (DecompilerContext.GetOption(IFernflowerPreferences.Remove_Empty_Ranges))
            {
                ExceptionDeobfuscator.RemoveEmptyRanges(graph);
            }
            if (DecompilerContext.GetOption(IFernflowerPreferences.Ensure_Synchronized_Monitor
                                            ))
            {
                // special case: search for 'synchronized' ranges w/o monitorexit instruction (as generated by Kotlin and Scala)
                DeadCodeHelper.ExtendSynchronizedRangeToMonitorexit(graph);
            }
            if (DecompilerContext.GetOption(IFernflowerPreferences.No_Exceptions_Return))
            {
                // special case: single return instruction outside of a protected range
                DeadCodeHelper.IncorporateValueReturns(graph);
            }
            //		ExceptionDeobfuscator.restorePopRanges(graph);
            ExceptionDeobfuscator.InsertEmptyExceptionHandlerBlocks(graph);
            DeadCodeHelper.MergeBasicBlocks(graph);
            DecompilerContext.GetCounterContainer().SetCounter(CounterContainer.Var_Counter,
                                                               mt.GetLocalVariables());
            if (ExceptionDeobfuscator.HasObfuscatedExceptions(graph))
            {
                DecompilerContext.GetLogger().WriteMessage("Heavily obfuscated exception ranges found!"
                                                           , IFernflowerLogger.Severity.Warn);
                if (!ExceptionDeobfuscator.HandleMultipleEntryExceptionRanges(graph))
                {
                    DecompilerContext.GetLogger().WriteMessage("Found multiple entry exception ranges which could not be splitted"
                                                               , IFernflowerLogger.Severity.Warn);
                }
                ExceptionDeobfuscator.InsertDummyExceptionHandlerBlocks(graph, cl.GetBytecodeVersion
                                                                            ());
            }
            RootStatement    root  = DomHelper.ParseGraph(graph);
            FinallyProcessor fProc = new FinallyProcessor(md, varProc);

            while (fProc.IterateGraph(mt, root, graph))
            {
                root = DomHelper.ParseGraph(graph);
            }
            // remove synchronized exception handler
            // not until now because of comparison between synchronized statements in the finally cycle
            DomHelper.RemoveSynchronizedHandler(root);
            //		LabelHelper.lowContinueLabels(root, new HashSet<StatEdge>());
            SequenceHelper.CondenseSequences(root);
            ClearStructHelper.ClearStatements(root);
            ExprProcessor proc = new ExprProcessor(md, varProc);

            proc.ProcessStatement(root, cl);
            SequenceHelper.CondenseSequences(root);
            StackVarsProcessor stackProc = new StackVarsProcessor();

            do
            {
                stackProc.SimplifyStackVars(root, mt, cl);
                varProc.SetVarVersions(root);
            }while (new PPandMMHelper().FindPPandMM(root));
            while (true)
            {
                LabelHelper.CleanUpEdges(root);
                do
                {
                    MergeHelper.EnhanceLoops(root);
                }while (LoopExtractHelper.ExtractLoops(root) || IfHelper.MergeAllIfs(root));
                if (DecompilerContext.GetOption(IFernflowerPreferences.Idea_Not_Null_Annotation))
                {
                    if (IdeaNotNullHelper.RemoveHardcodedChecks(root, mt))
                    {
                        SequenceHelper.CondenseSequences(root);
                        stackProc.SimplifyStackVars(root, mt, cl);
                        varProc.SetVarVersions(root);
                    }
                }
                LabelHelper.IdentifyLabels(root);
                if (InlineSingleBlockHelper.InlineSingleBlocks(root))
                {
                    continue;
                }
                // initializer may have at most one return point, so no transformation of method exits permitted
                if (isInitializer || !ExitHelper.CondenseExits(root))
                {
                    break;
                }
            }
            // FIXME: !!
            //if(!EliminateLoopsHelper.eliminateLoops(root)) {
            //  break;
            //}
            ExitHelper.RemoveRedundantReturns(root);
            SecondaryFunctionsHelper.IdentifySecondaryFunctions(root, varProc);
            varProc.SetVarDefinitions(root);
            // must be the last invocation, because it makes the statement structure inconsistent
            // FIXME: new edge type needed
            LabelHelper.ReplaceContinueWithBreak(root);
            mt.ReleaseResources();
            return(root);
        }