Search in sources :

Example 76 with Method

use of org.objectweb.asm.commons.Method 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.ASM9, 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 77 with Method

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

the class AbstractWovenProxyAdapter method writeCreateNewProxyInstanceAndConstructor.

/**
 * We write createNewProxyInstance separately because it isn't final, and is
 * overridden on each class, we also write a constructor for this method to
 * use if we don't have one.
 */
private final void writeCreateNewProxyInstanceAndConstructor() {
    GeneratorAdapter methodAdapter = getMethodGenerator(ACC_PUBLIC, new Method("org_apache_aries_proxy_weaving_WovenProxy_createNewProxyInstance", WOVEN_PROXY_IFACE_TYPE, DISPATCHER_LISTENER_METHOD_ARGS));
    // /////////////////////////////////////////////////////
    // Implement the method
    // Create and instantiate a new instance, then return it
    methodAdapter.newInstance(typeBeingWoven);
    methodAdapter.dup();
    methodAdapter.loadArgs();
    methodAdapter.invokeConstructor(typeBeingWoven, new Method("<init>", Type.VOID_TYPE, DISPATCHER_LISTENER_METHOD_ARGS));
    methodAdapter.returnValue();
    methodAdapter.endMethod();
    // ////////////////////////////////////////////////////////
    // Write a protected no-args constructor for this class
    methodAdapter = getMethodGenerator(ACC_PROTECTED | ACC_SYNTHETIC, ARGS_CONSTRUCTOR);
    if (implementWovenProxy) {
        methodAdapter.loadThis();
        if (superHasNoArgsConstructor)
            methodAdapter.invokeConstructor(superType, NO_ARGS_CONSTRUCTOR);
        else {
            if (hasNoArgsConstructor)
                methodAdapter.invokeConstructor(typeBeingWoven, NO_ARGS_CONSTRUCTOR);
            else
                throw new RuntimeException(new UnableToProxyException(typeBeingWoven.getClassName(), String.format("The class %s and its superclass %s do not have no-args constructors and cannot be woven.", typeBeingWoven.getClassName(), superType.getClassName())));
        }
        methodAdapter.loadThis();
        methodAdapter.loadArg(0);
        methodAdapter.putField(typeBeingWoven, DISPATCHER_FIELD, DISPATCHER_TYPE);
        methodAdapter.loadThis();
        methodAdapter.loadArg(1);
        methodAdapter.putField(typeBeingWoven, LISTENER_FIELD, LISTENER_TYPE);
    } else {
        // We just invoke the super with args
        methodAdapter.loadThis();
        methodAdapter.loadArgs();
        methodAdapter.invokeConstructor(superType, ARGS_CONSTRUCTOR);
    }
    // Throw an NPE if the dispatcher is null, return otherwise
    methodAdapter.loadArg(0);
    Label returnValue = methodAdapter.newLabel();
    methodAdapter.ifNonNull(returnValue);
    methodAdapter.newInstance(NPE_TYPE);
    methodAdapter.dup();
    methodAdapter.push("The dispatcher must never be null!");
    methodAdapter.invokeConstructor(NPE_TYPE, NPE_CONSTRUCTOR);
    methodAdapter.throwException();
    methodAdapter.mark(returnValue);
    methodAdapter.returnValue();
    methodAdapter.endMethod();
// ////////////////////////////////////////////////////////
}
Also used : Label(org.objectweb.asm.Label) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) UnableToProxyException(org.apache.aries.proxy.UnableToProxyException) Method(org.objectweb.asm.commons.Method)

Example 78 with Method

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

the class AbstractWovenProxyAdapter method writeStaticInitMethod.

/**
 * Create fields and an initialiser for {@link java.lang.reflect.Method}
 * objects in our class
 */
private final void writeStaticInitMethod() {
    for (String methodStaticFieldName : transformedMethods.keySet()) {
        // add a private static field for the method
        cv.visitField(ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, methodStaticFieldName, METHOD_TYPE.getDescriptor(), null, null).visitEnd();
    }
    GeneratorAdapter staticAdapter = new GeneratorAdapter(staticInitMethodFlags, staticInitMethod, null, null, cv);
    for (Entry<String, TypeMethod> entry : transformedMethods.entrySet()) {
        // Add some more code to the static initializer
        TypeMethod m = entry.getValue();
        Type[] targetMethodParameters = m.method.getArgumentTypes();
        String methodStaticFieldName = entry.getKey();
        Label beginPopulate = staticAdapter.newLabel();
        Label endPopulate = staticAdapter.newLabel();
        Label catchHandler = staticAdapter.newLabel();
        staticAdapter.visitTryCatchBlock(beginPopulate, endPopulate, catchHandler, THROWABLE_INAME);
        staticAdapter.mark(beginPopulate);
        staticAdapter.push(m.declaringClass);
        // push the method name string arg onto the stack
        staticAdapter.push(m.method.getName());
        // create an array of the method parm class[] arg
        staticAdapter.push(targetMethodParameters.length);
        staticAdapter.newArray(CLASS_TYPE);
        int index = 0;
        for (Type t : targetMethodParameters) {
            staticAdapter.dup();
            staticAdapter.push(index);
            staticAdapter.push(t);
            staticAdapter.arrayStore(CLASS_TYPE);
            index++;
        }
        // invoke the getMethod
        staticAdapter.invokeVirtual(CLASS_TYPE, new Method("getDeclaredMethod", METHOD_TYPE, new Type[] { STRING_TYPE, CLASS_ARRAY_TYPE }));
        // store the reflected method in the static field
        staticAdapter.putStatic(typeBeingWoven, methodStaticFieldName, METHOD_TYPE);
        Label afterCatch = staticAdapter.newLabel();
        staticAdapter.mark(endPopulate);
        staticAdapter.goTo(afterCatch);
        staticAdapter.mark(catchHandler);
        // We don't care about the exception, so pop it off
        staticAdapter.pop();
        // store the reflected method in the static field
        staticAdapter.visitInsn(ACONST_NULL);
        staticAdapter.putStatic(typeBeingWoven, methodStaticFieldName, METHOD_TYPE);
        staticAdapter.mark(afterCatch);
    }
    staticAdapter.returnValue();
    staticAdapter.endMethod();
}
Also used : Type(org.objectweb.asm.Type) Label(org.objectweb.asm.Label) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) Method(org.objectweb.asm.commons.Method)

Aggregations

Method (org.objectweb.asm.commons.Method)78 GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)58 Type (org.objectweb.asm.Type)38 ClassWriter (org.objectweb.asm.ClassWriter)14 Label (org.objectweb.asm.Label)14 MethodVisitor (org.objectweb.asm.MethodVisitor)9 IOException (java.io.IOException)7 ClassReader (org.objectweb.asm.ClassReader)7 TypeInfo (com.google.template.soy.jbcsrc.restricted.TypeInfo)6 MethodNode (org.objectweb.asm.tree.MethodNode)6 ExprString (lucee.transformer.expression.ExprString)5 LitString (lucee.transformer.expression.literal.LitString)5 ClassVisitor (org.objectweb.asm.ClassVisitor)5 Schema (co.cask.cdap.api.data.schema.Schema)4 ArrayList (java.util.ArrayList)4 File (java.io.File)3 Set (java.util.Set)3 Nullable (javax.annotation.Nullable)3 ExprDouble (lucee.transformer.expression.ExprDouble)3 MetricsContext (co.cask.cdap.api.metrics.MetricsContext)2