Package org.nutz.aop.asm

Source Code of org.nutz.aop.asm.AopMethodAdapter

package org.nutz.aop.asm;

import org.nutz.repo.org.objectweb.asm.Attribute;
import org.nutz.repo.org.objectweb.asm.Label;
import org.nutz.repo.org.objectweb.asm.MethodVisitor;
import org.nutz.repo.org.objectweb.asm.Opcodes;
import org.nutz.repo.org.objectweb.asm.Type;

/**
*
* @author wendal(wendal1985@gmail.com)
*
*/
class AopMethodAdapter extends NormalMethodAdapter implements Opcodes {

    int methodIndex;

    String myName;

    String enhancedSuperName;

    String methodName;

    Type returnType;

    AopMethodAdapter(MethodVisitor mv,
                            int access,
                            String methodName,
                            String desc,
                            int methodIndex,
                            String myName,
                            String enhancedSuperName) {
        super(mv, desc, access);
        this.methodIndex = methodIndex;
        this.myName = myName;
        this.enhancedSuperName = enhancedSuperName;
        this.methodName = methodName;
        this.returnType = Type.getReturnType(desc);
    }

    void enhandMethod_Void() {
        mv.visitCode();
        Label l0 = new Label();
        Label l1 = new Label();
        Label l2 = new Label();
        mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Throwable");
        mv.visitLabel(l0);
        mv.visitTypeInsn(NEW, "org/nutz/aop/InterceptorChain");
        mv.visitInsn(DUP);
        visitX(methodIndex);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETSTATIC, myName, AsmClassAgent.MethodArray_FieldName, "[Ljava/lang/reflect/Method;");
        visitX(methodIndex);
        mv.visitInsn(AALOAD);
        mv.visitFieldInsn(GETSTATIC, myName, AsmClassAgent.MethodInterceptorList_FieldName, "[Ljava/util/List;");
        visitX(methodIndex);
        mv.visitInsn(AALOAD);
        loadArgsAsArray();
        mv.visitMethodInsn(    INVOKESPECIAL,
                            "org/nutz/aop/InterceptorChain",
                            "<init>",
                            "(ILjava/lang/Object;Ljava/lang/reflect/Method;Ljava/util/List;[Ljava/lang/Object;)V");
        mv.visitMethodInsn(    INVOKEVIRTUAL,
                            "org/nutz/aop/InterceptorChain",
                            "doChain",
                            "()Lorg/nutz/aop/InterceptorChain;");

        {
            if (Type.getReturnType(desc).equals(Type.VOID_TYPE)) {
                mv.visitInsn(POP);
            } else {
                mv.visitMethodInsn(    INVOKEVIRTUAL,
                                    "org/nutz/aop/InterceptorChain",
                                    "getReturn",
                                    "()Ljava/lang/Object;");
                AsmHelper.checkCast(returnType,mv);
                returnIt();
            }
        }

        mv.visitLabel(l1);
        Label l3 = new Label();
        mv.visitJumpInsn(GOTO, l3);
        mv.visitLabel(l2);
        mv.visitVarInsn(ASTORE, 3);
        mv.visitVarInsn(ALOAD, 3);
        // mv.visitMethodInsn(INVOKESTATIC, "org/nutz/lang/Lang", "wrapThrow",
        // "(Ljava/lang/Throwable;)Ljava/lang/RuntimeException;");
        mv.visitInsn(ATHROW);
        mv.visitLabel(l3);
        mv.visitInsn(RETURN);
        mv.visitMaxs(8, 4);
        mv.visitEnd();
    }

    void visitCode() {
        enhandMethod_Void();
    }

    void loadArgsAsArray() {
        visitX(argumentTypes.length);
        mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
        int index = 1;
        for (int i = 0; i < argumentTypes.length; i++) {
            mv.visitInsn(DUP);
            visitX(i);
            Type t = argumentTypes[i];
            loadInsn(t, index);
            index += t.getSize();
            AsmHelper.packagePrivateData(t,mv);
            mv.visitInsn(AASTORE);
        }
    }

    void visitX(int i) {
        if (i < 6) {
            mv.visitInsn(i + ICONST_0);
        } else {
            if (i < Byte.MAX_VALUE)
                mv.visitIntInsn(BIPUSH, i);
            else
                mv.visitIntInsn(SIPUSH, i);
        }
    }

    void returnIt() {
        mv.visitInsn(returnType.getOpcode(IRETURN));
    }

    void visitAttribute() {
        Attribute attr = new Attribute("LocalVariableTable");
        attr.value= new byte[]{0,0};
        mv.visitAttribute(attr);
    }
}
TOP

Related Classes of org.nutz.aop.asm.AopMethodAdapter

TOP
Copyright © 2018 www.massapi.com. 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.