Search in sources :

Example 11 with RegisterSpecSet

use of com.android.dx.rop.code.RegisterSpecSet in project buck by facebook.

the class RopTranslator method outputBlock.

/**
     * Helper for {@link #outputInstructions}, which does the processing
     * and output of one block.
     *
     * @param block {@code non-null;} the block to process and output
     * @param nextLabel {@code >= -1;} the next block that will be processed, or
     * {@code -1} if there is no next block
     */
private void outputBlock(BasicBlock block, int nextLabel) {
    // Append the code address for this block.
    CodeAddress startAddress = addresses.getStart(block);
    output.add(startAddress);
    // Append the local variable state for the block.
    if (locals != null) {
        RegisterSpecSet starts = locals.getStarts(block);
        output.add(new LocalSnapshot(startAddress.getPosition(), starts));
    }
    /*
         * Choose and append an output instruction for each original
         * instruction.
         */
    translationVisitor.setBlock(block, addresses.getLast(block));
    block.getInsns().forEach(translationVisitor);
    // Insert the block end code address.
    output.add(addresses.getEnd(block));
    // Set up for end-of-block activities.
    int succ = block.getPrimarySuccessor();
    Insn lastInsn = block.getLastInsn();
    if ((succ >= 0) && (succ != nextLabel)) {
        /*
             * The block has a "primary successor" and that primary
             * successor isn't the next block to be output.
             */
        Rop lastRop = lastInsn.getOpcode();
        if ((lastRop.getBranchingness() == Rop.BRANCH_IF) && (block.getSecondarySuccessor() == nextLabel)) {
            /*
                 * The block ends with an "if" of some sort, and its
                 * secondary successor (the "then") is in fact the
                 * next block to output. So, reverse the sense of
                 * the test, so that we can just emit the next block
                 * without an interstitial goto.
                 */
            output.reverseBranch(1, addresses.getStart(succ));
        } else {
            /*
                 * Our only recourse is to add a goto here to get the
                 * flow to be correct.
                 */
            TargetInsn insn = new TargetInsn(Dops.GOTO, lastInsn.getPosition(), RegisterSpecList.EMPTY, addresses.getStart(succ));
            output.add(insn);
        }
    }
}
Also used : ThrowingCstInsn(com.android.dx.rop.code.ThrowingCstInsn) ThrowingInsn(com.android.dx.rop.code.ThrowingInsn) Insn(com.android.dx.rop.code.Insn) SwitchInsn(com.android.dx.rop.code.SwitchInsn) PlainInsn(com.android.dx.rop.code.PlainInsn) FillArrayDataInsn(com.android.dx.rop.code.FillArrayDataInsn) PlainCstInsn(com.android.dx.rop.code.PlainCstInsn) Rop(com.android.dx.rop.code.Rop) RegisterSpecSet(com.android.dx.rop.code.RegisterSpecSet)

Example 12 with RegisterSpecSet

use of com.android.dx.rop.code.RegisterSpecSet in project J2ME-Loader by nikita36078.

the class OutputFinisher method hasLocalInfo.

/**
 * Helper for {@link #add} which scrutinizes a single
 * instruction for local variable information.
 *
 * @param insn {@code non-null;} instruction to scrutinize
 * @return {@code true} iff the instruction refers to any
 * named locals
 */
private static boolean hasLocalInfo(DalvInsn insn) {
    if (insn instanceof LocalSnapshot) {
        RegisterSpecSet specs = ((LocalSnapshot) insn).getLocals();
        int size = specs.size();
        for (int i = 0; i < size; i++) {
            if (hasLocalInfo(specs.get(i))) {
                return true;
            }
        }
    } else if (insn instanceof LocalStart) {
        RegisterSpec spec = ((LocalStart) insn).getLocal();
        if (hasLocalInfo(spec)) {
            return true;
        }
    }
    return false;
}
Also used : RegisterSpecSet(com.android.dx.rop.code.RegisterSpecSet) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 13 with RegisterSpecSet

use of com.android.dx.rop.code.RegisterSpecSet in project J2ME-Loader by nikita36078.

the class OutputFinisher method addConstants.

/**
 * Helper for {@link #getAllConstants} which adds all the info for
 * a single instruction.
 *
 * @param result {@code non-null;} result set to add to
 * @param insn {@code non-null;} instruction to scrutinize
 */
private static void addConstants(HashSet<Constant> result, DalvInsn insn) {
    if (insn instanceof CstInsn) {
        Constant cst = ((CstInsn) insn).getConstant();
        result.add(cst);
    } else if (insn instanceof MultiCstInsn) {
        MultiCstInsn m = (MultiCstInsn) insn;
        for (int i = 0; i < m.getNumberOfConstants(); i++) {
            result.add(m.getConstant(i));
        }
    } else if (insn instanceof LocalSnapshot) {
        RegisterSpecSet specs = ((LocalSnapshot) insn).getLocals();
        int size = specs.size();
        for (int i = 0; i < size; i++) {
            addConstants(result, specs.get(i));
        }
    } else if (insn instanceof LocalStart) {
        RegisterSpec spec = ((LocalStart) insn).getLocal();
        addConstants(result, spec);
    }
}
Also used : RegisterSpecSet(com.android.dx.rop.code.RegisterSpecSet) Constant(com.android.dx.rop.cst.Constant) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 14 with RegisterSpecSet

use of com.android.dx.rop.code.RegisterSpecSet in project J2ME-Loader by nikita36078.

the class LocalVariableInfo method mergeStarts.

/**
 * Merges the given register set into the set for the block with the
 * given index. If there was not already an associated set, then this
 * is the same as calling {@link #setStarts}. Otherwise, this will
 * merge the two sets and call {@link #setStarts} on the result of the
 * merge.
 *
 * @param index {@code >= 0;} the block index
 * @param specs {@code non-null;} the register set to merge into the start set
 * for the block
 * @return {@code true} if the merge resulted in an actual change
 * to the associated set (including storing one for the first time) or
 * {@code false} if there was no change
 */
public boolean mergeStarts(int index, RegisterSpecSet specs) {
    RegisterSpecSet start = getStarts0(index);
    boolean changed = false;
    if (start == null) {
        setStarts(index, specs);
        return true;
    }
    RegisterSpecSet newStart = start.mutableCopy();
    newStart.intersect(specs, true);
    if (start.equals(newStart)) {
        return false;
    }
    newStart.setImmutable();
    setStarts(index, newStart);
    return true;
}
Also used : RegisterSpecSet(com.android.dx.rop.code.RegisterSpecSet)

Aggregations

RegisterSpecSet (com.android.dx.rop.code.RegisterSpecSet)14 RegisterSpec (com.android.dx.rop.code.RegisterSpec)10 FillArrayDataInsn (com.android.dx.rop.code.FillArrayDataInsn)2 Insn (com.android.dx.rop.code.Insn)2 PlainCstInsn (com.android.dx.rop.code.PlainCstInsn)2 PlainInsn (com.android.dx.rop.code.PlainInsn)2 Rop (com.android.dx.rop.code.Rop)2 SwitchInsn (com.android.dx.rop.code.SwitchInsn)2 ThrowingCstInsn (com.android.dx.rop.code.ThrowingCstInsn)2 ThrowingInsn (com.android.dx.rop.code.ThrowingInsn)2 Constant (com.android.dx.rop.cst.Constant)2 IntList (com.android.dx.util.IntList)2 InvokePolymorphicInsn (com.android.dx.rop.code.InvokePolymorphicInsn)1