private TextBuffer WrapOperandString(Exprent expr, bool eq, int indent, BytecodeMappingTracer tracer) { int myprec = GetPrecedence(); int exprprec = expr.GetPrecedence(); bool parentheses = exprprec > myprec; if (!parentheses && eq) { parentheses = (exprprec == myprec); if (parentheses) { if (expr.type == Exprent.Exprent_Function && ((FunctionExprent)expr).GetFuncType( ) == funcType) { parentheses = !Associativity.Contains(funcType); } } } TextBuffer res = expr.ToJava(indent, tracer); if (parentheses) { res.Enclose("(", ")"); } return(res); }
public MonitorExprent(int monType, Exprent value, HashSet <int> bytecodeOffsets) : base(Exprent_Monitor) { this.monType = monType; this.value = value; AddBytecodeOffsets(bytecodeOffsets); }
public override void ReplaceExprent(Exprent oldExpr, Exprent newExpr) { if (oldExpr == instance) { instance = newExpr; } }
public override void ReplaceExprent(Exprent oldExpr, Exprent newExpr) { if (oldExpr == condition) { condition = newExpr; } }
public override void ReplaceExprent(Exprent oldExpr, Exprent newExpr) { if (oldExpr == constructor) { constructor = (InvocationExprent)newExpr; } if (constructor != null) { constructor.ReplaceExprent(oldExpr, newExpr); } for (int i = 0; i < lstDims.Count; i++) { if (oldExpr == lstDims[i]) { lstDims[i] = newExpr; } } for (int i = 0; i < lstArrayElements.Count; i++) { if (oldExpr == lstArrayElements[i]) { lstArrayElements[i] = newExpr; } } }
public override void ReplaceExprent(Exprent oldExpr, Exprent newExpr) { if (oldExpr == value) { value = newExpr; } }
public ExitExprent(int exitType, Exprent value, VarType retType, HashSet <int> bytecodeOffsets ) : base(Exprent_Exit) { this.exitType = exitType; this.value = value; this.retType = retType; AddBytecodeOffsets(bytecodeOffsets); }
public ArrayExprent(Exprent array, Exprent index, VarType hardType, HashSet <int> bytecodeOffsets) : base(Exprent_Array) { this.array = array; this.index = index; this.hardType = hardType; AddBytecodeOffsets(bytecodeOffsets); }
// TODO: order of operands insignificant public override void ReplaceExprent(Exprent oldExpr, Exprent newExpr) { for (int i = 0; i < lstOperands.Count; i++) { if (oldExpr == lstOperands[i]) { lstOperands[i] = newExpr; } } }
public override void ReplaceExprent(Exprent oldExpr, Exprent newExpr) { if (oldExpr == left) { left = newExpr; } if (oldExpr == right) { right = newExpr; } }
public override void ReplaceExprent(Exprent oldExpr, Exprent newExpr) { if (oldExpr == array) { array = newExpr; } if (oldExpr == index) { index = newExpr; } }
public FieldExprent(string name, string classname, bool isStatic, Exprent instance , FieldDescriptor descriptor, HashSet <int> bytecodeOffsets) : base(Exprent_Field) { this.name = name; this.classname = classname; this.isStatic__ = isStatic; this.instance = instance; this.descriptor = descriptor; AddBytecodeOffsets(bytecodeOffsets); }
public override void ReplaceExprent(Exprent oldExpr, Exprent newExpr) { if (oldExpr == instance) { instance = newExpr; } for (int i = 0; i < lstParameters.Count; i++) { if (oldExpr == lstParameters[i]) { lstParameters[i] = newExpr; } } }
public override CheckTypesResult CheckExprTypeBounds() { CheckTypesResult result = new CheckTypesResult(); for (int i = 0; i < lstParameters.Count; i++) { Exprent parameter = lstParameters[i]; VarType leftType = descriptor.@params[i]; result.AddMinTypeExprent(parameter, VarType.GetMinTypeInFamily(leftType.typeFamily )); result.AddMaxTypeExprent(parameter, leftType); } return(result); }
public virtual bool ContainsExprent(Exprent exprent) { if (Equals(exprent)) { return(true); } List <Exprent> lst = GetAllExprents(); for (int i = lst.Count - 1; i >= 0; i--) { if (lst[i].ContainsExprent(exprent)) { return(true); } } return(false); }
public AssignmentExprent(Exprent left, Exprent right, HashSet <int> bytecodeOffsets ) : base(Exprent_Assignment) { // FUNCTION_ADD // FUNCTION_SUB // FUNCTION_MUL // FUNCTION_DIV // FUNCTION_AND // FUNCTION_OR // FUNCTION_XOR // FUNCTION_REM // FUNCTION_SHL // FUNCTION_SHR // FUNCTION_USHR this.left = left; this.right = right; AddBytecodeOffsets(bytecodeOffsets); }
public override List <Exprent> GetAllExprents() { List <Exprent> lst = new List <Exprent>(); if (newType.arrayDim != 0) { Sharpen.Collections.AddAll(lst, lstDims); Sharpen.Collections.AddAll(lst, lstArrayElements); } else if (constructor != null) { Exprent constructor = this.constructor.GetInstance(); if (constructor != null) { // should be true only for a lambda expression with a virtual content method lst.Add(constructor); } Sharpen.Collections.AddAll(lst, this.constructor.GetLstParameters()); } return(lst); }
private InvocationExprent(InvocationExprent expr) : this() { name = expr.GetName(); classname = expr.GetClassname(); isStatic__ = expr.IsStatic(); canIgnoreBoxing = expr.canIgnoreBoxing; functype = expr.GetFunctype(); instance = expr.GetInstance(); if (instance != null) { instance = instance.Copy(); } invocationTyp = expr.GetInvocationTyp(); invokeDynamicClassSuffix = expr.GetInvokeDynamicClassSuffix(); stringDescriptor = expr.GetStringDescriptor(); descriptor = expr.GetDescriptor(); lstParameters = new List <Exprent>(expr.GetLstParameters()); ExprProcessor.CopyEntries(lstParameters); AddBytecodeOffsets(expr.bytecode); bootstrapArguments = expr.GetBootstrapArguments(); }
private static string GetQualifiedNewInstance(string classname, List <Exprent> lstParams , int indent, BytecodeMappingTracer tracer) { ClassesProcessor.ClassNode node = DecompilerContext.GetClassProcessor().GetMapRootClasses ().GetOrNull(classname); if (node != null && node.type != ClassesProcessor.ClassNode.Class_Root && node.type != ClassesProcessor.ClassNode.Class_Local && (node.access & ICodeConstants.Acc_Static ) == 0) { if (!(lstParams.Count == 0)) { Exprent enclosing = lstParams[0]; bool isQualifiedNew = false; if (enclosing.type == Exprent.Exprent_Var) { VarExprent varEnclosing = (VarExprent)enclosing; StructClass current_class = ((ClassesProcessor.ClassNode)DecompilerContext.GetProperty (DecompilerContext.Current_Class_Node)).classStruct; string this_classname = varEnclosing.GetProcessor().GetThisVars().GetOrNull(new VarVersionPair (varEnclosing)); if (!current_class.qualifiedName.Equals(this_classname)) { isQualifiedNew = true; } } else { isQualifiedNew = true; } if (isQualifiedNew) { return(enclosing.ToJava(indent, tracer).ToString()); } } } return(null); }
public IfExprent(int ifType, ListStack <Exprent> stack, HashSet <int> bytecodeOffsets ) : this(null, bytecodeOffsets) { //public static final int IF_CAND = 16; //public static final int IF_COR = 17; //public static final int IF_NOT = 18; if (ifType <= If_Le) { stack.Push(new ConstExprent(0, true, null)); } else if (ifType <= If_Nonnull) { stack.Push(new ConstExprent(VarType.Vartype_Null, null, null)); } if (ifType == If_Value) { condition = stack.Pop(); } else { condition = new FunctionExprent(Func_Types[ifType], stack, bytecodeOffsets); } }
public override CheckTypesResult CheckExprTypeBounds() { CheckTypesResult result = new CheckTypesResult(); Exprent param1 = lstOperands[0]; VarType type1 = param1.GetExprType(); Exprent param2 = null; VarType type2 = null; if (lstOperands.Count > 1) { param2 = lstOperands[1]; type2 = param2.GetExprType(); } switch (funcType) { case Function_Iif: { VarType supertype = GetExprType(); result.AddMinTypeExprent(param1, VarType.Vartype_Boolean); result.AddMinTypeExprent(param2, VarType.GetMinTypeInFamily(supertype.typeFamily) ); result.AddMinTypeExprent(lstOperands[2], VarType.GetMinTypeInFamily(supertype.typeFamily )); break; } case Function_I2l: case Function_I2f: case Function_I2d: case Function_I2b: case Function_I2c: case Function_I2s: { result.AddMinTypeExprent(param1, VarType.Vartype_Bytechar); result.AddMaxTypeExprent(param1, VarType.Vartype_Int); break; } case Function_Imm: case Function_Ipp: case Function_Mmi: case Function_Ppi: { result.AddMinTypeExprent(param1, implicitType); result.AddMaxTypeExprent(param1, implicitType); break; } case Function_Add: case Function_Sub: case Function_Mul: case Function_Div: case Function_Rem: case Function_Shl: case Function_Shr: case Function_Ushr: case Function_Lt: case Function_Ge: case Function_Gt: case Function_Le: { result.AddMinTypeExprent(param2, VarType.Vartype_Bytechar); goto case Function_Bit_Not; } case Function_Bit_Not: case Function_Neg: { // case FUNCTION_BOOL_NOT: result.AddMinTypeExprent(param1, VarType.Vartype_Bytechar); break; } case Function_And: case Function_Or: case Function_Xor: case Function_Eq: case Function_Ne: { if (type1.type == ICodeConstants.Type_Boolean) { if (type2.IsStrictSuperset(type1)) { result.AddMinTypeExprent(param1, VarType.Vartype_Bytechar); } else { // both are booleans bool param1_false_boolean = type1.IsFalseBoolean() || (param1.type == Exprent.Exprent_Const && !((ConstExprent)param1).HasBooleanValue()); bool param2_false_boolean = type1.IsFalseBoolean() || (param2.type == Exprent.Exprent_Const && !((ConstExprent)param2).HasBooleanValue()); if (param1_false_boolean || param2_false_boolean) { result.AddMinTypeExprent(param1, VarType.Vartype_Bytechar); result.AddMinTypeExprent(param2, VarType.Vartype_Bytechar); } } } else if (type2.type == ICodeConstants.Type_Boolean) { if (type1.IsStrictSuperset(type2)) { result.AddMinTypeExprent(param2, VarType.Vartype_Bytechar); } } break; } } return(result); }
public FieldExprent(LinkConstant cn, Exprent instance, HashSet <int> bytecodeOffsets ) : this(cn.elementname, cn.classname, instance == null, instance, FieldDescriptor. ParseDescriptor(cn.descriptor), bytecodeOffsets) { }
public InvocationExprent(int opcode, LinkConstant cn, List <PooledConstant> bootstrapArguments , ListStack <Exprent> stack, HashSet <int> bytecodeOffsets) : this() { name = cn.elementname; classname = cn.classname; this.bootstrapArguments = bootstrapArguments; switch (opcode) { case ICodeConstants.opc_invokestatic: { invocationTyp = Invoke_Static; break; } case ICodeConstants.opc_invokespecial: { invocationTyp = Invoke_Special; break; } case ICodeConstants.opc_invokevirtual: { invocationTyp = Invoke_Virtual; break; } case ICodeConstants.opc_invokeinterface: { invocationTyp = Invoke_Interface; break; } case ICodeConstants.opc_invokedynamic: { invocationTyp = Invoke_Dynamic; classname = "java/lang/Class"; // dummy class name invokeDynamicClassSuffix = "##Lambda_" + cn.index1 + "_" + cn.index2; break; } } if (ICodeConstants.Init_Name.Equals(name)) { functype = Typ_Init; } else if (ICodeConstants.Clinit_Name.Equals(name)) { functype = Typ_Clinit; } stringDescriptor = cn.descriptor; descriptor = MethodDescriptor.ParseDescriptor(cn.descriptor); foreach (VarType ignored in descriptor.@params) { lstParameters.Add(0, stack.Pop()); } if (opcode == ICodeConstants.opc_invokedynamic) { int dynamicInvocationType = -1; if (bootstrapArguments != null) { if (bootstrapArguments.Count > 1) { // INVOKEDYNAMIC is used not only for lambdas PooledConstant link = bootstrapArguments[1]; if (link is LinkConstant) { dynamicInvocationType = ((LinkConstant)link).index1; } } } if (dynamicInvocationType == ICodeConstants.CONSTANT_MethodHandle_REF_invokeStatic) { isStatic__ = true; } else if (!(lstParameters.Count == 0)) { // FIXME: remove the first parameter completely from the list. It's the object type for a virtual lambda method. instance = lstParameters[0]; } } else if (opcode == ICodeConstants.opc_invokestatic) { isStatic__ = true; } else { instance = stack.Pop(); } AddBytecodeOffsets(bytecodeOffsets); }
public SwitchExprent(Exprent value, HashSet <int> bytecodeOffsets) : base(Exprent_Switch) { this.value = value; AddBytecodeOffsets(bytecodeOffsets); }
public FunctionExprent(int funcType, ListStack <Exprent> stack, HashSet <int> bytecodeOffsets ) : this(funcType, new List <Exprent>(), bytecodeOffsets) { // FUNCTION_ADD // FUNCTION_SUB // FUNCTION_MUL // FUNCTION_DIV // FUNCTION_AND // FUNCTION_OR // FUNCTION_XOR // FUNCTION_REM // FUNCTION_SHL // FUNCTION_SHR // FUNCTION_USHR // FUNCTION_BIT_NOT // FUNCTION_BOOL_NOT // FUNCTION_NEG // FUNCTION_I2L // FUNCTION_I2F // FUNCTION_I2D // FUNCTION_L2I // FUNCTION_L2F // FUNCTION_L2D // FUNCTION_F2I // FUNCTION_F2L // FUNCTION_F2D // FUNCTION_D2I // FUNCTION_D2L // FUNCTION_D2F // FUNCTION_I2B // FUNCTION_I2C // FUNCTION_I2S // FUNCTION_CAST // FUNCTION_INSTANCEOF // FUNCTION_ARRAY_LENGTH // FUNCTION_IMM // FUNCTION_MMI // FUNCTION_IPP // FUNCTION_PPI // FUNCTION_IFF // FUNCTION_LCMP // FUNCTION_FCMPL // FUNCTION_FCMPG // FUNCTION_DCMPL // FUNCTION_DCMPG // FUNCTION_EQ = 41; // FUNCTION_NE = 42; // FUNCTION_LT = 43; // FUNCTION_GE = 44; // FUNCTION_GT = 45; // FUNCTION_LE = 46; // FUNCTION_CADD = 47; // FUNCTION_COR = 48; // FUNCTION_STR_CONCAT = 49; if (funcType >= Function_Bit_Not && funcType <= Function_Ppi && funcType != Function_Cast && funcType != Function_Instanceof) { lstOperands.Add(stack.Pop()); } else if (funcType == Function_Iif) { throw new Exception("no direct instantiation possible"); } else { Exprent expr = stack.Pop(); lstOperands.Add(stack.Pop()); lstOperands.Add(expr); } }
public virtual void ReplaceExprent(Exprent oldExpr, Exprent newExpr) { }
public FunctionExprent(int funcType, Exprent operand, HashSet <int> bytecodeOffsets ) : this(funcType, new List <Exprent>(1), bytecodeOffsets) { lstOperands.Add(operand); }
public virtual void SetRight(Exprent right) { this.right = right; }
public override VarType GetExprType() { VarType exprType = null; if (funcType <= Function_Neg || funcType == Function_Ipp || funcType == Function_Ppi || funcType == Function_Imm || funcType == Function_Mmi) { VarType type1 = lstOperands[0].GetExprType(); VarType type2 = null; if (lstOperands.Count > 1) { type2 = lstOperands[1].GetExprType(); } switch (funcType) { case Function_Imm: case Function_Mmi: case Function_Ipp: case Function_Ppi: { exprType = implicitType; break; } case Function_Bool_Not: { exprType = VarType.Vartype_Boolean; break; } case Function_Shl: case Function_Shr: case Function_Ushr: case Function_Bit_Not: case Function_Neg: { exprType = GetMaxVarType(new VarType[] { type1 }); break; } case Function_Add: case Function_Sub: case Function_Mul: case Function_Div: case Function_Rem: { exprType = GetMaxVarType(new VarType[] { type1, type2 }); break; } case Function_And: case Function_Or: case Function_Xor: { if (type1.type == ICodeConstants.Type_Boolean & type2.type == ICodeConstants.Type_Boolean) { exprType = VarType.Vartype_Boolean; } else { exprType = GetMaxVarType(new VarType[] { type1, type2 }); } break; } } } else if (funcType == Function_Cast) { exprType = lstOperands[1].GetExprType(); } else if (funcType == Function_Iif) { Exprent param1 = lstOperands[1]; Exprent param2 = lstOperands[2]; VarType supertype = VarType.GetCommonSupertype(param1.GetExprType(), param2.GetExprType ()); if (param1.type == Exprent.Exprent_Const && param2.type == Exprent.Exprent_Const && supertype.type != ICodeConstants.Type_Boolean && VarType.Vartype_Int.IsSuperset (supertype)) { exprType = VarType.Vartype_Int; } else { exprType = supertype; } } else if (funcType == Function_Str_Concat) { exprType = VarType.Vartype_String; } else if (funcType >= Function_Eq || funcType == Function_Instanceof) { exprType = VarType.Vartype_Boolean; } else if (funcType >= Function_Array_Length) { exprType = VarType.Vartype_Int; } else { exprType = Types[funcType - Function_I2l]; } return(exprType); }
public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer) { tracer.AddMapping(bytecode); if (funcType <= Function_Ushr) { return(WrapOperandString(lstOperands[0], false, indent, tracer).Append(Operators[ funcType]).Append(WrapOperandString(lstOperands[1], true, indent, tracer))); } // try to determine more accurate type for 'char' literals if (funcType >= Function_Eq) { if (funcType <= Function_Le) { Exprent left = lstOperands[0]; Exprent right = lstOperands[1]; if (right.type == Exprent_Const) { ((ConstExprent)right).AdjustConstType(left.GetExprType()); } else if (left.type == Exprent_Const) { ((ConstExprent)left).AdjustConstType(right.GetExprType()); } } return(WrapOperandString(lstOperands[0], false, indent, tracer).Append(Operators[ funcType - Function_Eq + 11]).Append(WrapOperandString(lstOperands[1], true, indent , tracer))); } switch (funcType) { case Function_Bit_Not: { return(WrapOperandString(lstOperands[0], true, indent, tracer).Prepend("~")); } case Function_Bool_Not: { return(WrapOperandString(lstOperands[0], true, indent, tracer).Prepend("!")); } case Function_Neg: { return(WrapOperandString(lstOperands[0], true, indent, tracer).Prepend("-")); } case Function_Cast: { return(lstOperands[1].ToJava(indent, tracer).Enclose("(", ")").Append(WrapOperandString (lstOperands[0], true, indent, tracer))); } case Function_Array_Length: { Exprent arr = lstOperands[0]; TextBuffer res = WrapOperandString(arr, false, indent, tracer); if (arr.GetExprType().arrayDim == 0) { VarType objArr = VarType.Vartype_Object.ResizeArrayDim(1); // type family does not change res.Enclose("((" + ExprProcessor.GetCastTypeName(objArr) + ")", ")"); } return(res.Append(".length")); } case Function_Iif: { return(WrapOperandString(lstOperands[0], true, indent, tracer).Append(" ? ").Append (WrapOperandString(lstOperands[1], true, indent, tracer)).Append(" : ").Append(WrapOperandString (lstOperands[2], true, indent, tracer))); } case Function_Ipp: { return(WrapOperandString(lstOperands[0], true, indent, tracer).Append("++")); } case Function_Ppi: { return(WrapOperandString(lstOperands[0], true, indent, tracer).Prepend("++")); } case Function_Imm: { return(WrapOperandString(lstOperands[0], true, indent, tracer).Append("--")); } case Function_Mmi: { return(WrapOperandString(lstOperands[0], true, indent, tracer).Prepend("--")); } case Function_Instanceof: { return(WrapOperandString(lstOperands[0], true, indent, tracer).Append(" instanceof " ).Append(WrapOperandString(lstOperands[1], true, indent, tracer))); } case Function_Lcmp: { // shouldn't appear in the final code return(WrapOperandString(lstOperands[0], true, indent, tracer).Prepend("__lcmp__(" ).Append(", ").Append(WrapOperandString(lstOperands[1], true, indent, tracer)).Append (")")); } case Function_Fcmpl: { // shouldn't appear in the final code return(WrapOperandString(lstOperands[0], true, indent, tracer).Prepend("__fcmpl__(" ).Append(", ").Append(WrapOperandString(lstOperands[1], true, indent, tracer)).Append (")")); } case Function_Fcmpg: { // shouldn't appear in the final code return(WrapOperandString(lstOperands[0], true, indent, tracer).Prepend("__fcmpg__(" ).Append(", ").Append(WrapOperandString(lstOperands[1], true, indent, tracer)).Append (")")); } case Function_Dcmpl: { // shouldn't appear in the final code return(WrapOperandString(lstOperands[0], true, indent, tracer).Prepend("__dcmpl__(" ).Append(", ").Append(WrapOperandString(lstOperands[1], true, indent, tracer)).Append (")")); } case Function_Dcmpg: { // shouldn't appear in the final code return(WrapOperandString(lstOperands[0], true, indent, tracer).Prepend("__dcmpg__(" ).Append(", ").Append(WrapOperandString(lstOperands[1], true, indent, tracer)).Append (")")); } } if (funcType <= Function_I2s) { return(WrapOperandString(lstOperands[0], true, indent, tracer).Prepend("(" + ExprProcessor .GetTypeName(Types[funcType - Function_I2l]) + ")")); } // return "<unknown function>"; throw new Exception("invalid function"); }