Package jadx.core.dex.nodes

Examples of jadx.core.dex.nodes.BlockNode


    }
    return false;
  }

  private CodeWriter makeLoop(LoopRegion region, CodeWriter code) throws CodegenException {
    BlockNode header = region.getHeader();
    if (header != null) {
      List<InsnNode> headerInsns = header.getInstructions();
      if (headerInsns.size() > 1) {
        ErrorsCounter.methodError(mth, "Found not inlined instructions from loop header");
        int last = headerInsns.size() - 1;
        for (int i = 0; i < last; i++) {
          InsnNode insn = headerInsns.get(i);
View Full Code Here


    return op;
  }

  public void invertCondition() {
    op = op.invert();
    BlockNode tmp = thenBlock;
    thenBlock = elseBlock;
    elseBlock = tmp;
    target = thenBlock.getStartOffset();
  }
View Full Code Here

  }

  private static void splitBasicBlocks(MethodNode mth) {
    InsnNode prevInsn = null;
    Map<Integer, BlockNode> blocksMap = new HashMap<Integer, BlockNode>();
    BlockNode curBlock = startNewBlock(mth, 0);
    mth.setEnterBlock(curBlock);

    // split into blocks
    for (InsnNode insn : mth.getInstructions()) {
      if (insn == null) {
        continue;
      }
      boolean startNew = false;
      if (prevInsn != null) {
        InsnType type = prevInsn.getType();
        if (type == InsnType.GOTO
            || type == InsnType.THROW
            || SEPARATE_INSNS.contains(type)) {

          if (type == InsnType.RETURN || type == InsnType.THROW) {
            mth.addExitBlock(curBlock);
          }
          BlockNode block = startNewBlock(mth, insn.getOffset());
          if (type == InsnType.MONITOR_ENTER || type == InsnType.MONITOR_EXIT) {
            connect(curBlock, block);
          }
          curBlock = block;
          startNew = true;
        } else {
          startNew = isSplitByJump(prevInsn, insn)
              || SEPARATE_INSNS.contains(insn.getType())
              || isDoWhile(blocksMap, curBlock, insn);
          if (startNew) {
            BlockNode block = startNewBlock(mth, insn.getOffset());
            connect(curBlock, block);
            curBlock = block;
          }
        }
      }
      // for try/catch make empty block for connect handlers
      if (insn.contains(AFlag.TRY_ENTER)) {
        BlockNode block;
        if (insn.getOffset() != 0 && !startNew) {
          block = startNewBlock(mth, insn.getOffset());
          connect(curBlock, block);
          curBlock = block;
        }
        blocksMap.put(insn.getOffset(), curBlock);

        // add this insn in new block
        block = startNewBlock(mth, -1);
        curBlock.add(AFlag.SYNTHETIC);
        SplitterBlockAttr splitter = new SplitterBlockAttr(curBlock);
        block.addAttr(splitter);
        curBlock.addAttr(splitter);
        connect(curBlock, block);
        curBlock = block;
      } else {
        blocksMap.put(insn.getOffset(), curBlock);
View Full Code Here

  private static void setupConnections(MethodNode mth, Map<Integer, BlockNode> blocksMap) {
    for (BlockNode block : mth.getBasicBlocks()) {
      for (InsnNode insn : block.getInstructions()) {
        List<JumpInfo> jumps = insn.getAll(AType.JUMP);
        for (JumpInfo jump : jumps) {
          BlockNode srcBlock = getBlock(jump.getSrc(), blocksMap);
          BlockNode thisBlock = getBlock(jump.getDest(), blocksMap);
          connect(srcBlock, thisBlock);
        }

        // connect exception handlers
        CatchAttr catches = insn.get(AType.CATCH_BLOCK);
        // get synthetic block for handlers
        SplitterBlockAttr spl = block.get(AType.SPLITTER_BLOCK);
        if (catches != null && spl != null) {
          BlockNode splitterBlock = spl.getBlock();
          boolean tryEnd = insn.contains(AFlag.TRY_LEAVE);
          for (ExceptionHandler h : catches.getTryBlock().getHandlers()) {
            BlockNode handlerBlock = getBlock(h.getHandleOffset(), blocksMap);
            // skip self loop in handler
            if (splitterBlock != handlerBlock) {
              connect(splitterBlock, handlerBlock);
            }
            if (tryEnd) {
View Full Code Here

  private static boolean isDoWhile(Map<Integer, BlockNode> blocksMap, BlockNode curBlock, InsnNode insn) {
    // split 'do-while' block (last instruction: 'if', target this block)
    if (insn.getType() == InsnType.IF) {
      IfNode ifs = (IfNode) (insn);
      BlockNode targetBlock = blocksMap.get(ifs.getTarget());
      if (targetBlock == curBlock) {
        return true;
      }
    }
    return false;
View Full Code Here

    registerLoops(mth);
    processNestedLoops(mth);
  }

  private static BlockNode getBlock(int offset, Map<Integer, BlockNode> blocksMap) {
    BlockNode block = blocksMap.get(offset);
    assert block != null;
    return block;
  }
View Full Code Here

    from.getSuccessors().remove(to);
    to.getPredecessors().remove(from);
  }

  private static BlockNode startNewBlock(MethodNode mth, int offset) {
    BlockNode block = new BlockNode(mth.getBasicBlocks().size(), offset);
    mth.getBasicBlocks().add(block);
    return block;
  }
View Full Code Here

  private static void computeDominators(MethodNode mth) {
    List<BlockNode> basicBlocks = mth.getBasicBlocks();
    int nBlocks = basicBlocks.size();
    for (int i = 0; i < nBlocks; i++) {
      BlockNode block = basicBlocks.get(i);
      block.setId(i);
      block.setDoms(new BitSet(nBlocks));
      block.getDoms().set(0, nBlocks);
    }

    BlockNode entryBlock = mth.getEnterBlock();
    entryBlock.getDoms().clear();
    entryBlock.getDoms().set(entryBlock.getId());

    BitSet dset = new BitSet(nBlocks);
    boolean changed;
    do {
      changed = false;
      for (BlockNode block : basicBlocks) {
        if (block == entryBlock) {
          continue;
        }
        BitSet d = block.getDoms();
        if (!changed) {
          dset.clear();
          dset.or(d);
        }
        for (BlockNode pred : block.getPredecessors()) {
          d.and(pred.getDoms());
        }
        d.set(block.getId());
        if (!changed && !d.equals(dset)) {
          changed = true;
        }
      }
    } while (changed);

    markLoops(mth);

    // clear self dominance
    for (BlockNode block : basicBlocks) {
      block.getDoms().clear(block.getId());
    }

    // calculate immediate dominators
    for (BlockNode block : basicBlocks) {
      if (block == entryBlock) {
        continue;
      }
      BlockNode idom;
      List<BlockNode> preds = block.getPredecessors();
      if (preds.size() == 1) {
        idom = preds.get(0);
      } else {
        BitSet bs = new BitSet(block.getDoms().length());
        bs.or(block.getDoms());
        for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1)) {
          BlockNode dom = basicBlocks.get(i);
          bs.andNot(dom.getDoms());
        }
        if (bs.cardinality() != 1) {
          throw new JadxRuntimeException("Can't find immediate dominator for block " + block
              + " in " + bs + " preds:" + preds);
        }
View Full Code Here

            break;
          }
        }
        if (oneHeader) {
          // several back edges connected to one loop header => make additional block
          BlockNode newLoopHeader = startNewBlock(mth, block.getStartOffset());
          newLoopHeader.add(AFlag.SYNTHETIC);
          connect(newLoopHeader, block);
          for (LoopInfo la : loops) {
            BlockNode node = la.getEnd();
            removeConnection(node, block);
            connect(node, newLoopHeader);
          }
          return true;
        }
      }
      if (loops.size() == 1) {
        LoopInfo loop = loops.get(0);
        // insert additional blocks for possible 'break' insertion
        List<Edge> edges = loop.getExitEdges();
        if (!edges.isEmpty()) {
          boolean change = false;
          for (Edge edge : edges) {
            BlockNode target = edge.getTarget();
            if (!target.contains(AFlag.SYNTHETIC)) {
              insertBlockBetween(mth, edge.getSource(), target);
              change = true;
            }
          }
          if (change) {
            return true;
          }
        }
        // insert additional blocks for possible 'continue' insertion
        BlockNode loopEnd = loop.getEnd();
        if (loopEnd.getPredecessors().size() > 1) {
          boolean change = false;
          List<BlockNode> nodes = new ArrayList<BlockNode>(loopEnd.getPredecessors());
          for (BlockNode pred : nodes) {
            if (!pred.contains(AFlag.SYNTHETIC)) {
              insertBlockBetween(mth, pred, loopEnd);
              change = true;
            }
View Full Code Here

  private RegionUtils() {
  }

  public static boolean hasExitEdge(IContainer container) {
    if (container instanceof BlockNode) {
      BlockNode block = (BlockNode) container;
      return !block.getSuccessors().isEmpty()
          && !block.contains(AFlag.RETURN);
    } else if (container instanceof IRegion) {
      IRegion region = (IRegion) container;
      List<IContainer> blocks = region.getSubBlocks();
      return !blocks.isEmpty() && hasExitEdge(blocks.get(blocks.size() - 1));
    } else {
View Full Code Here

TOP

Related Classes of jadx.core.dex.nodes.BlockNode

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.