Package jadx.core.dex.regions

Examples of jadx.core.dex.regions.SwitchRegion


    stack.pop();
    return currentIf.getOutBlock();
  }

  private BlockNode processSwitch(IRegion currentRegion, BlockNode block, SwitchNode insn, RegionStack stack) {
    SwitchRegion sw = new SwitchRegion(currentRegion, block);
    currentRegion.getSubBlocks().add(sw);

    int len = insn.getTargets().length;
    // sort by target
    Map<Integer, List<Object>> casesMap = new LinkedHashMap<Integer, List<Object>>(len);
    for (int i = 0; i < len; i++) {
      Object key = insn.getKeys()[i];
      int targ = insn.getTargets()[i];
      List<Object> keys = casesMap.get(targ);
      if (keys == null) {
        keys = new ArrayList<Object>(2);
        casesMap.put(targ, keys);
      }
      keys.add(key);
    }

    Map<BlockNode, List<Object>> blocksMap = new LinkedHashMap<BlockNode, List<Object>>(len);
    for (Map.Entry<Integer, List<Object>> entry : casesMap.entrySet()) {
      BlockNode c = getBlockByOffset(entry.getKey(), block.getSuccessors());
      assert c != null;
      blocksMap.put(c, entry.getValue());
    }

    BitSet succ = BlockUtils.blocksToBitSet(mth, block.getSuccessors());
    BitSet domsOn = BlockUtils.blocksToBitSet(mth, block.getDominatesOn());
    domsOn.xor(succ); // filter 'out' block

    BlockNode defCase = getBlockByOffset(insn.getDefaultCaseOffset(), block.getSuccessors());
    if (defCase != null) {
      blocksMap.remove(defCase);
    }

    int outCount = domsOn.cardinality();
    if (outCount > 1) {
      // remove exception handlers
      BlockUtils.cleanBitSet(mth, domsOn);
      outCount = domsOn.cardinality();
    }
    if (outCount > 1) {
      // filter successors of other blocks
      List<BlockNode> blocks = mth.getBasicBlocks();
      for (int i = domsOn.nextSetBit(0); i >= 0; i = domsOn.nextSetBit(i + 1)) {
        BlockNode b = blocks.get(i);
        for (BlockNode s : b.getCleanSuccessors()) {
          domsOn.clear(s.getId());
        }
      }
      outCount = domsOn.cardinality();
    }

    BlockNode out = null;
    if (outCount == 1) {
      out = mth.getBasicBlocks().get(domsOn.nextSetBit(0));
    } else if (outCount == 0) {
      // one or several case blocks are empty,
      // run expensive algorithm for find 'out' block
      for (BlockNode maybeOut : block.getSuccessors()) {
        boolean allReached = true;
        for (BlockNode s : block.getSuccessors()) {
          if (!isPathExists(s, maybeOut)) {
            allReached = false;
            break;
          }
        }
        if (allReached) {
          out = maybeOut;
          break;
        }
      }
    }

    stack.push(sw);
    if (out != null) {
      stack.addExit(out);
    }

    if (!stack.containsExit(defCase)) {
      sw.setDefaultCase(makeRegion(defCase, stack));
    }
    for (Entry<BlockNode, List<Object>> entry : blocksMap.entrySet()) {
      BlockNode c = entry.getKey();
      if (stack.containsExit(c)) {
        // empty case block
        sw.addCase(entry.getValue(), new Region(stack.peekRegion()));
      } else {
        sw.addCase(entry.getValue(), makeRegion(c, stack));
      }
    }

    stack.pop();
    return out;
View Full Code Here

TOP

Related Classes of jadx.core.dex.regions.SwitchRegion

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.