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

The following examples show how to use com.android.dx.util.IntList#size() . 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: BasicBlockList.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Gets the preferred successor for the given block. If the block
 * only has one successor, then that is the preferred successor.
 * Otherwise, if the block has a primay successor, then that is
 * the preferred successor. If the block has no successors, then
 * this returns {@code null}.
 *
 * @param block {@code non-null;} the block in question
 * @return {@code null-ok;} the preferred successor, if any
 */
public BasicBlock preferredSuccessorOf(BasicBlock block) {
    int primarySuccessor = block.getPrimarySuccessor();
    IntList successors = block.getSuccessors();
    int succSize = successors.size();

    switch (succSize) {
        case 0: {
            return null;
        }
        case 1: {
            return labelToBlock(successors.get(0));
        }
    }

    if (primarySuccessor != -1) {
        return labelToBlock(primarySuccessor);
    } else {
        return labelToBlock(successors.get(0));
    }
}
 
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: 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 4
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 5
Source File: SsaMethod.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Builds an IntList of block indices from a basic block list and a list
 * of labels taken from Rop form.
 *
 * @param ropBlocks Rop blocks
 * @param labelList list of rop block labels
 * @return IntList of block indices
 */
public static IntList indexListFromLabelList(BasicBlockList ropBlocks,
        IntList labelList) {

    IntList result = new IntList(labelList.size());

    for (int i = 0, sz = labelList.size(); i < sz; i++) {
        result.add(ropBlocks.indexOfLabel(labelList.get(i)));
    }

    return result;
}
 
Example 6
Source File: SwitchData.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Constructs an instance. The output address of this instance is initially
 * unknown ({@code -1}).
 *
 * @param position {@code non-null;} source position
 * @param user {@code non-null;} address representing the instruction that
 * uses this instance
 * @param cases {@code non-null;} sorted list of switch cases (keys)
 * @param targets {@code non-null;} corresponding list of code addresses; the
 * branch target for each case
 */
public SwitchData(SourcePosition position, CodeAddress user,
                  IntList cases, CodeAddress[] targets) {
    super(position, RegisterSpecList.EMPTY);

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

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

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

    int sz = cases.size();

    if (sz != targets.length) {
        throw new IllegalArgumentException("cases / targets mismatch");
    }

    if (sz > 65535) {
        throw new IllegalArgumentException("too many cases");
    }

    this.user = user;
    this.cases = cases;
    this.targets = targets;
    this.packed = shouldPack(cases);
}
 
Example 7
Source File: SsaMethod.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Builds an IntList of block indices from a basic block list and a list
 * of labels taken from Rop form.
 *
 * @param ropBlocks Rop blocks
 * @param labelList list of rop block labels
 * @return IntList of block indices
 */
public static IntList indexListFromLabelList(BasicBlockList ropBlocks,
        IntList labelList) {

    IntList result = new IntList(labelList.size());

    for (int i = 0, sz = labelList.size(); i < sz; i++) {
        result.add(ropBlocks.indexOfLabel(labelList.get(i)));
    }

    return result;
}
 
Example 8
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 9
Source File: SwitchData.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Constructs an instance. The output address of this instance is initially
 * unknown ({@code -1}).
 *
 * @param position {@code non-null;} source position
 * @param user {@code non-null;} address representing the instruction that
 * uses this instance
 * @param cases {@code non-null;} sorted list of switch cases (keys)
 * @param targets {@code non-null;} corresponding list of code addresses; the
 * branch target for each case
 */
public SwitchData(SourcePosition position, CodeAddress user,
                  IntList cases, CodeAddress[] targets) {
    super(position, RegisterSpecList.EMPTY);

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

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

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

    int sz = cases.size();

    if (sz != targets.length) {
        throw new IllegalArgumentException("cases / targets mismatch");
    }

    if (sz > 65535) {
        throw new IllegalArgumentException("too many cases");
    }

    this.user = user;
    this.cases = cases;
    this.targets = targets;
    this.packed = shouldPack(cases);
}
 
Example 10
Source File: SsaToRop.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Converts a single basic block to rop form.
 *
 * @param block SSA block to process
 * @return {@code non-null;} ROP block
 */
private BasicBlock convertBasicBlock(SsaBasicBlock block) {
    IntList successorList = block.getRopLabelSuccessorList();
    int primarySuccessorLabel = block.getPrimarySuccessorRopLabel();

    // Filter out any reference to the SSA form's exit block.

    // Exit block may be null.
    SsaBasicBlock exitBlock = ssaMeth.getExitBlock();
    int exitRopLabel = (exitBlock == null) ? -1 : exitBlock.getRopLabel();

    if (successorList.contains(exitRopLabel)) {
        if (successorList.size() > 1) {
            throw new RuntimeException(
                    "Exit predecessor must have no other successors"
                            + Hex.u2(block.getRopLabel()));
        } else {
            successorList = IntList.EMPTY;
            primarySuccessorLabel = -1;

            verifyValidExitPredecessor(block);
        }
    }

    successorList.setImmutable();

    BasicBlock result = new BasicBlock(
            block.getRopLabel(), convertInsns(block.getInsns()),
            successorList,
            primarySuccessorLabel);

    return result;
}
 
Example 11
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 12
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 13
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);
}
 
Example 14
Source File: RopTranslator.java    From J2ME-Loader with Apache License 2.0 4 votes vote down vote up
/** {@inheritDoc} */
@Override
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);
}
 
Example 15
Source File: Frame.java    From Box 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 16
Source File: Frame.java    From Box 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: BasicBlockList.java    From buck 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 18
Source File: Ropper.java    From J2ME-Loader with Apache License 2.0 2 votes vote down vote up
/**
 * Checks to see if a specified label is involved in a specified
 * subroutine.
 *
 * @param label {@code >= 0;} a basic block label
 * @param subroutineStart {@code >= 0;} a subroutine as identified
 * by the label of its start block
 * @return true if the block is dominated by the subroutine call
 */
private boolean involvedInSubroutine(int label, int subroutineStart) {
    IntList subroutinesList = labelToSubroutines.get(label);
    return (subroutinesList != null && subroutinesList.size() > 0
            && subroutinesList.top() == subroutineStart);
}
 
Example 19
Source File: SwitchData.java    From Box with Apache License 2.0 2 votes vote down vote up
/**
 * Gets the size of a sparse table for the given cases, in 16-bit code
 * units.
 *
 * @param cases {@code non-null;} sorted list of cases
 * @return {@code > 0;} the sparse table size
 */
private static long sparseCodeSize(IntList cases) {
    int sz = cases.size();

    return (sz * 4L) + 2;
}
 
Example 20
Source File: Ropper.java    From Box with Apache License 2.0 2 votes vote down vote up
/**
 * Checks to see if a specified label is involved in a specified
 * subroutine.
 *
 * @param label {@code >= 0;} a basic block label
 * @param subroutineStart {@code >= 0;} a subroutine as identified
 * by the label of its start block
 * @return true if the block is dominated by the subroutine call
 */
private boolean involvedInSubroutine(int label, int subroutineStart) {
    IntList subroutinesList = labelToSubroutines.get(label);
    return (subroutinesList != null && subroutinesList.size() > 0
            && subroutinesList.top() == subroutineStart);
}