public override CheckTypesResult CheckExprTypeBounds()
        {
            CheckTypesResult result = new CheckTypesResult();

            result.AddMinTypeExprent(value, VarType.Vartype_Bytechar);
            result.AddMaxTypeExprent(value, VarType.Vartype_Int);
            VarType valType = value.GetExprType();

            foreach (List <Exprent> lst in caseValues)
            {
                foreach (Exprent expr in lst)
                {
                    if (expr != null)
                    {
                        VarType caseType = expr.GetExprType();
                        if (!caseType.Equals(valType))
                        {
                            valType = VarType.GetCommonSupertype(caseType, valType);
                            result.AddMinTypeExprent(value, valType);
                        }
                    }
                }
            }
            return(result);
        }
Exemple #2
0
        public override bool Equals(object obj)
        {
            PointerVarType v2 = (obj as PointerVarType);

            if (v2 == null)
            {
                return(false);
            }
            return(pointedToType.Equals(v2.pointedToType));
        }
Exemple #3
0
        public override bool Equals(object obj)
        {
            ArrayVarType v2 = (obj as ArrayVarType);

            if (v2 == null)
            {
                return(false);
            }
            return(baseType.Equals(v2.baseType) && this.arrayDimensions.SequenceEqual(v2.arrayDimensions));
        }
Exemple #4
0
 public virtual void AdjustConstType(VarType expectedType)
 {
     // BYTECHAR and SHORTCHAR => CHAR in the CHAR context
     if ((expectedType.Equals(VarType.Vartype_Char) || expectedType.Equals(VarType.Vartype_Character
                                                                           )) && (constType.Equals(VarType.Vartype_Bytechar) || constType.Equals(VarType.Vartype_Shortchar
                                                                                                                                                 )))
     {
         int intValue = GetIntValue();
         if (IsPrintableAscii(intValue) || Char_Escapes.ContainsKey(intValue))
         {
             SetConstType(VarType.Vartype_Char);
         }
     }
     else if ((expectedType.Equals(VarType.Vartype_Int) || expectedType.Equals(VarType
                                                                               .Vartype_Integer)) && constType.typeFamily == ICodeConstants.Type_Family_Integer)
     {
         // BYTE, BYTECHAR, SHORTCHAR, SHORT, CHAR => INT in the INT context
         SetConstType(VarType.Vartype_Int);
     }
 }
Exemple #5
0
        private static bool IsAppendConcat(InvocationExprent expr, VarType cltype)
        {
            if ("append".Equals(expr.GetName()))
            {
                MethodDescriptor md = expr.GetDescriptor();
                if (md.ret.Equals(cltype) && [email protected] == 1)
                {
                    VarType param = md.@params[0];
                    switch (param.type)
                    {
                    case ICodeConstants.Type_Object:
                    {
                        if (!param.Equals(VarType.Vartype_String) && !param.Equals(VarType.Vartype_Object
                                                                                   ))
                        {
                            break;
                        }
                        goto case ICodeConstants.Type_Boolean;
                    }

                    case ICodeConstants.Type_Boolean:
                    case ICodeConstants.Type_Char:
                    case ICodeConstants.Type_Double:
                    case ICodeConstants.Type_Float:
                    case ICodeConstants.Type_Int:
                    case ICodeConstants.Type_Long:
                    {
                        return(true);
                    }

                    default:
                    {
                        break;
                    }
                    }
                }
            }
            return(false);
        }
Exemple #6
0
        public override VarType GetExprType()
        {
            VarType exprType = array.GetExprType();

            if (exprType.Equals(VarType.Vartype_Null))
            {
                return(hardType.Copy());
            }
            else
            {
                return(exprType.DecreaseArrayDim());
            }
        }
Exemple #7
0
        private static Exprent RemoveStringValueOf(Exprent exprent)
        {
            if (exprent.type == Exprent.Exprent_Invocation)
            {
                InvocationExprent iex = (InvocationExprent)exprent;
                if ("valueOf".Equals(iex.GetName()) && stringClass.Equals(iex.GetClassname()))
                {
                    MethodDescriptor md = iex.GetDescriptor();
                    if ([email protected] == 1)
                    {
                        VarType param = md.@params[0];
                        switch (param.type)
                        {
                        case ICodeConstants.Type_Object:
                        {
                            if (!param.Equals(VarType.Vartype_Object))
                            {
                                break;
                            }
                            goto case ICodeConstants.Type_Boolean;
                        }

                        case ICodeConstants.Type_Boolean:
                        case ICodeConstants.Type_Char:
                        case ICodeConstants.Type_Double:
                        case ICodeConstants.Type_Float:
                        case ICodeConstants.Type_Int:
                        case ICodeConstants.Type_Long:
                        {
                            return(iex.GetLstParameters()[0]);
                        }
                        }
                    }
                }
            }
            return(exprent);
        }
Exemple #8
0
        private static InvocationExprent IsAssertionError(Statement stat)
        {
            if (stat == null || stat.GetExprents() == null || stat.GetExprents().Count != 1)
            {
                return(null);
            }
            Exprent expr = stat.GetExprents()[0];

            if (expr.type == Exprent.Exprent_Exit)
            {
                ExitExprent exexpr = (ExitExprent)expr;
                if (exexpr.GetExitType() == ExitExprent.Exit_Throw && exexpr.GetValue().type == Exprent
                    .Exprent_New)
                {
                    NewExprent nexpr = (NewExprent)exexpr.GetValue();
                    if (Class_Assertion_Error.Equals(nexpr.GetNewType()) && nexpr.GetConstructor() !=
                        null)
                    {
                        return(nexpr.GetConstructor());
                    }
                }
            }
            return(null);
        }
        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);
        }
Exemple #10
0
        private void SetNewVarIndices(VarTypeProcessor typeProcessor, DirectGraph graph,
                                      VarVersionsProcessor previousVersionsProcessor)
        {
            Dictionary <VarVersionPair, VarType> mapExprentMaxTypes = typeProcessor.GetMapExprentMaxTypes
                                                                          ();
            Dictionary <VarVersionPair, VarType> mapExprentMinTypes = typeProcessor.GetMapExprentMinTypes
                                                                          ();
            Dictionary <VarVersionPair, int> mapFinalVars = typeProcessor.GetMapFinalVars();
            CounterContainer counters = DecompilerContext.GetCounterContainer();
            Dictionary <VarVersionPair, int> mapVarPaar = new Dictionary <VarVersionPair, int>
                                                              ();
            Dictionary <int, int> mapOriginalVarIndices = new Dictionary <int, int>();

            // map var-version pairs on new var indexes
            foreach (VarVersionPair pair in new List <VarVersionPair>(mapExprentMinTypes.Keys))
            {
                if (pair.version >= 0)
                {
                    int newIndex = pair.version == 1 ? pair.var : counters.GetCounterAndIncrement(CounterContainer
                                                                                                  .Var_Counter);
                    VarVersionPair newVar = new VarVersionPair(newIndex, 0);
                    Sharpen.Collections.Put(mapExprentMinTypes, newVar, mapExprentMinTypes.GetOrNull(
                                                pair));
                    Sharpen.Collections.Put(mapExprentMaxTypes, newVar, mapExprentMaxTypes.GetOrNull(
                                                pair));
                    if (mapFinalVars.ContainsKey(pair))
                    {
                        Sharpen.Collections.Put(mapFinalVars, newVar, Sharpen.Collections.Remove(mapFinalVars
                                                                                                 , pair));
                    }
                    Sharpen.Collections.Put(mapVarPaar, pair, newIndex);
                    Sharpen.Collections.Put(mapOriginalVarIndices, newIndex, pair.var);
                }
            }
            // set new vars
            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 newVar = (VarExprent)expr;
                        int?newVarIndex   = mapVarPaar.GetOrNullable(new VarVersionPair(newVar));
                        if (newVarIndex != null)
                        {
                            newVar.SetIndex(newVarIndex.Value);
                            newVar.SetVersion(0);
                        }
                    }
                    else if (expr.type == Exprent.Exprent_Const)
                    {
                        VarType maxType = mapExprentMaxTypes.GetOrNull(new VarVersionPair(expr.id, -1));
                        if (maxType != null && maxType.Equals(VarType.Vartype_Char))
                        {
                            ((ConstExprent)expr).SetConstType(maxType);
                        }
                    }
                }
                return(0);
            }
                                  );
            if (previousVersionsProcessor != null)
            {
                Dictionary <int, int> oldIndices = previousVersionsProcessor.GetMapOriginalVarIndices
                                                       ();
                this.mapOriginalVarIndices = new Dictionary <int, int>(mapOriginalVarIndices.Count
                                                                       );
                foreach (KeyValuePair <int, int> entry in mapOriginalVarIndices)
                {
                    int value    = entry.Value;
                    int?oldValue = oldIndices.GetOrNullable(value);
                    value = oldValue != null ? oldValue.Value : value;
                    Sharpen.Collections.Put(this.mapOriginalVarIndices, entry.Key, value);
                }
            }
            else
            {
                this.mapOriginalVarIndices = mapOriginalVarIndices;
            }
        }
Exemple #11
0
        private static void SimpleMerge(VarTypeProcessor typeProcessor, DirectGraph graph
                                        , StructMethod mt)
        {
            Dictionary <VarVersionPair, VarType> mapExprentMaxTypes = typeProcessor.GetMapExprentMaxTypes
                                                                          ();
            Dictionary <VarVersionPair, VarType> mapExprentMinTypes = typeProcessor.GetMapExprentMinTypes
                                                                          ();
            Dictionary <int, HashSet <int> > mapVarVersions = new Dictionary <int, HashSet <int> >
                                                                  ();

            foreach (VarVersionPair pair in mapExprentMinTypes.Keys)
            {
                if (pair.version >= 0)
                {
                    // don't merge constants
                    mapVarVersions.ComputeIfAbsent(pair.var, (int k) => new HashSet <int>()).Add(pair.
                                                                                                 version);
                }
            }
            bool is_method_static = mt.HasModifier(ICodeConstants.Acc_Static);
            Dictionary <VarVersionPair, int> mapMergedVersions = new Dictionary <VarVersionPair
                                                                                 , int>();

            foreach (KeyValuePair <int, HashSet <int> > ent in mapVarVersions)
            {
                if (ent.Value.Count > 1)
                {
                    List <int> lstVersions = new List <int>(ent.Value);
                    lstVersions.Sort();
                    for (int i = 0; i < lstVersions.Count; i++)
                    {
                        VarVersionPair firstPair = new VarVersionPair(ent.Key, lstVersions[i]);
                        VarType        firstType = mapExprentMinTypes.GetOrNull(firstPair);
                        if (firstPair.var == 0 && firstPair.version == 1 && !is_method_static)
                        {
                            continue;
                        }
                        // don't merge 'this' variable
                        for (int j = i + 1; j < lstVersions.Count; j++)
                        {
                            VarVersionPair secondPair = new VarVersionPair(ent.Key, lstVersions[j]);
                            VarType        secondType = mapExprentMinTypes.GetOrNull(secondPair);
                            if (firstType.Equals(secondType) || (firstType.Equals(VarType.Vartype_Null) && secondType
                                                                 .type == ICodeConstants.Type_Object) || (secondType.Equals(VarType.Vartype_Null) &&
                                                                                                          firstType.type == ICodeConstants.Type_Object))
                            {
                                VarType firstMaxType  = mapExprentMaxTypes.GetOrNull(firstPair);
                                VarType secondMaxType = mapExprentMaxTypes.GetOrNull(secondPair);
                                VarType type          = firstMaxType == null ? secondMaxType : secondMaxType == null ? firstMaxType
                                                                         : VarType.GetCommonMinType(firstMaxType, secondMaxType);
                                Sharpen.Collections.Put(mapExprentMaxTypes, firstPair, type);
                                Sharpen.Collections.Put(mapMergedVersions, secondPair, firstPair.version);
                                Sharpen.Collections.Remove(mapExprentMaxTypes, secondPair);
                                Sharpen.Collections.Remove(mapExprentMinTypes, secondPair);
                                if (firstType.Equals(VarType.Vartype_Null))
                                {
                                    Sharpen.Collections.Put(mapExprentMinTypes, firstPair, secondType);
                                    firstType = secondType;
                                }
                                Sharpen.Collections.Put(typeProcessor.GetMapFinalVars(), firstPair, VarTypeProcessor
                                                        .Var_Non_Final);
                                lstVersions.RemoveAtReturningValue(j);
                                //noinspection AssignmentToForLoopParameter
                                j--;
                            }
                        }
                    }
                }
            }
            if (!(mapMergedVersions.Count == 0))
            {
                UpdateVersions(graph, mapMergedVersions);
            }
        }
Exemple #12
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);
        }
        public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer)
        {
            VarType leftType         = left.GetExprType();
            VarType rightType        = right.GetExprType();
            bool    fieldInClassInit = false;
            bool    hiddenField      = false;

            if (left.type == Exprent.Exprent_Field)
            {
                // first assignment to a final field. Field name without "this" in front of it
                FieldExprent field = (FieldExprent)left;
                ClassesProcessor.ClassNode node = ((ClassesProcessor.ClassNode)DecompilerContext.
                                                   GetProperty(DecompilerContext.Current_Class_Node));
                if (node != null)
                {
                    StructField fd = node.classStruct.GetField(field.GetName(), field.GetDescriptor()
                                                               .descriptorString);
                    if (fd != null)
                    {
                        if (field.IsStatic() && fd.HasModifier(ICodeConstants.Acc_Final))
                        {
                            fieldInClassInit = true;
                        }
                        if (node.GetWrapper() != null && node.GetWrapper().GetHiddenMembers().Contains(InterpreterUtil
                                                                                                       .MakeUniqueKey(fd.GetName(), fd.GetDescriptor())))
                        {
                            hiddenField = true;
                        }
                    }
                }
            }
            if (hiddenField)
            {
                return(new TextBuffer());
            }
            TextBuffer buffer = new TextBuffer();

            if (fieldInClassInit)
            {
                buffer.Append(((FieldExprent)left).GetName());
            }
            else
            {
                buffer.Append(left.ToJava(indent, tracer));
            }
            if (right.type == Exprent_Const)
            {
                ((ConstExprent)right).AdjustConstType(leftType);
            }
            TextBuffer res = right.ToJava(indent, tracer);

            if (condType == Condition_None && !leftType.IsSuperset(rightType) && (rightType.Equals
                                                                                      (VarType.Vartype_Object) || leftType.type != ICodeConstants.Type_Object))
            {
                if (right.GetPrecedence() >= FunctionExprent.GetPrecedence(FunctionExprent.Function_Cast
                                                                           ))
                {
                    res.Enclose("(", ")");
                }
                res.Prepend("(" + ExprProcessor.GetCastTypeName(leftType) + ")");
            }
            buffer.Append(condType == Condition_None ? " = " : Operators[condType]).Append(res
                                                                                           );
            tracer.AddMapping(bytecode);
            return(buffer);
        }
Exemple #14
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);
        }
        private BitSet GetAmbiguousParameters()
        {
            StructClass cl = DecompilerContext.GetStructContext().GetClass(classname);

            if (cl == null)
            {
                return(Empty_Bit_Set);
            }
            // check number of matches
            List <MethodDescriptor> matches = new List <MethodDescriptor>();

            foreach (StructMethod mt in cl.GetMethods())
            {
                if (name.Equals(mt.GetName()))
                {
                    MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt.GetDescriptor());
                    if ([email protected] == [email protected])
                    {
                        for (int i = 0; i < [email protected]; i++)
                        {
                            if (md.@params[i].typeFamily != descriptor.@params[i].typeFamily)
                            {
                                goto nextMethod_continue;
                            }
                        }
                        matches.Add(md);
                    }
                }
            }
            nextMethod_break    :;
            nextMethod_continue :
            if (matches.Count == 1)
            {
                return(Empty_Bit_Set);
            }
            // check if a call is unambiguous
            StructMethod mt_1 = cl.GetMethod(InterpreterUtil.MakeUniqueKey(name, stringDescriptor
                                                                           ));

            if (mt_1 != null)
            {
                MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt_1.GetDescriptor());
                if ([email protected] == lstParameters.Count)
                {
                    bool exact = true;
                    for (int i = 0; i < [email protected]; i++)
                    {
                        if (!md.@params[i].Equals(lstParameters[i].GetExprType()))
                        {
                            exact = false;
                            break;
                        }
                    }
                    if (exact)
                    {
                        return(Empty_Bit_Set);
                    }
                }
            }
            // mark parameters
            BitSet ambiguous = new BitSet([email protected]);

            for (int i = 0; i < [email protected]; i++)
            {
                VarType paramType = descriptor.@params[i];
                foreach (MethodDescriptor md in matches)
                {
                    if (!paramType.Equals(md.@params[i]))
                    {
                        ambiguous.Set(i);
                        break;
                    }
                }
            }
            return(ambiguous);
        }
        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);
        }