fix: additional insns reorder checks (#1904)

This commit is contained in:
Skylot 2023-06-10 23:36:14 +01:00
parent f558203a9d
commit 38c3f8bf9a
No known key found for this signature in database
GPG Key ID: 1E23F5B52567AA39
2 changed files with 59 additions and 2 deletions

View File

@ -4,6 +4,8 @@ import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
import org.jetbrains.annotations.Nullable;
import jadx.core.dex.instructions.InsnType;
import jadx.core.dex.instructions.args.InsnArg;
import jadx.core.dex.instructions.args.InsnWrapArg;
@ -20,6 +22,7 @@ final class ArgsInfo {
private final int pos;
private int inlineBorder;
private ArgsInfo inlinedInsn;
private @Nullable List<ArgsInfo> wrappedInsns;
public ArgsInfo(InsnNode insn, List<ArgsInfo> argsList, int pos) {
this.insn = insn;
@ -69,7 +72,6 @@ final class ArgsInfo {
private boolean canMove(int from, int to) {
ArgsInfo startInfo = argsList.get(from);
List<RegisterArg> movedArgs = startInfo.getArgs();
int start = from + 1;
if (start == to) {
// previous instruction or on edge of inline border
@ -79,6 +81,7 @@ final class ArgsInfo {
throw new JadxRuntimeException("Invalid inline insn positions: " + start + " - " + to);
}
BitSet movedSet;
List<RegisterArg> movedArgs = startInfo.getArgs();
if (movedArgs.isEmpty()) {
if (startInfo.insn.isConstInsn()) {
return true;
@ -90,7 +93,7 @@ final class ArgsInfo {
movedSet.set(arg.getRegNum());
}
}
boolean canReorder = startInfo.insn.canReorder();
boolean canReorder = startInfo.canReorder();
for (int i = start; i < to; i++) {
ArgsInfo argsInfo = argsList.get(i);
if (argsInfo.getInlinedInsn() == this) {
@ -110,6 +113,21 @@ final class ArgsInfo {
return true;
}
private boolean canReorder() {
if (!insn.canReorder()) {
return false;
}
List<ArgsInfo> wrapList = wrappedInsns;
if (wrapList != null) {
for (ArgsInfo wrapInsn : wrapList) {
if (!wrapInsn.canReorder()) {
return false;
}
}
}
return true;
}
static boolean usedArgAssign(InsnNode insn, BitSet args) {
if (args.isEmpty()) {
return false;
@ -124,6 +142,10 @@ final class ArgsInfo {
WrapInfo inline(int assignInsnPos, RegisterArg arg) {
ArgsInfo argsInfo = argsList.get(assignInsnPos);
argsInfo.inlinedInsn = this;
if (wrappedInsns == null) {
wrappedInsns = new ArrayList<>(args.size());
}
wrappedInsns.add(argsInfo);
return new WrapInfo(argsInfo.insn, arg);
}

View File

@ -0,0 +1,35 @@
package jadx.tests.integration.others;
import org.junit.jupiter.api.Test;
import jadx.tests.api.IntegrationTest;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class TestFieldAccessReorder extends IntegrationTest {
public static class TestCls {
private long field = 10;
public final boolean test() {
long value = longCall();
long diff = value - this.field;
this.field = value;
return diff > 250;
}
public static long longCall() {
return 261L;
}
public void check() {
assertTrue(test());
}
}
@Test
public void test() {
noDebugInfo();
getClassNode(TestCls.class);
// auto check should pass
}
}