Пример #1
0
  private void processExcHandler(ExceptionHandler handler, Set<BlockNode> exits) {
    BlockNode start = handler.getHandlerBlock();
    if (start == null) {
      return;
    }
    RegionStack stack = new RegionStack(mth);
    BlockNode dom;
    if (handler.isFinally()) {
      SplitterBlockAttr splitterAttr = start.get(AType.SPLITTER_BLOCK);
      if (splitterAttr == null) {
        return;
      }
      dom = splitterAttr.getBlock();
    } else {
      dom = start;
      stack.addExits(exits);
    }
    BitSet domFrontier = dom.getDomFrontier();
    List<BlockNode> handlerExits = BlockUtils.bitSetToBlocks(mth, domFrontier);
    boolean inLoop = mth.getLoopForBlock(start) != null;
    for (BlockNode exit : handlerExits) {
      if ((!inLoop || BlockUtils.isPathExists(start, exit))
          && RegionUtils.isRegionContainsBlock(mth.getRegion(), exit)) {
        stack.addExit(exit);
      }
    }
    handler.setHandlerRegion(makeRegion(start, stack));

    ExcHandlerAttr excHandlerAttr = start.get(AType.EXC_HANDLER);
    if (excHandlerAttr == null) {
      LOG.warn("Missing exception handler attribute for start block");
    } else {
      handler.getHandlerRegion().addAttr(excHandlerAttr);
    }
  }
Пример #2
0
 private static boolean removePhiList(MethodNode mth, List<PhiInsn> insnToRemove) {
   if (insnToRemove.isEmpty()) {
     return false;
   }
   for (BlockNode block : mth.getBasicBlocks()) {
     PhiListAttr phiList = block.get(AType.PHI_LIST);
     if (phiList == null) {
       continue;
     }
     List<PhiInsn> list = phiList.getList();
     for (PhiInsn phiInsn : insnToRemove) {
       if (list.remove(phiInsn)) {
         for (InsnArg arg : phiInsn.getArguments()) {
           SSAVar sVar = ((RegisterArg) arg).getSVar();
           if (sVar != null) {
             sVar.setUsedInPhi(null);
           }
         }
         InstructionRemover.remove(mth, block, phiInsn);
       }
     }
     if (list.isEmpty()) {
       block.remove(AType.PHI_LIST);
     }
   }
   insnToRemove.clear();
   return true;
 }
Пример #3
0
 private static void renameVar(MethodNode mth, SSAVar[] vars, int[] vers, BlockNode block) {
   SSAVar[] inputVars = Arrays.copyOf(vars, vars.length);
   for (InsnNode insn : block.getInstructions()) {
     if (insn.getType() != InsnType.PHI) {
       for (InsnArg arg : insn.getArguments()) {
         if (!arg.isRegister()) {
           continue;
         }
         RegisterArg reg = (RegisterArg) arg;
         int regNum = reg.getRegNum();
         SSAVar var = vars[regNum];
         if (var == null) {
           throw new JadxRuntimeException(
               "Not initialized variable reg: "
                   + regNum
                   + ", insn: "
                   + insn
                   + ", block:"
                   + block
                   + ", method: "
                   + mth);
         }
         var.use(reg);
       }
     }
     RegisterArg result = insn.getResult();
     if (result != null) {
       int regNum = result.getRegNum();
       vars[regNum] = mth.makeNewSVar(regNum, vers, result);
     }
   }
   for (BlockNode s : block.getSuccessors()) {
     PhiListAttr phiList = s.get(AType.PHI_LIST);
     if (phiList == null) {
       continue;
     }
     int j = s.getPredecessors().indexOf(block);
     if (j == -1) {
       throw new JadxRuntimeException("Can't find predecessor for " + block + " " + s);
     }
     for (PhiInsn phiInsn : phiList.getList()) {
       if (j >= phiInsn.getArgsCount()) {
         continue;
       }
       int regNum = phiInsn.getResult().getRegNum();
       SSAVar var = vars[regNum];
       if (var == null) {
         continue;
       }
       var.use(phiInsn.getArg(j));
       var.setUsedInPhi(phiInsn);
     }
   }
   for (BlockNode domOn : block.getDominatesOn()) {
     renameVar(mth, vars, vers, domOn);
   }
   System.arraycopy(inputVars, 0, vars, 0, vars.length);
 }
Пример #4
0
 private static void addPhi(BlockNode block, int regNum) {
   PhiListAttr phiList = block.get(AType.PHI_LIST);
   if (phiList == null) {
     phiList = new PhiListAttr();
     block.addAttr(phiList);
   }
   PhiInsn phiInsn = new PhiInsn(regNum, block.getPredecessors().size());
   phiList.getList().add(phiInsn);
   phiInsn.setOffset(block.getStartOffset());
   block.getInstructions().add(0, phiInsn);
 }
Пример #5
0
 private static void fixLastTryCatchAssign(MethodNode mth) {
   for (BlockNode block : mth.getBasicBlocks()) {
     PhiListAttr phiList = block.get(AType.PHI_LIST);
     if (phiList == null || !block.contains(AType.EXC_HANDLER)) {
       continue;
     }
     for (PhiInsn phi : phiList.getList()) {
       for (int i = 0; i < phi.getArgsCount(); i++) {
         RegisterArg arg = phi.getArg(i);
         InsnNode parentInsn = arg.getAssignInsn();
         if (parentInsn != null
             && parentInsn.getResult() != null
             && parentInsn.contains(AFlag.TRY_LEAVE)) {
           phi.removeArg(arg);
         }
       }
     }
   }
 }
Пример #6
0
 private static boolean removeUselessPhi(MethodNode mth) {
   List<PhiInsn> insnToRemove = new ArrayList<PhiInsn>();
   for (SSAVar var : mth.getSVars()) {
     // phi result not used
     if (var.getUseCount() == 0) {
       InsnNode assignInsn = var.getAssign().getParentInsn();
       if (assignInsn != null && assignInsn.getType() == InsnType.PHI) {
         insnToRemove.add((PhiInsn) assignInsn);
       }
     }
   }
   for (BlockNode block : mth.getBasicBlocks()) {
     PhiListAttr phiList = block.get(AType.PHI_LIST);
     if (phiList == null) {
       continue;
     }
     for (PhiInsn phi : phiList.getList()) {
       removePhiWithSameArgs(phi, insnToRemove);
     }
   }
   return removePhiList(mth, insnToRemove);
 }