Search in sources :

Example 1 with AdviceAdapter

use of org.objectweb.asm.commons.AdviceAdapter in project aries by apache.

the class AbstractWovenProxyAdapter method visitMethod.

/**
   * This method is called on each method implemented on this object (but not
   * for superclass methods) Each of these methods is visited in turn and the
   * code here generates the byte code for the calls to the InovcationListener
   * around the existing method
   */
public final MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    LOGGER.debug(Constants.LOG_ENTRY, "visitMethod", new Object[] { access, name, desc, signature, exceptions });
    Method currentMethod = new Method(name, desc);
    getKnownMethods().add(currentMethod);
    MethodVisitor methodVisitorToReturn = null;
    // compiler generated ones.
    if ((access & (ACC_STATIC | ACC_PRIVATE | ACC_SYNTHETIC | ACC_NATIVE | ACC_BRIDGE)) == 0 && !!!name.equals("<init>") && !!!name.equals("<clinit>")) {
        // found a method we should weave
        //Create a field name and store it for later
        String methodStaticFieldName = "methodField" + getSanitizedUUIDString();
        transformedMethods.put(methodStaticFieldName, new TypeMethod(currentMethodDeclaringType, currentMethod));
        // Surround the MethodVisitor with our weaver so we can manipulate the code
        methodVisitorToReturn = getWeavingMethodVisitor(access, name, desc, signature, exceptions, currentMethod, methodStaticFieldName, currentMethodDeclaringType, currentMethodDeclaringTypeIsInterface);
    } else if (name.equals("<clinit>")) {
        //there is an existing clinit method, change the fields we use
        //to write our init code to static_init_UUID instead
        staticInitMethod = new Method("static_init_" + UU_ID, Type.VOID_TYPE, NO_ARGS);
        staticInitMethodFlags = staticInitMethodFlags | ACC_FINAL;
        methodVisitorToReturn = new AdviceAdapter(Opcodes.ASM5, cv.visitMethod(access, name, desc, signature, exceptions), access, name, desc) {

            @Override
            protected void onMethodEnter() {
                //add into the <clinit> a call to our synthetic static_init_UUID
                invokeStatic(typeBeingWoven, staticInitMethod);
                super.onMethodEnter();
            }
        };
    } else {
        if (currentMethod.getArgumentTypes().length == 0 && name.equals("<init>"))
            hasNoArgsConstructor = true;
        //This isn't a method we want to weave, so just get the default visitor
        methodVisitorToReturn = cv.visitMethod(access, name, desc, signature, exceptions);
    }
    LOGGER.debug(Constants.LOG_EXIT, "visitMethod", methodVisitorToReturn);
    return methodVisitorToReturn;
}
Also used : AdviceAdapter(org.objectweb.asm.commons.AdviceAdapter) Method(org.objectweb.asm.commons.Method) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 2 with AdviceAdapter

use of org.objectweb.asm.commons.AdviceAdapter in project cdap by caskdata.

the class SparkClassRewriter method rewriteConstructor.

/**
   * Rewrites the constructors who don't delegate to other constructor with the given {@link ConstructorRewriter}.
   *
   * @param classType type of the class to be defined
   * @param byteCodeStream {@link InputStream} for reading the original bytecode of the class
   * @param rewriter a {@link ConstructorRewriter} for rewriting the constructor
   * @return the rewritten bytecode
   */
private byte[] rewriteConstructor(final Type classType, InputStream byteCodeStream, final ConstructorRewriter rewriter) throws IOException {
    ClassReader cr = new ClassReader(byteCodeStream);
    ClassWriter cw = new ClassWriter(0);
    cr.accept(new ClassVisitor(Opcodes.ASM5, cw) {

        @Override
        public MethodVisitor visitMethod(int access, final String name, final String desc, String signature, String[] exceptions) {
            // Call super so that the method signature is registered with the ClassWriter (parent)
            MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
            // We only attempt to rewrite constructor
            if (!"<init>".equals(name)) {
                return mv;
            }
            return new AdviceAdapter(Opcodes.ASM5, mv, access, name, desc) {

                boolean calledThis;

                @Override
                public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
                    // See if in this constructor it is calling other constructor (this(..)).
                    calledThis = calledThis || (opcode == Opcodes.INVOKESPECIAL && Type.getObjectType(owner).equals(classType) && name.equals("<init>") && Type.getReturnType(desc).equals(Type.VOID_TYPE));
                    super.visitMethodInsn(opcode, owner, name, desc, itf);
                }

                @Override
                protected void onMethodEnter() {
                    if (calledThis) {
                        // For constructors that call this(), we don't need rewrite
                        return;
                    }
                    rewriter.onMethodEnter(name, desc, this);
                }

                @Override
                protected void onMethodExit(int opcode) {
                    if (calledThis) {
                        // For constructors that call this(), we don't need rewrite
                        return;
                    }
                    // Add a call to SparkContextCache.setContext() for the normal method return path
                    if (opcode == RETURN) {
                        rewriter.onMethodExit(name, desc, this);
                    }
                }
            };
        }
    }, ClassReader.EXPAND_FRAMES);
    return cw.toByteArray();
}
Also used : AdviceAdapter(org.objectweb.asm.commons.AdviceAdapter) ClassReader(org.objectweb.asm.ClassReader) ClassVisitor(org.objectweb.asm.ClassVisitor) ClassWriter(org.objectweb.asm.ClassWriter) MethodVisitor(org.objectweb.asm.MethodVisitor)

Aggregations

MethodVisitor (org.objectweb.asm.MethodVisitor)2 AdviceAdapter (org.objectweb.asm.commons.AdviceAdapter)2 ClassReader (org.objectweb.asm.ClassReader)1 ClassVisitor (org.objectweb.asm.ClassVisitor)1 ClassWriter (org.objectweb.asm.ClassWriter)1 Method (org.objectweb.asm.commons.Method)1