提交 f366eac7 编写于 作者: S Skylot

core: fix switch in loop (fix #52)

上级 46d3992b
...@@ -663,7 +663,8 @@ public class RegionMaker { ...@@ -663,7 +663,8 @@ public class RegionMaker {
Map<BlockNode, BlockNode> fallThroughCases = new LinkedHashMap<BlockNode, BlockNode>(); Map<BlockNode, BlockNode> fallThroughCases = new LinkedHashMap<BlockNode, BlockNode>();
BitSet outs = new BitSet(mth.getBasicBlocks().size()); List<BlockNode> basicBlocks = mth.getBasicBlocks();
BitSet outs = new BitSet(basicBlocks.size());
outs.or(block.getDomFrontier()); outs.or(block.getDomFrontier());
for (BlockNode s : block.getCleanSuccessors()) { for (BlockNode s : block.getCleanSuccessors()) {
BitSet df = s.getDomFrontier(); BitSet df = s.getDomFrontier();
...@@ -672,8 +673,8 @@ public class RegionMaker { ...@@ -672,8 +673,8 @@ public class RegionMaker {
if (df.cardinality() > 2) { if (df.cardinality() > 2) {
LOG.debug("Unexpected case pattern, block: {}, mth: {}", s, mth); LOG.debug("Unexpected case pattern, block: {}, mth: {}", s, mth);
} else { } else {
BlockNode first = mth.getBasicBlocks().get(df.nextSetBit(0)); BlockNode first = basicBlocks.get(df.nextSetBit(0));
BlockNode second = mth.getBasicBlocks().get(df.nextSetBit(first.getId() + 1)); BlockNode second = basicBlocks.get(df.nextSetBit(first.getId() + 1));
if (second.getDomFrontier().get(first.getId())) { if (second.getDomFrontier().get(first.getId())) {
fallThroughCases.put(s, second); fallThroughCases.put(s, second);
df = new BitSet(df.size()); df = new BitSet(df.size());
...@@ -687,6 +688,11 @@ public class RegionMaker { ...@@ -687,6 +688,11 @@ public class RegionMaker {
} }
outs.or(df); outs.or(df);
} }
outs.clear(block.getId());
if (loop != null) {
outs.clear(loop.getStart().getId());
}
stack.push(sw); stack.push(sw);
stack.addExits(BlockUtils.bitSetToBlocks(mth, outs)); stack.addExits(BlockUtils.bitSetToBlocks(mth, outs));
...@@ -709,9 +715,8 @@ public class RegionMaker { ...@@ -709,9 +715,8 @@ public class RegionMaker {
} }
if (outs.cardinality() > 1) { if (outs.cardinality() > 1) {
// filter loop start and successors of other blocks // filter loop start and successors of other blocks
List<BlockNode> blocks = mth.getBasicBlocks();
for (int i = outs.nextSetBit(0); i >= 0; i = outs.nextSetBit(i + 1)) { for (int i = outs.nextSetBit(0); i >= 0; i = outs.nextSetBit(i + 1)) {
BlockNode b = blocks.get(i); BlockNode b = basicBlocks.get(i);
outs.andNot(b.getDomFrontier()); outs.andNot(b.getDomFrontier());
if (b.contains(AFlag.LOOP_START)) { if (b.contains(AFlag.LOOP_START)) {
outs.clear(b.getId()); outs.clear(b.getId());
...@@ -745,7 +750,7 @@ public class RegionMaker { ...@@ -745,7 +750,7 @@ public class RegionMaker {
} }
BlockNode out = null; BlockNode out = null;
if (outs.cardinality() == 1) { if (outs.cardinality() == 1) {
out = mth.getBasicBlocks().get(outs.nextSetBit(0)); out = basicBlocks.get(outs.nextSetBit(0));
stack.addExit(out); stack.addExit(out);
} else if (loop == null && outs.cardinality() > 1) { } else if (loop == null && outs.cardinality() > 1) {
LOG.warn("Can't detect out node for switch block: {} in {}", block, mth); LOG.warn("Can't detect out node for switch block: {} in {}", block, mth);
......
package jadx.tests.integration.switches;
import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.IntegrationTest;
import org.junit.Test;
import static jadx.tests.api.utils.JadxMatchers.containsOne;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
public class TestSwitchInLoop extends IntegrationTest {
public static class TestCls {
public int test(int k) {
int a = 0;
while (true) {
switch (k) {
case 0:
return a;
default:
a++;
k >>= 1;
}
}
}
public void check() {
assertEquals(1, test(1));
}
}
@Test
public void test() {
ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString();
assertThat(code, containsOne("switch (k) {"));
assertThat(code, containsOne("case 0:"));
assertThat(code, containsOne("return a;"));
assertThat(code, containsOne("default:"));
assertThat(code, containsOne("a++;"));
assertThat(code, containsOne("k >>= 1;"));
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册