Search in sources :

Example 41 with RegisterSpec

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

the class PhiInsn method updateSourcesToDefinitions.

/**
     * Updates the TypeBearers of all the sources (phi operands) to be
     * the current TypeBearer of the register-defining instruction's result.
     * This is used during phi-type resolution.<p>
     *
     * Note that local association of operands are preserved in this step.
     *
     * @param ssaMeth method that contains this insn
     */
public void updateSourcesToDefinitions(SsaMethod ssaMeth) {
    for (Operand o : operands) {
        RegisterSpec def = ssaMeth.getDefinitionForRegister(o.regSpec.getReg()).getResult();
        o.regSpec = o.regSpec.withType(def.getType());
    }
    sources = null;
}
Also used : RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 42 with RegisterSpec

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

the class PhiTypeResolver method run.

/**
     * Runs the phi-type resolver.
     */
private void run() {
    int regCount = ssaMeth.getRegCount();
    for (int reg = 0; reg < regCount; reg++) {
        SsaInsn definsn = ssaMeth.getDefinitionForRegister(reg);
        if (definsn != null && (definsn.getResult().getBasicType() == Type.BT_VOID)) {
            worklist.set(reg);
        }
    }
    int reg;
    while (0 <= (reg = worklist.nextSetBit(0))) {
        worklist.clear(reg);
        /*
             * definitions on the worklist have a type of BT_VOID, which
             * must have originated from a PhiInsn.
             */
        PhiInsn definsn = (PhiInsn) ssaMeth.getDefinitionForRegister(reg);
        if (resolveResultType(definsn)) {
            /*
                 * If the result type has changed, re-resolve all phis
                 * that use this.
                 */
            List<SsaInsn> useList = ssaMeth.getUseListForRegister(reg);
            int sz = useList.size();
            for (int i = 0; i < sz; i++) {
                SsaInsn useInsn = useList.get(i);
                RegisterSpec resultReg = useInsn.getResult();
                if (resultReg != null && useInsn instanceof PhiInsn) {
                    worklist.set(resultReg.getReg());
                }
            }
        }
    }
}
Also used : RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 43 with RegisterSpec

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

the class Ropper method addSynchExceptionHandlerBlock.

/**
 * Constructs and adds, if necessary, the catch-all exception handler
 * block to deal with unwinding the lock taken on entry to a synchronized
 * method.
 */
private void addSynchExceptionHandlerBlock() {
    if (!synchNeedsExceptionHandler) {
        /*
             * The method being converted either isn't synchronized or
             * can't possibly throw exceptions in its main body, so
             * there's no need for a synchronized method exception
             * handler.
             */
        return;
    }
    SourcePosition pos = method.makeSourcePosistion(0);
    RegisterSpec exReg = RegisterSpec.make(0, Type.THROWABLE);
    BasicBlock bb;
    Insn insn;
    InsnList insns = new InsnList(2);
    insn = new PlainInsn(Rops.opMoveException(Type.THROWABLE), pos, exReg, RegisterSpecList.EMPTY);
    insns.set(0, insn);
    insn = new ThrowingInsn(Rops.MONITOR_EXIT, pos, RegisterSpecList.make(getSynchReg()), StdTypeList.EMPTY);
    insns.set(1, insn);
    insns.setImmutable();
    int label2 = getSpecialLabel(SYNCH_CATCH_2);
    bb = new BasicBlock(getSpecialLabel(SYNCH_CATCH_1), insns, IntList.makeImmutable(label2), label2);
    addBlock(bb, IntList.EMPTY);
    insns = new InsnList(1);
    insn = new ThrowingInsn(Rops.THROW, pos, RegisterSpecList.make(exReg), StdTypeList.EMPTY);
    insns.set(0, insn);
    insns.setImmutable();
    bb = new BasicBlock(label2, insns, IntList.EMPTY, -1);
    addBlock(bb, IntList.EMPTY);
}
Also used : PlainInsn(com.android.dx.rop.code.PlainInsn) ThrowingCstInsn(com.android.dx.rop.code.ThrowingCstInsn) ThrowingInsn(com.android.dx.rop.code.ThrowingInsn) PlainInsn(com.android.dx.rop.code.PlainInsn) Insn(com.android.dx.rop.code.Insn) PlainCstInsn(com.android.dx.rop.code.PlainCstInsn) SourcePosition(com.android.dx.rop.code.SourcePosition) BasicBlock(com.android.dx.rop.code.BasicBlock) InsnList(com.android.dx.rop.code.InsnList) ThrowingInsn(com.android.dx.rop.code.ThrowingInsn) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 44 with RegisterSpec

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

the class Ropper method addSetupBlocks.

/**
 * Constructs and adds the blocks that perform setup for the rest of
 * the method. This includes a first block which merely contains
 * assignments from parameters to the same-numbered registers and
 * a possible second block which deals with synchronization.
 */
private void addSetupBlocks() {
    LocalVariableList localVariables = method.getLocalVariables();
    SourcePosition pos = method.makeSourcePosistion(0);
    Prototype desc = method.getEffectiveDescriptor();
    StdTypeList params = desc.getParameterTypes();
    int sz = params.size();
    InsnList insns = new InsnList(sz + 1);
    int at = 0;
    for (int i = 0; i < sz; i++) {
        Type one = params.get(i);
        LocalVariableList.Item local = localVariables.pcAndIndexToLocal(0, at);
        RegisterSpec result = (local == null) ? RegisterSpec.make(at, one) : RegisterSpec.makeLocalOptional(at, one, local.getLocalItem());
        Insn insn = new PlainCstInsn(Rops.opMoveParam(one), pos, result, RegisterSpecList.EMPTY, CstInteger.make(at));
        insns.set(i, insn);
        at += one.getCategory();
    }
    insns.set(sz, new PlainInsn(Rops.GOTO, pos, null, RegisterSpecList.EMPTY));
    insns.setImmutable();
    boolean synch = isSynchronized();
    int label = synch ? getSpecialLabel(SYNCH_SETUP_1) : 0;
    BasicBlock bb = new BasicBlock(getSpecialLabel(PARAM_ASSIGNMENT), insns, IntList.makeImmutable(label), label);
    addBlock(bb, IntList.EMPTY);
    if (synch) {
        RegisterSpec synchReg = getSynchReg();
        Insn insn;
        if (isStatic()) {
            insn = new ThrowingCstInsn(Rops.CONST_OBJECT, pos, RegisterSpecList.EMPTY, StdTypeList.EMPTY, method.getDefiningClass());
            insns = new InsnList(1);
            insns.set(0, insn);
        } else {
            insns = new InsnList(2);
            insn = new PlainCstInsn(Rops.MOVE_PARAM_OBJECT, pos, synchReg, RegisterSpecList.EMPTY, CstInteger.VALUE_0);
            insns.set(0, insn);
            insns.set(1, new PlainInsn(Rops.GOTO, pos, null, RegisterSpecList.EMPTY));
        }
        int label2 = getSpecialLabel(SYNCH_SETUP_2);
        insns.setImmutable();
        bb = new BasicBlock(label, insns, IntList.makeImmutable(label2), label2);
        addBlock(bb, IntList.EMPTY);
        insns = new InsnList(isStatic() ? 2 : 1);
        if (isStatic()) {
            insns.set(0, new PlainInsn(Rops.opMoveResultPseudo(synchReg), pos, synchReg, RegisterSpecList.EMPTY));
        }
        insn = new ThrowingInsn(Rops.MONITOR_ENTER, pos, RegisterSpecList.make(synchReg), StdTypeList.EMPTY);
        insns.set(isStatic() ? 1 : 0, insn);
        insns.setImmutable();
        bb = new BasicBlock(label2, insns, IntList.makeImmutable(0), 0);
        addBlock(bb, IntList.EMPTY);
    }
}
Also used : ThrowingCstInsn(com.android.dx.rop.code.ThrowingCstInsn) ThrowingInsn(com.android.dx.rop.code.ThrowingInsn) PlainInsn(com.android.dx.rop.code.PlainInsn) Insn(com.android.dx.rop.code.Insn) PlainCstInsn(com.android.dx.rop.code.PlainCstInsn) Prototype(com.android.dx.rop.type.Prototype) ThrowingCstInsn(com.android.dx.rop.code.ThrowingCstInsn) BasicBlock(com.android.dx.rop.code.BasicBlock) InsnList(com.android.dx.rop.code.InsnList) ThrowingInsn(com.android.dx.rop.code.ThrowingInsn) PlainCstInsn(com.android.dx.rop.code.PlainCstInsn) PlainInsn(com.android.dx.rop.code.PlainInsn) Type(com.android.dx.rop.type.Type) CstType(com.android.dx.rop.cst.CstType) StdTypeList(com.android.dx.rop.type.StdTypeList) SourcePosition(com.android.dx.rop.code.SourcePosition) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 45 with RegisterSpec

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

the class RopperMachine method getSources.

/**
 * Helper for {@link #run}, which gets the list of sources for the.
 * instruction.
 *
 * @param opcode the opcode being translated
 * @param stackPointer {@code >= 0;} the stack pointer after the
 * instruction's arguments have been popped
 * @return {@code non-null;} the sources
 */
private RegisterSpecList getSources(int opcode, int stackPointer) {
    int count = argCount();
    if (count == 0) {
        // We get an easy out if there aren't any sources.
        return RegisterSpecList.EMPTY;
    }
    int localIndex = getLocalIndex();
    RegisterSpecList sources;
    if (localIndex >= 0) {
        // The instruction is operating on a local variable.
        sources = new RegisterSpecList(1);
        sources.set(0, RegisterSpec.make(localIndex, arg(0)));
    } else {
        sources = new RegisterSpecList(count);
        int regAt = stackPointer;
        for (int i = 0; i < count; i++) {
            RegisterSpec spec = RegisterSpec.make(regAt, arg(i));
            sources.set(i, spec);
            regAt += spec.getCategory();
        }
        switch(opcode) {
            case ByteOps.IASTORE:
                {
                    /*
                     * The Java argument order for array stores is
                     * (array, index, value), but the rop argument
                     * order is (value, array, index). The following
                     * code gets the right arguments in the right
                     * places.
                     */
                    if (count != 3) {
                        throw new RuntimeException("shouldn't happen");
                    }
                    RegisterSpec array = sources.get(0);
                    RegisterSpec index = sources.get(1);
                    RegisterSpec value = sources.get(2);
                    sources.set(0, value);
                    sources.set(1, array);
                    sources.set(2, index);
                    break;
                }
            case ByteOps.PUTFIELD:
                {
                    /*
                     * Similar to above: The Java argument order for
                     * putfield is (object, value), but the rop
                     * argument order is (value, object).
                     */
                    if (count != 2) {
                        throw new RuntimeException("shouldn't happen");
                    }
                    RegisterSpec obj = sources.get(0);
                    RegisterSpec value = sources.get(1);
                    sources.set(0, value);
                    sources.set(1, obj);
                    break;
                }
        }
    }
    sources.setImmutable();
    return sources;
}
Also used : RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Aggregations

RegisterSpec (com.android.dx.rop.code.RegisterSpec)135 RegisterSpecList (com.android.dx.rop.code.RegisterSpecList)50 PlainInsn (com.android.dx.rop.code.PlainInsn)24 Constant (com.android.dx.rop.cst.Constant)20 TypedConstant (com.android.dx.rop.cst.TypedConstant)16 TypeBearer (com.android.dx.rop.type.TypeBearer)16 ArrayList (java.util.ArrayList)16 Insn (com.android.dx.rop.code.Insn)14 PlainCstInsn (com.android.dx.rop.code.PlainCstInsn)14 Rop (com.android.dx.rop.code.Rop)14 ThrowingCstInsn (com.android.dx.rop.code.ThrowingCstInsn)14 CstType (com.android.dx.rop.cst.CstType)14 BitSet (java.util.BitSet)11 LocalItem (com.android.dx.rop.code.LocalItem)10 RegisterSpecSet (com.android.dx.rop.code.RegisterSpecSet)10 ThrowingInsn (com.android.dx.rop.code.ThrowingInsn)10 CstString (com.android.dx.rop.cst.CstString)10 HashSet (java.util.HashSet)10 SourcePosition (com.android.dx.rop.code.SourcePosition)8 CstFieldRef (com.android.dx.rop.cst.CstFieldRef)8