private static void HideEmptySuper(ClassWrapper wrapper) { foreach (MethodWrapper method in wrapper.GetMethods()) { if (ICodeConstants.Init_Name.Equals(method.methodStruct.GetName()) && method.root != null) { Statement firstData = Statements.FindFirstData(method.root); if (firstData == null || (firstData.GetExprents().Count == 0)) { return; } Exprent exprent = firstData.GetExprents()[0]; if (exprent.type == Exprent.Exprent_Invocation) { InvocationExprent invExpr = (InvocationExprent)exprent; if (Statements.IsInvocationInitConstructor(invExpr, method, wrapper, false) && (invExpr .GetLstParameters().Count == 0)) { firstData.GetExprents().RemoveAtReturningValue(0); } } } } }
private static Exprent IsSimpleConstructorInvocation(Exprent exprent) { List <Exprent> lst = exprent.GetAllExprents(); foreach (Exprent expr in lst) { Exprent ret = IsSimpleConstructorInvocation(expr); if (ret != null) { exprent.ReplaceExprent(expr, ret); } } if (exprent.type == Exprent.Exprent_Invocation) { InvocationExprent @in = (InvocationExprent)exprent; if (@in.GetFunctype() == InvocationExprent.Typ_Init && @in.GetInstance().type == Exprent.Exprent_New) { NewExprent newExpr = (NewExprent)@in.GetInstance(); newExpr.SetConstructor(@in); @in.SetInstance(null); return(newExpr); } } return(null); }
private static string IsClass14Invocation(Exprent exprent, ClassWrapper wrapper, MethodWrapper meth) { if (exprent.type == Exprent.Exprent_Function) { FunctionExprent fexpr = (FunctionExprent)exprent; if (fexpr.GetFuncType() == FunctionExprent.Function_Iif) { if (fexpr.GetLstOperands()[0].type == Exprent.Exprent_Function) { FunctionExprent headexpr = (FunctionExprent)fexpr.GetLstOperands()[0]; if (headexpr.GetFuncType() == FunctionExprent.Function_Eq) { if (headexpr.GetLstOperands()[0].type == Exprent.Exprent_Field && headexpr.GetLstOperands ()[1].type == Exprent.Exprent_Const && ((ConstExprent)headexpr.GetLstOperands()[ 1]).GetConstType().Equals(VarType.Vartype_Null)) { FieldExprent field = (FieldExprent)headexpr.GetLstOperands()[0]; ClassesProcessor.ClassNode fieldnode = DecompilerContext.GetClassProcessor().GetMapRootClasses ().GetOrNull(field.GetClassname()); if (fieldnode != null && fieldnode.classStruct.qualifiedName.Equals(wrapper.GetClassStruct ().qualifiedName)) { // source class StructField fd = wrapper.GetClassStruct().GetField(field.GetName(), field.GetDescriptor ().descriptorString); // FIXME: can be null! why?? if (fd != null && fd.HasModifier(ICodeConstants.Acc_Static) && (fd.IsSynthetic() || DecompilerContext.GetOption(IFernflowerPreferences.Synthetic_Not_Set))) { if (fexpr.GetLstOperands()[1].type == Exprent.Exprent_Assignment && fexpr.GetLstOperands ()[2].Equals(field)) { AssignmentExprent asexpr = (AssignmentExprent)fexpr.GetLstOperands()[1]; if (asexpr.GetLeft().Equals(field) && asexpr.GetRight().type == Exprent.Exprent_Invocation) { InvocationExprent invexpr = (InvocationExprent)asexpr.GetRight(); if (invexpr.GetClassname().Equals(wrapper.GetClassStruct().qualifiedName) && invexpr .GetName().Equals(meth.methodStruct.GetName()) && invexpr.GetStringDescriptor(). Equals(meth.methodStruct.GetDescriptor())) { if (invexpr.GetLstParameters()[0].type == Exprent.Exprent_Const) { wrapper.GetHiddenMembers().Add(InterpreterUtil.MakeUniqueKey(fd.GetName(), fd.GetDescriptor ())); // hide synthetic field return(((ConstExprent)invexpr.GetLstParameters()[0]).GetValue().ToString()); } } } } } } } } } } } return(null); }
private static Exprent IsLambda(Exprent exprent, StructClass cl) { List <Exprent> lst = exprent.GetAllExprents(); foreach (Exprent expr in lst) { Exprent ret = IsLambda(expr, cl); if (ret != null) { exprent.ReplaceExprent(expr, ret); } } if (exprent.type == Exprent.Exprent_Invocation) { InvocationExprent @in = (InvocationExprent)exprent; if (@in.GetInvocationTyp() == InvocationExprent.Invoke_Dynamic) { string lambda_class_name = cl.qualifiedName + @in.GetInvokeDynamicClassSuffix(); ClassesProcessor.ClassNode lambda_class = DecompilerContext.GetClassProcessor().GetMapRootClasses ().GetOrNull(lambda_class_name); if (lambda_class != null) { // real lambda class found, replace invocation with an anonymous class NewExprent newExpr = new NewExprent(new VarType(lambda_class_name, true), null, 0 , @in.bytecode); newExpr.SetConstructor(@in); // note: we don't set the instance to null with in.setInstance(null) like it is done for a common constructor invocation // lambda can also be a reference to a virtual method (e.g. String x; ...(x::toString);) // in this case instance will hold the corresponding object return(newExpr); } } } return(null); }
private static bool IsQualifiedNewGetClass(Exprent first, Exprent second) { if (first.type == Exprent.Exprent_Invocation) { InvocationExprent invocation = (InvocationExprent)first; if (!invocation.IsStatic() && invocation.GetInstance().type == Exprent.Exprent_Var && invocation.GetName().Equals("getClass") && invocation.GetStringDescriptor(). Equals("()Ljava/lang/Class;")) { List <Exprent> lstExprents = second.GetAllExprents(); lstExprents.Add(second); foreach (Exprent expr in lstExprents) { if (expr.type == Exprent.Exprent_New) { NewExprent newExpr = (NewExprent)expr; if (newExpr.GetConstructor() != null && !(newExpr.GetConstructor().GetLstParameters ().Count == 0) && newExpr.GetConstructor().GetLstParameters()[0].Equals(invocation .GetInstance())) { string classname = newExpr.GetNewType().value; ClassesProcessor.ClassNode node = DecompilerContext.GetClassProcessor().GetMapRootClasses ().GetOrNull(classname); if (node != null && node.type != ClassesProcessor.ClassNode.Class_Root) { return(true); } } } } } } return(false); }
private static StructField FindAssertionField(ClassesProcessor.ClassNode node) { ClassWrapper wrapper = node.GetWrapper(); bool noSynthFlag = DecompilerContext.GetOption(IFernflowerPreferences.Synthetic_Not_Set ); foreach (StructField fd in wrapper.GetClassStruct().GetFields()) { string keyField = InterpreterUtil.MakeUniqueKey(fd.GetName(), fd.GetDescriptor()); // initializer exists if (wrapper.GetStaticFieldInitializers().ContainsKey(keyField)) { // access flags set if (fd.HasModifier(ICodeConstants.Acc_Static) && fd.HasModifier(ICodeConstants.Acc_Final ) && (noSynthFlag || fd.IsSynthetic())) { // field type boolean FieldDescriptor fdescr = FieldDescriptor.ParseDescriptor(fd.GetDescriptor()); if (VarType.Vartype_Boolean.Equals(fdescr.type)) { Exprent initializer = wrapper.GetStaticFieldInitializers().GetWithKey(keyField); if (initializer.type == Exprent.Exprent_Function) { FunctionExprent fexpr = (FunctionExprent)initializer; if (fexpr.GetFuncType() == FunctionExprent.Function_Bool_Not && fexpr.GetLstOperands ()[0].type == Exprent.Exprent_Invocation) { InvocationExprent invexpr = (InvocationExprent)fexpr.GetLstOperands()[0]; if (invexpr.GetInstance() != null && invexpr.GetInstance().type == Exprent.Exprent_Const && "desiredAssertionStatus".Equals(invexpr.GetName()) && "java/lang/Class".Equals (invexpr.GetClassname()) && (invexpr.GetLstParameters().Count == 0)) { ConstExprent cexpr = (ConstExprent)invexpr.GetInstance(); if (VarType.Vartype_Class.Equals(cexpr.GetConstType())) { ClassesProcessor.ClassNode nd = node; while (nd != null) { if (nd.GetWrapper().GetClassStruct().qualifiedName.Equals(cexpr.GetValue())) { break; } nd = nd.parent; } if (nd != null) { // found enclosing class with the same name return(fd); } } } } } } } } } return(null); }
// See StringConcatFactory in jdk sources private static List <Exprent> ExtractParameters(List <PooledConstant> bootstrapArguments , InvocationExprent expr) { List <Exprent> parameters = expr.GetLstParameters(); if (bootstrapArguments != null) { PooledConstant constant = bootstrapArguments[0]; if (constant.type == ICodeConstants.CONSTANT_String) { string recipe = ((PrimitiveConstant)constant).GetString(); List <Exprent> res = new List <Exprent>(); StringBuilder acc = new StringBuilder(); int parameterId = 0; for (int i = 0; i < recipe.Length; i++) { char c = recipe[i]; if (c == Tag_Const || c == Tag_Arg) { // Detected a special tag, flush all accumulated characters // as a constant first: if (acc.Length > 0) { res.Add(new ConstExprent(VarType.Vartype_String, acc.ToString(), expr.bytecode)); acc.Length = 0; } if (c == Tag_Const) { } // skip for now if (c == Tag_Arg) { res.Add(parameters[parameterId++]); } } else { // Not a special characters, this is a constant embedded into // the recipe itself. acc.Append(c); } } // Flush the remaining characters as constant: if (acc.Length > 0) { res.Add(new ConstExprent(VarType.Vartype_String, acc.ToString(), expr.bytecode)); } return(res); } } return(new List <Exprent>(parameters)); }
public static void ClearEnum(ClassWrapper wrapper) { StructClass cl = wrapper.GetClassStruct(); // hide values/valueOf methods and super() invocations foreach (MethodWrapper method in wrapper.GetMethods()) { StructMethod mt = method.methodStruct; string name = mt.GetName(); string descriptor = mt.GetDescriptor(); if ("values".Equals(name)) { if (descriptor.Equals("()[L" + cl.qualifiedName + ";")) { wrapper.GetHiddenMembers().Add(InterpreterUtil.MakeUniqueKey(name, descriptor)); } } else if ("valueOf".Equals(name)) { if (descriptor.Equals("(Ljava/lang/String;)L" + cl.qualifiedName + ";")) { wrapper.GetHiddenMembers().Add(InterpreterUtil.MakeUniqueKey(name, descriptor)); } } else if (ICodeConstants.Init_Name.Equals(name)) { Statement firstData = Statements.FindFirstData(method.root); if (firstData != null && !(firstData.GetExprents().Count == 0)) { Exprent exprent = firstData.GetExprents()[0]; if (exprent.type == Exprent.Exprent_Invocation) { InvocationExprent invExpr = (InvocationExprent)exprent; if (Statements.IsInvocationInitConstructor(invExpr, method, wrapper, false)) { firstData.GetExprents().RemoveAtReturningValue(0); } } } } } // hide synthetic fields of enum and it's constants foreach (StructField fd in cl.GetFields()) { string descriptor = fd.GetDescriptor(); if (fd.IsSynthetic() && descriptor.Equals("[L" + cl.qualifiedName + ";")) { wrapper.GetHiddenMembers().Add(InterpreterUtil.MakeUniqueKey(fd.GetName(), descriptor )); } } }
public static bool IsInvocationInitConstructor(InvocationExprent inv, MethodWrapper method, ClassWrapper wrapper, bool withThis) { if (inv.GetFunctype() == InvocationExprent.Typ_Init && inv.GetInstance().type == Exprent.Exprent_Var) { VarExprent instVar = (VarExprent)inv.GetInstance(); VarVersionPair varPair = new VarVersionPair(instVar); string className = method.varproc.GetThisVars().GetOrNull(varPair); if (className != null) { // any this instance. TODO: Restrict to current class? return(withThis || !wrapper.GetClassStruct().qualifiedName.Equals(inv.GetClassname ())); } } return(false); }
// propagate (var = new X) forward to the <init> invocation private static bool IsConstructorInvocationRemote(List <Exprent> list, int index) { Exprent current = list[index]; if (current.type == Exprent.Exprent_Assignment) { AssignmentExprent @as = (AssignmentExprent)current; if (@as.GetLeft().type == Exprent.Exprent_Var && @as.GetRight().type == Exprent.Exprent_New) { NewExprent newExpr = (NewExprent)@as.GetRight(); VarType newType = newExpr.GetNewType(); VarVersionPair leftPair = new VarVersionPair((VarExprent)@as.GetLeft()); if (newType.type == ICodeConstants.Type_Object && newType.arrayDim == 0 && newExpr .GetConstructor() == null) { for (int i = index + 1; i < list.Count; i++) { Exprent remote = list[i]; // <init> invocation if (remote.type == Exprent.Exprent_Invocation) { InvocationExprent @in = (InvocationExprent)remote; if (@in.GetFunctype() == InvocationExprent.Typ_Init && @in.GetInstance().type == Exprent.Exprent_Var && @as.GetLeft().Equals(@in.GetInstance())) { newExpr.SetConstructor(@in); @in.SetInstance(null); list[i] = @as.Copy(); return(true); } } // check for variable in use HashSet <VarVersionPair> setVars = remote.GetAllVariables(); if (setVars.Contains(leftPair)) { // variable used somewhere in between -> exit, need a better reduced code return(false); } } } } } return(false); }
private static Exprent ReplaceFunction(InvocationExprent invexpr, Exprent source) { FunctionExprent functionExprent = (FunctionExprent)((ExitExprent)source).GetValue ().Copy(); List <Exprent> lstParameters = invexpr.GetLstParameters(); FieldExprent fieldExprent = (FieldExprent)functionExprent.GetLstOperands()[0]; if (fieldExprent.IsStatic()) { if (!(lstParameters.Count == 0)) { return(null); } return(functionExprent); } if (lstParameters.Count != 1) { return(null); } fieldExprent.ReplaceExprent(fieldExprent.GetInstance(), lstParameters[0]); return(functionExprent); }
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); }
static ClassReference14Processor() { InvocationExprent invFor = new InvocationExprent(); invFor.SetName("forName"); invFor.SetClassname("java/lang/Class"); invFor.SetStringDescriptor("(Ljava/lang/String;)Ljava/lang/Class;"); invFor.SetDescriptor(MethodDescriptor.ParseDescriptor("(Ljava/lang/String;)Ljava/lang/Class;" )); invFor.SetStatic(true); invFor.SetLstParameters(new [] { new VarExprent(0, VarType .Vartype_String, null) }.Cast <Exprent>().ToList()); Body_Expr = new ExitExprent(ExitExprent.Exit_Return, invFor, VarType.Vartype_Class , null); InvocationExprent ctor = new InvocationExprent(); ctor.SetName(ICodeConstants.Init_Name); ctor.SetClassname("java/lang/NoClassDefFoundError"); ctor.SetStringDescriptor("()V"); ctor.SetFunctype(InvocationExprent.Typ_Init); ctor.SetDescriptor(MethodDescriptor.ParseDescriptor("()V")); NewExprent newExpr = new NewExprent(new VarType(ICodeConstants.Type_Object, 0, "java/lang/NoClassDefFoundError" ), new List <Exprent>(), null); newExpr.SetConstructor(ctor); InvocationExprent invCause = new InvocationExprent(); invCause.SetName("initCause"); invCause.SetClassname("java/lang/NoClassDefFoundError"); invCause.SetStringDescriptor("(Ljava/lang/Throwable;)Ljava/lang/Throwable;"); invCause.SetDescriptor(MethodDescriptor.ParseDescriptor("(Ljava/lang/Throwable;)Ljava/lang/Throwable;" )); invCause.SetInstance(newExpr); invCause.SetLstParameters(new List <Exprent>(new [] { new VarExprent(2, new VarType(ICodeConstants.Type_Object, 0, "java/lang/ClassNotFoundException"), null) }.ToList())); Handler_Expr = new ExitExprent(ExitExprent.Exit_Throw, invCause, null, null); }
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); }
private static bool ReplaceAssertion(Statement parent, IfStatement stat, string classname , string key) { bool throwInIf = true; Statement ifstat = stat.GetIfstat(); InvocationExprent throwError = IsAssertionError(ifstat); if (throwError == null) { //check else: Statement elsestat = stat.GetElsestat(); throwError = IsAssertionError(elsestat); if (throwError == null) { return(false); } else { throwInIf = false; } } object[] exprres = GetAssertionExprent(stat.GetHeadexprent().GetCondition().Copy( ), classname, key, throwInIf); if (!(bool)exprres[1]) { return(false); } List <Exprent> lstParams = new List <Exprent>(); Exprent ascond = null; Exprent retcond = null; if (throwInIf) { if (exprres[0] != null) { ascond = new FunctionExprent(FunctionExprent.Function_Bool_Not, (Exprent)exprres[ 0], throwError.bytecode); retcond = SecondaryFunctionsHelper.PropagateBoolNot(ascond); } } else { ascond = (Exprent)exprres[0]; retcond = ascond; } lstParams.Add(retcond == null ? ascond : retcond); if (!(throwError.GetLstParameters().Count == 0)) { lstParams.Add(throwError.GetLstParameters()[0]); } AssertExprent asexpr = new AssertExprent(lstParams); Statement newstat = new BasicBlockStatement(new BasicBlock(DecompilerContext.GetCounterContainer ().GetCounterAndIncrement(CounterContainer.Statement_Counter))); newstat.SetExprents(Sharpen.Arrays.AsList(new Exprent[] { asexpr })); Statement first = stat.GetFirst(); if (stat.iftype == IfStatement.Iftype_Ifelse || (first.GetExprents() != null && ! (first.GetExprents().Count == 0))) { first.RemoveSuccessor(stat.GetIfEdge()); first.RemoveSuccessor(stat.GetElseEdge()); List <Statement> lstStatements = new List <Statement>(); if (first.GetExprents() != null && !(first.GetExprents().Count == 0)) { lstStatements.Add(first); } lstStatements.Add(newstat); if (stat.iftype == IfStatement.Iftype_Ifelse) { if (throwInIf) { lstStatements.Add(stat.GetElsestat()); } else { lstStatements.Add(stat.GetIfstat()); } } SequenceStatement sequence = new SequenceStatement(lstStatements); sequence.SetAllParent(); for (int i = 0; i < sequence.GetStats().Count - 1; i++) { sequence.GetStats()[i].AddSuccessor(new StatEdge(StatEdge.Type_Regular, sequence. GetStats()[i], sequence.GetStats()[i + 1])); } if (stat.iftype == IfStatement.Iftype_Ifelse || !throwInIf) { Statement stmts; if (throwInIf) { stmts = stat.GetElsestat(); } else { stmts = stat.GetIfstat(); } List <StatEdge> lstSuccs = stmts.GetAllSuccessorEdges(); if (!(lstSuccs.Count == 0)) { StatEdge endedge = lstSuccs[0]; if (endedge.closure == stat) { sequence.AddLabeledEdge(endedge); } } } newstat = sequence; } Sharpen.Collections.AddAll(newstat.GetVarDefinitions(), stat.GetVarDefinitions()); parent.ReplaceStatement(stat, newstat); return(true); }
private void ComputeMethodType(ClassesProcessor.ClassNode node, MethodWrapper method ) { NestedMemberAccess.MethodAccess type = NestedMemberAccess.MethodAccess.Normal; if (method.root != null) { DirectGraph graph = method.GetOrBuildGraph(); StructMethod mt = method.methodStruct; if ((noSynthFlag || mt.IsSynthetic()) && mt.HasModifier(ICodeConstants.Acc_Static )) { if (graph.nodes.Count == 2) { // incl. dummy exit node if (graph.first.exprents.Count == 1) { Exprent exprent = graph.first.exprents[0]; MethodDescriptor mtdesc = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); int parcount = [email protected]; Exprent exprCore = exprent; if (exprent.type == Exprent.Exprent_Exit) { ExitExprent exexpr = (ExitExprent)exprent; if (exexpr.GetExitType() == ExitExprent.Exit_Return && exexpr.GetValue() != null) { exprCore = exexpr.GetValue(); } } switch (exprCore.type) { case Exprent.Exprent_Field: { FieldExprent fexpr = (FieldExprent)exprCore; if ((parcount == 1 && !fexpr.IsStatic()) || (parcount == 0 && fexpr.IsStatic())) { if (fexpr.GetClassname().Equals(node.classStruct.qualifiedName)) { // FIXME: check for private flag of the field if (fexpr.IsStatic() || (fexpr.GetInstance().type == Exprent.Exprent_Var && ((VarExprent )fexpr.GetInstance()).GetIndex() == 0)) { type = NestedMemberAccess.MethodAccess.Field_Get; } } } break; } case Exprent.Exprent_Var: { // qualified this if (parcount == 1) { // this or final variable if (((VarExprent)exprCore).GetIndex() != 0) { type = NestedMemberAccess.MethodAccess.Field_Get; } } break; } case Exprent.Exprent_Function: { // for now detect only increment/decrement FunctionExprent functionExprent = (FunctionExprent)exprCore; if (functionExprent.GetFuncType() >= FunctionExprent.Function_Imm && functionExprent .GetFuncType() <= FunctionExprent.Function_Ppi) { if (functionExprent.GetLstOperands()[0].type == Exprent.Exprent_Field) { type = NestedMemberAccess.MethodAccess.Function; } } break; } case Exprent.Exprent_Invocation: { type = NestedMemberAccess.MethodAccess.Method; break; } case Exprent.Exprent_Assignment: { AssignmentExprent asexpr = (AssignmentExprent)exprCore; if (asexpr.GetLeft().type == Exprent.Exprent_Field && asexpr.GetRight().type == Exprent .Exprent_Var) { FieldExprent fexpras = (FieldExprent)asexpr.GetLeft(); if ((parcount == 2 && !fexpras.IsStatic()) || (parcount == 1 && fexpras.IsStatic( ))) { if (fexpras.GetClassname().Equals(node.classStruct.qualifiedName)) { // FIXME: check for private flag of the field if (fexpras.IsStatic() || (fexpras.GetInstance().type == Exprent.Exprent_Var && ( (VarExprent)fexpras.GetInstance()).GetIndex() == 0)) { if (((VarExprent)asexpr.GetRight()).GetIndex() == parcount - 1) { type = NestedMemberAccess.MethodAccess.Field_Set; } } } } } break; } } if (type == NestedMemberAccess.MethodAccess.Method) { // FIXME: check for private flag of the method type = NestedMemberAccess.MethodAccess.Normal; InvocationExprent invexpr = (InvocationExprent)exprCore; bool isStatic = invexpr.IsStatic(); if ((isStatic && invexpr.GetLstParameters().Count == parcount) || (!isStatic && invexpr .GetInstance().type == Exprent.Exprent_Var && ((VarExprent)invexpr.GetInstance() ).GetIndex() == 0 && invexpr.GetLstParameters().Count == parcount - 1)) { bool equalpars = true; int index = isStatic ? 0 : 1; for (int i = 0; i < invexpr.GetLstParameters().Count; i++) { Exprent parexpr = invexpr.GetLstParameters()[i]; if (parexpr.type != Exprent.Exprent_Var || ((VarExprent)parexpr).GetIndex() != index) { equalpars = false; break; } index += mtdesc.@params[i + (isStatic ? 0 : 1)].stackSize; } if (equalpars) { type = NestedMemberAccess.MethodAccess.Method; } } } } else if (graph.first.exprents.Count == 2) { Exprent exprentFirst = graph.first.exprents[0]; Exprent exprentSecond = graph.first.exprents[1]; if (exprentFirst.type == Exprent.Exprent_Assignment && exprentSecond.type == Exprent .Exprent_Exit) { MethodDescriptor mtdesc = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); int parcount = [email protected]; AssignmentExprent asexpr = (AssignmentExprent)exprentFirst; if (asexpr.GetLeft().type == Exprent.Exprent_Field && asexpr.GetRight().type == Exprent .Exprent_Var) { FieldExprent fexpras = (FieldExprent)asexpr.GetLeft(); if ((parcount == 2 && !fexpras.IsStatic()) || (parcount == 1 && fexpras.IsStatic( ))) { if (fexpras.GetClassname().Equals(node.classStruct.qualifiedName)) { // FIXME: check for private flag of the field if (fexpras.IsStatic() || (fexpras.GetInstance().type == Exprent.Exprent_Var && ( (VarExprent)fexpras.GetInstance()).GetIndex() == 0)) { if (((VarExprent)asexpr.GetRight()).GetIndex() == parcount - 1) { ExitExprent exexpr = (ExitExprent)exprentSecond; if (exexpr.GetExitType() == ExitExprent.Exit_Return && exexpr.GetValue() != null) { if (exexpr.GetValue().type == Exprent.Exprent_Var && ((VarExprent)asexpr.GetRight ()).GetIndex() == parcount - 1) { type = NestedMemberAccess.MethodAccess.Field_Set; } } } } } } } } } } } } if (type != NestedMemberAccess.MethodAccess.Normal) { Sharpen.Collections.Put(mapMethodType, method, type); } else { Sharpen.Collections.Remove(mapMethodType, method); } }
private Exprent ReplaceAccessExprent(ClassesProcessor.ClassNode caller, MethodWrapper methdest, InvocationExprent invexpr) { ClassesProcessor.ClassNode node = DecompilerContext.GetClassProcessor().GetMapRootClasses ().GetOrNull(invexpr.GetClassname()); MethodWrapper methsource = null; if (node != null && node.GetWrapper() != null) { methsource = node.GetWrapper().GetMethodWrapper(invexpr.GetName(), invexpr.GetStringDescriptor ()); } if (methsource == null || !mapMethodType.ContainsKey(methsource)) { return(null); } // if same method, return if (node.classStruct.qualifiedName.Equals(caller.classStruct.qualifiedName) && methsource .methodStruct.GetName().Equals(methdest.methodStruct.GetName()) && methsource.methodStruct .GetDescriptor().Equals(methdest.methodStruct.GetDescriptor())) { // no recursive invocations permitted! return(null); } NestedMemberAccess.MethodAccess type = mapMethodType.GetOrNull(methsource); // // FIXME: impossible case. MethodAccess.NORMAL is not saved in the map // if(type == MethodAccess.NORMAL) { // return null; // } if (!SameTree(caller, node)) { return(null); } DirectGraph graph = methsource.GetOrBuildGraph(); Exprent source = graph.first.exprents[0]; Exprent retexprent = null; switch (type.ordinal()) { case 1: { ExitExprent exsource = (ExitExprent)source; if (exsource.GetValue().type == Exprent.Exprent_Var) { // qualified this VarExprent var = (VarExprent)exsource.GetValue(); string varname = methsource.varproc.GetVarName(new VarVersionPair(var)); if (!methdest.setOuterVarNames.Contains(varname)) { VarNamesCollector vnc = new VarNamesCollector(); vnc.AddName(varname); methdest.varproc.RefreshVarNames(vnc); methdest.setOuterVarNames.Add(varname); } int index = methdest.counter.GetCounterAndIncrement(CounterContainer.Var_Counter); VarExprent ret = new VarExprent(index, var.GetVarType(), methdest.varproc); methdest.varproc.SetVarName(new VarVersionPair(index, 0), varname); retexprent = ret; } else { // field FieldExprent ret = (FieldExprent)exsource.GetValue().Copy(); if (!ret.IsStatic()) { ret.ReplaceExprent(ret.GetInstance(), invexpr.GetLstParameters()[0]); } retexprent = ret; } break; } case 2: { AssignmentExprent ret_1; if (source.type == Exprent.Exprent_Exit) { ExitExprent extex = (ExitExprent)source; ret_1 = (AssignmentExprent)extex.GetValue().Copy(); } else { ret_1 = (AssignmentExprent)source.Copy(); } FieldExprent fexpr = (FieldExprent)ret_1.GetLeft(); if (fexpr.IsStatic()) { ret_1.ReplaceExprent(ret_1.GetRight(), invexpr.GetLstParameters()[0]); } else { ret_1.ReplaceExprent(ret_1.GetRight(), invexpr.GetLstParameters()[1]); fexpr.ReplaceExprent(fexpr.GetInstance(), invexpr.GetLstParameters()[0]); } // do not use copied bytecodes ret_1.GetLeft().bytecode = null; ret_1.GetRight().bytecode = null; retexprent = ret_1; break; } case 4: { retexprent = ReplaceFunction(invexpr, source); break; } case 3: { if (source.type == Exprent.Exprent_Exit) { source = ((ExitExprent)source).GetValue(); } InvocationExprent invret = (InvocationExprent)source.Copy(); int index_1 = 0; if (!invret.IsStatic()) { invret.ReplaceExprent(invret.GetInstance(), invexpr.GetLstParameters()[0]); index_1 = 1; } for (int i = 0; i < invret.GetLstParameters().Count; i++) { invret.ReplaceExprent(invret.GetLstParameters()[i], invexpr.GetLstParameters()[i + index_1]); } retexprent = invret; break; } } if (retexprent != null) { // preserve original bytecodes retexprent.bytecode = null; retexprent.AddBytecodeOffsets(invexpr.bytecode); // hide synthetic access method bool hide = true; if (node.type == ClassesProcessor.ClassNode.Class_Root || (node.access & ICodeConstants .Acc_Static) != 0) { StructMethod mt = methsource.methodStruct; if (!mt.IsSynthetic()) { hide = false; } } if (hide) { node.GetWrapper().GetHiddenMembers().Add(InterpreterUtil.MakeUniqueKey(invexpr.GetName (), invexpr.GetStringDescriptor())); } } return(retexprent); }
public static Exprent ContractStringConcat(Exprent expr) { Exprent exprTmp = null; VarType cltype = null; // first quick test if (expr.type == Exprent.Exprent_Invocation) { InvocationExprent iex = (InvocationExprent)expr; if ("toString".Equals(iex.GetName())) { if (builderClass.Equals(iex.GetClassname())) { cltype = builderType; } else if (bufferClass.Equals(iex.GetClassname())) { cltype = bufferType; } if (cltype != null) { exprTmp = iex.GetInstance(); } } else if ("makeConcatWithConstants".Equals(iex.GetName())) { // java 9 style List <Exprent> parameters = ExtractParameters(iex.GetBootstrapArguments(), iex); if (parameters.Count >= 2) { return(CreateConcatExprent(parameters, expr.bytecode)); } } } if (exprTmp == null) { return(expr); } // iterate in depth, collecting possible operands List <Exprent> lstOperands = new List <Exprent>(); while (true) { int found = 0; switch (exprTmp.type) { case Exprent.Exprent_Invocation: { InvocationExprent iex = (InvocationExprent)exprTmp; if (IsAppendConcat(iex, cltype)) { lstOperands.Add(0, iex.GetLstParameters()[0]); exprTmp = iex.GetInstance(); found = 1; } break; } case Exprent.Exprent_New: { NewExprent nex = (NewExprent)exprTmp; if (IsNewConcat(nex, cltype)) { VarType[] @params = nex.GetConstructor().GetDescriptor().@params; if (@params.Length == 1) { lstOperands.Add(0, nex.GetConstructor().GetLstParameters()[0]); } found = 2; } break; } } if (found == 0) { return(expr); } else if (found == 2) { break; } } int first2str = 0; int index = 0; while (index < lstOperands.Count && index < 2) { if (lstOperands[index].GetExprType().Equals(VarType.Vartype_String)) { first2str |= (index + 1); } index++; } if (first2str == 0) { lstOperands.Add(0, new ConstExprent(VarType.Vartype_String, string.Empty, expr.bytecode )); } // remove redundant String.valueOf for (int i = 0; i < lstOperands.Count; i++) { Exprent rep = RemoveStringValueOf(lstOperands[i]); bool ok = (i > 1); if (!ok) { bool isstr = rep.GetExprType().Equals(VarType.Vartype_String); ok = isstr || first2str != i + 1; if (i == 0) { first2str &= 2; } } if (ok) { lstOperands[i] = rep; } } return(CreateConcatExprent(lstOperands, expr.bytecode)); }