Search in sources :

Example 1 with BasicValue

use of org.apache.tapestry5.internal.plastic.asm.tree.analysis.BasicValue in project tapestry-5 by apache.

the class BasicVerifier method naryOperation.

@Override
public BasicValue naryOperation(final AbstractInsnNode insn, final List<? extends BasicValue> values) throws AnalyzerException {
    int opcode = insn.getOpcode();
    if (opcode == MULTIANEWARRAY) {
        for (BasicValue value : values) {
            if (!BasicValue.INT_VALUE.equals(value)) {
                throw new AnalyzerException(insn, null, BasicValue.INT_VALUE, value);
            }
        }
    } else {
        int i = 0;
        int j = 0;
        if (opcode != INVOKESTATIC && opcode != INVOKEDYNAMIC) {
            Type owner = Type.getObjectType(((MethodInsnNode) insn).owner);
            if (!isSubTypeOf(values.get(i++), newValue(owner))) {
                throw new AnalyzerException(insn, "Method owner", newValue(owner), values.get(0));
            }
        }
        String methodDescriptor = (opcode == INVOKEDYNAMIC) ? ((InvokeDynamicInsnNode) insn).desc : ((MethodInsnNode) insn).desc;
        Type[] args = Type.getArgumentTypes(methodDescriptor);
        while (i < values.size()) {
            BasicValue expected = newValue(args[j++]);
            BasicValue actual = values.get(i++);
            if (!isSubTypeOf(actual, expected)) {
                throw new AnalyzerException(insn, "Argument " + j, expected, actual);
            }
        }
    }
    return super.naryOperation(insn, values);
}
Also used : Type(org.apache.tapestry5.internal.plastic.asm.Type)

Example 2 with BasicValue

use of org.apache.tapestry5.internal.plastic.asm.tree.analysis.BasicValue in project tapestry-5 by apache.

the class BasicVerifier method binaryOperation.

@Override
public BasicValue binaryOperation(final AbstractInsnNode insn, final BasicValue value1, final BasicValue value2) throws AnalyzerException {
    BasicValue expected1;
    BasicValue expected2;
    switch(insn.getOpcode()) {
        case IALOAD:
            expected1 = newValue(Type.getType("[I"));
            expected2 = BasicValue.INT_VALUE;
            break;
        case BALOAD:
            if (isSubTypeOf(value1, newValue(Type.getType("[Z")))) {
                expected1 = newValue(Type.getType("[Z"));
            } else {
                expected1 = newValue(Type.getType("[B"));
            }
            expected2 = BasicValue.INT_VALUE;
            break;
        case CALOAD:
            expected1 = newValue(Type.getType("[C"));
            expected2 = BasicValue.INT_VALUE;
            break;
        case SALOAD:
            expected1 = newValue(Type.getType("[S"));
            expected2 = BasicValue.INT_VALUE;
            break;
        case LALOAD:
            expected1 = newValue(Type.getType("[J"));
            expected2 = BasicValue.INT_VALUE;
            break;
        case FALOAD:
            expected1 = newValue(Type.getType("[F"));
            expected2 = BasicValue.INT_VALUE;
            break;
        case DALOAD:
            expected1 = newValue(Type.getType("[D"));
            expected2 = BasicValue.INT_VALUE;
            break;
        case AALOAD:
            expected1 = newValue(Type.getType("[Ljava/lang/Object;"));
            expected2 = BasicValue.INT_VALUE;
            break;
        case IADD:
        case ISUB:
        case IMUL:
        case IDIV:
        case IREM:
        case ISHL:
        case ISHR:
        case IUSHR:
        case IAND:
        case IOR:
        case IXOR:
        case IF_ICMPEQ:
        case IF_ICMPNE:
        case IF_ICMPLT:
        case IF_ICMPGE:
        case IF_ICMPGT:
        case IF_ICMPLE:
            expected1 = BasicValue.INT_VALUE;
            expected2 = BasicValue.INT_VALUE;
            break;
        case FADD:
        case FSUB:
        case FMUL:
        case FDIV:
        case FREM:
        case FCMPL:
        case FCMPG:
            expected1 = BasicValue.FLOAT_VALUE;
            expected2 = BasicValue.FLOAT_VALUE;
            break;
        case LADD:
        case LSUB:
        case LMUL:
        case LDIV:
        case LREM:
        case LAND:
        case LOR:
        case LXOR:
        case LCMP:
            expected1 = BasicValue.LONG_VALUE;
            expected2 = BasicValue.LONG_VALUE;
            break;
        case LSHL:
        case LSHR:
        case LUSHR:
            expected1 = BasicValue.LONG_VALUE;
            expected2 = BasicValue.INT_VALUE;
            break;
        case DADD:
        case DSUB:
        case DMUL:
        case DDIV:
        case DREM:
        case DCMPL:
        case DCMPG:
            expected1 = BasicValue.DOUBLE_VALUE;
            expected2 = BasicValue.DOUBLE_VALUE;
            break;
        case IF_ACMPEQ:
        case IF_ACMPNE:
            expected1 = BasicValue.REFERENCE_VALUE;
            expected2 = BasicValue.REFERENCE_VALUE;
            break;
        case PUTFIELD:
            FieldInsnNode fieldInsn = (FieldInsnNode) insn;
            expected1 = newValue(Type.getObjectType(fieldInsn.owner));
            expected2 = newValue(Type.getType(fieldInsn.desc));
            break;
        default:
            throw new AssertionError();
    }
    if (!isSubTypeOf(value1, expected1)) {
        throw new AnalyzerException(insn, "First argument", expected1, value1);
    } else if (!isSubTypeOf(value2, expected2)) {
        throw new AnalyzerException(insn, "Second argument", expected2, value2);
    }
    if (insn.getOpcode() == AALOAD) {
        return getElementValue(value1);
    } else {
        return super.binaryOperation(insn, value1, value2);
    }
}
Also used : FieldInsnNode(org.apache.tapestry5.internal.plastic.asm.tree.FieldInsnNode)

Example 3 with BasicValue

use of org.apache.tapestry5.internal.plastic.asm.tree.analysis.BasicValue in project tapestry-5 by apache.

the class CheckClassAdapter method printAnalyzerResult.

static void printAnalyzerResult(final MethodNode method, final Analyzer<BasicValue> analyzer, final PrintWriter printWriter) {
    Textifier textifier = new Textifier();
    TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(textifier);
    printWriter.println(method.name + method.desc);
    for (int i = 0; i < method.instructions.size(); ++i) {
        method.instructions.get(i).accept(traceMethodVisitor);
        StringBuilder stringBuilder = new StringBuilder();
        Frame<BasicValue> frame = analyzer.getFrames()[i];
        if (frame == null) {
            stringBuilder.append('?');
        } else {
            for (int j = 0; j < frame.getLocals(); ++j) {
                stringBuilder.append(getUnqualifiedName(frame.getLocal(j).toString())).append(' ');
            }
            stringBuilder.append(" : ");
            for (int j = 0; j < frame.getStackSize(); ++j) {
                stringBuilder.append(getUnqualifiedName(frame.getStack(j).toString())).append(' ');
            }
        }
        while (stringBuilder.length() < method.maxStack + method.maxLocals + 1) {
            stringBuilder.append(' ');
        }
        printWriter.print(Integer.toString(i + 100000).substring(1));
        printWriter.print(" " + stringBuilder + " : " + textifier.text.get(textifier.text.size() - 1));
    }
    for (TryCatchBlockNode tryCatchBlock : method.tryCatchBlocks) {
        tryCatchBlock.accept(traceMethodVisitor);
        printWriter.print(" " + textifier.text.get(textifier.text.size() - 1));
    }
    printWriter.println();
}
Also used : TryCatchBlockNode(org.apache.tapestry5.internal.plastic.asm.tree.TryCatchBlockNode) BasicValue(org.apache.tapestry5.internal.plastic.asm.tree.analysis.BasicValue)

Example 4 with BasicValue

use of org.apache.tapestry5.internal.plastic.asm.tree.analysis.BasicValue in project tapestry-5 by apache.

the class CheckClassAdapter method verify.

/**
 * Checks the given class.
 *
 * @param classReader the class to be checked.
 * @param loader a <code>ClassLoader</code> which will be used to load referenced classes. May be
 *     {@literal null}.
 * @param printResults whether to print the results of the bytecode verification.
 * @param printWriter where the results (or the stack trace in case of error) must be printed.
 */
public static void verify(final ClassReader classReader, final ClassLoader loader, final boolean printResults, final PrintWriter printWriter) {
    ClassNode classNode = new ClassNode();
    classReader.accept(new CheckClassAdapter(/*latest*/
    Opcodes.ASM10_EXPERIMENTAL, classNode, false) {
    }, ClassReader.SKIP_DEBUG);
    Type syperType = classNode.superName == null ? null : Type.getObjectType(classNode.superName);
    List<MethodNode> methods = classNode.methods;
    List<Type> interfaces = new ArrayList<>();
    for (String interfaceName : classNode.interfaces) {
        interfaces.add(Type.getObjectType(interfaceName));
    }
    for (MethodNode method : methods) {
        SimpleVerifier verifier = new SimpleVerifier(Type.getObjectType(classNode.name), syperType, interfaces, (classNode.access & Opcodes.ACC_INTERFACE) != 0);
        Analyzer<BasicValue> analyzer = new Analyzer<>(verifier);
        if (loader != null) {
            verifier.setClassLoader(loader);
        }
        try {
            analyzer.analyze(classNode.name, method);
        } catch (AnalyzerException e) {
            e.printStackTrace(printWriter);
        }
        if (printResults) {
            printAnalyzerResult(method, analyzer, printWriter);
        }
    }
    printWriter.flush();
}
Also used : ClassNode(org.apache.tapestry5.internal.plastic.asm.tree.ClassNode) AnalyzerException(org.apache.tapestry5.internal.plastic.asm.tree.analysis.AnalyzerException) SimpleVerifier(org.apache.tapestry5.internal.plastic.asm.tree.analysis.SimpleVerifier) ArrayList(java.util.ArrayList) Analyzer(org.apache.tapestry5.internal.plastic.asm.tree.analysis.Analyzer) BasicValue(org.apache.tapestry5.internal.plastic.asm.tree.analysis.BasicValue) Type(org.apache.tapestry5.internal.plastic.asm.Type) MethodNode(org.apache.tapestry5.internal.plastic.asm.tree.MethodNode)

Example 5 with BasicValue

use of org.apache.tapestry5.internal.plastic.asm.tree.analysis.BasicValue in project tapestry-5 by apache.

the class SimpleVerifier method merge.

@Override
public BasicValue merge(final BasicValue value1, final BasicValue value2) {
    if (!value1.equals(value2)) {
        Type type1 = value1.getType();
        Type type2 = value2.getType();
        if (type1 != null && (type1.getSort() == Type.OBJECT || type1.getSort() == Type.ARRAY) && type2 != null && (type2.getSort() == Type.OBJECT || type2.getSort() == Type.ARRAY)) {
            if (type1.equals(NULL_TYPE)) {
                return value2;
            }
            if (type2.equals(NULL_TYPE)) {
                return value1;
            }
            if (isAssignableFrom(type1, type2)) {
                return value1;
            }
            if (isAssignableFrom(type2, type1)) {
                return value2;
            }
            int numDimensions = 0;
            if (type1.getSort() == Type.ARRAY && type2.getSort() == Type.ARRAY && type1.getDimensions() == type2.getDimensions() && type1.getElementType().getSort() == Type.OBJECT && type2.getElementType().getSort() == Type.OBJECT) {
                numDimensions = type1.getDimensions();
                type1 = type1.getElementType();
                type2 = type2.getElementType();
            }
            while (true) {
                if (type1 == null || isInterface(type1)) {
                    return newArrayValue(Type.getObjectType("java/lang/Object"), numDimensions);
                }
                type1 = getSuperClass(type1);
                if (isAssignableFrom(type1, type2)) {
                    return newArrayValue(type1, numDimensions);
                }
            }
        }
        return BasicValue.UNINITIALIZED_VALUE;
    }
    return value1;
}
Also used : Type(org.apache.tapestry5.internal.plastic.asm.Type)

Aggregations

Type (org.apache.tapestry5.internal.plastic.asm.Type)4 BasicValue (org.apache.tapestry5.internal.plastic.asm.tree.analysis.BasicValue)2 ArrayList (java.util.ArrayList)1 ClassNode (org.apache.tapestry5.internal.plastic.asm.tree.ClassNode)1 FieldInsnNode (org.apache.tapestry5.internal.plastic.asm.tree.FieldInsnNode)1 MethodNode (org.apache.tapestry5.internal.plastic.asm.tree.MethodNode)1 TryCatchBlockNode (org.apache.tapestry5.internal.plastic.asm.tree.TryCatchBlockNode)1 Analyzer (org.apache.tapestry5.internal.plastic.asm.tree.analysis.Analyzer)1 AnalyzerException (org.apache.tapestry5.internal.plastic.asm.tree.analysis.AnalyzerException)1 SimpleVerifier (org.apache.tapestry5.internal.plastic.asm.tree.analysis.SimpleVerifier)1