Package com.android.dx.rop.code

Examples of com.android.dx.rop.code.Rop


        /** {@inheritDoc} */
        public void visitFillArrayDataInsn(FillArrayDataInsn insn) {
            SourcePosition pos = insn.getPosition();
            Constant cst = insn.getConstant();
            ArrayList<Constant> values = insn.getInitValues();
            Rop rop = insn.getOpcode();

            if (rop.getBranchingness() != Rop.BRANCH_NONE) {
                throw new RuntimeException("shouldn't happen");
            }
            CodeAddress dataAddress = new CodeAddress(pos);
            ArrayData dataInsn =
                new ArrayData(pos, lastAddress, values, cst);
View Full Code Here


            this.lastAddress = lastAddress;
        }

        /** {@inheritDoc} */
        public void visitPlainInsn(PlainInsn insn) {
            Rop rop = insn.getOpcode();
            if (rop.getOpcode() == RegOps.MARK_LOCAL) {
                /*
                 * Ignore these. They're dealt with by
                 * the LocalVariableAwareTranslationVisitor
                 */
                return;
            }
            if (rop.getOpcode() == RegOps.MOVE_RESULT_PSEUDO) {
                // These get skipped
                return;
            }

            SourcePosition pos = insn.getPosition();
            Dop opcode = RopToDop.dopFor(insn);
            DalvInsn di;

            switch (rop.getBranchingness()) {
                case Rop.BRANCH_NONE:
                case Rop.BRANCH_RETURN:
                case Rop.BRANCH_THROW: {
                    di = new SimpleInsn(opcode, pos, getRegs(insn));
                    break;
View Full Code Here

        /** {@inheritDoc} */
        public void visitPlainCstInsn(PlainCstInsn insn) {
            SourcePosition pos = insn.getPosition();
            Dop opcode = RopToDop.dopFor(insn);
            Rop rop = insn.getOpcode();
            int ropOpcode = rop.getOpcode();
            DalvInsn di;

            if (rop.getBranchingness() != Rop.BRANCH_NONE) {
                throw new RuntimeException("shouldn't happen");
            }

            if (ropOpcode == RegOps.MOVE_PARAM) {
                if (!paramsAreInOrder) {
View Full Code Here

        /** {@inheritDoc} */
        public void visitThrowingCstInsn(ThrowingCstInsn insn) {
            SourcePosition pos = insn.getPosition();
            Dop opcode = RopToDop.dopFor(insn);
            Rop rop = insn.getOpcode();
            Constant cst = insn.getConstant();

            if (rop.getBranchingness() != Rop.BRANCH_THROW) {
                throw new RuntimeException("shouldn't happen");
            }

            addOutput(lastAddress);

            if (rop.isCallLike()) {
                RegisterSpecList regs = insn.getSources();
                DalvInsn di = new CstInsn(opcode, pos, regs, cst);

                addOutput(di);
            } else {
                RegisterSpec realResult = getNextMoveResultPseudo();

                RegisterSpecList regs = getRegs(insn, realResult);
                DalvInsn di;

                boolean hasResult = opcode.hasResult()
                        || (rop.getOpcode() == RegOps.CHECK_CAST);

                if (hasResult != (realResult != null)) {
                    throw new RuntimeException(
                            "Insn with result/move-result-pseudo mismatch " +
                            insn);
                }
               
                if ((rop.getOpcode() == RegOps.NEW_ARRAY) &&
                    (opcode.getOpcode() != DalvOps.NEW_ARRAY)) {
                    /*
                     * It's a type-specific new-array-<primitive>, and
                     * so it should be turned into a SimpleInsn (no
                     * constant ref as it's implicit).
View Full Code Here

        /** {@inheritDoc} */
        public void visitThrowingInsn(ThrowingInsn insn) {
            SourcePosition pos = insn.getPosition();
            Dop opcode = RopToDop.dopFor(insn);
            Rop rop = insn.getOpcode();
            RegisterSpec realResult;

            if (rop.getBranchingness() != Rop.BRANCH_THROW) {
                throw new RuntimeException("shouldn't happen");
            }

            realResult = getNextMoveResultPseudo();

View Full Code Here

        /** {@inheritDoc} */
        public void visitFillArrayDataInsn(FillArrayDataInsn insn) {
            SourcePosition pos = insn.getPosition();
            Constant cst = insn.getConstant();
            ArrayList<Constant> values = insn.getInitValues();
            Rop rop = insn.getOpcode();

            if (rop.getBranchingness() != Rop.BRANCH_NONE) {
                throw new RuntimeException("shouldn't happen");
            }
            CodeAddress dataAddress = new CodeAddress(pos);
            ArrayData dataInsn =
                new ArrayData(pos, lastAddress, values, cst);
View Full Code Here

        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
View Full Code Here

     * @param insn {@code non-null;} the original instruction
     * @return the corresponding dalvik opcode; one of the constants in
     * {@link Dops}
     */
    public static Dop dopFor(Insn insn) {
        Rop rop = insn.getOpcode();

        /*
         * First, just try looking up the rop in the MAP of easy
         * cases.
         */
        Dop result = MAP.get(rop);
        if (result != null) {
            return result;
        }

        /*
         * There was no easy case for the rop, so look up the opcode, and
         * do something special for each:
         *
         * The move_exception, new_array, filled_new_array, and
         * invoke* opcodes won't be found in MAP, since they'll each
         * have different source and/or result register types / lists.
         *
         * The get* and put* opcodes for (non-long) integral types
         * aren't in the map, since the type signatures aren't
         * sufficient to distinguish between the types (the salient
         * source or result will always be just "int").
         *
         * And const instruction need to distinguish between strings and
         * classes.
         */

        switch (rop.getOpcode()) {
            case RegOps.MOVE_EXCEPTION:   return Dops.MOVE_EXCEPTION;
            case RegOps.INVOKE_STATIC:    return Dops.INVOKE_STATIC;
            case RegOps.INVOKE_VIRTUAL:   return Dops.INVOKE_VIRTUAL;
            case RegOps.INVOKE_SUPER:     return Dops.INVOKE_SUPER;
            case RegOps.INVOKE_DIRECT:    return Dops.INVOKE_DIRECT;
View Full Code Here

        }               

        TypeBearer destType = (dest != null) ? dest : Type.VOID;
        Constant cst = getAuxCst();
        int ropOpcode;
        Rop rop;
        Insn insn;

        if (opcode == ByteOps.MULTIANEWARRAY) {
            blockCanThrow = true;

            // Add the extra instructions for handling multianewarray.

            extraBlockCount = 6;

            /*
             * Add an array constructor for the int[] containing all the
             * dimensions.
             */
            RegisterSpec dimsReg =
                RegisterSpec.make(dest.getNextReg(), Type.INT_ARRAY);
            rop = Rops.opFilledNewArray(Type.INT_ARRAY, sourceCount);
            insn = new ThrowingCstInsn(rop, pos, sources, catches,
                    CstType.INT_ARRAY);
            insns.add(insn);

            // Add a move-result for the new-filled-array
            rop = Rops.opMoveResult(Type.INT_ARRAY);
            insn = new PlainInsn(rop, pos, dimsReg, RegisterSpecList.EMPTY);
            insns.add(insn);

            /*
             * Add a const-class instruction for the specified array
             * class.
             */

            /*
             * Remove as many dimensions from the originally specified
             * class as are given in the explicit list of dimensions,
             * so as to pass the right component class to the standard
             * Java library array constructor.
             */
            Type componentType = ((CstType) cst).getClassType();
            for (int i = 0; i < sourceCount; i++) {
                componentType = componentType.getComponentType();
            }

            RegisterSpec classReg =
                RegisterSpec.make(dest.getReg(), Type.CLASS);

            if (componentType.isPrimitive()) {
                /*
                 * The component type is primitive (e.g., int as opposed
                 * to Integer), so we have to fetch the corresponding
                 * TYPE class.
                 */
                CstFieldRef typeField =
                    CstFieldRef.forPrimitiveType(componentType);
                insn = new ThrowingCstInsn(Rops.GET_STATIC_OBJECT, pos,
                                           RegisterSpecList.EMPTY,
                                           catches, typeField);
            } else {
                /*
                 * The component type is an object type, so just make a
                 * normal class reference.
                 */
                insn = new ThrowingCstInsn(Rops.CONST_OBJECT, pos,
                                           RegisterSpecList.EMPTY, catches,
                                           new CstType(componentType));
            }

            insns.add(insn);

            // Add a move-result-pseudo for the get-static or const
            rop = Rops.opMoveResultPseudo(classReg.getType());
            insn = new PlainInsn(rop, pos, classReg, RegisterSpecList.EMPTY);
            insns.add(insn);

            /*
             * Add a call to the "multianewarray method," that is,
             * Array.newInstance(class, dims). Note: The result type
             * of newInstance() is Object, which is why the last
             * instruction in this sequence is a cast to the right
             * type for the original instruction.
             */

            RegisterSpec objectReg =
                RegisterSpec.make(dest.getReg(), Type.OBJECT);
           
            insn = new ThrowingCstInsn(
                    Rops.opInvokeStatic(MULTIANEWARRAY_METHOD.getPrototype()),
                    pos, RegisterSpecList.make(classReg, dimsReg),
                    catches, MULTIANEWARRAY_METHOD);
            insns.add(insn);

            // Add a move-result.
            rop = Rops.opMoveResult(MULTIANEWARRAY_METHOD.getPrototype()
                    .getReturnType());
            insn = new PlainInsn(rop, pos, objectReg, RegisterSpecList.EMPTY);
            insns.add(insn);

            /*
             * And finally, set up for the remainder of this method to
             * add an appropriate cast.
             */

            opcode = ByteOps.CHECKCAST;
            sources = RegisterSpecList.make(objectReg);
        } else if (opcode == ByteOps.JSR) {
            // JSR has no Rop instruction
            hasJsr = true;
            return;
        } else if (opcode == ByteOps.RET) {
            try {
                returnAddress = (ReturnAddress)arg(0);
            } catch (ClassCastException ex) {
                throw new RuntimeException(
                        "Argument to RET was not a ReturnAddress", ex);
            }
            // RET has no Rop instruction.
            return;
        }

        ropOpcode = jopToRopOpcode(opcode, cst);
        rop = Rops.ropFor(ropOpcode, destType, sources, cst);

        Insn moveResult = null;
        if (dest != null && rop.isCallLike()) {
            /*
             * We're going to want to have a move-result in the next
             * basic block.
             */
            extraBlockCount++;

            moveResult = new PlainInsn(
                    Rops.opMoveResult(((CstBaseMethodRef) cst).getPrototype()
                    .getReturnType()), pos, dest, RegisterSpecList.EMPTY);

            dest = null;
        } else if (dest != null && rop.canThrow()) {
            /*
             * We're going to want to have a move-result-pseudo in the
             * next basic block.
             */
            extraBlockCount++;

            moveResult = new PlainInsn(
                    Rops.opMoveResultPseudo(dest.getTypeBearer()),
                    pos, dest, RegisterSpecList.EMPTY);

            dest = null;
        }
        if (ropOpcode == RegOps.NEW_ARRAY) {
            /*
             * In the original bytecode, this was either a primitive
             * array constructor "newarray" or an object array
             * constructor "anewarray". In the former case, there is
             * no explicit constant, and in the latter, the constant
             * is for the element type and not the array type. The rop
             * instruction form for both of these is supposed to be
             * the resulting array type, so we initialize / alter
             * "cst" here, accordingly. Conveniently enough, the rop
             * opcode already gets constructed with the proper array
             * type.
             */
            cst = CstType.intern(rop.getResult());
        } else if ((cst == null) && (sourceCount == 2)) {
            TypeBearer lastType = sources.get(1).getTypeBearer();

            if (lastType.isConstant()
                    && advice.hasConstantOperation(rop,
                    sources.get(0), sources.get(1))) {
                /*
                 * The target architecture has an instruction that can
                 * build in the constant found in the second argument,
                 * so pull it out of the sources and just use it as a
                 * constant here.
                 */
                cst = (Constant) lastType;
                sources = sources.withoutLast();
                rop = Rops.ropFor(ropOpcode, destType, sources, cst);
            }
        }

        SwitchList cases = getAuxCases();
        ArrayList<Constant> initValues = getInitValues();
        boolean canThrow = rop.canThrow();

        blockCanThrow |= canThrow;

        if (cases != null) {
            if (cases.size() == 0) {
View Full Code Here

            }

            public void visitNonMoveInsn(NormalSsaInsn insn) {

                Insn originalRopInsn = insn.getOriginalRopInsn();
                Rop opcode = originalRopInsn.getOpcode();
                RegisterSpecList sources = insn.getSources();

                if (sources.size() != 2 ) {
                    // We're only dealing with two-source insns here.
                    return;
                }

                if (opcode.getBranchingness() == Rop.BRANCH_IF) {
                    /*
                     * An if instruction can become an if-*z instruction.
                     */
                    if (isConstIntZeroOrKnownNull(sources.get(0))) {
                        replacePlainInsn(insn, sources.withoutFirst(),
                                RegOps.flippedIfOpcode(opcode.getOpcode()));
                    } else if (isConstIntZeroOrKnownNull(sources.get(1))) {
                        replacePlainInsn(insn, sources.withoutLast(),
                                opcode.getOpcode());
                    }
                } else if (advice.hasConstantOperation(
                        opcode, sources.get(0), sources.get(1))) {
                    insn.upgradeToLiteral();
                } else  if (opcode.isCommutative()
                        && advice.hasConstantOperation(
                        opcode, sources.get(1), sources.get(0))) {
                    /*
                     * An instruction can be commuted to a literal operation
                     */
 
View Full Code Here

TOP

Related Classes of com.android.dx.rop.code.Rop

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.