示例#1
0
        private static Exprent IsSimpleConstructorInvocation(Exprent exprent)
        {
            List <Exprent> lst = exprent.GetAllExprents();

            foreach (Exprent expr in lst)
            {
                Exprent ret = IsSimpleConstructorInvocation(expr);
                if (ret != null)
                {
                    exprent.ReplaceExprent(expr, ret);
                }
            }
            if (exprent.type == Exprent.Exprent_Invocation)
            {
                InvocationExprent @in = (InvocationExprent)exprent;
                if (@in.GetFunctype() == InvocationExprent.Typ_Init && @in.GetInstance().type ==
                    Exprent.Exprent_New)
                {
                    NewExprent newExpr = (NewExprent)@in.GetInstance();
                    newExpr.SetConstructor(@in);
                    @in.SetInstance(null);
                    return(newExpr);
                }
            }
            return(null);
        }
示例#2
0
        private static Exprent IsLambda(Exprent exprent, StructClass cl)
        {
            List <Exprent> lst = exprent.GetAllExprents();

            foreach (Exprent expr in lst)
            {
                Exprent ret = IsLambda(expr, cl);
                if (ret != null)
                {
                    exprent.ReplaceExprent(expr, ret);
                }
            }
            if (exprent.type == Exprent.Exprent_Invocation)
            {
                InvocationExprent @in = (InvocationExprent)exprent;
                if (@in.GetInvocationTyp() == InvocationExprent.Invoke_Dynamic)
                {
                    string lambda_class_name = cl.qualifiedName + @in.GetInvokeDynamicClassSuffix();
                    ClassesProcessor.ClassNode lambda_class = DecompilerContext.GetClassProcessor().GetMapRootClasses
                                                                  ().GetOrNull(lambda_class_name);
                    if (lambda_class != null)
                    {
                        // real lambda class found, replace invocation with an anonymous class
                        NewExprent newExpr = new NewExprent(new VarType(lambda_class_name, true), null, 0
                                                            , @in.bytecode);
                        newExpr.SetConstructor(@in);
                        // note: we don't set the instance to null with in.setInstance(null) like it is done for a common constructor invocation
                        // lambda can also be a reference to a virtual method (e.g. String x; ...(x::toString);)
                        // in this case instance will hold the corresponding object
                        return(newExpr);
                    }
                }
            }
            return(null);
        }
        private static bool ReplaceInvocations(Exprent exprent, ClassWrapper wrapper, MethodWrapper
                                               meth)
        {
            bool res = false;

            while (true)
            {
                bool found = false;
                foreach (Exprent expr in exprent.GetAllExprents())
                {
                    string cl = IsClass14Invocation(expr, wrapper, meth);
                    if (cl != null)
                    {
                        exprent.ReplaceExprent(expr, new ConstExprent(VarType.Vartype_Class, cl.Replace('.'
                                                                                                        , '/'), expr.bytecode));
                        found = true;
                        res   = true;
                        break;
                    }
                    res |= ReplaceInvocations(expr, wrapper, meth);
                }
                if (!found)
                {
                    break;
                }
            }
            return(res);
        }
        private bool ReplaceInvocations(ClassesProcessor.ClassNode caller, MethodWrapper
                                        meth, Exprent exprent)
        {
            bool res = false;

            foreach (Exprent expr in exprent.GetAllExprents())
            {
                res |= ReplaceInvocations(caller, meth, expr);
            }
            while (true)
            {
                bool found = false;
                foreach (Exprent expr in exprent.GetAllExprents())
                {
                    if (expr.type == Exprent.Exprent_Invocation)
                    {
                        Exprent newexpr = ReplaceAccessExprent(caller, meth, (InvocationExprent)expr);
                        if (newexpr != null)
                        {
                            exprent.ReplaceExprent(expr, newexpr);
                            found = true;
                            res   = true;
                            break;
                        }
                    }
                }
                if (!found)
                {
                    break;
                }
            }
            return(res);
        }
示例#5
0
        private static void ReplaceSingleVar(Exprent parent, VarExprent var, Exprent dest
                                             , SSAUConstructorSparseEx ssau)
        {
            parent.ReplaceExprent(var, dest);
            // live sets
            SFormsFastMapDirect      livemap = ssau.GetLiveVarVersionsMap(new VarVersionPair(var));
            HashSet <VarVersionPair> setVars = GetAllVersions(dest);

            foreach (VarVersionPair varpaar in setVars)
            {
                VarVersionNode node      = ssau.GetSsuversions().nodes.GetWithKey(varpaar);
                var            toRemove  = new List <KeyValuePair <int, FastSparseSetFactory <int> .FastSparseSet <int> > >();
                var            entryList = node.live.EntryList();
                for (var index = 0; index < entryList.Count; index++)
                {
                    var itent = entryList[index];
                    KeyValuePair <int, FastSparseSetFactory <int> .FastSparseSet <int> > ent =
                        entryList.ElementAtOrDefault(index + 1);
                    if (ent.Value == null)
                    {
                        break;
                    }

                    int key = ent.Key;
                    if (!livemap.ContainsKey(key))
                    {
                        toRemove.Add(itent);
                    }
                    else
                    {
                        FastSparseSetFactory <int> .FastSparseSet <int> set = ent.Value;
                        set.Complement(livemap.Get(key));
                        if (set.IsEmpty())
                        {
                            toRemove.Add(itent);
                        }
                    }
                }

                foreach (var keyValuePair in toRemove)
                {
                    node.live.PutInternal(keyValuePair.Key, keyValuePair.Value, true);
                    // entryList.RemoveAll(c => c.Key == keyValuePair.Key);
                }
            }
        }
示例#6
0
        private Exprent ProcessExprentRecursive(Exprent exprent)
        {
            bool replaced = true;

            while (replaced)
            {
                replaced = false;
                foreach (Exprent expr in exprent.GetAllExprents())
                {
                    Exprent retexpr = ProcessExprentRecursive(expr);
                    if (retexpr != null)
                    {
                        exprent.ReplaceExprent(expr, retexpr);
                        replaced        = true;
                        exprentReplaced = true;
                        break;
                    }
                }
            }
            if (exprent.type == Exprent.Exprent_Assignment)
            {
                AssignmentExprent @as = (AssignmentExprent)exprent;
                if (@as.GetRight().type == Exprent.Exprent_Function)
                {
                    FunctionExprent func     = (FunctionExprent)@as.GetRight();
                    VarType         midlayer = null;
                    if (func.GetFuncType() >= FunctionExprent.Function_I2l && func.GetFuncType() <= FunctionExprent
                        .Function_I2s)
                    {
                        midlayer = func.GetSimpleCastType();
                        if (func.GetLstOperands()[0].type == Exprent.Exprent_Function)
                        {
                            func = (FunctionExprent)func.GetLstOperands()[0];
                        }
                        else
                        {
                            return(null);
                        }
                    }
                    if (func.GetFuncType() == FunctionExprent.Function_Add || func.GetFuncType() == FunctionExprent
                        .Function_Sub)
                    {
                        Exprent econd  = func.GetLstOperands()[0];
                        Exprent econst = func.GetLstOperands()[1];
                        if (econst.type != Exprent.Exprent_Const && econd.type == Exprent.Exprent_Const &&
                            func.GetFuncType() == FunctionExprent.Function_Add)
                        {
                            econd  = econst;
                            econst = func.GetLstOperands()[0];
                        }
                        if (econst.type == Exprent.Exprent_Const && ((ConstExprent)econst).HasValueOne())
                        {
                            Exprent left     = @as.GetLeft();
                            VarType condtype = econd.GetExprType();
                            if (left.Equals(econd) && (midlayer == null || midlayer.Equals(condtype)))
                            {
                                FunctionExprent ret = new FunctionExprent(func.GetFuncType() == FunctionExprent.Function_Add
                                                                         ? FunctionExprent.Function_Ppi : FunctionExprent.Function_Mmi, econd, func.bytecode
                                                                          );
                                ret.SetImplicitType(condtype);
                                exprentReplaced = true;
                                return(ret);
                            }
                        }
                    }
                }
            }
            return(null);
        }
示例#7
0
        private static object[] IterateChildExprent(Exprent exprent, Exprent parent, Exprent
                                                    next, Dictionary <VarVersionPair, Exprent> mapVarValues, SSAUConstructorSparseEx
                                                    ssau)
        {
            bool changed = false;

            foreach (Exprent expr in exprent.GetAllExprents())
            {
                var oldExpr = expr;
                while (true)
                {
                    object[] arr     = IterateChildExprent(oldExpr, parent, next, mapVarValues, ssau);
                    Exprent  retexpr = (Exprent)arr[0];
                    changed |= (bool)arr[1];
                    bool isReplaceable = (bool)arr[2];
                    if (retexpr != null)
                    {
                        if (isReplaceable)
                        {
                            ReplaceSingleVar(exprent, (VarExprent)oldExpr, retexpr, ssau);
                            oldExpr = retexpr;
                        }
                        else
                        {
                            exprent.ReplaceExprent(oldExpr, retexpr);
                        }
                        changed = true;
                    }
                    if (!isReplaceable)
                    {
                        break;
                    }
                }
            }
            Exprent dest = IsReplaceableVar(exprent, mapVarValues);

            if (dest != null)
            {
                return(new object[] { dest, true, true });
            }
            VarExprent left  = null;
            Exprent    right = null;

            if (exprent.type == Exprent.Exprent_Assignment)
            {
                AssignmentExprent @as = (AssignmentExprent)exprent;
                if (@as.GetLeft().type == Exprent.Exprent_Var)
                {
                    left  = (VarExprent)@as.GetLeft();
                    right = @as.GetRight();
                }
            }
            if (left == null)
            {
                return(new object[] { null, changed, false });
            }
            bool isHeadSynchronized = false;

            if (next == null && parent.type == Exprent.Exprent_Monitor)
            {
                MonitorExprent monexpr = (MonitorExprent)parent;
                if (monexpr.GetMonType() == MonitorExprent.Monitor_Enter && exprent.Equals(monexpr
                                                                                           .GetValue()))
                {
                    isHeadSynchronized = true;
                }
            }
            // stack variable or synchronized head exprent
            if (!left.IsStack() && !isHeadSynchronized)
            {
                return(new object[] { null, changed, false });
            }
            VarVersionPair        leftpaar = new VarVersionPair(left);
            List <VarVersionNode> usedVers = new List <VarVersionNode>();
            bool notdom = GetUsedVersions(ssau, leftpaar, usedVers);

            if (!notdom && (usedVers.Count == 0))
            {
                return(new object[] { right, changed, false });
            }
            // stack variables only
            if (!left.IsStack())
            {
                return(new object[] { null, changed, false });
            }
            int useflags = right.GetExprentUse();

            if ((useflags & Exprent.Both_Flags) != Exprent.Both_Flags)
            {
                return(new object[] { null, changed, false });
            }
            Dictionary <int, HashSet <VarVersionPair> > mapVars = GetAllVarVersions(leftpaar, right
                                                                                    , ssau);

            if (mapVars.ContainsKey(leftpaar.var) && notdom)
            {
                return(new object[] { null, changed, false });
            }
            Sharpen.Collections.Remove(mapVars, leftpaar.var);
            HashSet <VarVersionPair> setAllowedVars = GetAllVersions(parent);

            if (next != null)
            {
                Sharpen.Collections.AddAll(setAllowedVars, GetAllVersions(next));
            }
            bool vernotreplaced = false;
            HashSet <VarVersionPair> setTempUsedVers = new HashSet <VarVersionPair>();

            foreach (VarVersionNode usedvar in usedVers)
            {
                VarVersionPair usedver = new VarVersionPair(usedvar.var, usedvar.version);
                if (IsVersionToBeReplaced(usedver, mapVars, ssau, leftpaar) && (right.type == Exprent
                                                                                .Exprent_Var || setAllowedVars.Contains(usedver)))
                {
                    setTempUsedVers.Add(usedver);
                }
                else
                {
                    vernotreplaced = true;
                }
            }
            if (!notdom && !vernotreplaced)
            {
                foreach (VarVersionPair usedver in setTempUsedVers)
                {
                    Exprent copy = right.Copy();
                    if (right.type == Exprent.Exprent_Field && ssau.GetMapFieldVars().ContainsKey(right
                                                                                                  .id))
                    {
                        Sharpen.Collections.Put(ssau.GetMapFieldVars(), copy.id, ssau.GetMapFieldVars().GetOrNullable
                                                    (right.id));
                    }
                    Sharpen.Collections.Put(mapVarValues, usedver, copy);
                }
                // remove assignment
                return(new object[] { right, changed, false });
            }
            return(new object[] { null, changed, false });
        }
示例#8
0
        private int[] IterateExprent(List <Exprent> lstExprents, int index, Exprent next,
                                     Dictionary <VarVersionPair, Exprent> mapVarValues, SSAUConstructorSparseEx ssau)
        {
            Exprent exprent = lstExprents[index];
            int     changed = 0;

            foreach (Exprent expr in exprent.GetAllExprents())
            {
                var oldExpr = expr;
                while (true)
                {
                    object[] arr     = IterateChildExprent(oldExpr, exprent, next, mapVarValues, ssau);
                    Exprent  retexpr = (Exprent)arr[0];
                    changed |= (bool)arr[1] ? 1 : 0;
                    bool isReplaceable = (bool)arr[2];
                    if (retexpr != null)
                    {
                        if (isReplaceable)
                        {
                            ReplaceSingleVar(exprent, (VarExprent)oldExpr, retexpr, ssau);
                            oldExpr = retexpr;
                        }
                        else
                        {
                            exprent.ReplaceExprent(oldExpr, retexpr);
                        }
                        changed = 1;
                    }
                    if (!isReplaceable)
                    {
                        break;
                    }
                }
            }
            // no var on the highest level, so no replacing
            VarExprent left  = null;
            Exprent    right = null;

            if (exprent.type == Exprent.Exprent_Assignment)
            {
                AssignmentExprent @as = (AssignmentExprent)exprent;
                if (@as.GetLeft().type == Exprent.Exprent_Var)
                {
                    left  = (VarExprent)@as.GetLeft();
                    right = @as.GetRight();
                }
            }
            if (left == null)
            {
                return(new int[] { -1, changed });
            }
            VarVersionPair        leftpaar = new VarVersionPair(left);
            List <VarVersionNode> usedVers = new List <VarVersionNode>();
            bool notdom = GetUsedVersions(ssau, leftpaar, usedVers);

            if (!notdom && (usedVers.Count == 0))
            {
                if (left.IsStack() && (right.type == Exprent.Exprent_Invocation || right.type ==
                                       Exprent.Exprent_Assignment || right.type == Exprent.Exprent_New))
                {
                    if (right.type == Exprent.Exprent_New)
                    {
                        // new Object(); permitted
                        NewExprent nexpr = (NewExprent)right;
                        if (nexpr.IsAnonymous() || nexpr.GetNewType().arrayDim > 0 || nexpr.GetNewType().
                            type != ICodeConstants.Type_Object)
                        {
                            return(new int[] { -1, changed });
                        }
                    }
                    lstExprents[index] = right;
                    return(new int[] { index + 1, 1 });
                }
                else if (right.type == Exprent.Exprent_Var)
                {
                    lstExprents.RemoveAtReturningValue(index);
                    return(new int[] { index, 1 });
                }
                else
                {
                    return(new int[] { -1, changed });
                }
            }
            int useflags = right.GetExprentUse();

            // stack variables only
            if (!left.IsStack() && (right.type != Exprent.Exprent_Var || ((VarExprent)right).
                                    IsStack()))
            {
                // special case catch(... ex)
                return(new int[] { -1, changed });
            }
            if ((useflags & Exprent.Multiple_Uses) == 0 && (notdom || usedVers.Count > 1))
            {
                return(new int[] { -1, changed });
            }
            Dictionary <int, HashSet <VarVersionPair> > mapVars = GetAllVarVersions(leftpaar, right
                                                                                    , ssau);
            bool isSelfReference = mapVars.ContainsKey(leftpaar.var);

            if (isSelfReference && notdom)
            {
                return(new int[] { -1, changed });
            }
            HashSet <VarVersionPair> setNextVars = next == null ? null : GetAllVersions(next);

            // FIXME: fix the entire method!
            if (right.type != Exprent.Exprent_Const && right.type != Exprent.Exprent_Var && setNextVars
                != null && mapVars.ContainsKey(leftpaar.var))
            {
                foreach (VarVersionNode usedvar in usedVers)
                {
                    if (!setNextVars.Contains(new VarVersionPair(usedvar.var, usedvar.version)))
                    {
                        return(new int[] { -1, changed });
                    }
                }
            }
            Sharpen.Collections.Remove(mapVars, leftpaar.var);
            bool vernotreplaced = false;
            bool verreplaced    = false;
            HashSet <VarVersionPair> setTempUsedVers = new HashSet <VarVersionPair>();

            foreach (VarVersionNode usedvar in usedVers)
            {
                VarVersionPair usedver = new VarVersionPair(usedvar.var, usedvar.version);
                if (IsVersionToBeReplaced(usedver, mapVars, ssau, leftpaar) && (right.type == Exprent
                                                                                .Exprent_Const || right.type == Exprent.Exprent_Var || right.type == Exprent.Exprent_Field ||
                                                                                setNextVars == null || setNextVars.Contains(usedver)))
                {
                    setTempUsedVers.Add(usedver);
                    verreplaced = true;
                }
                else
                {
                    vernotreplaced = true;
                }
            }
            if (isSelfReference && vernotreplaced)
            {
                return(new int[] { -1, changed });
            }
            else
            {
                foreach (VarVersionPair usedver in setTempUsedVers)
                {
                    Exprent copy = right.Copy();
                    if (right.type == Exprent.Exprent_Field && ssau.GetMapFieldVars().ContainsKey(right
                                                                                                  .id))
                    {
                        Sharpen.Collections.Put(ssau.GetMapFieldVars(), copy.id, ssau.GetMapFieldVars().GetOrNullable
                                                    (right.id));
                    }
                    Sharpen.Collections.Put(mapVarValues, usedver, copy);
                }
            }
            if (!notdom && !vernotreplaced)
            {
                // remove assignment
                lstExprents.RemoveAtReturningValue(index);
                return(new int[] { index, 1 });
            }
            else if (verreplaced)
            {
                return(new int[] { index + 1, changed });
            }
            else
            {
                return(new int[] { -1, changed });
            }
        }
示例#9
0
        private static Exprent IdentifySecondaryFunctions(Exprent exprent, bool statement_level
                                                          , VarProcessor varProc)
        {
            if (exprent.type == Exprent.Exprent_Function)
            {
                FunctionExprent fexpr = (FunctionExprent)exprent;
                switch (fexpr.GetFuncType())
                {
                case FunctionExprent.Function_Bool_Not:
                {
                    Exprent retparam = PropagateBoolNot(fexpr);
                    if (retparam != null)
                    {
                        return(retparam);
                    }
                    break;
                }

                case FunctionExprent.Function_Eq:
                case FunctionExprent.Function_Ne:
                case FunctionExprent.Function_Gt:
                case FunctionExprent.Function_Ge:
                case FunctionExprent.Function_Lt:
                case FunctionExprent.Function_Le:
                {
                    Exprent expr1 = fexpr.GetLstOperands()[0];
                    Exprent expr2 = fexpr.GetLstOperands()[1];
                    if (expr1.type == Exprent.Exprent_Const)
                    {
                        expr2 = expr1;
                        expr1 = fexpr.GetLstOperands()[1];
                    }
                    if (expr1.type == Exprent.Exprent_Function && expr2.type == Exprent.Exprent_Const)
                    {
                        FunctionExprent funcexpr = (FunctionExprent)expr1;
                        ConstExprent    cexpr    = (ConstExprent)expr2;
                        int             functype = funcexpr.GetFuncType();
                        if (functype == FunctionExprent.Function_Lcmp || functype == FunctionExprent.Function_Fcmpg ||
                            functype == FunctionExprent.Function_Fcmpl || functype == FunctionExprent.Function_Dcmpg ||
                            functype == FunctionExprent.Function_Dcmpl)
                        {
                            int    desttype = -1;
                            int?[] destcons = mapNumComparisons.GetOrNull(fexpr.GetFuncType());
                            if (destcons != null)
                            {
                                int index = cexpr.GetIntValue() + 1;
                                if (index >= 0 && index <= 2)
                                {
                                    int?destcon = destcons[index];
                                    if (destcon != null)
                                    {
                                        desttype = destcon.Value;
                                    }
                                }
                            }
                            if (desttype >= 0)
                            {
                                return(new FunctionExprent(desttype, funcexpr.GetLstOperands(), funcexpr.bytecode
                                                           ));
                            }
                        }
                    }
                    break;
                }
                }
            }
            bool replaced = true;

            while (replaced)
            {
                replaced = false;
                foreach (Exprent expr in exprent.GetAllExprents())
                {
                    Exprent retexpr = IdentifySecondaryFunctions(expr, false, varProc);
                    if (retexpr != null)
                    {
                        exprent.ReplaceExprent(expr, retexpr);
                        replaced = true;
                        break;
                    }
                }
            }
            switch (exprent.type)
            {
            case Exprent.Exprent_Function:
            {
                FunctionExprent fexpr_1     = (FunctionExprent)exprent;
                List <Exprent>  lstOperands = fexpr_1.GetLstOperands();
                switch (fexpr_1.GetFuncType())
                {
                case FunctionExprent.Function_Xor:
                {
                    for (int i = 0; i < 2; i++)
                    {
                        Exprent operand     = lstOperands[i];
                        VarType operandtype = operand.GetExprType();
                        if (operand.type == Exprent.Exprent_Const && operandtype.type != ICodeConstants.Type_Boolean)
                        {
                            ConstExprent cexpr = (ConstExprent)operand;
                            long         val;
                            if (operandtype.type == ICodeConstants.Type_Long)
                            {
                                val = (long)cexpr.GetValue();
                            }
                            else
                            {
                                val = (int)cexpr.GetValue();
                            }
                            if (val == -1)
                            {
                                List <Exprent> lstBitNotOperand = new List <Exprent>();
                                lstBitNotOperand.Add(lstOperands[1 - i]);
                                return(new FunctionExprent(FunctionExprent.Function_Bit_Not, lstBitNotOperand, fexpr_1
                                                           .bytecode));
                            }
                        }
                    }
                    break;
                }

                case FunctionExprent.Function_Eq:
                case FunctionExprent.Function_Ne:
                {
                    if (lstOperands[0].GetExprType().type == ICodeConstants.Type_Boolean && lstOperands
                        [1].GetExprType().type == ICodeConstants.Type_Boolean)
                    {
                        for (int i = 0; i < 2; i++)
                        {
                            if (lstOperands[i].type == Exprent.Exprent_Const)
                            {
                                ConstExprent cexpr = (ConstExprent)lstOperands[i];
                                int          val   = (int)cexpr.GetValue();
                                if ((fexpr_1.GetFuncType() == FunctionExprent.Function_Eq && val == 1) || (fexpr_1
                                                                                                           .GetFuncType() == FunctionExprent.Function_Ne && val == 0))
                                {
                                    return(lstOperands[1 - i]);
                                }
                                else
                                {
                                    List <Exprent> lstNotOperand = new List <Exprent>();
                                    lstNotOperand.Add(lstOperands[1 - i]);
                                    return(new FunctionExprent(FunctionExprent.Function_Bool_Not, lstNotOperand, fexpr_1
                                                               .bytecode));
                                }
                            }
                        }
                    }
                    break;
                }

                case FunctionExprent.Function_Bool_Not:
                {
                    if (lstOperands[0].type == Exprent.Exprent_Const)
                    {
                        int val = ((ConstExprent)lstOperands[0]).GetIntValue();
                        if (val == 0)
                        {
                            return(new ConstExprent(VarType.Vartype_Boolean, 1, fexpr_1.bytecode));
                        }
                        else
                        {
                            return(new ConstExprent(VarType.Vartype_Boolean, 0, fexpr_1.bytecode));
                        }
                    }
                    break;
                }

                case FunctionExprent.Function_Iif:
                {
                    Exprent expr1_1 = lstOperands[1];
                    Exprent expr2_1 = lstOperands[2];
                    if (expr1_1.type == Exprent.Exprent_Const && expr2_1.type == Exprent.Exprent_Const)
                    {
                        ConstExprent cexpr1 = (ConstExprent)expr1_1;
                        ConstExprent cexpr2 = (ConstExprent)expr2_1;
                        if (cexpr1.GetExprType().type == ICodeConstants.Type_Boolean && cexpr2.GetExprType
                                ().type == ICodeConstants.Type_Boolean)
                        {
                            if (cexpr1.GetIntValue() == 0 && cexpr2.GetIntValue() != 0)
                            {
                                return(new FunctionExprent(FunctionExprent.Function_Bool_Not, lstOperands[0], fexpr_1
                                                           .bytecode));
                            }
                            else if (cexpr1.GetIntValue() != 0 && cexpr2.GetIntValue() == 0)
                            {
                                return(lstOperands[0]);
                            }
                        }
                    }
                    break;
                }

                case FunctionExprent.Function_Lcmp:
                case FunctionExprent.Function_Fcmpl:
                case FunctionExprent.Function_Fcmpg:
                case FunctionExprent.Function_Dcmpl:
                case FunctionExprent.Function_Dcmpg:
                {
                    int var = DecompilerContext.GetCounterContainer().GetCounterAndIncrement(CounterContainer
                                                                                             .Var_Counter);
                    VarType         type = lstOperands[0].GetExprType();
                    FunctionExprent iff  = new FunctionExprent(FunctionExprent.Function_Iif, Sharpen.Arrays.AsList <Exprent>
                                                                   (new FunctionExprent(FunctionExprent.Function_Lt, Sharpen.Arrays.AsList <Exprent>(new VarExprent
                                                                                                                                                         (var, type, varProc), ConstExprent.GetZeroConstant(type.type)), null), new ConstExprent
                                                                       (VarType.Vartype_Int, -1, null), new ConstExprent(VarType.Vartype_Int, 1, null))
                                                               , null);
                    FunctionExprent head = new FunctionExprent(FunctionExprent.Function_Eq, Sharpen.Arrays.AsList <Exprent>
                                                                   (new AssignmentExprent(new VarExprent(var, type, varProc), new FunctionExprent(FunctionExprent
                                                                                                                                                  .Function_Sub, Sharpen.Arrays.AsList(lstOperands[0], lstOperands[1]), null), null
                                                                                          ), ConstExprent.GetZeroConstant(type.type)), null);
                    varProc.SetVarType(new VarVersionPair(var, 0), type);
                    return(new FunctionExprent(FunctionExprent.Function_Iif, Sharpen.Arrays.AsList <Exprent>(head
                                                                                                             , new ConstExprent(VarType.Vartype_Int, 0, null), iff), fexpr_1.bytecode));
                }
                }
                break;
            }

            case Exprent.Exprent_Assignment:
            {
                // check for conditional assignment
                AssignmentExprent asexpr = (AssignmentExprent)exprent;
                Exprent           right  = asexpr.GetRight();
                Exprent           left   = asexpr.GetLeft();
                if (right.type == Exprent.Exprent_Function)
                {
                    FunctionExprent func     = (FunctionExprent)right;
                    VarType         midlayer = null;
                    if (func.GetFuncType() >= FunctionExprent.Function_I2l && func.GetFuncType() <= FunctionExprent
                        .Function_I2s)
                    {
                        right    = func.GetLstOperands()[0];
                        midlayer = func.GetSimpleCastType();
                        if (right.type == Exprent.Exprent_Function)
                        {
                            func = (FunctionExprent)right;
                        }
                        else
                        {
                            return(null);
                        }
                    }
                    List <Exprent> lstFuncOperands = func.GetLstOperands();
                    Exprent        cond            = null;
                    switch (func.GetFuncType())
                    {
                    case FunctionExprent.Function_Add:
                    case FunctionExprent.Function_And:
                    case FunctionExprent.Function_Or:
                    case FunctionExprent.Function_Xor:
                    {
                        if (left.Equals(lstFuncOperands[1]))
                        {
                            cond = lstFuncOperands[0];
                            break;
                        }
                        goto case FunctionExprent.Function_Sub;
                    }

                    case FunctionExprent.Function_Sub:
                    case FunctionExprent.Function_Mul:
                    case FunctionExprent.Function_Div:
                    case FunctionExprent.Function_Rem:
                    case FunctionExprent.Function_Shl:
                    case FunctionExprent.Function_Shr:
                    case FunctionExprent.Function_Ushr:
                    {
                        if (left.Equals(lstFuncOperands[0]))
                        {
                            cond = lstFuncOperands[1];
                        }
                        break;
                    }
                    }
                    if (cond != null && (midlayer == null || midlayer.Equals(cond.GetExprType())))
                    {
                        asexpr.SetRight(cond);
                        asexpr.SetCondType(func.GetFuncType());
                    }
                }
                break;
            }

            case Exprent.Exprent_Invocation:
            {
                if (!statement_level)
                {
                    // simplify if exprent is a real expression. The opposite case is pretty absurd, can still happen however (and happened at least once).
                    Exprent retexpr = ConcatenationHelper.ContractStringConcat(exprent);
                    if (!exprent.Equals(retexpr))
                    {
                        return(retexpr);
                    }
                }
                break;
            }
            }
            return(null);
        }