mirror of
https://github.com/skylot/jadx.git
synced 2024-11-23 21:00:06 +00:00
core: fix source line for some return instructions
This commit is contained in:
parent
ec3b71e5b6
commit
2b7f8931a4
@ -249,7 +249,9 @@ public class CodeShrinker extends AbstractVisitor {
|
||||
private static boolean inline(RegisterArg arg, InsnNode insn, @Nullable BlockNode block, MethodNode mth) {
|
||||
InsnNode parentInsn = arg.getParentInsn();
|
||||
// replace move instruction if needed
|
||||
if (parentInsn != null && parentInsn.getType() == InsnType.MOVE) {
|
||||
if (parentInsn != null) {
|
||||
switch (parentInsn.getType()) {
|
||||
case MOVE: {
|
||||
if (block == null) {
|
||||
block = BlockUtils.getBlockByInsn(mth, parentInsn);
|
||||
}
|
||||
@ -264,6 +266,13 @@ public class CodeShrinker extends AbstractVisitor {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RETURN: {
|
||||
parentInsn.setSourceLine(insn.getSourceLine());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// simple case
|
||||
return arg.wrapInstruction(insn) != null;
|
||||
|
@ -69,7 +69,7 @@ public class ConstInlinerVisitor extends AbstractVisitor {
|
||||
if (!arg.getType().isTypeKnown()) {
|
||||
arg.merge(resType);
|
||||
}
|
||||
return replaceConst(mth, sVar, lit);
|
||||
return replaceConst(mth, insn, lit);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,13 +98,11 @@ public class ConstInlinerVisitor extends AbstractVisitor {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean replaceConst(MethodNode mth, SSAVar sVar, long literal) {
|
||||
private static boolean replaceConst(MethodNode mth, InsnNode constInsn, long literal) {
|
||||
SSAVar sVar = constInsn.getResult().getSVar();
|
||||
List<RegisterArg> use = new ArrayList<RegisterArg>(sVar.getUseList());
|
||||
int replaceCount = 0;
|
||||
for (RegisterArg arg : use) {
|
||||
// if (arg.getSVar().isUsedInPhi()) {
|
||||
// continue;
|
||||
// }
|
||||
InsnNode useInsn = arg.getParentInsn();
|
||||
if (useInsn == null || useInsn.getType() == InsnType.PHI) {
|
||||
continue;
|
||||
@ -125,6 +123,9 @@ public class ConstInlinerVisitor extends AbstractVisitor {
|
||||
if (useInsn.replaceArg(arg, litArg)) {
|
||||
fixTypes(mth, useInsn, litArg);
|
||||
replaceCount++;
|
||||
if (useInsn.getType() == InsnType.RETURN) {
|
||||
useInsn.setSourceLine(constInsn.getSourceLine());
|
||||
}
|
||||
|
||||
FieldNode f = null;
|
||||
ArgType litArgType = litArg.getType();
|
||||
|
@ -41,9 +41,8 @@ public class TestTernary3 extends IntegrationTest {
|
||||
ClassNode cls = getClassNode(TestCls.class);
|
||||
String code = cls.getCode().toString();
|
||||
|
||||
// TODO:
|
||||
assertThat(code, containsOne("return (n == null || !(arg instanceof Named)) "
|
||||
+ "? false : n.equals(((Named) arg).getName());"));
|
||||
assertThat(code, containsOne("if (n == null || !(arg instanceof Named)) {"));
|
||||
assertThat(code, containsOne("return n.equals(((Named) arg).getName());"));
|
||||
|
||||
assertThat(code, not(containsString("if ((arg instanceof RegisterArg)) {")));
|
||||
}
|
||||
|
@ -0,0 +1,75 @@
|
||||
package jadx.tests.integration.debuginfo;
|
||||
|
||||
import jadx.core.codegen.CodeWriter;
|
||||
import jadx.core.dex.attributes.nodes.LineAttrNode;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
import jadx.core.dex.nodes.MethodNode;
|
||||
import jadx.tests.api.IntegrationTest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static jadx.tests.api.utils.JadxMatchers.containsOne;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class TestReturnSourceLine extends IntegrationTest {
|
||||
|
||||
public static class TestCls {
|
||||
public int test1(boolean v) {
|
||||
if (v) {
|
||||
f();
|
||||
return 1;
|
||||
}
|
||||
f();
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int test2(int v) {
|
||||
if (v == 0) {
|
||||
f();
|
||||
return v - 1;
|
||||
}
|
||||
f();
|
||||
return v + 1;
|
||||
}
|
||||
|
||||
public int test3(int v) {
|
||||
if (v == 0) {
|
||||
f();
|
||||
return v;
|
||||
}
|
||||
f();
|
||||
return v + 1;
|
||||
}
|
||||
|
||||
private void f() {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
ClassNode cls = getClassNode(TestCls.class);
|
||||
CodeWriter codeWriter = cls.getCode();
|
||||
String code = codeWriter.toString();
|
||||
String[] lines = code.split(CodeWriter.NL);
|
||||
|
||||
MethodNode test1 = cls.searchMethodByName("test1(Z)I");
|
||||
checkLine(lines, codeWriter, test1, 3, "return 1;");
|
||||
|
||||
MethodNode test2 = cls.searchMethodByName("test2(I)I");
|
||||
checkLine(lines, codeWriter, test2, 3, "return v - 1;");
|
||||
|
||||
// TODO:
|
||||
// MethodNode test3 = cls.searchMethodByName("test3(I)I");
|
||||
// checkLine(lines, codeWriter, test3, 3, "return v;");
|
||||
}
|
||||
|
||||
private static void checkLine(String[] lines, CodeWriter cw, LineAttrNode node, int offset, String str) {
|
||||
int decompiledLine = node.getDecompiledLine() + offset;
|
||||
assertThat(lines[decompiledLine - 1], containsOne(str));
|
||||
Integer sourceLine = cw.getLineMapping().get(decompiledLine);
|
||||
assertNotNull(sourceLine);
|
||||
assertEquals(node.getSourceLine() + offset, (int) sourceLine);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user