Search in sources :

Example 26 with IntList

use of com.taobao.android.dx.util.IntList in project atlas by alibaba.

the class Ropper method forEachNonSubBlockDepthFirst0.

/**
 * 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);
        }
    }
}
Also used : IntList(com.taobao.android.dx.util.IntList)

Example 27 with IntList

use of com.taobao.android.dx.util.IntList in project atlas by alibaba.

the class Frame method subFrameForLabel.

/**
 * Returns a Frame instance representing the frame state that should
 * be used when returning from a subroutine. The stack state of all
 * subroutine invocations is identical, but the locals state may differ.
 *
 * @param startLabel {@code >=0;} The label of the returning subroutine's
 * start block
 * @param subLabel {@code >=0;} A calling label of a subroutine
 * @return {@code null-ok;} an appropriatly-constructed instance, or null
 * if label is not in the set
 */
public Frame subFrameForLabel(int startLabel, int subLabel) {
    LocalsArray subLocals = null;
    if (locals instanceof LocalsArraySet) {
        subLocals = ((LocalsArraySet) locals).subArrayForLabel(subLabel);
    }
    IntList newSubroutines;
    try {
        newSubroutines = subroutines.mutableCopy();
        if (newSubroutines.pop() != startLabel) {
            throw new RuntimeException("returning from invalid subroutine");
        }
        newSubroutines.setImmutable();
    } catch (IndexOutOfBoundsException ex) {
        throw new RuntimeException("returning from invalid subroutine");
    } catch (NullPointerException ex) {
        throw new NullPointerException("can't return from non-subroutine");
    }
    return (subLocals == null) ? null : new Frame(subLocals, stack, newSubroutines);
}
Also used : IntList(com.taobao.android.dx.util.IntList)

Example 28 with IntList

use of com.taobao.android.dx.util.IntList in project atlas by alibaba.

the class Frame method mergeWithSubroutineCaller.

/**
 * 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);
}
Also used : IntList(com.taobao.android.dx.util.IntList)

Example 29 with IntList

use of com.taobao.android.dx.util.IntList in project atlas by alibaba.

the class Frame method mergeSubroutineLists.

/**
 * 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;
}
Also used : IntList(com.taobao.android.dx.util.IntList)

Example 30 with IntList

use of com.taobao.android.dx.util.IntList in project atlas by alibaba.

the class BasicBlocker method getBlockList.

/**
 * Extracts the list of basic blocks from the bit sets.
 *
 * @return {@code non-null;} the list of basic blocks
 */
private ByteBlockList getBlockList() {
    BytecodeArray bytes = method.getCode();
    ByteBlock[] bbs = new ByteBlock[bytes.size()];
    int count = 0;
    for (int at = 0, next; ; /*at*/
    at = next) {
        next = Bits.findFirst(blockSet, at + 1);
        if (next < 0) {
            break;
        }
        if (Bits.get(liveSet, at)) {
            /*
                 * Search backward for the branch or throwing
                 * instruction at the end of this block, if any. If
                 * there isn't any, then "next" is the sole target.
                 */
            IntList targets = null;
            int targetsAt = -1;
            ByteCatchList blockCatches;
            for (int i = next - 1; i >= at; i--) {
                targets = targetLists[i];
                if (targets != null) {
                    targetsAt = i;
                    break;
                }
            }
            if (targets == null) {
                targets = IntList.makeImmutable(next);
                blockCatches = ByteCatchList.EMPTY;
            } else {
                blockCatches = catchLists[targetsAt];
                if (blockCatches == null) {
                    blockCatches = ByteCatchList.EMPTY;
                }
            }
            bbs[count] = new ByteBlock(at, at, next, targets, blockCatches);
            count++;
        }
    }
    ByteBlockList result = new ByteBlockList(count);
    for (int i = 0; i < count; i++) {
        result.set(i, bbs[i]);
    }
    return result;
}
Also used : IntList(com.taobao.android.dx.util.IntList)

Aggregations

IntList (com.taobao.android.dx.util.IntList)30 BasicBlock (com.taobao.android.dx.rop.code.BasicBlock)11 RopMethod (com.taobao.android.dx.rop.code.RopMethod)4 CstType (com.taobao.android.dx.rop.cst.CstType)4 BasicBlockList (com.taobao.android.dx.rop.code.BasicBlockList)3 DexTranslationAdvice (com.taobao.android.dx.rop.code.DexTranslationAdvice)3 Insn (com.taobao.android.dx.rop.code.Insn)3 TranslationAdvice (com.taobao.android.dx.rop.code.TranslationAdvice)3 BytecodeArray (com.taobao.android.dx.cf.code.BytecodeArray)2 ConcreteMethod (com.taobao.android.dx.cf.code.ConcreteMethod)2 Method (com.taobao.android.dx.cf.iface.Method)2 InsnList (com.taobao.android.dx.rop.code.InsnList)2 PlainCstInsn (com.taobao.android.dx.rop.code.PlainCstInsn)2 PlainInsn (com.taobao.android.dx.rop.code.PlainInsn)2 RegisterSpec (com.taobao.android.dx.rop.code.RegisterSpec)2 SourcePosition (com.taobao.android.dx.rop.code.SourcePosition)2 ThrowingCstInsn (com.taobao.android.dx.rop.code.ThrowingCstInsn)2 ThrowingInsn (com.taobao.android.dx.rop.code.ThrowingInsn)2 Type (com.taobao.android.dx.rop.type.Type)2 TypeList (com.taobao.android.dx.rop.type.TypeList)2