com.android.dx.util.Bits Java Examples

The following examples show how to use com.android.dx.util.Bits. 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: BasicBlocker.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Constructs an instance. This class is not publicly instantiable; use
 * {@link #identifyBlocks}.
 *
 * @param method {@code non-null;} method to convert
 */
private BasicBlocker(ConcreteMethod method) {
    if (method == null) {
        throw new NullPointerException("method == null");
    }

    this.method = method;

    /*
     * The "+1" below is so the idx-past-end is also valid,
     * avoiding a special case, but without preventing
     * flow-of-control falling past the end of the method from
     * getting properly reported.
     */
    int sz = method.getCode().size() + 1;

    workSet = Bits.makeBitSet(sz);
    liveSet = Bits.makeBitSet(sz);
    blockSet = Bits.makeBitSet(sz);
    targetLists = new IntList[sz];
    catchLists = new ByteCatchList[sz];
    previousOffset = -1;
}
 
Example #2
Source File: Ropper.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Merges the specified frame into this subroutine's successors,
 * setting {@code workSet} as appropriate. To be called with
 * the frame of a subroutine ret block.
 *
 * @param frame {@code non-null;} frame from ret block to merge
 * @param workSet {@code non-null;} workset to update
 */
void mergeToSuccessors(Frame frame, int[] workSet) {
    for (int label = callerBlocks.nextSetBit(0); label >= 0;
         label = callerBlocks.nextSetBit(label+1)) {
        BasicBlock subCaller = labelToBlock(label);
        int succLabel = subCaller.getSuccessors().get(0);

        Frame subFrame = frame.subFrameForLabel(startBlock, label);

        if (subFrame != null) {
            mergeAndWorkAsNecessary(succLabel, -1, null,
                    subFrame, workSet);
        } else {
            Bits.set(workSet, label);
        }
    }
}
 
Example #3
Source File: BytecodeArray.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Processes the given "work set" by repeatedly finding the lowest bit
 * in the set, clearing it, and parsing and visiting the instruction at
 * the indicated offset (that is, the bit index), repeating until the
 * work set is empty. It is expected that the visitor will regularly
 * set new bits in the work set during the process.
 *
 * @param workSet {@code non-null;} the work set to process
 * @param visitor {@code non-null;} visitor to call back to for
 * each instruction
 */
public void processWorkSet(int[] workSet, Visitor visitor) {
    if (visitor == null) {
        throw new NullPointerException("visitor == null");
    }

    for (;;) {
        int offset = Bits.findFirst(workSet, 0);
        if (offset < 0) {
            break;
        }
        Bits.clear(workSet, offset);
        parseInstruction(offset, visitor);
        visitor.setPreviousOffset(offset);
    }
}
 
Example #4
Source File: BasicBlocker.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Helper method used by all the visitor methods.
 *
 * @param offset offset to the instruction
 * @param length length of the instruction, in bytes
 * @param nextIsLive {@code true} iff the instruction after
 * the indicated one is possibly-live (because this one isn't an
 * unconditional branch, a return, or a switch)
 */
private void visitCommon(int offset, int length, boolean nextIsLive) {
    Bits.set(liveSet, offset);

    if (nextIsLive) {
        /*
         * If the next instruction is flowed to by this one, just
         * add it to the work set, and then a subsequent visit*()
         * will deal with it as appropriate.
         */
        addWorkIfNecessary(offset + length, false);
    } else {
        /*
         * If the next instruction isn't flowed to by this one,
         * then mark it as a start of a block but *don't* add it
         * to the work set, so that in the final phase we can know
         * dead code blocks as those marked as blocks but not also marked
         * live.
         */
        Bits.set(blockSet, offset + length);
    }
}
 
Example #5
Source File: BasicBlocker.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * Constructs an instance. This class is not publicly instantiable; use
 * {@link #identifyBlocks}.
 *
 * @param method {@code non-null;} method to convert
 */
private BasicBlocker(ConcreteMethod method) {
    if (method == null) {
        throw new NullPointerException("method == null");
    }

    this.method = method;

    /*
     * The "+1" below is so the idx-past-end is also valid,
     * avoiding a special case, but without preventing
     * flow-of-control falling past the end of the method from
     * getting properly reported.
     */
    int sz = method.getCode().size() + 1;

    workSet = Bits.makeBitSet(sz);
    liveSet = Bits.makeBitSet(sz);
    blockSet = Bits.makeBitSet(sz);
    targetLists = new IntList[sz];
    catchLists = new ByteCatchList[sz];
    previousOffset = -1;
}
 
Example #6
Source File: BasicBlocker.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Constructs an instance. This class is not publicly instantiable; use
 * {@link #identifyBlocks}.
 *
 * @param method {@code non-null;} method to convert
 */
private BasicBlocker(ConcreteMethod method) {
    if (method == null) {
        throw new NullPointerException("method == null");
    }

    this.method = method;

    /*
     * The "+1" below is so the idx-past-end is also valid,
     * avoiding a special case, but without preventing
     * flow-of-control falling past the end of the method from
     * getting properly reported.
     */
    int sz = method.getCode().size() + 1;

    workSet = Bits.makeBitSet(sz);
    liveSet = Bits.makeBitSet(sz);
    blockSet = Bits.makeBitSet(sz);
    targetLists = new IntList[sz];
    catchLists = new ByteCatchList[sz];
    previousOffset = -1;
}
 
Example #7
Source File: BasicBlocker.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * Helper method used by all the visitor methods.
 *
 * @param offset offset to the instruction
 * @param length length of the instruction, in bytes
 * @param nextIsLive {@code true} iff the instruction after
 * the indicated one is possibly-live (because this one isn't an
 * unconditional branch, a return, or a switch)
 */
private void visitCommon(int offset, int length, boolean nextIsLive) {
    Bits.set(liveSet, offset);

    if (nextIsLive) {
        /*
         * If the next instruction is flowed to by this one, just
         * add it to the work set, and then a subsequent visit*()
         * will deal with it as appropriate.
         */
        addWorkIfNecessary(offset + length, false);
    } else {
        /*
         * If the next instruction isn't flowed to by this one,
         * then mark it as a start of a block but *don't* add it
         * to the work set, so that in the final phase we can know
         * dead code blocks as those marked as blocks but not also marked
         * live.
         */
        Bits.set(blockSet, offset + length);
    }
}
 
Example #8
Source File: BytecodeArray.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * Processes the given "work set" by repeatedly finding the lowest bit
 * in the set, clearing it, and parsing and visiting the instruction at
 * the indicated offset (that is, the bit index), repeating until the
 * work set is empty. It is expected that the visitor will regularly
 * set new bits in the work set during the process.
 *
 * @param workSet {@code non-null;} the work set to process
 * @param visitor {@code non-null;} visitor to call back to for
 * each instruction
 */
public void processWorkSet(int[] workSet, Visitor visitor) {
    if (visitor == null) {
        throw new NullPointerException("visitor == null");
    }

    for (;;) {
        int offset = Bits.findFirst(workSet, 0);
        if (offset < 0) {
            break;
        }
        Bits.clear(workSet, offset);
        parseInstruction(offset, visitor);
        visitor.setPreviousOffset(offset);
    }
}
 
Example #9
Source File: Ropper.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * Merges the specified frame into this subroutine's successors,
 * setting {@code workSet} as appropriate. To be called with
 * the frame of a subroutine ret block.
 *
 * @param frame {@code non-null;} frame from ret block to merge
 * @param workSet {@code non-null;} workset to update
 */
void mergeToSuccessors(Frame frame, int[] workSet) {
    for (int label = callerBlocks.nextSetBit(0); label >= 0;
         label = callerBlocks.nextSetBit(label+1)) {
        BasicBlock subCaller = labelToBlock(label);
        int succLabel = subCaller.getSuccessors().get(0);

        Frame subFrame = frame.subFrameForLabel(startBlock, label);

        if (subFrame != null) {
            mergeAndWorkAsNecessary(succLabel, -1, null,
                    subFrame, workSet);
        } else {
            Bits.set(workSet, label);
        }
    }
}
 
Example #10
Source File: Ropper.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Merges the specified frame into this subroutine's successors,
 * setting {@code workSet} as appropriate. To be called with
 * the frame of a subroutine ret block.
 *
 * @param frame {@code non-null;} frame from ret block to merge
 * @param workSet {@code non-null;} workset to update
 */
void mergeToSuccessors(Frame frame, int[] workSet) {
    for (int label = callerBlocks.nextSetBit(0); label >= 0;
         label = callerBlocks.nextSetBit(label+1)) {
        BasicBlock subCaller = labelToBlock(label);
        int succLabel = subCaller.getSuccessors().get(0);

        Frame subFrame = frame.subFrameForLabel(startBlock, label);

        if (subFrame != null) {
            mergeAndWorkAsNecessary(succLabel, -1, null,
                    subFrame, workSet);
        } else {
            Bits.set(workSet, label);
        }
    }
}
 
Example #11
Source File: BytecodeArray.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Processes the given "work set" by repeatedly finding the lowest bit
 * in the set, clearing it, and parsing and visiting the instruction at
 * the indicated offset (that is, the bit index), repeating until the
 * work set is empty. It is expected that the visitor will regularly
 * set new bits in the work set during the process.
 *
 * @param workSet {@code non-null;} the work set to process
 * @param visitor {@code non-null;} visitor to call back to for
 * each instruction
 */
public void processWorkSet(int[] workSet, Visitor visitor) {
    if (visitor == null) {
        throw new NullPointerException("visitor == null");
    }

    for (;;) {
        int offset = Bits.findFirst(workSet, 0);
        if (offset < 0) {
            break;
        }
        Bits.clear(workSet, offset);
        parseInstruction(offset, visitor);
        visitor.setPreviousOffset(offset);
    }
}
 
Example #12
Source File: BasicBlocker.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Constructs an instance. This class is not publicly instantiable; use
 * {@link #identifyBlocks}.
 *
 * @param method {@code non-null;} method to convert
 */
private BasicBlocker(ConcreteMethod method) {
    if (method == null) {
        throw new NullPointerException("method == null");
    }

    this.method = method;

    /*
     * The "+1" below is so the idx-past-end is also valid,
     * avoiding a special case, but without preventing
     * flow-of-control falling past the end of the method from
     * getting properly reported.
     */
    int sz = method.getCode().size() + 1;

    workSet = Bits.makeBitSet(sz);
    liveSet = Bits.makeBitSet(sz);
    blockSet = Bits.makeBitSet(sz);
    targetLists = new IntList[sz];
    catchLists = new ByteCatchList[sz];
    previousOffset = -1;
}
 
Example #13
Source File: BasicBlocker.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Helper method used by all the visitor methods.
 *
 * @param offset offset to the instruction
 * @param length length of the instruction, in bytes
 * @param nextIsLive {@code true} iff the instruction after
 * the indicated one is possibly-live (because this one isn't an
 * unconditional branch, a return, or a switch)
 */
private void visitCommon(int offset, int length, boolean nextIsLive) {
    Bits.set(liveSet, offset);

    if (nextIsLive) {
        /*
         * If the next instruction is flowed to by this one, just
         * add it to the work set, and then a subsequent visit*()
         * will deal with it as appropriate.
         */
        addWorkIfNecessary(offset + length, false);
    } else {
        /*
         * If the next instruction isn't flowed to by this one,
         * then mark it as a start of a block but *don't* add it
         * to the work set, so that in the final phase we can know
         * dead code blocks as those marked as blocks but not also marked
         * live.
         */
        Bits.set(blockSet, offset + length);
    }
}
 
Example #14
Source File: Ropper.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Merges the specified frame into this subroutine's successors,
 * setting {@code workSet} as appropriate. To be called with
 * the frame of a subroutine ret block.
 *
 * @param frame {@code non-null;} frame from ret block to merge
 * @param workSet {@code non-null;} workset to update
 */
void mergeToSuccessors(Frame frame, int[] workSet) {
    for (int label = callerBlocks.nextSetBit(0); label >= 0;
         label = callerBlocks.nextSetBit(label+1)) {
        BasicBlock subCaller = labelToBlock(label);
        int succLabel = subCaller.getSuccessors().get(0);

        Frame subFrame = frame.subFrameForLabel(startBlock, label);

        if (subFrame != null) {
            mergeAndWorkAsNecessary(succLabel, -1, null,
                    subFrame, workSet);
        } else {
            Bits.set(workSet, label);
        }
    }
}
 
Example #15
Source File: BytecodeArray.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Processes the given "work set" by repeatedly finding the lowest bit
 * in the set, clearing it, and parsing and visiting the instruction at
 * the indicated offset (that is, the bit index), repeating until the
 * work set is empty. It is expected that the visitor will regularly
 * set new bits in the work set during the process.
 *
 * @param workSet {@code non-null;} the work set to process
 * @param visitor {@code non-null;} visitor to call back to for
 * each instruction
 */
public void processWorkSet(int[] workSet, Visitor visitor) {
    if (visitor == null) {
        throw new NullPointerException("visitor == null");
    }

    for (;;) {
        int offset = Bits.findFirst(workSet, 0);
        if (offset < 0) {
            break;
        }
        Bits.clear(workSet, offset);
        parseInstruction(offset, visitor);
        visitor.setPreviousOffset(offset);
    }
}
 
Example #16
Source File: BasicBlocker.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Helper method used by all the visitor methods.
 *
 * @param offset offset to the instruction
 * @param length length of the instruction, in bytes
 * @param nextIsLive {@code true} iff the instruction after
 * the indicated one is possibly-live (because this one isn't an
 * unconditional branch, a return, or a switch)
 */
private void visitCommon(int offset, int length, boolean nextIsLive) {
    Bits.set(liveSet, offset);

    if (nextIsLive) {
        /*
         * If the next instruction is flowed to by this one, just
         * add it to the work set, and then a subsequent visit*()
         * will deal with it as appropriate.
         */
        addWorkIfNecessary(offset + length, false);
    } else {
        /*
         * If the next instruction isn't flowed to by this one,
         * then mark it as a start of a block but *don't* add it
         * to the work set, so that in the final phase we can know
         * dead code blocks as those marked as blocks but not also marked
         * live.
         */
        Bits.set(blockSet, offset + length);
    }
}
 
Example #17
Source File: BasicBlocker.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Does basic block identification.
 */
private void doit() {
    BytecodeArray bytes = method.getCode();
    ByteCatchList catches = method.getCatches();
    int catchSz = catches.size();

    /*
     * Start by setting offset 0 as the start of a block and in need
     * of work...
     */
    Bits.set(workSet, 0);
    Bits.set(blockSet, 0);

    /*
     * And then process the work set, add new work based on
     * exception ranges that are active, and iterate until there's
     * nothing left to work on.
     */
    while (!Bits.isEmpty(workSet)) {
        try {
            bytes.processWorkSet(workSet, this);
        } catch (IllegalArgumentException ex) {
            // Translate the exception.
            throw new SimException("flow of control falls off " +
                                   "end of method",
                                   ex);
        }

        for (int i = 0; i < catchSz; i++) {
            ByteCatchList.Item item = catches.get(i);
            int start = item.getStartPc();
            int end = item.getEndPc();
            if (Bits.anyInRange(liveSet, start, end)) {
                Bits.set(blockSet, start);
                Bits.set(blockSet, end);
                addWorkIfNecessary(item.getHandlerPc(), true);
            }
        }
    }
}
 
Example #18
Source File: Ropper.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Does the conversion.
 */
private void doit() {
    int[] workSet = Bits.makeBitSet(maxLabel);

    Bits.set(workSet, 0);
    addSetupBlocks();
    setFirstFrame();

    for (;;) {
        int offset = Bits.findFirst(workSet, 0);
        if (offset < 0) {
            break;
        }
        Bits.clear(workSet, offset);
        ByteBlock block = blocks.labelToBlock(offset);
        Frame frame = startFrames[offset];
        try {
            processBlock(block, frame, workSet);
        } catch (SimException ex) {
            ex.addContext("...while working on block " + Hex.u2(offset));
            throw ex;
        }
    }

    addReturnBlock();
    addSynchExceptionHandlerBlock();
    addExceptionSetupBlocks();

    if (hasSubroutines) {
        // Subroutines are very rare, so skip this step if it's n/a
        inlineSubroutines();
    }
}
 
Example #19
Source File: Ropper.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Helper for {@link #processBlock}, which merges frames and
 * adds to the work set, as necessary.
 *
 * @param label {@code >= 0;} label to work on
 * @param pred  predecessor label; must be {@code >= 0} when
 * {@code label} is a subroutine start block and calledSubroutine
 * is non-null. Otherwise, may be -1.
 * @param calledSubroutine {@code null-ok;} a Subroutine instance if
 * {@code label} is the first block in a subroutine.
 * @param frame {@code non-null;} new frame for the labelled block
 * @param workSet {@code non-null;} bits representing work to do,
 * which this method may add to
 */
private void mergeAndWorkAsNecessary(int label, int pred,
        Subroutine calledSubroutine, Frame frame, int[] workSet) {
    Frame existing = startFrames[label];
    Frame merged;

    if (existing != null) {
        /*
         * Some other block also continues at this label. Merge
         * the frames, and re-set the bit in the work set if there
         * was a change.
         */
        if (calledSubroutine != null) {
            merged = existing.mergeWithSubroutineCaller(frame,
                    calledSubroutine.getStartBlock(), pred);
        } else {
            merged = existing.mergeWith(frame);
        }
        if (merged != existing) {
            startFrames[label] = merged;
            Bits.set(workSet, label);
        }
    } else {
        // This is the first time this label has been encountered.
        if (calledSubroutine != null) {
            startFrames[label]
                    = frame.makeNewSubroutineStartFrame(label, pred);
        } else {
            startFrames[label] = frame;
        }
        Bits.set(workSet, label);
    }
}
 
Example #20
Source File: LocalVariableExtractor.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Constructs an instance. This method is private. Use {@link #extract}.
 *
 * @param method {@code non-null;} the method to extract from
 */
private LocalVariableExtractor(RopMethod method) {
    if (method == null) {
        throw new NullPointerException("method == null");
    }

    BasicBlockList blocks = method.getBlocks();
    int maxLabel = blocks.getMaxLabel();

    this.method = method;
    this.blocks = blocks;
    this.resultInfo = new LocalVariableInfo(method);
    this.workSet = Bits.makeBitSet(maxLabel);
}
 
Example #21
Source File: LocalVariableExtractor.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Does the extraction.
 *
 * @return {@code non-null;} the extracted information
 */
private LocalVariableInfo doit() {
    for (int label = method.getFirstLabel();
         label >= 0;
         label = Bits.findFirst(workSet, 0)) {
        Bits.clear(workSet, label);
        processBlock(label);
    }

    resultInfo.setImmutable();
    return resultInfo;
}
 
Example #22
Source File: LocalVariableExtractor.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Does the extraction.
 *
 * @return {@code non-null;} the extracted information
 */
private LocalVariableInfo doit() {
    for (int label = method.getFirstLabel();
         label >= 0;
         label = Bits.findFirst(workSet, 0)) {
        Bits.clear(workSet, label);
        processBlock(label);
    }

    resultInfo.setImmutable();
    return resultInfo;
}
 
Example #23
Source File: BasicBlocker.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Sets a bit in the work set, but only if the instruction in question
 * isn't yet known to be possibly-live.
 *
 * @param offset offset to the instruction in question
 * @param blockStart {@code true} iff this instruction starts a
 * basic block
 */
private void addWorkIfNecessary(int offset, boolean blockStart) {
    if (!Bits.get(liveSet, offset)) {
        Bits.set(workSet, offset);
    }

    if (blockStart) {
        Bits.set(blockSet, offset);
    }
}
 
Example #24
Source File: BytecodeArray.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Finds the offset to each instruction in the bytecode array. The
 * result is a bit set with the offset of each opcode-per-se flipped on.
 *
 * @see Bits
 * @return {@code non-null;} appropriately constructed bit set
 */
public int[] getInstructionOffsets() {
    int sz = bytes.size();
    int[] result = Bits.makeBitSet(sz);
    int at = 0;

    while (at < sz) {
        Bits.set(result, at, true);
        int length = parseInstruction(at, null);
        at += length;
    }

    return result;
}
 
Example #25
Source File: Ropper.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Does the conversion.
 */
private void doit() {
    int[] workSet = Bits.makeBitSet(maxLabel);

    Bits.set(workSet, 0);
    addSetupBlocks();
    setFirstFrame();

    for (;;) {
        int offset = Bits.findFirst(workSet, 0);
        if (offset < 0) {
            break;
        }
        Bits.clear(workSet, offset);
        ByteBlock block = blocks.labelToBlock(offset);
        Frame frame = startFrames[offset];
        try {
            processBlock(block, frame, workSet);
        } catch (SimException ex) {
            ex.addContext("...while working on block " + Hex.u2(offset));
            throw ex;
        }
    }

    addReturnBlock();
    addSynchExceptionHandlerBlock();
    addExceptionSetupBlocks();

    if (hasSubroutines) {
        // Subroutines are very rare, so skip this step if it's n/a
        inlineSubroutines();
    }
}
 
Example #26
Source File: Ropper.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Helper for {@link #processBlock}, which merges frames and
 * adds to the work set, as necessary.
 *
 * @param label {@code >= 0;} label to work on
 * @param pred  predecessor label; must be {@code >= 0} when
 * {@code label} is a subroutine start block and calledSubroutine
 * is non-null. Otherwise, may be -1.
 * @param calledSubroutine {@code null-ok;} a Subroutine instance if
 * {@code label} is the first block in a subroutine.
 * @param frame {@code non-null;} new frame for the labelled block
 * @param workSet {@code non-null;} bits representing work to do,
 * which this method may add to
 */
private void mergeAndWorkAsNecessary(int label, int pred,
        Subroutine calledSubroutine, Frame frame, int[] workSet) {
    Frame existing = startFrames[label];
    Frame merged;

    if (existing != null) {
        /*
         * Some other block also continues at this label. Merge
         * the frames, and re-set the bit in the work set if there
         * was a change.
         */
        if (calledSubroutine != null) {
            merged = existing.mergeWithSubroutineCaller(frame,
                    calledSubroutine.getStartBlock(), pred);
        } else {
            merged = existing.mergeWith(frame);
        }
        if (merged != existing) {
            startFrames[label] = merged;
            Bits.set(workSet, label);
        }
    } else {
        // This is the first time this label has been encountered.
        if (calledSubroutine != null) {
            startFrames[label]
                    = frame.makeNewSubroutineStartFrame(label, pred);
        } else {
            startFrames[label] = frame;
        }
        Bits.set(workSet, label);
    }
}
 
Example #27
Source File: LocalVariableExtractor.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Constructs an instance. This method is private. Use {@link #extract}.
 *
 * @param method {@code non-null;} the method to extract from
 */
private LocalVariableExtractor(RopMethod method) {
    if (method == null) {
        throw new NullPointerException("method == null");
    }

    BasicBlockList blocks = method.getBlocks();
    int maxLabel = blocks.getMaxLabel();

    this.method = method;
    this.blocks = blocks;
    this.resultInfo = new LocalVariableInfo(method);
    this.workSet = Bits.makeBitSet(maxLabel);
}
 
Example #28
Source File: LocalVariableExtractor.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Does the extraction.
 *
 * @return {@code non-null;} the extracted information
 */
private LocalVariableInfo doit() {
    for (int label = method.getFirstLabel();
         label >= 0;
         label = Bits.findFirst(workSet, 0)) {
        Bits.clear(workSet, label);
        processBlock(label);
    }

    resultInfo.setImmutable();
    return resultInfo;
}
 
Example #29
Source File: BasicBlocker.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Does basic block identification.
 */
private void doit() {
    BytecodeArray bytes = method.getCode();
    ByteCatchList catches = method.getCatches();
    int catchSz = catches.size();

    /*
     * Start by setting offset 0 as the start of a block and in need
     * of work...
     */
    Bits.set(workSet, 0);
    Bits.set(blockSet, 0);

    /*
     * And then process the work set, add new work based on
     * exception ranges that are active, and iterate until there's
     * nothing left to work on.
     */
    while (!Bits.isEmpty(workSet)) {
        try {
            bytes.processWorkSet(workSet, this);
        } catch (IllegalArgumentException ex) {
            // Translate the exception.
            throw new SimException("flow of control falls off " +
                                   "end of method",
                                   ex);
        }

        for (int i = 0; i < catchSz; i++) {
            ByteCatchList.Item item = catches.get(i);
            int start = item.getStartPc();
            int end = item.getEndPc();
            if (Bits.anyInRange(liveSet, start, end)) {
                Bits.set(blockSet, start);
                Bits.set(blockSet, end);
                addWorkIfNecessary(item.getHandlerPc(), true);
            }
        }
    }
}
 
Example #30
Source File: BasicBlocker.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Does basic block identification.
 */
private void doit() {
    BytecodeArray bytes = method.getCode();
    ByteCatchList catches = method.getCatches();
    int catchSz = catches.size();

    /*
     * Start by setting offset 0 as the start of a block and in need
     * of work...
     */
    Bits.set(workSet, 0);
    Bits.set(blockSet, 0);

    /*
     * And then process the work set, add new work based on
     * exception ranges that are active, and iterate until there's
     * nothing left to work on.
     */
    while (!Bits.isEmpty(workSet)) {
        try {
            bytes.processWorkSet(workSet, this);
        } catch (IllegalArgumentException ex) {
            // Translate the exception.
            throw new SimException("flow of control falls off " +
                                   "end of method",
                                   ex);
        }

        for (int i = 0; i < catchSz; i++) {
            ByteCatchList.Item item = catches.get(i);
            int start = item.getStartPc();
            int end = item.getEndPc();
            if (Bits.anyInRange(liveSet, start, end)) {
                Bits.set(blockSet, start);
                Bits.set(blockSet, end);
                addWorkIfNecessary(item.getHandlerPc(), true);
            }
        }
    }
}