From 8e73f37eba655a280a3a6749ab64a6dd5b73ef91 Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 30 Jan 2016 16:29:22 -0500 Subject: [PATCH] boolean ifeq vs ificmpne. I want to unwrap these smaller ifs into larger ones to simplify code. --- .../attributes/code/instructions/IfEq.java | 21 ++++++++++++++++++- .../code/instructions/IfICmpEq.java | 14 +++++++++++-- .../net/runelite/deob/execution/Type.java | 5 +++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IfEq.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IfEq.java index 75aa94efd1..3dd9c408a7 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IfEq.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IfEq.java @@ -2,6 +2,7 @@ package net.runelite.deob.attributes.code.instructions; import net.runelite.deob.attributes.code.InstructionType; import net.runelite.deob.attributes.code.Instructions; +import static net.runelite.deob.attributes.code.instructions.IfICmpEq.isOne; import static net.runelite.deob.attributes.code.instructions.IfICmpEq.isZero; import net.runelite.deob.deobfuscators.rename.ParallelExecutorMapping; import net.runelite.deob.execution.InstructionContext; @@ -31,6 +32,12 @@ public class IfEq extends If0 if (isZero(s1) || isZero(s2)) return true; + + if (otherIc.getInstruction() instanceof IfICmpNe) + { + if ((isOne(s1) && s2.getType().isBoolean()) || (isOne(s2) && s1.getType().isBoolean())) + return true; + } } return false; @@ -39,7 +46,19 @@ public class IfEq extends If0 @Override public void map(ParallelExecutorMapping mapping, InstructionContext ctx, InstructionContext other) { - if (other.getInstruction() instanceof IfNe || other.getInstruction() instanceof IfICmpNe) + if (other.getInstruction() instanceof IfICmpNe) + { + StackContext s1 = other.getPops().get(0), + s2 = other.getPops().get(1); + + if (isZero(s1) || isZero(s2)) + super.mapOtherBranch(mapping, ctx, other); // ifeq 0 vs ificmpne 0 + else if (isOne(s1) || isOne(s2)) + super.map(mapping, ctx, other); // iseq 0 vs ifne 1 + else + assert false; + } + else if (other.getInstruction() instanceof IfNe) { super.mapOtherBranch(mapping, ctx, other); } diff --git a/src/main/java/net/runelite/deob/attributes/code/instructions/IfICmpEq.java b/src/main/java/net/runelite/deob/attributes/code/instructions/IfICmpEq.java index 0f75242989..7f5f94a8c8 100644 --- a/src/main/java/net/runelite/deob/attributes/code/instructions/IfICmpEq.java +++ b/src/main/java/net/runelite/deob/attributes/code/instructions/IfICmpEq.java @@ -14,20 +14,30 @@ public class IfICmpEq extends If super(instructions, type, pc); } - static boolean isZero(StackContext s) + static boolean is(StackContext s, int val) { if (s.getPushed().getInstruction() instanceof PushConstantInstruction) { PushConstantInstruction pc = (PushConstantInstruction) s.getPushed().getInstruction(); Object o = pc.getConstant().getObject(); - if (o instanceof Integer && (int) o == 0) + if (o instanceof Integer && (int) o == val) return true; } return false; } + static boolean isZero(StackContext s) + { + return is(s, 0); + } + + static boolean isOne(StackContext s) + { + return is(s, 1); + } + @Override public boolean isSame(InstructionContext thisIc, InstructionContext otherIc) { diff --git a/src/main/java/net/runelite/deob/execution/Type.java b/src/main/java/net/runelite/deob/execution/Type.java index 91e113f001..49277da0fd 100644 --- a/src/main/java/net/runelite/deob/execution/Type.java +++ b/src/main/java/net/runelite/deob/execution/Type.java @@ -31,6 +31,11 @@ public class Type return toStackType().equals(new Type(int.class.getName())); } + public boolean isBoolean() + { + return type.equals("boolean"); + } + private static String asmTypeToClass(String type) { switch (type)