From 08c9d1228a454c6d93d454c572a7087aab5936eb Mon Sep 17 00:00:00 2001 From: Skylot Date: Fri, 2 May 2014 19:33:15 +0400 Subject: [PATCH] core: inline 'cmp' instruction --- .../java/jadx/core/dex/regions/Compare.java | 4 ++ .../jadx/core/dex/regions/IfCondition.java | 20 ++++++ .../tests/internal/conditions/TestCmpOp.java | 67 +++++++++++++++++++ .../tests/internal/conditions/TestCmpOp2.java | 32 +++++++++ 4 files changed, 123 insertions(+) create mode 100644 jadx-core/src/test/java/jadx/tests/internal/conditions/TestCmpOp.java create mode 100644 jadx-core/src/test/java/jadx/tests/internal/conditions/TestCmpOp2.java diff --git a/jadx-core/src/main/java/jadx/core/dex/regions/Compare.java b/jadx-core/src/main/java/jadx/core/dex/regions/Compare.java index 5716f4ec..d070f5fc 100644 --- a/jadx-core/src/main/java/jadx/core/dex/regions/Compare.java +++ b/jadx-core/src/main/java/jadx/core/dex/regions/Compare.java @@ -24,6 +24,10 @@ public final class Compare { return insn.getArg(1); } + public IfNode getInsn() { + return insn; + } + public Compare invert() { insn.invertCondition(); return this; diff --git a/jadx-core/src/main/java/jadx/core/dex/regions/IfCondition.java b/jadx-core/src/main/java/jadx/core/dex/regions/IfCondition.java index fb85b489..c0452c14 100644 --- a/jadx-core/src/main/java/jadx/core/dex/regions/IfCondition.java +++ b/jadx-core/src/main/java/jadx/core/dex/regions/IfCondition.java @@ -2,10 +2,13 @@ package jadx.core.dex.regions; import jadx.core.dex.instructions.IfNode; import jadx.core.dex.instructions.IfOp; +import jadx.core.dex.instructions.InsnType; import jadx.core.dex.instructions.args.InsnArg; +import jadx.core.dex.instructions.args.InsnWrapArg; import jadx.core.dex.instructions.args.LiteralArg; import jadx.core.dex.instructions.args.RegisterArg; import jadx.core.dex.nodes.BlockNode; +import jadx.core.dex.nodes.InsnNode; import jadx.core.utils.exceptions.JadxRuntimeException; import java.util.ArrayList; @@ -132,6 +135,7 @@ public final class IfCondition { public static IfCondition simplify(IfCondition cond) { if (cond.isCompare()) { Compare c = cond.getCompare(); + simplifyCmpOp(c); if (c.getOp() == IfOp.EQ && c.getB().isLiteral() && c.getB().equals(LiteralArg.FALSE)) { return not(new IfCondition(c.invert())); } else { @@ -177,6 +181,22 @@ public final class IfCondition { return cond; } + private static void simplifyCmpOp(Compare c) { + if (!c.getA().isInsnWrap()) { + return; + } + if (!c.getB().isLiteral() || ((LiteralArg) c.getB()).getLiteral() != 0) { + return; + } + InsnNode wrapInsn = ((InsnWrapArg) c.getA()).getWrapInsn(); + InsnType type = wrapInsn.getType(); + if (type != InsnType.CMP_L && type != InsnType.CMP_G) { + return; + } + IfNode insn = c.getInsn(); + insn.changeCondition(insn.getOp(), wrapInsn.getArg(0), wrapInsn.getArg(1)); + } + public List getRegisterArgs() { List list = new LinkedList(); if (mode == Mode.COMPARE) { diff --git a/jadx-core/src/test/java/jadx/tests/internal/conditions/TestCmpOp.java b/jadx-core/src/test/java/jadx/tests/internal/conditions/TestCmpOp.java new file mode 100644 index 00000000..9253bdc1 --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/internal/conditions/TestCmpOp.java @@ -0,0 +1,67 @@ +package jadx.tests.internal.conditions; + +import jadx.api.InternalJadxTest; +import jadx.core.dex.nodes.ClassNode; + +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; + +public class TestCmpOp extends InternalJadxTest { + + public static class TestCls { + public boolean testGT(float a) { + return a > 3.0f; + } + + public boolean testLT(float b) { + return b < 2.0f; + } + + public boolean testEQ(float c) { + return c == 1.0f; + } + + public boolean testNE(float d) { + return d != 0.0f; + } + + public boolean testGE(float e) { + return e >= -1.0f; + } + + public boolean testLE(float f) { + return f <= -2.0f; + } + + public boolean testGT2(float g) { + return 4.0f > g; + } + + public boolean testLT2(long h) { + return 5 < h; + } + + public boolean testGE2(double i) { + return 6.5d < i; + } + } + + @Test + public void test() { + ClassNode cls = getClassNode(TestCls.class); + String code = cls.getCode().toString(); + System.out.println(code); + + assertThat(code, containsString("return a > 3.0f;")); + assertThat(code, containsString("return b < 2.0f;")); + assertThat(code, containsString("return c == 1.0f;")); + assertThat(code, containsString("return d != 0.0f;")); + assertThat(code, containsString("return e >= -1.0f;")); + assertThat(code, containsString("return f <= -2.0f;")); + assertThat(code, containsString("return 4.0f > g;")); + assertThat(code, containsString("return 5 < h;")); + assertThat(code, containsString("return 6.5d < i;")); + } +} diff --git a/jadx-core/src/test/java/jadx/tests/internal/conditions/TestCmpOp2.java b/jadx-core/src/test/java/jadx/tests/internal/conditions/TestCmpOp2.java new file mode 100644 index 00000000..674bc5c2 --- /dev/null +++ b/jadx-core/src/test/java/jadx/tests/internal/conditions/TestCmpOp2.java @@ -0,0 +1,32 @@ +package jadx.tests.internal.conditions; + +import jadx.api.InternalJadxTest; +import jadx.core.dex.nodes.ClassNode; + +import org.junit.Test; + +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertThat; + +public class TestCmpOp2 extends InternalJadxTest { + + public static class TestCls { + public boolean testGT(float a, float b) { + return a > b; + } + + public boolean testLT(float c, double d) { + return c < d; + } + } + + @Test + public void test() { + ClassNode cls = getClassNode(TestCls.class); + String code = cls.getCode().toString(); + System.out.println(code); + + assertThat(code, containsString("return a > b;")); + assertThat(code, containsString("return ((double) c) < d;")); + } +} -- GitLab