Java Code Examples for com.android.dx.util.IntList#get()

The following examples show how to use com.android.dx.util.IntList#get() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: IdenticalBlockCombiner.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Combines blocks proven identical into one alpha block, re-writing
 * all of the successor links that point to the beta blocks to point
 * to the alpha block instead.
 *
 * @param alphaLabel block that will replace all the beta block
 * @param betaLabels label list of blocks to combine
 */
private void combineBlocks(int alphaLabel, IntList betaLabels) {
    int szBetas = betaLabels.size();

    for (int i = 0; i < szBetas; i++) {
        int betaLabel = betaLabels.get(i);
        BasicBlock bb = blocks.labelToBlock(betaLabel);
        IntList preds = ropMethod.labelToPredecessors(bb.getLabel());
        int szPreds = preds.size();

        for (int j = 0; j < szPreds; j++) {
            BasicBlock predBlock = newBlocks.labelToBlock(preds.get(j));
            replaceSucc(predBlock, betaLabel, alphaLabel);
        }
    }
}
 
Example 2
Source File: Ropper.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Helper for {@link #addOrReplaceBlock} which recursively removes
 * the given block and all blocks that are (direct and indirect)
 * successors of it whose labels indicate that they are not in the
 * normally-translated range.
 *
 * @param idx {@code non-null;} block to remove (etc.)
 */
private void removeBlockAndSpecialSuccessors(int idx) {
    int minLabel = getMinimumUnreservedLabel();
    BasicBlock block = result.get(idx);
    IntList successors = block.getSuccessors();
    int sz = successors.size();

    result.remove(idx);
    resultSubroutines.remove(idx);

    for (int i = 0; i < sz; i++) {
        int label = successors.get(i);
        if (label >= minLabel) {
            idx = labelToResultIndex(label);
            if (idx < 0) {
                throw new RuntimeException("Invalid label "
                        + Hex.u2(label));
            }
            removeBlockAndSpecialSuccessors(idx);
        }
    }
}
 
Example 3
Source File: IdenticalBlockCombiner.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Combines blocks proven identical into one alpha block, re-writing
 * all of the successor links that point to the beta blocks to point
 * to the alpha block instead.
 *
 * @param alphaLabel block that will replace all the beta block
 * @param betaLabels label list of blocks to combine
 */
private void combineBlocks(int alphaLabel, IntList betaLabels) {
    int szBetas = betaLabels.size();

    for (int i = 0; i < szBetas; i++) {
        int betaLabel = betaLabels.get(i);
        BasicBlock bb = blocks.labelToBlock(betaLabel);
        IntList preds = ropMethod.labelToPredecessors(bb.getLabel());
        int szPreds = preds.size();

        for (int j = 0; j < szPreds; j++) {
            BasicBlock predBlock = newBlocks.labelToBlock(preds.get(j));
            replaceSucc(predBlock, betaLabel, alphaLabel);
        }
    }
}
 
Example 4
Source File: Frame.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Merges this frame's subroutine lists with another. The result
 * is the deepest common nesting (effectively, the common prefix of the
 * two lists).
 *
 * @param otherSubroutines label list of subroutine start blocks, from
 * least-nested to most-nested.
 * @return {@code non-null;} merged subroutine nest list as described above
 */
private IntList mergeSubroutineLists(IntList otherSubroutines) {
    if (subroutines.equals(otherSubroutines)) {
        return subroutines;
    }

    IntList resultSubroutines = new IntList();

    int szSubroutines = subroutines.size();
    int szOthers = otherSubroutines.size();
    for (int i = 0; i < szSubroutines && i < szOthers
            && (subroutines.get(i) == otherSubroutines.get(i)); i++) {
        resultSubroutines.add(i);
    }

    resultSubroutines.setImmutable();

    return resultSubroutines;
}
 
Example 5
Source File: Ropper.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Helper for {@link #addOrReplaceBlock} which recursively removes
 * the given block and all blocks that are (direct and indirect)
 * successors of it whose labels indicate that they are not in the
 * normally-translated range.
 *
 * @param idx {@code non-null;} block to remove (etc.)
 */
private void removeBlockAndSpecialSuccessors(int idx) {
    int minLabel = getMinimumUnreservedLabel();
    BasicBlock block = result.get(idx);
    IntList successors = block.getSuccessors();
    int sz = successors.size();

    result.remove(idx);
    resultSubroutines.remove(idx);

    for (int i = 0; i < sz; i++) {
        int label = successors.get(i);
        if (label >= minLabel) {
            idx = labelToResultIndex(label);
            if (idx < 0) {
                throw new RuntimeException("Invalid label "
                        + Hex.u2(label));
            }
            removeBlockAndSpecialSuccessors(idx);
        }
    }
}
 
Example 6
Source File: IdenticalBlockCombiner.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * Combines blocks proven identical into one alpha block, re-writing
 * all of the successor links that point to the beta blocks to point
 * to the alpha block instead.
 *
 * @param alphaLabel block that will replace all the beta block
 * @param betaLabels label list of blocks to combine
 */
private void combineBlocks(int alphaLabel, IntList betaLabels) {
    int szBetas = betaLabels.size();

    for (int i = 0; i < szBetas; i++) {
        int betaLabel = betaLabels.get(i);
        BasicBlock bb = blocks.labelToBlock(betaLabel);
        IntList preds = ropMethod.labelToPredecessors(bb.getLabel());
        int szPreds = preds.size();

        for (int j = 0; j < szPreds; j++) {
            BasicBlock predBlock = newBlocks.labelToBlock(preds.get(j));
            replaceSucc(predBlock, betaLabel, alphaLabel);
        }
    }
}
 
Example 7
Source File: Frame.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Merges this frame's subroutine lists with another. The result
 * is the deepest common nesting (effectively, the common prefix of the
 * two lists).
 *
 * @param otherSubroutines label list of subroutine start blocks, from
 * least-nested to most-nested.
 * @return {@code non-null;} merged subroutine nest list as described above
 */
private IntList mergeSubroutineLists(IntList otherSubroutines) {
    if (subroutines.equals(otherSubroutines)) {
        return subroutines;
    }

    IntList resultSubroutines = new IntList();

    int szSubroutines = subroutines.size();
    int szOthers = otherSubroutines.size();
    for (int i = 0; i < szSubroutines && i < szOthers
            && (subroutines.get(i) == otherSubroutines.get(i)); i++) {
        resultSubroutines.add(i);
    }

    resultSubroutines.setImmutable();

    return resultSubroutines;
}
 
Example 8
Source File: ByteBlock.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Constructs an instance.
 *
 * @param label {@code >= 0;} target label for this block
 * @param start {@code >= 0;} bytecode offset (inclusive) of the start
 * of the block
 * @param end {@code > start;} bytecode offset (exclusive) of the end
 * of the block
 * @param successors {@code non-null;} list of successors that this block may
 * branch to
 * @param catches {@code non-null;} list of exceptions caught and their
 * handler targets
 */
public ByteBlock(int label, int start, int end, IntList successors,
                 ByteCatchList catches) {
    if (label < 0) {
        throw new IllegalArgumentException("label < 0");
    }

    if (start < 0) {
        throw new IllegalArgumentException("start < 0");
    }

    if (end <= start) {
        throw new IllegalArgumentException("end <= start");
    }

    if (successors == null) {
        throw new NullPointerException("targets == null");
    }

    int sz = successors.size();
    for (int i = 0; i < sz; i++) {
        if (successors.get(i) < 0) {
            throw new IllegalArgumentException("successors[" + i +
                                               "] == " +
                                               successors.get(i));
        }
    }

    if (catches == null) {
        throw new NullPointerException("catches == null");
    }

    this.label = label;
    this.start = start;
    this.end = end;
    this.successors = successors;
    this.catches = catches;
}
 
Example 9
Source File: ByteBlock.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Constructs an instance.
 *
 * @param label {@code >= 0;} target label for this block
 * @param start {@code >= 0;} bytecode offset (inclusive) of the start
 * of the block
 * @param end {@code > start;} bytecode offset (exclusive) of the end
 * of the block
 * @param successors {@code non-null;} list of successors that this block may
 * branch to
 * @param catches {@code non-null;} list of exceptions caught and their
 * handler targets
 */
public ByteBlock(int label, int start, int end, IntList successors,
                 ByteCatchList catches) {
    if (label < 0) {
        throw new IllegalArgumentException("label < 0");
    }

    if (start < 0) {
        throw new IllegalArgumentException("start < 0");
    }

    if (end <= start) {
        throw new IllegalArgumentException("end <= start");
    }

    if (successors == null) {
        throw new NullPointerException("targets == null");
    }

    int sz = successors.size();
    for (int i = 0; i < sz; i++) {
        if (successors.get(i) < 0) {
            throw new IllegalArgumentException("successors[" + i +
                                               "] == " +
                                               successors.get(i));
        }
    }

    if (catches == null) {
        throw new NullPointerException("catches == null");
    }

    this.label = label;
    this.start = start;
    this.end = end;
    this.successors = successors;
    this.catches = catches;
}
 
Example 10
Source File: SwitchData.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Gets the size of a packed table for the given cases, in 16-bit code
 * units.
 *
 * @param cases {@code non-null;} sorted list of cases
 * @return {@code >= -1;} the packed table size or {@code -1} if the
 * cases couldn't possibly be represented as a packed table
 */
private static long packedCodeSize(IntList cases) {
    int sz = cases.size();
    long low = cases.get(0);
    long high = cases.get(sz - 1);
    long result = ((high - low + 1)) * 2 + 4;

    return (result <= 0x7fffffff) ? result : -1;
}
 
Example 11
Source File: Ropper.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Visits each block once in depth-first successor order, ignoring
 * {@code jsr} targets. Worker for {@link #forEachNonSubBlockDepthFirst}.
 *
 * @param next next block to visit
 * @param v callback interface
 * @param visited set of blocks already visited
 */
private void forEachNonSubBlockDepthFirst0(
        BasicBlock next, BasicBlock.Visitor v, BitSet visited) {
    v.visitBlock(next);
    visited.set(next.getLabel());

    IntList successors = next.getSuccessors();
    int sz = successors.size();

    for (int i = 0; i < sz; i++) {
        int succ = successors.get(i);

        if (visited.get(succ)) {
            continue;
        }

        if (isSubroutineCaller(next) && i > 0) {
            // ignore jsr targets
            continue;
        }

        /*
         * Ignore missing labels: they're successors of
         * subroutines that never invoke a ret.
         */
        int idx = labelToResultIndex(succ);
        if (idx >= 0) {
            forEachNonSubBlockDepthFirst0(result.get(idx), v, visited);
        }
    }
}
 
Example 12
Source File: ByteBlock.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Constructs an instance.
 *
 * @param label {@code >= 0;} target label for this block
 * @param start {@code >= 0;} bytecode offset (inclusive) of the start
 * of the block
 * @param end {@code > start;} bytecode offset (exclusive) of the end
 * of the block
 * @param successors {@code non-null;} list of successors that this block may
 * branch to
 * @param catches {@code non-null;} list of exceptions caught and their
 * handler targets
 */
public ByteBlock(int label, int start, int end, IntList successors,
                 ByteCatchList catches) {
    if (label < 0) {
        throw new IllegalArgumentException("label < 0");
    }

    if (start < 0) {
        throw new IllegalArgumentException("start < 0");
    }

    if (end <= start) {
        throw new IllegalArgumentException("end <= start");
    }

    if (successors == null) {
        throw new NullPointerException("targets == null");
    }

    int sz = successors.size();
    for (int i = 0; i < sz; i++) {
        if (successors.get(i) < 0) {
            throw new IllegalArgumentException("successors[" + i +
                                               "] == " +
                                               successors.get(i));
        }
    }

    if (catches == null) {
        throw new NullPointerException("catches == null");
    }

    this.label = label;
    this.start = start;
    this.end = end;
    this.successors = successors;
    this.catches = catches;
}
 
Example 13
Source File: Ropper.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Checks to see if the basic block is a subroutine caller block.
 *
 * @param bb {@code non-null;} the basic block in question
 * @return true if this block calls a subroutine
 */
private boolean isSubroutineCaller(BasicBlock bb) {
    IntList successors = bb.getSuccessors();
    if (successors.size() < 2) return false;

    int subLabel = successors.get(1);

    return (subLabel < subroutines.length)
            && (subroutines[subLabel] != null);
}
 
Example 14
Source File: IdenticalBlockCombiner.java    From J2ME-Loader with Apache License 2.0 4 votes vote down vote up
/**
 * Runs algorithm. TODO: This is n^2, and could be made linear-ish with
 * a hash. In particular, hash the contents of each block and only
 * compare blocks with the same hash.
 *
 * @return {@code non-null;} new method that has been processed
 */
public RopMethod process() {
    int szBlocks = blocks.size();
    // indexed by label
    BitSet toDelete = new BitSet(blocks.getMaxLabel());

    // For each non-deleted block...
    for (int bindex = 0; bindex < szBlocks; bindex++) {
        BasicBlock b = blocks.get(bindex);

        if (toDelete.get(b.getLabel())) {
            // doomed block
            continue;
        }

        IntList preds = ropMethod.labelToPredecessors(b.getLabel());

        // ...look at all of it's predecessors that have only one succ...
        int szPreds = preds.size();
        for (int i = 0; i < szPreds; i++) {
            int iLabel = preds.get(i);

            BasicBlock iBlock = blocks.labelToBlock(iLabel);

            if (toDelete.get(iLabel)
                    || iBlock.getSuccessors().size() > 1
                    || iBlock.getFirstInsn().getOpcode().getOpcode() ==
                        RegOps.MOVE_RESULT) {
                continue;
            }

            IntList toCombine = new IntList();

            // ...and see if they can be combined with any other preds...
            for (int j = i + 1; j < szPreds; j++) {
                int jLabel = preds.get(j);
                BasicBlock jBlock = blocks.labelToBlock(jLabel);

                if (jBlock.getSuccessors().size() == 1
                        && compareInsns(iBlock, jBlock)) {

                    toCombine.add(jLabel);
                    toDelete.set(jLabel);
                }
            }

            combineBlocks(iLabel, toCombine);
        }
    }

    for (int i = szBlocks - 1; i >= 0; i--) {
        if (toDelete.get(newBlocks.get(i).getLabel())) {
            newBlocks.set(i, null);
        }
    }

    newBlocks.shrinkToFit();
    newBlocks.setImmutable();

    return new RopMethod(newBlocks, ropMethod.getFirstLabel());
}
 
Example 15
Source File: BasicBlockList.java    From Box with Apache License 2.0 4 votes vote down vote up
/**
 * Compares the catches of two blocks for equality. This includes
 * both the catch types and target labels.
 *
 * @param block1 {@code non-null;} one block to compare
 * @param block2 {@code non-null;} the other block to compare
 * @return {@code true} if the two blocks' non-primary successors
 * are identical
 */
public boolean catchesEqual(BasicBlock block1, BasicBlock block2) {
    TypeList catches1 = block1.getExceptionHandlerTypes();
    TypeList catches2 = block2.getExceptionHandlerTypes();

    if (!StdTypeList.equalContents(catches1, catches2)) {
        return false;
    }

    IntList succ1 = block1.getSuccessors();
    IntList succ2 = block2.getSuccessors();
    int size = succ1.size(); // Both are guaranteed to be the same size.

    int primary1 = block1.getPrimarySuccessor();
    int primary2 = block2.getPrimarySuccessor();

    if (((primary1 == -1) || (primary2 == -1))
            && (primary1 != primary2)) {
        /*
         * For the current purpose, both blocks in question must
         * either both have a primary or both not have a primary to
         * be considered equal, and it turns out here that that's not
         * the case.
         */
        return false;
    }

    for (int i = 0; i < size; i++) {
        int label1 = succ1.get(i);
        int label2 = succ2.get(i);

        if (label1 == primary1) {
            /*
             * It should be the case that block2's primary is at the
             * same index. If not, we consider the blocks unequal for
             * the current purpose.
             */
            if (label2 != primary2) {
                return false;
            }
            continue;
        }

        if (label1 != label2) {
            return false;
        }
    }

    return true;
}
 
Example 16
Source File: Frame.java    From J2ME-Loader with Apache License 2.0 4 votes vote down vote up
/**
 * Merges this frame with the frame of a subroutine caller at
 * {@code predLabel}. Only called on the frame at the first
 * block of a subroutine.
 *
 * @param other {@code non-null;} another frame
 * @param subLabel label of subroutine start block
 * @param predLabel label of calling block
 * @return {@code non-null;} the result of merging the two frames
 */
public Frame mergeWithSubroutineCaller(Frame other, int subLabel,
        int predLabel) {
    LocalsArray resultLocals;
    ExecutionStack resultStack;

    resultLocals = getLocals().mergeWithSubroutineCaller(
            other.getLocals(), predLabel);
    resultStack = getStack().merge(other.getStack());

    IntList newOtherSubroutines = other.subroutines.mutableCopy();
    newOtherSubroutines.add(subLabel);
    newOtherSubroutines.setImmutable();

    if ((resultLocals == getLocals())
            && (resultStack == getStack())
            && subroutines.equals(newOtherSubroutines)) {
        return this;
    }

    IntList resultSubroutines;

    if (subroutines.equals(newOtherSubroutines)) {
        resultSubroutines = subroutines;
    } else {
        /*
         * The new subroutines list should be the deepest of the two
         * lists being merged, but the postfix of the resultant list
         * must be equal to the shorter list.
         */
        IntList nonResultSubroutines;

        if (subroutines.size() > newOtherSubroutines.size()) {
            resultSubroutines = subroutines;
            nonResultSubroutines = newOtherSubroutines;
        } else {
            resultSubroutines = newOtherSubroutines;
            nonResultSubroutines = subroutines;
        }

        int szResult = resultSubroutines.size();
        int szNonResult = nonResultSubroutines.size();

        for (int i = szNonResult - 1; i >=0; i-- ) {
            if (nonResultSubroutines.get(i)
                    != resultSubroutines.get(
                    i + (szResult - szNonResult))) {
                throw new
                        RuntimeException("Incompatible merged subroutines");
            }
        }

    }

    return new Frame(resultLocals, resultStack, resultSubroutines);
}
 
Example 17
Source File: BlockDumper.java    From Box with Apache License 2.0 4 votes vote down vote up
/**
 * Does a registerizing dump.
 *
 * @param meth {@code non-null;} method data to dump
 */
private void ropDump(ConcreteMethod meth) {
    TranslationAdvice advice = DexTranslationAdvice.THE_ONE;
    BytecodeArray code = meth.getCode();
    ByteArray bytes = code.getBytes();
    RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods(), dexOptions);
    StringBuilder sb = new StringBuilder(2000);

    if (optimize) {
        boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags());
        int paramWidth = computeParamWidth(meth, isStatic);
        rmeth =
            Optimizer.optimize(rmeth, paramWidth, isStatic, true, advice);
    }

    BasicBlockList blocks = rmeth.getBlocks();
    int[] order = blocks.getLabelsInOrder();

    sb.append("first " + Hex.u2(rmeth.getFirstLabel()) + "\n");

    for (int label : order) {
        BasicBlock bb = blocks.get(blocks.indexOfLabel(label));
        sb.append("block ");
        sb.append(Hex.u2(label));
        sb.append("\n");

        IntList preds = rmeth.labelToPredecessors(label);
        int psz = preds.size();
        for (int i = 0; i < psz; i++) {
            sb.append("  pred ");
            sb.append(Hex.u2(preds.get(i)));
            sb.append("\n");
        }

        InsnList il = bb.getInsns();
        int ilsz = il.size();
        for (int i = 0; i < ilsz; i++) {
            Insn one = il.get(i);
            sb.append("  ");
            sb.append(il.get(i).toHuman());
            sb.append("\n");
        }

        IntList successors = bb.getSuccessors();
        int ssz = successors.size();
        if (ssz == 0) {
            sb.append("  returns\n");
        } else {
            int primary = bb.getPrimarySuccessor();
            for (int i = 0; i < ssz; i++) {
                int succ = successors.get(i);
                sb.append("  next ");
                sb.append(Hex.u2(succ));

                if ((ssz != 1) && (succ == primary)) {
                    sb.append(" *");
                }

                sb.append("\n");
            }
        }
    }

    suppressDump = false;
    parsed(bytes, 0, bytes.size(), sb.toString());
    suppressDump = true;
}
 
Example 18
Source File: StdCatchBuilder.java    From J2ME-Loader with Apache License 2.0 4 votes vote down vote up
/**
 * Makes the {@link CatchHandlerList} for the given basic block.
 *
 * @param block {@code non-null;} block to get entries for
 * @param addresses {@code non-null;} address objects for each block
 * @return {@code non-null;} array of entries
 */
private static CatchHandlerList handlersFor(BasicBlock block,
        BlockAddresses addresses) {
    IntList successors = block.getSuccessors();
    int succSize = successors.size();
    int primary = block.getPrimarySuccessor();
    TypeList catches = block.getLastInsn().getCatches();
    int catchSize = catches.size();

    if (catchSize == 0) {
        return CatchHandlerList.EMPTY;
    }

    if (((primary == -1) && (succSize != catchSize))
            || ((primary != -1) &&
                    ((succSize != (catchSize + 1))
                            || (primary != successors.get(catchSize))))) {
        /*
         * Blocks that throw are supposed to list their primary
         * successor -- if any -- last in the successors list, but
         * that constraint appears to be violated here.
         */
        throw new RuntimeException(
                "shouldn't happen: weird successors list");
    }

    /*
     * Reduce the effective catchSize if we spot a catch-all that
     * isn't at the end.
     */
    for (int i = 0; i < catchSize; i++) {
        Type type = catches.getType(i);
        if (type.equals(Type.OBJECT)) {
            catchSize = i + 1;
            break;
        }
    }

    CatchHandlerList result = new CatchHandlerList(catchSize);

    for (int i = 0; i < catchSize; i++) {
        CstType oneType = new CstType(catches.getType(i));
        CodeAddress oneHandler = addresses.getStart(successors.get(i));
        result.set(i, oneType, oneHandler.getAddress());
    }

    result.setImmutable();
    return result;
}
 
Example 19
Source File: BasicBlockList.java    From Box with Apache License 2.0 4 votes vote down vote up
/**
 * Compares the catches of two blocks for equality. This includes
 * both the catch types and target labels.
 *
 * @param block1 {@code non-null;} one block to compare
 * @param block2 {@code non-null;} the other block to compare
 * @return {@code true} if the two blocks' non-primary successors
 * are identical
 */
public boolean catchesEqual(BasicBlock block1, BasicBlock block2) {
    TypeList catches1 = block1.getExceptionHandlerTypes();
    TypeList catches2 = block2.getExceptionHandlerTypes();

    if (!StdTypeList.equalContents(catches1, catches2)) {
        return false;
    }

    IntList succ1 = block1.getSuccessors();
    IntList succ2 = block2.getSuccessors();
    int size = succ1.size(); // Both are guaranteed to be the same size.

    int primary1 = block1.getPrimarySuccessor();
    int primary2 = block2.getPrimarySuccessor();

    if (((primary1 == -1) || (primary2 == -1))
            && (primary1 != primary2)) {
        /*
         * For the current purpose, both blocks in question must
         * either both have a primary or both not have a primary to
         * be considered equal, and it turns out here that that's not
         * the case.
         */
        return false;
    }

    for (int i = 0; i < size; i++) {
        int label1 = succ1.get(i);
        int label2 = succ2.get(i);

        if (label1 == primary1) {
            /*
             * It should be the case that block2's primary is at the
             * same index. If not, we consider the blocks unequal for
             * the current purpose.
             */
            if (label2 != primary2) {
                return false;
            }
            continue;
        }

        if (label1 != label2) {
            return false;
        }
    }

    return true;
}
 
Example 20
Source File: RopTranslator.java    From buck with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
public void visitSwitchInsn(SwitchInsn insn) {
    SourcePosition pos = insn.getPosition();
    IntList cases = insn.getCases();
    IntList successors = block.getSuccessors();
    int casesSz = cases.size();
    int succSz = successors.size();
    int primarySuccessor = block.getPrimarySuccessor();

    /*
     * Check the assumptions that the number of cases is one
     * less than the number of successors and that the last
     * successor in the list is the primary (in this case, the
     * default). This test is here to guard against forgetting
     * to change this code if the way switch instructions are
     * constructed also gets changed.
     */
    if ((casesSz != (succSz - 1)) ||
        (primarySuccessor != successors.get(casesSz))) {
        throw new RuntimeException("shouldn't happen");
    }

    CodeAddress[] switchTargets = new CodeAddress[casesSz];

    for (int i = 0; i < casesSz; i++) {
        int label = successors.get(i);
        switchTargets[i] = addresses.getStart(label);
    }

    CodeAddress dataAddress = new CodeAddress(pos);
    // make a new address that binds closely to the switch instruction
    CodeAddress switchAddress =
        new CodeAddress(lastAddress.getPosition(), true);
    SwitchData dataInsn =
        new SwitchData(pos, switchAddress, cases, switchTargets);
    Dop opcode = dataInsn.isPacked() ?
        Dops.PACKED_SWITCH : Dops.SPARSE_SWITCH;
    TargetInsn switchInsn =
        new TargetInsn(opcode, pos, getRegs(insn), dataAddress);

    addOutput(switchAddress);
    addOutput(switchInsn);

    addOutputSuffix(new OddSpacer(pos));
    addOutputSuffix(dataAddress);
    addOutputSuffix(dataInsn);
}