Search in sources :

Example 96 with MethodNode

use of org.objectweb.asm.tree.MethodNode in project groovy by apache.

the class VerifyClass method readClass.

private boolean readClass(String clazz) throws IOException {
    ClassNode ca;
    try (final InputStream inputStream = new BufferedInputStream(new FileInputStream(clazz))) {
        ClassReader cr = new ClassReader(inputStream);
        ca = new ClassNode() {

            @Override
            public void visitEnd() {
            // accept(cv);
            }
        };
        cr.accept(new CheckClassAdapter(ca), ClassWriter.COMPUTE_MAXS);
    }
    boolean failed = false;
    List<MethodNode> methods = ca.methods;
    for (MethodNode method : methods) {
        if (method.instructions.size() > 0) {
            Analyzer<?> a = new Analyzer<>(new SimpleVerifier());
            try {
                a.analyze(ca.name, method);
                continue;
            } catch (Exception e) {
                e.printStackTrace();
            }
            if (!failed) {
                failed = true;
                log("verifying of class " + clazz + " failed");
            }
            if (verbose)
                log(method.name + method.desc);
            TraceMethodVisitor mv = new TraceMethodVisitor(null);
            for (int j = 0; j < method.instructions.size(); ++j) {
                AbstractInsnNode insn = method.instructions.get(j);
                if (insn != null) {
                    insn.accept(mv);
                } else {
                    mv.visitLabel(null);
                }
            }
            mv.visitMaxs(method.maxStack, method.maxLocals);
        }
    }
    return !failed;
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) SimpleVerifier(org.objectweb.asm.tree.analysis.SimpleVerifier) BufferedInputStream(java.io.BufferedInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) Analyzer(org.objectweb.asm.tree.analysis.Analyzer) AbstractInsnNode(org.objectweb.asm.tree.AbstractInsnNode) TraceMethodVisitor(org.objectweb.asm.util.TraceMethodVisitor) FileInputStream(java.io.FileInputStream) BuildException(org.apache.tools.ant.BuildException) IOException(java.io.IOException) MethodNode(org.objectweb.asm.tree.MethodNode) BufferedInputStream(java.io.BufferedInputStream) CheckClassAdapter(org.objectweb.asm.util.CheckClassAdapter) ClassReader(org.objectweb.asm.ClassReader)

Example 97 with MethodNode

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

the class InstrumentClass method visitMethod.

@Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) {
    SuspendableType markedSuspendable = null;
    if (suspendableInterface)
        markedSuspendable = SuspendableType.SUSPENDABLE_SUPER;
    if (markedSuspendable == null)
        markedSuspendable = classifier.isSuspendable(db, sourceName, sourceDebugInfo, isInterface, className, classEntry.getSuperName(), classEntry.getInterfaces(), name, desc, signature, exceptions);
    final SuspendableType setSuspendable = classEntry.check(name, desc);
    if (setSuspendable == null)
        classEntry.set(name, desc, markedSuspendable != null ? markedSuspendable : SuspendableType.NON_SUSPENDABLE);
    final SuspendableType suspendable = max(markedSuspendable, setSuspendable, SuspendableType.NON_SUSPENDABLE);
    if (checkAccessForMethodVisitor(access) && !isYieldMethod(className, name)) {
        if (methods == null)
            methods = new ArrayList<>();
        final MethodNode mn = new MethodNode(access, name, desc, signature, exceptions);
        return new MethodVisitor(ASMAPI, mn) {

            private SuspendableType susp = suspendable;

            private boolean commited = false;

            @Override
            public AnnotationVisitor visitAnnotation(String adesc, boolean visible) {
                // look for @Suspendable or @DontInstrument annotation
                if (adesc.equals(SUSPENDABLE_DESC))
                    susp = SuspendableType.SUSPENDABLE;
                else if (adesc.equals(DONT_INSTRUMENT_DESC))
                    susp = SuspendableType.NON_SUSPENDABLE;
                susp = suspendableToSuperIfAbstract(access, susp);
                return super.visitAnnotation(adesc, visible);
            }

            @Override
            public void visitCode() {
                commit();
                super.visitCode();
            }

            @Override
            public void visitEnd() {
                if (exception != null)
                    return;
                commit();
                try {
                    super.visitEnd();
                } catch (RuntimeException e) {
                    exception = e;
                }
            }

            private void commit() {
                if (commited)
                    return;
                commited = true;
                if (db.isDebug())
                    db.log(LogLevel.INFO, "Method %s#%s%s suspendable: %s (markedSuspendable: %s setSuspendable: %s)", className, name, desc, susp, susp, setSuspendable);
                classEntry.set(name, desc, susp);
                if (susp == SuspendableType.SUSPENDABLE && checkAccessForMethodInstrumentation(access)) {
                    if (isSynchronized(access)) {
                        if (!db.isAllowMonitors())
                            throw new UnableToInstrumentException("synchronization", className, name, desc);
                        else
                            db.log(LogLevel.WARNING, "Method %s#%s%s is synchronized", className, name, desc);
                    }
                    methods.add(mn);
                } else {
                    MethodVisitor _mv = makeOutMV(mn);
                    _mv = new JSRInlinerAdapter(_mv, access, name, desc, signature, exceptions);
                    mn.accept(new MethodVisitor(ASMAPI, _mv) {

                        @Override
                        public void visitEnd() {
                        // don't call visitEnd on MV
                        }
                    });
                    // write method as-is
                    this.mv = _mv;
                }
            }
        };
    }
    return super.visitMethod(access, name, desc, signature, exceptions);
}
Also used : SuspendableType(co.paralleluniverse.fibers.instrument.MethodDatabase.SuspendableType) MethodNode(org.objectweb.asm.tree.MethodNode) ArrayList(java.util.ArrayList) JSRInlinerAdapter(org.objectweb.asm.commons.JSRInlinerAdapter) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 98 with MethodNode

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

the class OldSuspendablesScanner method findSuperDeclarations.

private boolean findSuperDeclarations(ClassNode cls, ClassNode declaringClass, MethodNode method) throws IOException {
    if (cls == null)
        return false;
    boolean foundMethod = false;
    MethodNode m;
    if ((m = getMethod(method, cls)) != null) {
        foundMethod = true;
        if (!ASMUtil.equals(cls, declaringClass) && !isSuspendable(cls, m)) {
            log("Found parent of annotated method: " + declaringClass.name + "." + method.name + method.signature + " in " + cls.name, Project.MSG_VERBOSE);
            results.add(cls.name.replace('/', '.') + '.' + method.name);
        }
    }
    // recursively look in superclass and interfaces
    boolean methodInParent = false;
    methodInParent |= findSuperDeclarations(getClassNode(cls.superName, cl, true), declaringClass, method);
    for (String iface : (List<String>) cls.interfaces) methodInParent |= findSuperDeclarations(getClassNode(iface, cl, true), declaringClass, method);
    if (!foundMethod && methodInParent) {
        log("Found parent of annotated method in a parent of: " + declaringClass.name + "." + method.name + method.signature + " in " + cls.name, Project.MSG_VERBOSE);
        results.add(cls.name.replace('/', '.') + '.' + method.name);
    }
    return foundMethod | methodInParent;
}
Also used : MethodNode(org.objectweb.asm.tree.MethodNode) ArrayList(java.util.ArrayList) List(java.util.List)

Example 99 with MethodNode

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

the class SuspOffsetsAfterInstrClassVisitor method visitMethod.

@Override
public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) {
    if ((access & Opcodes.ACC_NATIVE) == 0 && !isYieldMethod(className, name)) {
        // Bytecode-level AST of a method, being a MethodVisitor itself can be filled through delegation from another visitor
        final MethodNode mn = new MethodNode(access, name, desc, signature, exceptions);
        // Analyze, fill and enqueue method ASTs
        final MethodVisitor outMV = super.visitMethod(access, name, desc, signature, exceptions);
        return new MethodVisitor(ASMAPI, outMV) {

            private Label currLabel = null;

            private int prevOffset = -1;

            private boolean instrumented;

            private boolean optimized = false;

            private int methodStart = -1, methodEnd = -1;

            private int[] suspCallSites = new int[0];

            private String[] suspCallSiteNames = new String[0];

            private List<Integer> suspOffsetsAfterInstrL = new ArrayList<>();

            @Override
            public AnnotationVisitor visitAnnotation(final String adesc, boolean visible) {
                if (Classes.INSTRUMENTED_DESC.equals(adesc)) {
                    instrumented = true;
                    return new // Only collect info
                    AnnotationVisitor(// Only collect info
                    ASMAPI) {

                        @Override
                        public void visit(String attrib, Object value) {
                            if (null != attrib)
                                switch(attrib) {
                                    case Instrumented.FIELD_NAME_METHOD_START:
                                        methodStart = (Integer) value;
                                        break;
                                    case Instrumented.FIELD_NAME_METHOD_END:
                                        methodEnd = (Integer) value;
                                        break;
                                    case Instrumented.FIELD_NAME_METHOD_OPTIMIZED:
                                        optimized = (Boolean) value;
                                        break;
                                    case Instrumented.FIELD_NAME_SUSPENDABLE_CALL_SITES:
                                        suspCallSites = (int[]) value;
                                        break;
                                    case Instrumented.FIELD_NAME_SUSPENDABLE_CALL_SITES_OFFSETS_AFTER_INSTR:
                                        // Ignore, we're filling it
                                        ;
                                        break;
                                    default:
                                        throw new RuntimeException("Unexpected `@Instrumented` field: " + attrib);
                                }
                        }

                        @Override
                        public AnnotationVisitor visitArray(String attrib) {
                            // String[] value not handled by visit
                            if (Instrumented.FIELD_NAME_SUSPENDABLE_CALL_SITE_NAMES.equals(attrib))
                                return new AnnotationVisitor(ASMAPI) {

                                    List<String> callSites = new ArrayList<>();

                                    @Override
                                    public void visit(String attrib, Object value) {
                                        callSites.add((String) value);
                                    }

                                    @Override
                                    public void visitEnd() {
                                        suspCallSiteNames = callSites.toArray(new String[0]);
                                    }
                                };
                            else
                                return super.visitArray(name);
                        }
                    };
                }
                return super.visitAnnotation(adesc, visible);
            }

            @Override
            public void visitLocalVariable(String name, String desc, String sig, Label lStart, Label lEnd, int slot) {
                super.visitLocalVariable(name, desc, sig, lStart, lEnd, slot);
            }

            @Override
            public void visitLabel(Label label) {
                if (instrumented) {
                    currLabel = label;
                }
                super.visitLabel(label);
            }

            @Override
            public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean isInterface) {
                if (instrumented) {
                    final int type = AbstractInsnNode.METHOD_INSN;
                    if (InstrumentMethod.isSuspendableCall(db, type, opcode, owner, name, desc) && // postRestore
                    !Classes.STACK_NAME.equals(owner) && currLabel != null && currLabel.info instanceof Integer)
                        addLine();
                }
                super.visitMethodInsn(opcode, owner, name, desc, isInterface);
            }

            @Override
            public void visitInvokeDynamicInsn(String name, String desc, Handle handle, Object... objects) {
                if (instrumented) {
                    final int type = AbstractInsnNode.INVOKE_DYNAMIC_INSN;
                    final int opcode = Opcodes.INVOKEDYNAMIC;
                    if (InstrumentMethod.isSuspendableCall(db, type, opcode, handle.getOwner(), name, desc) && // postRestore
                    !Classes.STACK_NAME.equals(handle.getOwner()) && currLabel != null && currLabel.info instanceof Integer)
                        addLine();
                }
                super.visitInvokeDynamicInsn(name, desc, handle, objects);
            }

            @Override
            public void visitEnd() {
                if (instrumented)
                    InstrumentMethod.emitInstrumentedAnn(db, outMV, mn, sourceName, className, optimized, methodStart, methodEnd, suspCallSites, suspCallSiteNames, toIntArray(suspOffsetsAfterInstrL));
                super.visitEnd();
            }

            private void addLine() {
                final int currOffset = (Integer) currLabel.info;
                if (currOffset > prevOffset) {
                    suspOffsetsAfterInstrL.add(currOffset);
                    prevOffset = currOffset;
                }
            }
        };
    }
    return super.visitMethod(access, name, desc, signature, exceptions);
}
Also used : MethodNode(org.objectweb.asm.tree.MethodNode)

Example 100 with MethodNode

use of org.objectweb.asm.tree.MethodNode in project spring-loaded by spring-projects.

the class SpringLoadedTests method checkAnnotations.

@SuppressWarnings("unchecked")
protected void checkAnnotations(byte[] bytes, String methodNameAndDescriptor, String... expected) {
    ClassNode cn = new ClassNode();
    ClassReader cr = new ClassReader(bytes);
    cr.accept(cn, 0);
    if (expected == null) {
        expected = new String[0];
    }
    boolean checked = false;
    List<MethodNode> methods = cn.methods;
    for (MethodNode mn : methods) {
        if (methodNameAndDescriptor.equals(mn.name + mn.desc)) {
            List<AnnotationNode> annotations = mn.visibleAnnotations;
            if (annotations == null) {
                annotations = Collections.emptyList();
            }
            Assert.assertEquals(expected.length, annotations.size());
            for (int i = 0; i < expected.length; i++) {
                // StringTokenizer tokenizer = new StringTokenizer(expected[i], ":");
                // String expectedName = tokenizer.nextToken();
                // String expectedDesc = tokenizer.nextToken();
                AnnotationNode annotation = annotations.get(i);
                Assert.assertEquals(expected[i], toString(annotation));
            }
            checked = true;
        }
    }
    if (!checked) {
        for (MethodNode mn : methods) {
            System.out.println(mn.name + mn.desc);
        }
        Assert.fail("Unable to find method " + methodNameAndDescriptor);
    }
}
Also used : ClassNode(org.objectweb.asm.tree.ClassNode) MethodNode(org.objectweb.asm.tree.MethodNode) AnnotationNode(org.objectweb.asm.tree.AnnotationNode) ClassReader(org.objectweb.asm.ClassReader)

Aggregations

MethodNode (org.objectweb.asm.tree.MethodNode)322 ClassNode (org.objectweb.asm.tree.ClassNode)123 Test (org.junit.Test)94 AbstractInsnNode (org.objectweb.asm.tree.AbstractInsnNode)59 ClassReader (org.objectweb.asm.ClassReader)57 InsnList (org.objectweb.asm.tree.InsnList)49 MethodInsnNode (org.objectweb.asm.tree.MethodInsnNode)47 Label (org.objectweb.asm.Label)44 VarInsnNode (org.objectweb.asm.tree.VarInsnNode)41 InsnNode (org.objectweb.asm.tree.InsnNode)34 ClassWriter (org.objectweb.asm.ClassWriter)26 FieldNode (org.objectweb.asm.tree.FieldNode)26 JumpInsnNode (org.objectweb.asm.tree.JumpInsnNode)26 ArrayList (java.util.ArrayList)24 FieldInsnNode (org.objectweb.asm.tree.FieldInsnNode)24 LdcInsnNode (org.objectweb.asm.tree.LdcInsnNode)21 LabelNode (org.objectweb.asm.tree.LabelNode)19 TypeInsnNode (org.objectweb.asm.tree.TypeInsnNode)19 List (java.util.List)17 Type (org.objectweb.asm.Type)17