Commit a135eb44 authored by Skylot's avatar Skylot

core: check registers numbers, fix fallback mode

parent 252ed0e1
......@@ -302,7 +302,7 @@ public class ClassGen {
}
}
MethodGen mthGen;
if (badCode || mth.contains(AType.JADX_ERROR)) {
if (badCode || mth.contains(AType.JADX_ERROR) || fallback) {
mthGen = MethodGen.getFallbackMethodGen(mth);
} else {
mthGen = new MethodGen(this, mth);
......@@ -313,7 +313,11 @@ public class ClassGen {
code.add('{');
code.incIndent();
insertSourceFileInfo(code, mth);
mthGen.addInstructions(code);
if (fallback) {
mthGen.addFallbackMethodCode(code);
} else {
mthGen.addInstructions(code);
}
code.decIndent();
code.startLine('}');
}
......@@ -535,7 +539,7 @@ public class ClassGen {
private void insertSourceFileInfo(CodeWriter code, AttrNode node) {
SourceFileAttr sourceFileAttr = node.get(AType.SOURCE_FILE);
if (sourceFileAttr != null) {
code.startLine("// compiled from: ").add(sourceFileAttr.getFileName());
code.startLine("/* compiled from: ").add(sourceFileAttr.getFileName()).add(" */");
}
}
......
......@@ -70,7 +70,7 @@ public class NameGen {
public String useArg(RegisterArg arg) {
String name = arg.getName();
if (name == null) {
if (name == null || fallback) {
return getFallbackName(arg);
}
return name;
......@@ -117,10 +117,7 @@ public class NameGen {
private String getFallbackName(RegisterArg arg) {
String name = arg.getName();
String base = "r" + arg.getRegNum();
if (name != null && !name.equals("this")) {
return base + "_" + name;
}
return base;
return name != null ? base + "_" + name : base;
}
private static String makeNameForType(ArgType type) {
......
......@@ -114,6 +114,26 @@ public class MethodNode extends LineAttrNode implements ILoadable {
}
}
public void checkInstructions() {
List<RegisterArg> list = new ArrayList<RegisterArg>();
for (InsnNode insnNode : instructions) {
if (insnNode == null) {
continue;
}
list.clear();
RegisterArg resultArg = insnNode.getResult();
if (resultArg != null) {
list.add(resultArg);
}
insnNode.getRegisterArgs(list);
for (int i = 0, listSize = list.size(); i < listSize; i++) {
if (list.get(i).getRegNum() >= regsCount) {
throw new JadxRuntimeException("Incorrect register number in instruction: " + insnNode);
}
}
}
}
private void initMethodTypes() {
if (!parseSignature()) {
retType = mthInfo.getReturnType();
......
......@@ -45,6 +45,8 @@ public class BlockMakerVisitor extends AbstractVisitor {
if (mth.isNoCode()) {
return;
}
mth.checkInstructions();
mth.initBasicBlocks();
splitBasicBlocks(mth);
processBlocksTree(mth);
......
package jadx.core.dex.visitors;
import jadx.core.dex.attributes.AType;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.utils.ErrorsCounter;
......@@ -23,6 +24,9 @@ public class DepthTraversal {
}
public static void visit(IDexTreeVisitor visitor, MethodNode mth) {
if (mth.contains(AType.JADX_ERROR)) {
return;
}
try {
visitor.visit(mth);
} catch (Throwable e) {
......
......@@ -335,13 +335,15 @@ public abstract class IntegrationTest extends TestUtils {
return files;
}
public void noDebugInfo() {
protected void noDebugInfo() {
this.withDebugInfo = false;
}
// Try to make test class compilable
@Deprecated
public void disableCompilation() {
protected void setFallback() {
this.isFallback = true;
}
protected void disableCompilation() {
this.compile = false;
}
......@@ -353,12 +355,6 @@ public abstract class IntegrationTest extends TestUtils {
// Use only for debug purpose
@Deprecated
protected void setFallback() {
this.isFallback = true;
}
// Use only for debug purpose
@Deprecated
protected void notDeleteTmpJar() {
this.deleteTmpFiles = false;
}
......
......@@ -25,7 +25,7 @@ public class SmaliTest extends IntegrationTest {
return getClassNodeFromFile(outDex, fullClsName);
}
private File getSmaliFile(String clsName) {
private static File getSmaliFile(String clsName) {
File smaliFile = new File(SMALI_TESTS_DIR, clsName + SMALI_TESTS_EXT);
if (smaliFile.exists()) {
return smaliFile;
......@@ -38,7 +38,7 @@ public class SmaliTest extends IntegrationTest {
return null;
}
public boolean compileSmali(File input, File output) {
private static boolean compileSmali(File input, File output) {
List<String> args = new ArrayList<String>();
args.add(input.getAbsolutePath());
......
package jadx.tests.integration.fallback;
import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.IntegrationTest;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;
public class TestFallbackMode extends IntegrationTest {
public static class TestCls {
public int test(int a) {
while (a < 10) {
a++;
}
return a;
}
}
@Test
public void test() {
setFallback();
disableCompilation();
ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString();
assertThat(code, containsString("public int test(int r2) {"));
assertThat(code, containsString("r1_this = this;"));
assertThat(code, containsString("L_0x0004:"));
assertThat(code, not(containsString("throw new UnsupportedOperationException")));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment