Search in sources :

Example 16 with IntList

use of com.android.dx.util.IntList in project buck by facebook.

the class LocalVariableExtractor method processBlock.

/**
     * Processes a single block.
     *
     * @param label {@code >= 0;} label of the block to process
     */
private void processBlock(int label) {
    RegisterSpecSet primaryState = resultInfo.mutableCopyOfStarts(label);
    BasicBlock block = blocks.labelToBlock(label);
    InsnList insns = block.getInsns();
    int insnSz = insns.size();
    /*
         * We may have to treat the last instruction specially: If it
         * can (but doesn't always) throw, and the exception can be
         * caught within the same method, then we need to use the
         * state *before* executing it to be what is merged into
         * exception targets.
         */
    boolean canThrowDuringLastInsn = block.hasExceptionHandlers() && (insns.getLast().getResult() != null);
    int freezeSecondaryStateAt = insnSz - 1;
    RegisterSpecSet secondaryState = primaryState;
    for (int i = 0; i < insnSz; i++) {
        if (canThrowDuringLastInsn && (i == freezeSecondaryStateAt)) {
            // Until this point, primaryState == secondaryState.
            primaryState.setImmutable();
            primaryState = primaryState.mutableCopy();
        }
        Insn insn = insns.get(i);
        RegisterSpec result;
        result = insn.getLocalAssignment();
        if (result == null) {
            /*
                 * If an assignment assigns over an existing local, make
                 * sure to mark the local as going out of scope.
                 */
            result = insn.getResult();
            if (result != null && primaryState.get(result.getReg()) != null) {
                primaryState.remove(primaryState.get(result.getReg()));
            }
            continue;
        }
        result = result.withSimpleType();
        RegisterSpec already = primaryState.get(result);
        /*
             * The equals() check ensures we only add new info if
             * the instruction causes a change to the set of
             * active variables.
             */
        if (!result.equals(already)) {
            /*
                 * If this insn represents a local moving from one register
                 * to another, remove the association between the old register
                 * and the local.
                 */
            RegisterSpec previous = primaryState.localItemToSpec(result.getLocalItem());
            if (previous != null && (previous.getReg() != result.getReg())) {
                primaryState.remove(previous);
            }
            resultInfo.addAssignment(insn, result);
            primaryState.put(result);
        }
    }
    primaryState.setImmutable();
    /*
         * Merge this state into the start state for each successor,
         * and update the work set where required (that is, in cases
         * where the start state for a block changes).
         */
    IntList successors = block.getSuccessors();
    int succSz = successors.size();
    int primarySuccessor = block.getPrimarySuccessor();
    for (int i = 0; i < succSz; i++) {
        int succ = successors.get(i);
        RegisterSpecSet state = (succ == primarySuccessor) ? primaryState : secondaryState;
        if (resultInfo.mergeStarts(succ, state)) {
            Bits.set(workSet, succ);
        }
    }
}
Also used : IntList(com.android.dx.util.IntList)

Example 17 with IntList

use of com.android.dx.util.IntList in project buck by facebook.

the class RopMethod method calcPredecessors.

/**
     * Calculates the predecessor sets for each block as well as for the
     * exit.
     */
private void calcPredecessors() {
    int maxLabel = blocks.getMaxLabel();
    IntList[] predecessors = new IntList[maxLabel];
    IntList exitPredecessors = new IntList(10);
    int sz = blocks.size();
    /*
         * For each block, find its successors, and add the block's label to
         * the successor's predecessors.
         */
    for (int i = 0; i < sz; i++) {
        BasicBlock one = blocks.get(i);
        int label = one.getLabel();
        IntList successors = one.getSuccessors();
        int ssz = successors.size();
        if (ssz == 0) {
            // This block exits.
            exitPredecessors.add(label);
        } else {
            for (int j = 0; j < ssz; j++) {
                int succLabel = successors.get(j);
                IntList succPreds = predecessors[succLabel];
                if (succPreds == null) {
                    succPreds = new IntList(10);
                    predecessors[succLabel] = succPreds;
                }
                succPreds.add(label);
            }
        }
    }
    // Sort and immutablize all the predecessor lists.
    for (int i = 0; i < maxLabel; i++) {
        IntList preds = predecessors[i];
        if (preds != null) {
            preds.sort();
            preds.setImmutable();
        }
    }
    exitPredecessors.sort();
    exitPredecessors.setImmutable();
    /*
         * The start label might not ever have had any predecessors
         * added to it (probably doesn't, because of how Java gets
         * translated into rop form). So, check for this and rectify
         * the situation if required.
         */
    if (predecessors[firstLabel] == null) {
        predecessors[firstLabel] = IntList.EMPTY;
    }
    this.predecessors = predecessors;
    this.exitPredecessors = exitPredecessors;
}
Also used : IntList(com.android.dx.util.IntList)

Example 18 with IntList

use of com.android.dx.util.IntList in project J2ME-Loader by nikita36078.

the class ByteCatchList method toTargetList.

/**
 * Returns a target list corresponding to this instance. The result
 * is a list of all the exception handler addresses, with the given
 * {@code noException} address appended if appropriate. The
 * result is automatically made immutable.
 *
 * @param noException {@code >= -1;} the no-exception address to append, or
 * {@code -1} not to append anything
 * @return {@code non-null;} list of exception targets, with
 * {@code noException} appended if necessary
 */
public IntList toTargetList(int noException) {
    if (noException < -1) {
        throw new IllegalArgumentException("noException < -1");
    }
    boolean hasDefault = (noException >= 0);
    int sz = size();
    if (sz == 0) {
        if (hasDefault) {
            /*
                 * The list is empty, but there is a no-exception
                 * address; so, the result is just that address.
                 */
            return IntList.makeImmutable(noException);
        }
        /*
             * The list is empty and there isn't even a no-exception
             * address.
             */
        return IntList.EMPTY;
    }
    IntList result = new IntList(sz + (hasDefault ? 1 : 0));
    for (int i = 0; i < sz; i++) {
        result.add(get(i).getHandlerPc());
    }
    if (hasDefault) {
        result.add(noException);
    }
    result.setImmutable();
    return result;
}
Also used : IntList(com.android.dx.util.IntList)

Example 19 with IntList

use of com.android.dx.util.IntList in project J2ME-Loader by nikita36078.

the class Frame method mergeWith.

/**
 * Merges two frames. If the merged result is the same as this frame,
 * then this instance is returned.
 *
 * @param other {@code non-null;} another frame
 * @return {@code non-null;} the result of merging the two frames
 */
public Frame mergeWith(Frame other) {
    LocalsArray resultLocals;
    ExecutionStack resultStack;
    IntList resultSubroutines;
    resultLocals = getLocals().merge(other.getLocals());
    resultStack = getStack().merge(other.getStack());
    resultSubroutines = mergeSubroutineLists(other.subroutines);
    resultLocals = adjustLocalsForSubroutines(resultLocals, resultSubroutines);
    if ((resultLocals == getLocals()) && (resultStack == getStack()) && subroutines == resultSubroutines) {
        return this;
    }
    return new Frame(resultLocals, resultStack, resultSubroutines);
}
Also used : IntList(com.android.dx.util.IntList)

Example 20 with IntList

use of com.android.dx.util.IntList in project J2ME-Loader by nikita36078.

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.android.dx.util.IntList)

Aggregations

IntList (com.android.dx.util.IntList)56 BasicBlock (com.android.dx.rop.code.BasicBlock)20 CstType (com.android.dx.rop.cst.CstType)7 Insn (com.android.dx.rop.code.Insn)5 RopMethod (com.android.dx.rop.code.RopMethod)5 BasicBlockList (com.android.dx.rop.code.BasicBlockList)4 PlainCstInsn (com.android.dx.rop.code.PlainCstInsn)4 PlainInsn (com.android.dx.rop.code.PlainInsn)4 RegisterSpec (com.android.dx.rop.code.RegisterSpec)4 SourcePosition (com.android.dx.rop.code.SourcePosition)4 ThrowingCstInsn (com.android.dx.rop.code.ThrowingCstInsn)4 ThrowingInsn (com.android.dx.rop.code.ThrowingInsn)4 Type (com.android.dx.rop.type.Type)4 TypeList (com.android.dx.rop.type.TypeList)4 DexTranslationAdvice (com.android.dx.rop.code.DexTranslationAdvice)3 InsnList (com.android.dx.rop.code.InsnList)3 TranslationAdvice (com.android.dx.rop.code.TranslationAdvice)3 SsaBasicBlock (com.android.dx.ssa.SsaBasicBlock)3 ArrayList (java.util.ArrayList)3 BitSet (java.util.BitSet)3