Commit 3d0c6e49 authored by Skylot's avatar Skylot

core: fix inline in 'move' instruction

parent 03da35b2
......@@ -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;")));
}
}
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