core: fix inline in 'move' instruction
This commit is contained in:
@@ -24,10 +24,6 @@ public class InsnNode extends LineAttrNode {
|
||||
protected int offset;
|
||||
protected int insnHashCode = super.hashCode();
|
||||
|
||||
protected InsnNode(InsnType type) {
|
||||
this(type, 1);
|
||||
}
|
||||
|
||||
public InsnNode(InsnType type, int argsCount) {
|
||||
this.insnType = type;
|
||||
this.offset = -1;
|
||||
@@ -155,8 +151,10 @@ public class InsnNode extends LineAttrNode {
|
||||
case STR_CONCAT:
|
||||
case MOVE_EXCEPTION:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,6 +16,11 @@ import jadx.core.utils.exceptions.JadxException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Prepare instructions for code generation pass,
|
||||
* most of this modification breaks register dependencies,
|
||||
* so this pass must be just before CodeGen.
|
||||
*/
|
||||
public class PrepareForCodeGen extends AbstractVisitor {
|
||||
|
||||
@Override
|
||||
@@ -26,7 +31,8 @@ public class PrepareForCodeGen extends AbstractVisitor {
|
||||
}
|
||||
for (BlockNode block : blocks) {
|
||||
removeInstructions(block);
|
||||
removeBrackets(block);
|
||||
checkInline(block);
|
||||
removeParenthesis(block);
|
||||
modifyArith(block);
|
||||
}
|
||||
}
|
||||
@@ -52,12 +58,31 @@ public class PrepareForCodeGen extends AbstractVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
private static void removeBrackets(BlockNode block) {
|
||||
private static void checkInline(BlockNode block) {
|
||||
List<InsnNode> list = block.getInstructions();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
InsnNode insn = list.get(i);
|
||||
// replace 'move' with inner wrapped instruction
|
||||
if (insn.getType() == InsnType.MOVE
|
||||
&& insn.getArg(0).isInsnWrap()
|
||||
&& !insn.getAttributes().contains(AttributeFlag.DECLARE_VAR)) {
|
||||
InsnNode wrapInsn = ((InsnWrapArg)insn.getArg(0)).getWrapInsn();
|
||||
wrapInsn.setResult(insn.getResult());
|
||||
list.set(i, wrapInsn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void removeParenthesis(BlockNode block) {
|
||||
for (InsnNode insn : block.getInstructions()) {
|
||||
checkInsn(insn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove parenthesis for wrapped insn in arith '+' or '-'
|
||||
* ('(a + b) +c' => 'a + b + c')
|
||||
*/
|
||||
private static void checkInsn(InsnNode insn) {
|
||||
if (insn.getType() == InsnType.ARITH) {
|
||||
ArithNode arith = (ArithNode) insn;
|
||||
@@ -82,6 +107,10 @@ public class PrepareForCodeGen extends AbstractVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace arithmetic operation with short form
|
||||
* ('a = a + 2' => 'a += 2')
|
||||
*/
|
||||
private static void modifyArith(BlockNode block) {
|
||||
List<InsnNode> list = block.getInstructions();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
|
||||
@@ -3,6 +3,8 @@ package jadx.tests.internal;
|
||||
import jadx.api.InternalJadxTest;
|
||||
import jadx.core.dex.nodes.ClassNode;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.not;
|
||||
import static org.junit.Assert.assertThat;
|
||||
@@ -19,12 +21,13 @@ public class TestArgInline extends InternalJadxTest {
|
||||
}
|
||||
}
|
||||
|
||||
//@Test
|
||||
@Test
|
||||
public void test() {
|
||||
ClassNode cls = getClassNode(TestCls.class);
|
||||
String code = cls.getCode().toString();
|
||||
System.out.println(code);
|
||||
assertThat(code, not(containsString("a = a + 1;")));
|
||||
|
||||
assertThat(code, containsString("a++;"));
|
||||
assertThat(code, not(containsString("a = a + 1;")));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user