/** * Inserts a new empty GOTO block as a predecessor to this block. All previous predecessors will * be predecessors to the new block. * * @return {@code non-null;} an appropriately-constructed instance */ public SsaBasicBlock insertNewPredecessor() { SsaBasicBlock newPred = parent.makeNewGotoBlock(); // Update the new block. newPred.predecessors = predecessors; newPred.successors.set(index); newPred.successorList.add(index); newPred.primarySuccessor = index; // Update us. predecessors = new BitSet(parent.getBlocks().size()); predecessors.set(newPred.index); // Update our (soon-to-be) old predecessors. for (int i = newPred.predecessors.nextSetBit(0); i >= 0; i = newPred.predecessors.nextSetBit(i + 1)) { SsaBasicBlock predBlock = parent.getBlocks().get(i); predBlock.replaceSuccessor(index, newPred.index); } return newPred; }
/** * Constructs and inserts a new empty GOTO block {@code Z} between this block ({@code A}) and a * current successor block ({@code B}). The new block will replace B as A's successor and A as B's * predecessor. A and B will no longer be directly connected. If B is listed as a successor * multiple times, all references are replaced. * * @param other current successor (B) * @return {@code non-null;} an appropriately-constructed instance */ public SsaBasicBlock insertNewSuccessor(SsaBasicBlock other) { SsaBasicBlock newSucc = parent.makeNewGotoBlock(); if (!successors.get(other.index)) { throw new RuntimeException( "Block " + other.getRopLabelString() + " not successor of " + getRopLabelString()); } // Update the new block. newSucc.predecessors.set(this.index); newSucc.successors.set(other.index); newSucc.successorList.add(other.index); newSucc.primarySuccessor = other.index; // Update us. for (int i = successorList.size() - 1; i >= 0; i--) { if (successorList.get(i) == other.index) { successorList.set(i, newSucc.index); } } if (primarySuccessor == other.index) { primarySuccessor = newSucc.index; } successors.clear(other.index); successors.set(newSucc.index); // Update "other". other.predecessors.set(newSucc.index); other.predecessors.set(index, successors.get(other.index)); return newSucc; }
/** * Creates a new SSA basic block from a ROP form basic block. * * @param rmeth original method * @param basicBlockIndex index this block will have * @param parent method of this block predecessor set will be updated * @return new instance */ public static SsaBasicBlock newFromRop( RopMethod rmeth, int basicBlockIndex, final SsaMethod parent) { BasicBlockList ropBlocks = rmeth.getBlocks(); BasicBlock bb = ropBlocks.get(basicBlockIndex); SsaBasicBlock result = new SsaBasicBlock(basicBlockIndex, bb.getLabel(), parent); InsnList ropInsns = bb.getInsns(); result.insns.ensureCapacity(ropInsns.size()); for (int i = 0, sz = ropInsns.size(); i < sz; i++) { result.insns.add(new NormalSsaInsn(ropInsns.get(i), result)); } result.predecessors = SsaMethod.bitSetFromLabelList(ropBlocks, rmeth.labelToPredecessors(bb.getLabel())); result.successors = SsaMethod.bitSetFromLabelList(ropBlocks, bb.getSuccessors()); result.successorList = SsaMethod.indexListFromLabelList(ropBlocks, bb.getSuccessors()); if (result.successorList.size() != 0) { int primarySuccessor = bb.getPrimarySuccessor(); result.primarySuccessor = (primarySuccessor < 0) ? -1 : ropBlocks.indexOfLabel(primarySuccessor); } return result; }