示例#1
0
 private static void ResetExprentTypes(DirectGraph graph)
 {
     graph.IterateExprents((Exprent exprent) => {
         List <Exprent> lst = exprent.GetAllExprents(true);
         lst.Add(exprent);
         foreach (Exprent expr in lst)
         {
             if (expr.type == Exprent.Exprent_Var)
             {
                 ((VarExprent)expr).SetVarType(VarType.Vartype_Unknown);
             }
             else if (expr.type == Exprent.Exprent_Const)
             {
                 ConstExprent constExpr = (ConstExprent)expr;
                 if (constExpr.GetConstType().typeFamily == ICodeConstants.Type_Family_Integer)
                 {
                     constExpr.SetConstType(new ConstExprent(constExpr.GetIntValue(), constExpr.IsBoolPermitted
                                                                 (), null).GetConstType());
                 }
             }
         }
         return(0);
     }
                           );
 }
示例#2
0
        private static StructField FindAssertionField(ClassesProcessor.ClassNode node)
        {
            ClassWrapper wrapper     = node.GetWrapper();
            bool         noSynthFlag = DecompilerContext.GetOption(IFernflowerPreferences.Synthetic_Not_Set
                                                                   );

            foreach (StructField fd in wrapper.GetClassStruct().GetFields())
            {
                string keyField = InterpreterUtil.MakeUniqueKey(fd.GetName(), fd.GetDescriptor());
                // initializer exists
                if (wrapper.GetStaticFieldInitializers().ContainsKey(keyField))
                {
                    // access flags set
                    if (fd.HasModifier(ICodeConstants.Acc_Static) && fd.HasModifier(ICodeConstants.Acc_Final
                                                                                    ) && (noSynthFlag || fd.IsSynthetic()))
                    {
                        // field type boolean
                        FieldDescriptor fdescr = FieldDescriptor.ParseDescriptor(fd.GetDescriptor());
                        if (VarType.Vartype_Boolean.Equals(fdescr.type))
                        {
                            Exprent initializer = wrapper.GetStaticFieldInitializers().GetWithKey(keyField);
                            if (initializer.type == Exprent.Exprent_Function)
                            {
                                FunctionExprent fexpr = (FunctionExprent)initializer;
                                if (fexpr.GetFuncType() == FunctionExprent.Function_Bool_Not && fexpr.GetLstOperands
                                        ()[0].type == Exprent.Exprent_Invocation)
                                {
                                    InvocationExprent invexpr = (InvocationExprent)fexpr.GetLstOperands()[0];
                                    if (invexpr.GetInstance() != null && invexpr.GetInstance().type == Exprent.Exprent_Const &&
                                        "desiredAssertionStatus".Equals(invexpr.GetName()) && "java/lang/Class".Equals
                                            (invexpr.GetClassname()) && (invexpr.GetLstParameters().Count == 0))
                                    {
                                        ConstExprent cexpr = (ConstExprent)invexpr.GetInstance();
                                        if (VarType.Vartype_Class.Equals(cexpr.GetConstType()))
                                        {
                                            ClassesProcessor.ClassNode nd = node;
                                            while (nd != null)
                                            {
                                                if (nd.GetWrapper().GetClassStruct().qualifiedName.Equals(cexpr.GetValue()))
                                                {
                                                    break;
                                                }
                                                nd = nd.parent;
                                            }
                                            if (nd != null)
                                            {
                                                // found enclosing class with the same name
                                                return(fd);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return(null);
        }
示例#3
0
 private static bool AddArrayInitializer(Exprent first, Exprent second)
 {
     if (first.type == Exprent.Exprent_Assignment)
     {
         AssignmentExprent @as = (AssignmentExprent)first;
         if (@as.GetRight().type == Exprent.Exprent_New && @as.GetLeft().type == Exprent.Exprent_Var)
         {
             NewExprent newExpr = (NewExprent)@as.GetRight();
             if (!(newExpr.GetLstArrayElements().Count == 0))
             {
                 VarExprent arrVar = (VarExprent)@as.GetLeft();
                 if (second.type == Exprent.Exprent_Assignment)
                 {
                     AssignmentExprent aas = (AssignmentExprent)second;
                     if (aas.GetLeft().type == Exprent.Exprent_Array)
                     {
                         ArrayExprent arrExpr = (ArrayExprent)aas.GetLeft();
                         if (arrExpr.GetArray().type == Exprent.Exprent_Var && arrVar.Equals(arrExpr.GetArray
                                                                                                 ()) && arrExpr.GetIndex().type == Exprent.Exprent_Const)
                         {
                             int constValue = ((ConstExprent)arrExpr.GetIndex()).GetIntValue();
                             if (constValue < newExpr.GetLstArrayElements().Count)
                             {
                                 Exprent init = newExpr.GetLstArrayElements()[constValue];
                                 if (init.type == Exprent.Exprent_Const)
                                 {
                                     ConstExprent cinit      = (ConstExprent)init;
                                     VarType      arrType    = newExpr.GetNewType().DecreaseArrayDim();
                                     ConstExprent defaultVal = ExprProcessor.GetDefaultArrayValue(arrType);
                                     if (cinit.Equals(defaultVal))
                                     {
                                         Exprent tempExpr = aas.GetRight();
                                         if (!tempExpr.ContainsExprent(arrVar))
                                         {
                                             newExpr.GetLstArrayElements()[constValue] = tempExpr;
                                             if (tempExpr.type == Exprent.Exprent_New)
                                             {
                                                 NewExprent tempNewExpr = (NewExprent)tempExpr;
                                                 int        dims        = newExpr.GetNewType().arrayDim;
                                                 if (dims > 1 && !(tempNewExpr.GetLstArrayElements().Count == 0))
                                                 {
                                                     tempNewExpr.SetDirectArrayInit(true);
                                                 }
                                             }
                                             return(true);
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
     return(false);
 }
        private static void ProcessClassRec(ClassesProcessor.ClassNode node, IDictionary
                                            <ClassWrapper, MethodWrapper> mapClassMeths, HashSet <ClassWrapper> setFound)
        {
            ClassWrapper wrapper = node.GetWrapper();

            // search code
            foreach (MethodWrapper meth in wrapper.GetMethods())
            {
                RootStatement root = meth.root;
                if (root != null)
                {
                    DirectGraph graph = meth.GetOrBuildGraph();
                    graph.IterateExprents((Exprent exprent) => {
                        foreach (KeyValuePair <ClassWrapper, MethodWrapper> ent in mapClassMeths)
                        {
                            if (ReplaceInvocations(exprent, ent.Key, ent.Value))
                            {
                                setFound.Add(ent.Key);
                            }
                        }
                        return(0);
                    }
                                          );
                }
            }
            // search initializers
            for (int j = 0; j < 2; j++)
            {
                VBStyleCollection <Exprent, string> initializers = j == 0 ? wrapper.GetStaticFieldInitializers
                                                                       () : wrapper.GetDynamicFieldInitializers();
                for (int i = 0; i < initializers.Count; i++)
                {
                    foreach (KeyValuePair <ClassWrapper, MethodWrapper> ent in mapClassMeths)
                    {
                        Exprent exprent = initializers[i];
                        if (ReplaceInvocations(exprent, ent.Key, ent.Value))
                        {
                            setFound.Add(ent.Key);
                        }
                        string cl = IsClass14Invocation(exprent, ent.Key, ent.Value);
                        if (cl != null)
                        {
                            initializers[i] = new ConstExprent(VarType.Vartype_Class, cl.Replace('.', '/'), exprent
                                                               .bytecode);
                            setFound.Add(ent.Key);
                        }
                    }
                }
            }
            // iterate nested classes
            foreach (ClassesProcessor.ClassNode nd in node.nested)
            {
                ProcessClassRec(nd, mapClassMeths, setFound);
            }
        }
示例#5
0
        private bool CheckTypeExprent(Exprent exprent)
        {
            foreach (Exprent expr in exprent.GetAllExprents())
            {
                if (!CheckTypeExprent(expr))
                {
                    return(false);
                }
            }
            if (exprent.type == Exprent.Exprent_Const)
            {
                ConstExprent constExpr = (ConstExprent)exprent;
                if (constExpr.GetConstType().typeFamily <= ICodeConstants.Type_Family_Integer)
                {
                    // boolean or integer
                    VarVersionPair pair = new VarVersionPair(constExpr.id, -1);
                    if (!mapExprentMinTypes.ContainsKey(pair))
                    {
                        Sharpen.Collections.Put(mapExprentMinTypes, pair, constExpr.GetConstType());
                    }
                }
            }
            CheckTypesResult result = exprent.CheckExprTypeBounds();
            bool             res    = true;

            if (result != null)
            {
                foreach (CheckTypesResult.ExprentTypePair entry in result.GetLstMaxTypeExprents())
                {
                    if (entry.type.typeFamily != ICodeConstants.Type_Family_Object)
                    {
                        ChangeExprentType(entry.exprent, entry.type, 1);
                    }
                }
                foreach (CheckTypesResult.ExprentTypePair entry in result.GetLstMinTypeExprents())
                {
                    res &= ChangeExprentType(entry.exprent, entry.type, 0);
                }
            }
            return(res);
        }
示例#6
0
        private static int IsArrayInitializer(List <Exprent> list, int index)
        {
            Exprent current = list[index];

            if (current.type == Exprent.Exprent_Assignment)
            {
                AssignmentExprent @as = (AssignmentExprent)current;
                if (@as.GetRight().type == Exprent.Exprent_New && @as.GetLeft().type == Exprent.Exprent_Var)
                {
                    NewExprent newExpr = (NewExprent)@as.GetRight();
                    if (newExpr.GetExprType().arrayDim > 0 && newExpr.GetLstDims().Count == 1 && (newExpr
                                                                                                  .GetLstArrayElements().Count == 0) && newExpr.GetLstDims()[0].type == Exprent.Exprent_Const)
                    {
                        int size = (int)((ConstExprent)newExpr.GetLstDims()[0]).GetValue();
                        if (size == 0)
                        {
                            return(0);
                        }
                        VarExprent arrVar = (VarExprent)@as.GetLeft();
                        Dictionary <int, Exprent> mapInit = new Dictionary <int, Exprent>();
                        int i = 1;
                        while (index + i < list.Count && i <= size)
                        {
                            bool    found = false;
                            Exprent expr  = list[index + i];
                            if (expr.type == Exprent.Exprent_Assignment)
                            {
                                AssignmentExprent aas = (AssignmentExprent)expr;
                                if (aas.GetLeft().type == Exprent.Exprent_Array)
                                {
                                    ArrayExprent arrExpr = (ArrayExprent)aas.GetLeft();
                                    if (arrExpr.GetArray().type == Exprent.Exprent_Var && arrVar.Equals(arrExpr.GetArray
                                                                                                            ()) && arrExpr.GetIndex().type == Exprent.Exprent_Const)
                                    {
                                        // TODO: check for a number type. Failure extremely improbable, but nevertheless...
                                        int constValue = ((ConstExprent)arrExpr.GetIndex()).GetIntValue();
                                        if (constValue < size && !mapInit.ContainsKey(constValue))
                                        {
                                            if (!aas.GetRight().ContainsExprent(arrVar))
                                            {
                                                Sharpen.Collections.Put(mapInit, constValue, aas.GetRight());
                                                found = true;
                                            }
                                        }
                                    }
                                }
                            }
                            if (!found)
                            {
                                break;
                            }
                            i++;
                        }
                        double fraction = ((double)mapInit.Count) / size;
                        if ((arrVar.IsStack() && fraction > 0) || (size <= 7 && fraction >= 0.3) || (size
                                                                                                     > 7 && fraction >= 0.7))
                        {
                            List <Exprent> lstRet     = new List <Exprent>();
                            VarType        arrayType  = newExpr.GetNewType().DecreaseArrayDim();
                            ConstExprent   defaultVal = ExprProcessor.GetDefaultArrayValue(arrayType);
                            for (int j = 0; j < size; j++)
                            {
                                lstRet.Add(defaultVal.Copy());
                            }
                            int dims = newExpr.GetNewType().arrayDim;
                            foreach (KeyValuePair <int, Exprent> ent in mapInit)
                            {
                                Exprent tempExpr = ent.Value;
                                lstRet[ent.Key] = tempExpr;
                                if (tempExpr.type == Exprent.Exprent_New)
                                {
                                    NewExprent tempNewExpr = (NewExprent)tempExpr;
                                    if (dims > 1 && !(tempNewExpr.GetLstArrayElements().Count == 0))
                                    {
                                        tempNewExpr.SetDirectArrayInit(true);
                                    }
                                }
                            }
                            newExpr.SetLstArrayElements(lstRet);
                            return(mapInit.Count);
                        }
                    }
                }
            }
            return(0);
        }
示例#7
0
        private bool ChangeExprentType(Exprent exprent, VarType newType, int minMax)
        {
            bool res = true;

            switch (exprent.type)
            {
            case Exprent.Exprent_Const:
            {
                ConstExprent constExpr = (ConstExprent)exprent;
                VarType      constType = constExpr.GetConstType();
                if (newType.typeFamily > ICodeConstants.Type_Family_Integer || constType.typeFamily
                    > ICodeConstants.Type_Family_Integer)
                {
                    return(true);
                }
                else if (newType.typeFamily == ICodeConstants.Type_Family_Integer)
                {
                    VarType minInteger = new ConstExprent((int)constExpr.GetValue(), false, null).GetConstType
                                             ();
                    if (minInteger.IsStrictSuperset(newType))
                    {
                        newType = minInteger;
                    }
                }
                goto case Exprent.Exprent_Var;
            }

            case Exprent.Exprent_Var:
            {
                VarVersionPair pair = null;
                if (exprent.type == Exprent.Exprent_Const)
                {
                    pair = new VarVersionPair(((ConstExprent)exprent).id, -1);
                }
                else if (exprent.type == Exprent.Exprent_Var)
                {
                    pair = new VarVersionPair((VarExprent)exprent);
                }
                if (minMax == 0)
                {
                    // min
                    VarType currentMinType = mapExprentMinTypes.GetOrNull(pair);
                    VarType newMinType;
                    if (currentMinType == null || newType.typeFamily > currentMinType.typeFamily)
                    {
                        newMinType = newType;
                    }
                    else if (newType.typeFamily < currentMinType.typeFamily)
                    {
                        return(true);
                    }
                    else
                    {
                        newMinType = VarType.GetCommonSupertype(currentMinType, newType);
                    }
                    Sharpen.Collections.Put(mapExprentMinTypes, pair, newMinType);
                    if (exprent.type == Exprent.Exprent_Const)
                    {
                        ((ConstExprent)exprent).SetConstType(newMinType);
                    }
                    if (currentMinType != null && (newMinType.typeFamily > currentMinType.typeFamily ||
                                                   newMinType.IsStrictSuperset(currentMinType)))
                    {
                        return(false);
                    }
                }
                else
                {
                    // max
                    VarType currentMaxType = mapExprentMaxTypes.GetOrNull(pair);
                    VarType newMaxType;
                    if (currentMaxType == null || newType.typeFamily < currentMaxType.typeFamily)
                    {
                        newMaxType = newType;
                    }
                    else if (newType.typeFamily > currentMaxType.typeFamily)
                    {
                        return(true);
                    }
                    else
                    {
                        newMaxType = VarType.GetCommonMinType(currentMaxType, newType);
                    }
                    Sharpen.Collections.Put(mapExprentMaxTypes, pair, newMaxType);
                }
                break;
            }

            case Exprent.Exprent_Assignment:
            {
                return(ChangeExprentType(((AssignmentExprent)exprent).GetRight(), newType, minMax
                                         ));
            }

            case Exprent.Exprent_Function:
            {
                FunctionExprent func = (FunctionExprent)exprent;
                switch (func.GetFuncType())
                {
                case FunctionExprent.Function_Iif:
                {
                    // FIXME:
                    res = ChangeExprentType(func.GetLstOperands()[1], newType, minMax) & ChangeExprentType
                              (func.GetLstOperands()[2], newType, minMax);
                    break;
                }

                case FunctionExprent.Function_And:
                case FunctionExprent.Function_Or:
                case FunctionExprent.Function_Xor:
                {
                    res = ChangeExprentType(func.GetLstOperands()[0], newType, minMax) & ChangeExprentType
                              (func.GetLstOperands()[1], newType, minMax);
                    break;
                }
                }
                break;
            }
            }
            return(res);
        }
示例#8
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);
        }