Avoid variable names clash
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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<String> mthArgsDecls;
|
||||
private final Map<String, ArgType> varDecls = new HashMap<String, ArgType>();
|
||||
private final ClassGen classGen;
|
||||
private final boolean fallback;
|
||||
private final AnnotationGen annotationGen;
|
||||
|
||||
private final Set<String> varNames = new HashSet<String>();
|
||||
|
||||
public MethodGen(ClassGen classGen, MethodNode mth) {
|
||||
this.mth = mth;
|
||||
this.classGen = classGen;
|
||||
@@ -50,9 +47,8 @@ public class MethodGen {
|
||||
this.annotationGen = classGen.getAnnotationGen();
|
||||
|
||||
List<RegisterArg> args = mth.getArguments(true);
|
||||
mthArgsDecls = new HashSet<String>(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<String, ArgType> 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);
|
||||
|
||||
@@ -107,13 +107,16 @@ public class ProcessVariables extends AbstractVisitor {
|
||||
|
||||
// reduce assigns map
|
||||
List<RegisterArg> mthArgs = mth.getArguments(true);
|
||||
for (RegisterArg arg : mthArgs) {
|
||||
usageMap.remove(arg);
|
||||
}
|
||||
|
||||
for (Iterator<Entry<RegisterArg, Usage>> it = usageMap.entrySet().iterator(); it.hasNext();) {
|
||||
Entry<RegisterArg, Usage> 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<RegisterArg, Usage> entry : usageMap.entrySet()) {
|
||||
Usage u = entry.getValue();
|
||||
// find common region which contains all usage regions
|
||||
|
||||
// find region which contain all usage regions
|
||||
Set<IRegion> set = u.getUseRegions();
|
||||
for (Iterator<IRegion> it = set.iterator(); it.hasNext();) {
|
||||
IRegion r = it.next();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user