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); }
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); }
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); }
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); }
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); }