From 0e04dc72b99d7501b49f4bf496207f63ee9d5043 Mon Sep 17 00:00:00 2001 From: Skylot Date: Sat, 27 Apr 2013 21:13:42 +0400 Subject: [PATCH] Avoid variable names clash --- src/main/java/jadx/codegen/InsnGen.java | 2 +- src/main/java/jadx/codegen/MethodGen.java | 43 ++++++++++--------- .../visitors/regions/ProcessVariables.java | 13 +++--- src/samples/java/jadx/samples/TestCF2.java | 13 ++++++ 4 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/main/java/jadx/codegen/InsnGen.java b/src/main/java/jadx/codegen/InsnGen.java index 7f64109c8..9d20976de 100644 --- a/src/main/java/jadx/codegen/InsnGen.java +++ b/src/main/java/jadx/codegen/InsnGen.java @@ -101,7 +101,7 @@ public class InsnGen { } public String declareVar(RegisterArg arg) throws CodegenException { - return useType(arg.getType()) + " " + arg(arg); + return useType(arg.getType()) + " " + mgen.assignArg(arg); } private String lit(LiteralArg arg) { diff --git a/src/main/java/jadx/codegen/MethodGen.java b/src/main/java/jadx/codegen/MethodGen.java index 6d6c22790..8450907d9 100644 --- a/src/main/java/jadx/codegen/MethodGen.java +++ b/src/main/java/jadx/codegen/MethodGen.java @@ -20,12 +20,9 @@ import jadx.utils.Utils; import jadx.utils.exceptions.CodegenException; import jadx.utils.exceptions.DecodeException; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Map; -import java.util.Map.Entry; import java.util.Set; import org.slf4j.Logger; @@ -37,12 +34,12 @@ public class MethodGen { private static final Logger LOG = LoggerFactory.getLogger(MethodGen.class); private final MethodNode mth; - private final Set mthArgsDecls; - private final Map varDecls = new HashMap(); private final ClassGen classGen; private final boolean fallback; private final AnnotationGen annotationGen; + private final Set varNames = new HashSet(); + public MethodGen(ClassGen classGen, MethodNode mth) { this.mth = mth; this.classGen = classGen; @@ -50,9 +47,8 @@ public class MethodGen { this.annotationGen = classGen.getAnnotationGen(); List args = mth.getArguments(true); - mthArgsDecls = new HashSet(args.size()); for (RegisterArg arg : args) { - mthArgsDecls.add(makeArgName(arg)); + varNames.add(makeArgName(arg)); } } @@ -183,11 +179,28 @@ public class MethodGen { */ public String assignArg(RegisterArg arg) { String name = makeArgName(arg); - if (!mthArgsDecls.contains(name)) - varDecls.put(name, arg.getType()); + if (varNames.add(name)) + return name; + + if (fallback) + return name; + + name = getUniqVarName(name); + arg.getTypedVar().setName(name); return name; } + private String getUniqVarName(String name) { + String r; + int i = 2; + do { + r = name + i; + i++; + } while (varNames.contains(r)); + varNames.add(r); + return r; + } + private void makeInitCode(CodeWriter code) throws CodegenException { InsnGen igen = new InsnGen(this, mth, fallback); // generate super call @@ -195,17 +208,6 @@ public class MethodGen { igen.makeInsn(mth.getSuperCall(), code); } - public void makeVariablesDeclaration(CodeWriter code) { - for (Entry var : varDecls.entrySet()) { - code.startLine(TypeGen.translate(classGen, var.getValue())); - code.add(" "); - code.add(var.getKey()); - code.add(";"); - } - if (!varDecls.isEmpty()) - code.endl(); - } - public CodeWriter makeInstructions(int mthIndent) throws CodegenException { CodeWriter code = new CodeWriter(mthIndent + 1); @@ -242,7 +244,6 @@ public class MethodGen { (new RegionGen(this, mth)).makeRegion(insns, mth.getRegion()); makeInitCode(code); - makeVariablesDeclaration(code); code.add(insns); } else { makeFallbackMethod(code, mth); diff --git a/src/main/java/jadx/dex/visitors/regions/ProcessVariables.java b/src/main/java/jadx/dex/visitors/regions/ProcessVariables.java index b5c76ee1f..1f7291354 100644 --- a/src/main/java/jadx/dex/visitors/regions/ProcessVariables.java +++ b/src/main/java/jadx/dex/visitors/regions/ProcessVariables.java @@ -107,13 +107,16 @@ public class ProcessVariables extends AbstractVisitor { // reduce assigns map List mthArgs = mth.getArguments(true); + for (RegisterArg arg : mthArgs) { + usageMap.remove(arg); + } + for (Iterator> it = usageMap.entrySet().iterator(); it.hasNext();) { Entry entry = it.next(); Usage u = entry.getValue(); - RegisterArg r = u.getArg(); - // if no assigns or method argument => remove - if (u.getAssigns().isEmpty() || mthArgs.indexOf(r) != -1) { + // if no assigns => remove + if (u.getAssigns().isEmpty()) { it.remove(); continue; } @@ -122,7 +125,7 @@ public class ProcessVariables extends AbstractVisitor { for (IRegion assignRegion : u.getAssigns()) { if (u.getArgRegion() == assignRegion && canDeclareInRegion(u, assignRegion)) { - r.getParentInsn().getAttributes().add(new DeclareVariableAttr()); + u.getArg().getParentInsn().getAttributes().add(new DeclareVariableAttr()); it.remove(); break; } @@ -132,8 +135,8 @@ public class ProcessVariables extends AbstractVisitor { // apply for (Entry entry : usageMap.entrySet()) { Usage u = entry.getValue(); - // find common region which contains all usage regions + // find region which contain all usage regions Set set = u.getUseRegions(); for (Iterator it = set.iterator(); it.hasNext();) { IRegion r = it.next(); diff --git a/src/samples/java/jadx/samples/TestCF2.java b/src/samples/java/jadx/samples/TestCF2.java index 988e496c1..b90cbd09d 100644 --- a/src/samples/java/jadx/samples/TestCF2.java +++ b/src/samples/java/jadx/samples/TestCF2.java @@ -4,6 +4,18 @@ public class TestCF2 extends AbstractTest { private final Object ready_mutex = new Object(); private boolean ready = false; + public int simple_loops() throws InterruptedException { + int[] a = new int[] { 1, 2, 4, 6, 8 }; + int b = 0; + for (int i = 0; i < a.length; i++) { + b += a[i]; + } + for (long i = b; i > 0; i--) { + b += i; + } + return b; + } + /** * Test infinite loop */ @@ -92,6 +104,7 @@ public class TestCF2 extends AbstractTest { @Override public boolean testRun() throws Exception { + assertEquals(simple_loops(), 252); // TODO add checks return true; }