Search in sources :

Example 6 with AnalyzerException

use of org.objectweb.asm.tree.analysis.AnalyzerException in project dex2jar by pxb1988.

the class TestUtils method verify.

@SuppressWarnings("rawtypes")
public static void verify(final ClassReader cr, PrintWriter out) throws AnalyzerException, IllegalArgumentException, IllegalAccessException {
    ClassNode cn = new ClassNode();
    cr.accept(new CheckClassAdapter(cn, false), ClassReader.SKIP_DEBUG);
    List methods = cn.methods;
    for (int i = 0; i < methods.size(); ++i) {
        MethodNode method = (MethodNode) methods.get(i);
        List tryCatchBlocks = method.tryCatchBlocks;
        for (int j = 0; j < tryCatchBlocks.size(); j++) {
            TryCatchBlockNode tcn = (TryCatchBlockNode) tryCatchBlocks.get(j);
            if (tcn.start.equals(tcn.end)) {
                throw new DexException("try/catch block %d in %s has same start(%s) and end(%s)", j, method.name, tcn.start.getLabel(), tcn.end.getLabel());
            }
        }
        BasicVerifier verifier = new BasicVerifier();
        Analyzer a = new Analyzer(verifier);
        try {
            a.analyze(cn.name, method);
        } catch (Exception e) {
            out.println(cr.getClassName() + "." + method.name + method.desc);
            printAnalyzerResult(method, a, out);
            e.printStackTrace(out);
            out.flush();
            throw new DexException("method " + method.name + " " + method.desc, e);
        }
    }
}
Also used : BasicVerifier(org.objectweb.asm.tree.analysis.BasicVerifier) ClassNode(org.objectweb.asm.tree.ClassNode) DexClassNode(com.googlecode.d2j.node.DexClassNode) TryCatchBlockNode(org.objectweb.asm.tree.TryCatchBlockNode) DexException(com.googlecode.d2j.DexException) DexMethodNode(com.googlecode.d2j.node.DexMethodNode) MethodNode(org.objectweb.asm.tree.MethodNode) CheckClassAdapter(org.objectweb.asm.util.CheckClassAdapter) List(java.util.List) ArrayList(java.util.ArrayList) Analyzer(org.objectweb.asm.tree.analysis.Analyzer) AnalyzerException(org.objectweb.asm.tree.analysis.AnalyzerException) DexException(com.googlecode.d2j.DexException) ZipException(java.util.zip.ZipException) ParseException(com.android.dx.cf.iface.ParseException)

Example 7 with AnalyzerException

use of org.objectweb.asm.tree.analysis.AnalyzerException in project dex2jar by pxb1988.

the class J2IRConverter method buildInterpreter.

private Interpreter<JvmValue> buildInterpreter() {
    return new Interpreter<JvmValue>(Opcodes.ASM4) {

        @Override
        public JvmValue newValue(Type type) {
            return null;
        }

        @Override
        public JvmValue newOperation(AbstractInsnNode insn) throws AnalyzerException {
            switch(insn.getOpcode()) {
                case ACONST_NULL:
                    return b(1, Exprs.nNull());
                case ICONST_M1:
                case ICONST_0:
                case ICONST_1:
                case ICONST_2:
                case ICONST_3:
                case ICONST_4:
                case ICONST_5:
                    return b(1, Exprs.nInt(insn.getOpcode() - ICONST_0));
                case LCONST_0:
                case LCONST_1:
                    return b(2, Exprs.nLong(insn.getOpcode() - LCONST_0));
                case FCONST_0:
                case FCONST_1:
                case FCONST_2:
                    return b(1, Exprs.nFloat(insn.getOpcode() - FCONST_0));
                case DCONST_0:
                case DCONST_1:
                    return b(2, Exprs.nDouble(insn.getOpcode() - DCONST_0));
                case BIPUSH:
                case SIPUSH:
                    return b(1, Exprs.nInt(((IntInsnNode) insn).operand));
                case LDC:
                    Object cst = ((LdcInsnNode) insn).cst;
                    if (cst instanceof Integer) {
                        return b(1, Exprs.nInt((Integer) cst));
                    } else if (cst instanceof Float) {
                        return b(1, Exprs.nFloat((Float) cst));
                    } else if (cst instanceof Long) {
                        return b(2, Exprs.nLong((Long) cst));
                    } else if (cst instanceof Double) {
                        return b(2, Exprs.nDouble((Double) cst));
                    } else if (cst instanceof String) {
                        return b(1, Exprs.nString((String) cst));
                    } else if (cst instanceof Type) {
                        Type type = (Type) cst;
                        int sort = type.getSort();
                        if (sort == Type.OBJECT || sort == Type.ARRAY) {
                            return b(1, Exprs.nType(type.getDescriptor()));
                        } else if (sort == Type.METHOD) {
                            throw new UnsupportedOperationException("Not supported yet.");
                        } else {
                            throw new IllegalArgumentException("Illegal LDC constant " + cst);
                        }
                    } else if (cst instanceof Handle) {
                        throw new UnsupportedOperationException("Not supported yet.");
                    } else {
                        throw new IllegalArgumentException("Illegal LDC constant " + cst);
                    }
                case JSR:
                    throw new UnsupportedOperationException("Not supported yet.");
                case GETSTATIC:
                    FieldInsnNode fin = (FieldInsnNode) insn;
                    return b(Type.getType(fin.desc).getSize(), Exprs.nStaticField("L" + fin.owner + ";", fin.name, fin.desc));
                case NEW:
                    return b(1, Exprs.nNew("L" + ((TypeInsnNode) insn).desc + ";"));
                default:
                    throw new Error("Internal error.");
            }
        }

        @Override
        public JvmValue copyOperation(AbstractInsnNode insn, JvmValue value) throws AnalyzerException {
            return b(value.getSize(), getLocal(value));
        }

        @Override
        public JvmValue unaryOperation(AbstractInsnNode insn, JvmValue value0) throws AnalyzerException {
            Local local = value0 == null ? null : getLocal(value0);
            switch(insn.getOpcode()) {
                case INEG:
                    return b(1, Exprs.nNeg(local, "I"));
                case IINC:
                    return b(1, Exprs.nAdd(local, Exprs.nInt(((IincInsnNode) insn).incr), "I"));
                case L2I:
                    return b(1, Exprs.nCast(local, "J", "I"));
                case F2I:
                    return b(1, Exprs.nCast(local, "F", "I"));
                case D2I:
                    return b(1, Exprs.nCast(local, "D", "I"));
                case I2B:
                    return b(1, Exprs.nCast(local, "I", "B"));
                case I2C:
                    return b(1, Exprs.nCast(local, "I", "C"));
                case I2S:
                    return b(1, Exprs.nCast(local, "I", "S"));
                case FNEG:
                    return b(1, Exprs.nNeg(local, "F"));
                case I2F:
                    return b(1, Exprs.nCast(local, "I", "F"));
                case L2F:
                    return b(1, Exprs.nCast(local, "J", "F"));
                case D2F:
                    return b(1, Exprs.nCast(local, "D", "F"));
                case LNEG:
                    return b(2, Exprs.nNeg(local, "J"));
                case I2L:
                    return b(2, Exprs.nCast(local, "I", "J"));
                case F2L:
                    return b(2, Exprs.nCast(local, "F", "J"));
                case D2L:
                    return b(2, Exprs.nCast(local, "D", "J"));
                case DNEG:
                    return b(2, Exprs.nNeg(local, "D"));
                case I2D:
                    return b(2, Exprs.nCast(local, "I", "D"));
                case L2D:
                    return b(2, Exprs.nCast(local, "J", "D"));
                case F2D:
                    return b(2, Exprs.nCast(local, "F", "D"));
                case IFEQ:
                    emit(Stmts.nIf(Exprs.nEq(local, Exprs.nInt(0), "I"), getLabel(((JumpInsnNode) insn).label)));
                    return null;
                case IFNE:
                    emit(Stmts.nIf(Exprs.nNe(local, Exprs.nInt(0), "I"), getLabel(((JumpInsnNode) insn).label)));
                    return null;
                case IFLT:
                    emit(Stmts.nIf(Exprs.nLt(local, Exprs.nInt(0), "I"), getLabel(((JumpInsnNode) insn).label)));
                    return null;
                case IFGE:
                    emit(Stmts.nIf(Exprs.nGe(local, Exprs.nInt(0), "I"), getLabel(((JumpInsnNode) insn).label)));
                    return null;
                case IFGT:
                    emit(Stmts.nIf(Exprs.nGt(local, Exprs.nInt(0), "I"), getLabel(((JumpInsnNode) insn).label)));
                    return null;
                case IFLE:
                    emit(Stmts.nIf(Exprs.nLe(local, Exprs.nInt(0), "I"), getLabel(((JumpInsnNode) insn).label)));
                    return null;
                case TABLESWITCH:
                    {
                        TableSwitchInsnNode ts = (TableSwitchInsnNode) insn;
                        LabelStmt[] targets = new LabelStmt[ts.labels.size()];
                        for (int i = 0; i < ts.labels.size(); i++) {
                            targets[i] = getLabel((LabelNode) ts.labels.get(i));
                        }
                        emit(Stmts.nTableSwitch(local, ts.min, targets, getLabel(ts.dflt)));
                        return null;
                    }
                case LOOKUPSWITCH:
                    {
                        LookupSwitchInsnNode ls = (LookupSwitchInsnNode) insn;
                        LabelStmt[] targets = new LabelStmt[ls.labels.size()];
                        int[] lookupValues = new int[ls.labels.size()];
                        for (int i = 0; i < ls.labels.size(); i++) {
                            targets[i] = getLabel((LabelNode) ls.labels.get(i));
                            lookupValues[i] = (Integer) ls.keys.get(i);
                        }
                        emit(Stmts.nLookupSwitch(local, lookupValues, targets, getLabel(ls.dflt)));
                        return null;
                    }
                case IRETURN:
                case LRETURN:
                case FRETURN:
                case DRETURN:
                case ARETURN:
                    // skip, move to returnOperation
                    return null;
                case PUTSTATIC:
                    {
                        FieldInsnNode fin = (FieldInsnNode) insn;
                        emit(Stmts.nAssign(Exprs.nStaticField("L" + fin.owner + ";", fin.name, fin.desc), local));
                        return null;
                    }
                case GETFIELD:
                    {
                        FieldInsnNode fin = (FieldInsnNode) insn;
                        Type fieldType = Type.getType(fin.desc);
                        return b(fieldType.getSize(), Exprs.nField(local, "L" + fin.owner + ";", fin.name, fin.desc));
                    }
                case NEWARRAY:
                    switch(((IntInsnNode) insn).operand) {
                        case T_BOOLEAN:
                            return b(1, Exprs.nNewArray("Z", local));
                        case T_CHAR:
                            return b(1, Exprs.nNewArray("C", local));
                        case T_BYTE:
                            return b(1, Exprs.nNewArray("B", local));
                        case T_SHORT:
                            return b(1, Exprs.nNewArray("S", local));
                        case T_INT:
                            return b(1, Exprs.nNewArray("I", local));
                        case T_FLOAT:
                            return b(1, Exprs.nNewArray("F", local));
                        case T_DOUBLE:
                            return b(1, Exprs.nNewArray("D", local));
                        case T_LONG:
                            return b(1, Exprs.nNewArray("D", local));
                        default:
                            throw new AnalyzerException(insn, "Invalid array type");
                    }
                case ANEWARRAY:
                    String desc = "L" + ((TypeInsnNode) insn).desc + ";";
                    return b(1, Exprs.nNewArray(desc, local));
                case ARRAYLENGTH:
                    return b(1, Exprs.nLength(local));
                case ATHROW:
                    emit(Stmts.nThrow(local));
                    return null;
                case CHECKCAST:
                    String orgDesc = ((TypeInsnNode) insn).desc;
                    desc = orgDesc.startsWith("[") ? orgDesc : ("L" + orgDesc + ";");
                    return b(1, Exprs.nCheckCast(local, desc));
                case INSTANCEOF:
                    return b(1, Exprs.nInstanceOf(local, "L" + ((TypeInsnNode) insn).desc + ";"));
                case MONITORENTER:
                    emit(Stmts.nLock(local));
                    return null;
                case MONITOREXIT:
                    emit(Stmts.nUnLock(local));
                    return null;
                case IFNULL:
                    emit(Stmts.nIf(Exprs.nEq(local, Exprs.nNull(), "L"), getLabel(((JumpInsnNode) insn).label)));
                    return null;
                case IFNONNULL:
                    emit(Stmts.nIf(Exprs.nNe(local, Exprs.nNull(), "L"), getLabel(((JumpInsnNode) insn).label)));
                    return null;
                case // special case
                GOTO:
                    emit(Stmts.nGoto(getLabel(((JumpInsnNode) insn).label)));
                    return null;
                default:
                    throw new Error("Internal error.");
            }
        }

        JvmValue b(int size, com.googlecode.dex2jar.ir.expr.Value value) {
            Local local = newLocal();
            emit(Stmts.nAssign(local, value));
            return new JvmValue(size, local);
        }

        @Override
        public JvmValue binaryOperation(AbstractInsnNode insn, JvmValue value10, JvmValue value20) throws AnalyzerException {
            Local local1 = getLocal(value10);
            Local local2 = getLocal(value20);
            switch(insn.getOpcode()) {
                case IALOAD:
                    return b(1, Exprs.nArray(local1, local2, "I"));
                case BALOAD:
                    return b(1, Exprs.nArray(local1, local2, "B"));
                case CALOAD:
                    return b(1, Exprs.nArray(local1, local2, "C"));
                case SALOAD:
                    return b(1, Exprs.nArray(local1, local2, "S"));
                case FALOAD:
                    return b(1, Exprs.nArray(local1, local2, "F"));
                case AALOAD:
                    return b(1, Exprs.nArray(local1, local2, "L"));
                case DALOAD:
                    return b(1, Exprs.nArray(local1, local2, "D"));
                case LALOAD:
                    return b(1, Exprs.nArray(local1, local2, "J"));
                case IADD:
                    return b(1, Exprs.nAdd(local1, local2, "I"));
                case ISUB:
                    return b(1, Exprs.nSub(local1, local2, "I"));
                case IMUL:
                    return b(1, Exprs.nMul(local1, local2, "I"));
                case IDIV:
                    return b(1, Exprs.nDiv(local1, local2, "I"));
                case IREM:
                    return b(1, Exprs.nRem(local1, local2, "I"));
                case ISHL:
                    return b(1, Exprs.nShl(local1, local2, "I"));
                case ISHR:
                    return b(1, Exprs.nShr(local1, local2, "I"));
                case IUSHR:
                    return b(1, Exprs.nUshr(local1, local2, "I"));
                case IAND:
                    return b(1, Exprs.nAnd(local1, local2, "I"));
                case IOR:
                    return b(1, Exprs.nOr(local1, local2, "I"));
                case IXOR:
                    return b(1, Exprs.nXor(local1, local2, "I"));
                case FADD:
                    return b(1, Exprs.nAdd(local1, local2, "F"));
                case FSUB:
                    return b(1, Exprs.nSub(local1, local2, "F"));
                case FMUL:
                    return b(1, Exprs.nMul(local1, local2, "F"));
                case FDIV:
                    return b(1, Exprs.nDiv(local1, local2, "F"));
                case FREM:
                    return b(1, Exprs.nRem(local1, local2, "F"));
                case LADD:
                    return b(2, Exprs.nAdd(local1, local2, "J"));
                case LSUB:
                    return b(2, Exprs.nSub(local1, local2, "J"));
                case LMUL:
                    return b(2, Exprs.nMul(local1, local2, "J"));
                case LDIV:
                    return b(2, Exprs.nDiv(local1, local2, "J"));
                case LREM:
                    return b(2, Exprs.nRem(local1, local2, "J"));
                case LSHL:
                    return b(2, Exprs.nShl(local1, local2, "J"));
                case LSHR:
                    return b(2, Exprs.nShr(local1, local2, "J"));
                case LUSHR:
                    return b(2, Exprs.nUshr(local1, local2, "J"));
                case LAND:
                    return b(2, Exprs.nAnd(local1, local2, "J"));
                case LOR:
                    return b(2, Exprs.nOr(local1, local2, "J"));
                case LXOR:
                    return b(2, Exprs.nXor(local1, local2, "J"));
                case DADD:
                    return b(2, Exprs.nAdd(local1, local2, "D"));
                case DSUB:
                    return b(2, Exprs.nSub(local1, local2, "D"));
                case DMUL:
                    return b(2, Exprs.nMul(local1, local2, "D"));
                case DDIV:
                    return b(2, Exprs.nDiv(local1, local2, "D"));
                case DREM:
                    return b(2, Exprs.nRem(local1, local2, "D"));
                case LCMP:
                    return b(2, Exprs.nLCmp(local1, local2));
                case FCMPL:
                    return b(1, Exprs.nFCmpl(local1, local2));
                case FCMPG:
                    return b(1, Exprs.nFCmpg(local1, local2));
                case DCMPL:
                    return b(2, Exprs.nDCmpl(local1, local2));
                case DCMPG:
                    return b(2, Exprs.nDCmpg(local1, local2));
                case IF_ICMPEQ:
                    emit(Stmts.nIf(Exprs.nEq(local1, local2, "I"), getLabel(((JumpInsnNode) insn).label)));
                    return null;
                case IF_ICMPNE:
                    emit(Stmts.nIf(Exprs.nNe(local1, local2, "I"), getLabel(((JumpInsnNode) insn).label)));
                    return null;
                case IF_ICMPLT:
                    emit(Stmts.nIf(Exprs.nLt(local1, local2, "I"), getLabel(((JumpInsnNode) insn).label)));
                    return null;
                case IF_ICMPGE:
                    emit(Stmts.nIf(Exprs.nGe(local1, local2, "I"), getLabel(((JumpInsnNode) insn).label)));
                    return null;
                case IF_ICMPGT:
                    emit(Stmts.nIf(Exprs.nGt(local1, local2, "I"), getLabel(((JumpInsnNode) insn).label)));
                    return null;
                case IF_ICMPLE:
                    emit(Stmts.nIf(Exprs.nLe(local1, local2, "I"), getLabel(((JumpInsnNode) insn).label)));
                    return null;
                case IF_ACMPEQ:
                    emit(Stmts.nIf(Exprs.nEq(local1, local2, "L"), getLabel(((JumpInsnNode) insn).label)));
                    return null;
                case IF_ACMPNE:
                    emit(Stmts.nIf(Exprs.nNe(local1, local2, "L"), getLabel(((JumpInsnNode) insn).label)));
                    return null;
                case PUTFIELD:
                    FieldInsnNode fin = (FieldInsnNode) insn;
                    emit(Stmts.nAssign(Exprs.nField(local1, "L" + fin.owner + ";", fin.name, fin.desc), local2));
                    return null;
                default:
                    throw new Error("Internal error.");
            }
        }

        @Override
        public JvmValue ternaryOperation(AbstractInsnNode insn, JvmValue value1, JvmValue value2, JvmValue value3) throws AnalyzerException {
            Local local1 = getLocal(value1);
            Local local2 = getLocal(value2);
            Local local3 = getLocal(value3);
            switch(insn.getOpcode()) {
                case IASTORE:
                    emit(Stmts.nAssign(Exprs.nArray(local1, local2, "I"), local3));
                    break;
                case LASTORE:
                    emit(Stmts.nAssign(Exprs.nArray(local1, local2, "J"), local3));
                    break;
                case FASTORE:
                    emit(Stmts.nAssign(Exprs.nArray(local1, local2, "F"), local3));
                    break;
                case DASTORE:
                    emit(Stmts.nAssign(Exprs.nArray(local1, local2, "D"), local3));
                    break;
                case AASTORE:
                    emit(Stmts.nAssign(Exprs.nArray(local1, local2, "L"), local3));
                    break;
                case BASTORE:
                    emit(Stmts.nAssign(Exprs.nArray(local1, local2, "B"), local3));
                    break;
                case CASTORE:
                    emit(Stmts.nAssign(Exprs.nArray(local1, local2, "C"), local3));
                    break;
                case SASTORE:
                    emit(Stmts.nAssign(Exprs.nArray(local1, local2, "S"), local3));
                    break;
            }
            return null;
        }

        public String[] toDescArray(Type[] ts) {
            String[] ds = new String[ts.length];
            for (int i = 0; i < ts.length; i++) {
                ds[i] = ts[i].getDescriptor();
            }
            return ds;
        }

        @Override
        public JvmValue naryOperation(AbstractInsnNode insn, List<? extends JvmValue> xvalues) throws AnalyzerException {
            com.googlecode.dex2jar.ir.expr.Value[] values = new com.googlecode.dex2jar.ir.expr.Value[xvalues.size()];
            for (int i = 0; i < xvalues.size(); i++) {
                values[i] = getLocal(xvalues.get(i));
            }
            if (insn.getOpcode() == MULTIANEWARRAY) {
                throw new UnsupportedOperationException("Not supported yet.");
            } else {
                MethodInsnNode mi = (MethodInsnNode) insn;
                com.googlecode.dex2jar.ir.expr.Value v = null;
                String ret = Type.getReturnType(mi.desc).getDescriptor();
                String owner = "L" + mi.owner + ";";
                String[] ps = toDescArray(Type.getArgumentTypes(mi.desc));
                switch(insn.getOpcode()) {
                    case INVOKEVIRTUAL:
                        v = Exprs.nInvokeVirtual(values, owner, mi.name, ps, ret);
                        break;
                    case INVOKESPECIAL:
                        v = Exprs.nInvokeSpecial(values, owner, mi.name, ps, ret);
                        break;
                    case INVOKESTATIC:
                        v = Exprs.nInvokeStatic(values, owner, mi.name, ps, ret);
                        break;
                    case INVOKEINTERFACE:
                        v = Exprs.nInvokeInterface(values, owner, mi.name, ps, ret);
                        break;
                    case INVOKEDYNAMIC:
                        throw new UnsupportedOperationException("Not supported yet.");
                }
                if ("V".equals(ret)) {
                    emit(Stmts.nVoidInvoke(v));
                    return null;
                } else {
                    return b(Type.getReturnType(mi.desc).getSize(), v);
                }
            }
        }

        @Override
        public JvmValue merge(JvmValue v, JvmValue w) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

        @Override
        public void returnOperation(AbstractInsnNode insn, JvmValue value, JvmValue expected) throws AnalyzerException {
            switch(insn.getOpcode()) {
                case IRETURN:
                case LRETURN:
                case FRETURN:
                case DRETURN:
                case ARETURN:
                    emit(Stmts.nReturn(getLocal(value)));
                    break;
                case RETURN:
                    emit(Stmts.nReturnVoid());
                    break;
            }
        }
    };
}
Also used : Interpreter(org.objectweb.asm.tree.analysis.Interpreter) AnalyzerException(org.objectweb.asm.tree.analysis.AnalyzerException) Local(com.googlecode.dex2jar.ir.expr.Local) Handle(org.objectweb.asm.Handle) Type(org.objectweb.asm.Type) Value(org.objectweb.asm.tree.analysis.Value)

Example 8 with AnalyzerException

use of org.objectweb.asm.tree.analysis.AnalyzerException in project enumerable by hraberg.

the class ExpressionInterpreter method unaryOperation.

public Value unaryOperation(final AbstractInsnNode insn, final Value value) throws AnalyzerException {
    ExpressionValue expressionValue = (ExpressionValue) value;
    switch(insn.getOpcode()) {
        case INEG:
            return new ExpressionValue(PRIMITIVE_INT, new UnaryExpr(expressionValue.expression, UnaryExpr.Operator.negative));
        case IINC:
            IincInsnNode node = (IincInsnNode) insn;
            NameExpr nameExpr = new NameExpr(getLocalVariable(node.var).name);
            if (node.incr == 1)
                iinc = new UnaryExpr(nameExpr, UnaryExpr.Operator.posIncrement);
            if (node.incr == -1)
                iinc = new UnaryExpr(nameExpr, UnaryExpr.Operator.posDecrement);
            if (node.incr > 1)
                iincAssign = new AssignExpr(nameExpr, new IntegerLiteralExpr(node.incr + ""), AssignExpr.Operator.plus);
            if (node.incr < -1)
                iincAssign = new AssignExpr(nameExpr, new IntegerLiteralExpr(-node.incr + ""), AssignExpr.Operator.minus);
            return value;
        case L2I:
        case F2I:
        case D2I:
            return new ExpressionValue(PRIMITIVE_INT, new CastExpr(PRIMITIVE_INT, expressionValue.expression));
        case I2B:
            return new ExpressionValue(PRIMITIVE_BYTE, new CastExpr(PRIMITIVE_BYTE, expressionValue.expression));
        case I2C:
            return new ExpressionValue(PRIMITIVE_CHAR, new CastExpr(PRIMITIVE_CHAR, expressionValue.expression));
        case I2S:
            return new ExpressionValue(PRIMITIVE_SHORT, new CastExpr(PRIMITIVE_SHORT, expressionValue.expression));
        case FNEG:
            return new ExpressionValue(PRIMITIVE_FLOAT, new UnaryExpr(expressionValue.expression, UnaryExpr.Operator.negative));
        case I2F:
        case L2F:
        case D2F:
            return new ExpressionValue(PRIMITIVE_FLOAT, new CastExpr(PRIMITIVE_FLOAT, expressionValue.expression));
        case LNEG:
            return new ExpressionValue(PRIMITIVE_LONG, new UnaryExpr(expressionValue.expression, UnaryExpr.Operator.negative));
        case I2L:
        case F2L:
        case D2L:
            return new ExpressionValue(PRIMITIVE_LONG, new CastExpr(PRIMITIVE_LONG, expressionValue.expression));
        case DNEG:
            return new ExpressionValue(PRIMITIVE_DOUBLE, new UnaryExpr(expressionValue.expression, UnaryExpr.Operator.negative));
        case I2D:
        case L2D:
        case F2D:
            return new ExpressionValue(PRIMITIVE_DOUBLE, new CastExpr(PRIMITIVE_DOUBLE, expressionValue.expression));
        case IFEQ:
            if (conditional != null) {
                if (conditional.getCondition() instanceof BinaryExpr && cmpConditional) {
                    ((BinaryExpr) conditional.getCondition()).setOperator(BinaryExpr.Operator.notEquals);
                    cmpConditional = false;
                } else {
                    handleNestedConditional(expressionValue.expression);
                }
            } else {
                conditional = new ConditionalExpr(expressionValue.expression, null, null);
            }
            return null;
        case IFNE:
            if (conditional != null) {
                if (conditional.getCondition() instanceof BinaryExpr && cmpConditional) {
                    ((BinaryExpr) conditional.getCondition()).setOperator(BinaryExpr.Operator.equals);
                    cmpConditional = false;
                } else {
                    handleNestedConditional(new UnaryExpr(expressionValue.expression, UnaryExpr.Operator.not));
                }
            } else {
                conditional = new ConditionalExpr(new UnaryExpr(expressionValue.expression, UnaryExpr.Operator.not), null, null);
            }
            return null;
        case IFGT:
            ((BinaryExpr) conditional.getCondition()).setOperator(BinaryExpr.Operator.lessEquals);
            cmpConditional = false;
            return null;
        case IFLE:
            ((BinaryExpr) conditional.getCondition()).setOperator(BinaryExpr.Operator.greater);
            cmpConditional = false;
            return null;
        case IFLT:
            ((BinaryExpr) conditional.getCondition()).setOperator(BinaryExpr.Operator.greaterEquals);
            cmpConditional = false;
            return null;
        case IFGE:
            ((BinaryExpr) conditional.getCondition()).setOperator(BinaryExpr.Operator.less);
            cmpConditional = false;
            return null;
        case TABLESWITCH:
        case LOOKUPSWITCH:
            throw new UnsupportedOperationException(AbstractVisitor.OPCODES[insn.getOpcode()]);
        case IRETURN:
        case LRETURN:
        case FRETURN:
        case DRETURN:
        case ARETURN:
            return null;
        case PUTSTATIC:
            FieldInsnNode fieldNode = (FieldInsnNode) insn;
            ExpressionValue putField = (ExpressionValue) newValue(getType(fieldNode.desc));
            putField.expression = new AssignExpr(new FieldAccessExpr(new NameExpr(removeJavaLang(getObjectType(fieldNode.owner).getClassName())), fieldNode.name), expressionValue.expression, AssignExpr.Operator.assign);
            assign = putField;
            return null;
        case GETFIELD:
            fieldNode = (FieldInsnNode) insn;
            ExpressionValue getField = (ExpressionValue) newValue(Type.getType(fieldNode.desc));
            getField.expression = new FieldAccessExpr(expressionValue.expression, fieldNode.name);
            return getField;
        case NEWARRAY:
            PrimitiveType type;
            switch(((IntInsnNode) insn).operand) {
                case T_BOOLEAN:
                    type = PRIMITIVE_BOOLEAN;
                    break;
                case T_CHAR:
                    type = PRIMITIVE_CHAR;
                    break;
                case T_BYTE:
                    type = PRIMITIVE_BYTE;
                    break;
                case T_SHORT:
                    type = PRIMITIVE_SHORT;
                    break;
                case T_INT:
                    type = PRIMITIVE_INT;
                    break;
                case T_FLOAT:
                    type = PRIMITIVE_FLOAT;
                    break;
                case T_DOUBLE:
                    type = PRIMITIVE_DOUBLE;
                    break;
                case T_LONG:
                    type = PRIMITIVE_LONG;
                    break;
                default:
                    throw new AnalyzerException(insn, "Invalid array type");
            }
            ArrayList<Expression> dimensions = new ArrayList<Expression>();
            dimensions.add(expressionValue.expression);
            return new ExpressionValue(new ReferenceType(type, 1), new ArrayCreationExpr(type, dimensions, 0));
        case ANEWARRAY:
            ExpressionValue newArray = (ExpressionValue) newValue(Type.getObjectType(((TypeInsnNode) insn).desc));
            dimensions = new ArrayList<Expression>();
            dimensions.add(expressionValue.expression);
            newArray.expression = new ArrayCreationExpr(newArray.type, dimensions, 0);
            return newArray;
        case ARRAYLENGTH:
            return new ExpressionValue(PRIMITIVE_INT, new FieldAccessExpr(expressionValue.expression, "length"));
        case ATHROW:
            throw new UnsupportedOperationException(AbstractVisitor.OPCODES[insn.getOpcode()]);
        case CHECKCAST:
            ExpressionValue cast = (ExpressionValue) newValue(Type.getObjectType(((TypeInsnNode) insn).desc));
            cast.expression = new CastExpr(new ReferenceType(cast.type), expressionValue.expression);
            return cast;
        case INSTANCEOF:
            ExpressionValue instanceOf = (ExpressionValue) newValue(Type.getObjectType(((TypeInsnNode) insn).desc));
            instanceOf.expression = new InstanceOfExpr(expressionValue.expression, new ReferenceType(instanceOf.type));
            return instanceOf;
        case MONITORENTER:
        case MONITOREXIT:
            throw new UnsupportedOperationException(AbstractVisitor.OPCODES[insn.getOpcode()]);
        case IFNULL:
            handleNestedConditional(new BinaryExpr(expressionValue.expression, new NullLiteralExpr(), BinaryExpr.Operator.notEquals));
            return null;
        case IFNONNULL:
            handleNestedConditional(new BinaryExpr(expressionValue.expression, new NullLiteralExpr(), BinaryExpr.Operator.equals));
            return null;
        default:
            throw new Error("Internal error.");
    }
}
Also used : AnalyzerException(org.objectweb.asm.tree.analysis.AnalyzerException) ArrayList(java.util.ArrayList) FieldInsnNode(org.objectweb.asm.tree.FieldInsnNode) IntInsnNode(org.objectweb.asm.tree.IntInsnNode) ReferenceType(japa.parser.ast.type.ReferenceType) IincInsnNode(org.objectweb.asm.tree.IincInsnNode) PrimitiveType(japa.parser.ast.type.PrimitiveType)

Example 9 with AnalyzerException

use of org.objectweb.asm.tree.analysis.AnalyzerException in project quasar by puniverse.

the class TypeInterpreter method binaryOperation.

@Override
public BasicValue binaryOperation(AbstractInsnNode insn, BasicValue value1, BasicValue value2) throws AnalyzerException {
    if (insn.getOpcode() == Opcodes.AALOAD) {
        final Type t1 = value1.getType();
        if (t1 == null)
            // f.e. if the AALOAD array argument is conditionally initialized.
            throw new AnalyzerException(insn, "AALOAD needs a first parameter");
        final Type resultType = Type.getType(t1.getDescriptor().substring(1));
        return new BasicValue(resultType);
    }
    return super.binaryOperation(insn, value1, value2);
}
Also used : Type(org.objectweb.asm.Type) AnalyzerException(org.objectweb.asm.tree.analysis.AnalyzerException) BasicValue(org.objectweb.asm.tree.analysis.BasicValue)

Example 10 with AnalyzerException

use of org.objectweb.asm.tree.analysis.AnalyzerException in project quasar by puniverse.

the class InstrumentClass method visitEnd.

@Override
@SuppressWarnings("CallToPrintStackTrace")
public void visitEnd() {
    if (exception != null)
        throw exception;
    classEntry.setRequiresInstrumentation(false);
    db.recordSuspendableMethods(className, classEntry);
    if (methods != null && !methods.isEmpty()) {
        if (alreadyInstrumented && !forceInstrumentation) {
            for (MethodNode mn : methods) {
                db.log(LogLevel.INFO, "Already instrumented and not forcing, so not touching method %s#%s%s", className, mn.name, mn.desc);
                mn.accept(makeOutMV(mn));
            }
        } else {
            if (!alreadyInstrumented) {
                emitInstrumentedAnn();
                classEntry.setInstrumented(true);
            }
            for (MethodNode mn : methods) {
                final MethodVisitor outMV = makeOutMV(mn);
                try {
                    InstrumentMethod im = new InstrumentMethod(db, sourceName, className, mn);
                    db.log(LogLevel.DEBUG, "About to instrument method %s#%s%s", className, mn.name, mn.desc);
                    im.accept(outMV, hasAnnotation(mn));
                } catch (UnableToInstrumentException e) {
                    db.log(LogLevel.WARNING, "UnableToInstrumentException encountered when instrumenting %s#%s%s: %s", className, mn.name, mn.desc, e.getMessage());
                    mn.accept(outMV);
                } catch (AnalyzerException ex) {
                    ex.printStackTrace();
                    throw new InternalError(ex.getMessage());
                }
            }
        }
    } else {
        // if we don't have any suspendable methods, but our superclass is instrumented, we mark this class as instrumented, too.
        if (!alreadyInstrumented && classEntry.getSuperName() != null) {
            ClassEntry superClass = db.getClassEntry(classEntry.getSuperName());
            if (superClass != null && superClass.isInstrumented()) {
                emitInstrumentedAnn();
                classEntry.setInstrumented(true);
            }
        }
    }
    super.visitEnd();
}
Also used : AnalyzerException(org.objectweb.asm.tree.analysis.AnalyzerException) MethodNode(org.objectweb.asm.tree.MethodNode) ClassEntry(co.paralleluniverse.fibers.instrument.MethodDatabase.ClassEntry) MethodVisitor(org.objectweb.asm.MethodVisitor)

Aggregations

AnalyzerException (org.objectweb.asm.tree.analysis.AnalyzerException)13 BasicValue (org.objectweb.asm.tree.analysis.BasicValue)5 ArrayList (java.util.ArrayList)4 MethodVisitor (org.objectweb.asm.MethodVisitor)4 MethodNode (org.objectweb.asm.tree.MethodNode)3 Value (org.objectweb.asm.tree.analysis.Value)3 ParseException (com.android.dx.cf.iface.ParseException)2 DexException (com.googlecode.d2j.DexException)2 DexMethodNode (com.googlecode.d2j.node.DexMethodNode)2 LinkedList (java.util.LinkedList)2 ZipException (java.util.zip.ZipException)2 CheckMethodVisitorFsm (org.apache.drill.exec.compile.CheckMethodVisitorFsm)2 Type (org.objectweb.asm.Type)2 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)2 IntInsnNode (org.objectweb.asm.tree.IntInsnNode)2 Frame (org.objectweb.asm.tree.analysis.Frame)2 ClassEntry (co.paralleluniverse.fibers.instrument.MethodDatabase.ClassEntry)1 DirectClassFile (com.android.dx.cf.direct.DirectClassFile)1 StdAttributeFactory (com.android.dx.cf.direct.StdAttributeFactory)1 DxContext (com.android.dx.command.dexer.DxContext)1