예제 #1
0
 private static bool IsStackAssignment(Exprent first, Exprent second)
 {
     if (first.type == Exprent.Exprent_Assignment && second.type == Exprent.Exprent_Assignment)
     {
         AssignmentExprent asf = (AssignmentExprent)first;
         AssignmentExprent ass = (AssignmentExprent)second;
         while (true)
         {
             if (asf.GetRight().Equals(ass.GetRight()))
             {
                 if ((asf.GetLeft().type == Exprent.Exprent_Var && ((VarExprent)asf.GetLeft()).IsStack
                          ()) && (ass.GetLeft().type != Exprent.Exprent_Var || !((VarExprent)ass.GetLeft()
                                                                                 ).IsStack()))
                 {
                     if (!ass.GetLeft().ContainsExprent(asf.GetLeft()))
                     {
                         asf.SetRight(ass);
                         return(true);
                     }
                 }
             }
             if (asf.GetRight().type == Exprent.Exprent_Assignment)
             {
                 asf = (AssignmentExprent)asf.GetRight();
             }
             else
             {
                 break;
             }
         }
     }
     return(false);
 }
예제 #2
0
        private static bool IsIPPorIMM2(Exprent first, Exprent second)
        {
            if (first.type != Exprent.Exprent_Assignment || second.type != Exprent.Exprent_Assignment)
            {
                return(false);
            }
            AssignmentExprent af  = (AssignmentExprent)first;
            AssignmentExprent @as = (AssignmentExprent)second;

            if (@as.GetRight().type != Exprent.Exprent_Function)
            {
                return(false);
            }
            FunctionExprent func = (FunctionExprent)@as.GetRight();

            if (func.GetFuncType() != FunctionExprent.Function_Add && func.GetFuncType() != FunctionExprent
                .Function_Sub)
            {
                return(false);
            }
            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() &&
                af.GetLeft().Equals(econd) && af.GetRight().Equals(@as.GetLeft()) && (af.GetLeft
                                                                                          ().GetExprentUse() & Exprent.Multiple_Uses) != 0)
            {
                int type = func.GetFuncType() == FunctionExprent.Function_Add ? FunctionExprent.Function_Ipp
                                         : FunctionExprent.Function_Imm;
                FunctionExprent ret = new FunctionExprent(type, af.GetRight(), func.bytecode);
                ret.SetImplicitType(VarType.Vartype_Int);
                af.SetRight(ret);
                return(true);
            }
            return(false);
        }
예제 #3
0
 private static bool IsStackAssignment2(Exprent first, Exprent second)
 {
     // e.g. 1.4-style class invocation
     if (first.type == Exprent.Exprent_Assignment && second.type == Exprent.Exprent_Assignment)
     {
         AssignmentExprent asf = (AssignmentExprent)first;
         AssignmentExprent ass = (AssignmentExprent)second;
         if (asf.GetLeft().type == Exprent.Exprent_Var && ass.GetRight().type == Exprent.Exprent_Var &&
             asf.GetLeft().Equals(ass.GetRight()) && ((VarExprent)asf.GetLeft()).IsStack(
                 ))
         {
             if (ass.GetLeft().type != Exprent.Exprent_Var || !((VarExprent)ass.GetLeft()).IsStack
                     ())
             {
                 asf.SetRight(new AssignmentExprent(ass.GetLeft(), asf.GetRight(), ass.bytecode));
                 return(true);
             }
         }
     }
     return(false);
 }
예제 #4
0
 private static bool IsIPPorIMM(Exprent first, Exprent second)
 {
     if (first.type == Exprent.Exprent_Assignment && second.type == Exprent.Exprent_Function)
     {
         AssignmentExprent @as = (AssignmentExprent)first;
         FunctionExprent   @in = (FunctionExprent)second;
         if ((@in.GetFuncType() == FunctionExprent.Function_Mmi || @in.GetFuncType() == FunctionExprent
              .Function_Ppi) && @in.GetLstOperands()[0].Equals(@as.GetRight()))
         {
             if (@in.GetFuncType() == FunctionExprent.Function_Mmi)
             {
                 @in.SetFuncType(FunctionExprent.Function_Imm);
             }
             else
             {
                 @in.SetFuncType(FunctionExprent.Function_Ipp);
             }
             @as.SetRight(@in);
             return(true);
         }
     }
     return(false);
 }
예제 #5
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);
        }