Search in sources :

Example 61 with Type

use of org.objectweb.asm.Type in project android_frameworks_base by DirtyUnicorns.

the class TransformClassAdapter method visitMethod.

/* Visits a method. */
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    if (mDeleteReturns != null) {
        Type t = Type.getReturnType(desc);
        if (t.getSort() == Type.OBJECT) {
            String returnType = t.getInternalName();
            if (returnType != null) {
                if (mDeleteReturns.contains(returnType)) {
                    return null;
                }
            }
        }
    }
    String methodSignature = mClassName.replace('/', '.') + "#" + name;
    // remove final
    access = access & ~Opcodes.ACC_FINAL;
    // and don't try to stub interfaces nor abstract non-native methods.
    if (!mIsInterface && ((access & (Opcodes.ACC_ABSTRACT | Opcodes.ACC_NATIVE)) != Opcodes.ACC_ABSTRACT) && (mStubAll || (access & Opcodes.ACC_NATIVE) != 0) || mStubMethods.contains(methodSignature)) {
        boolean isStatic = (access & Opcodes.ACC_STATIC) != 0;
        boolean isNative = (access & Opcodes.ACC_NATIVE) != 0;
        // remove abstract, final and native
        access = access & ~(Opcodes.ACC_ABSTRACT | Opcodes.ACC_FINAL | Opcodes.ACC_NATIVE);
        String invokeSignature = methodSignature + desc;
        mLog.debug("  Stub: %s (%s)", invokeSignature, isNative ? "native" : "");
        MethodVisitor mw = super.visitMethod(access, name, desc, signature, exceptions);
        return new StubMethodAdapter(mw, name, returnType(desc), invokeSignature, isStatic, isNative);
    } else {
        mLog.debug("  Keep: %s %s", name, desc);
        return super.visitMethod(access, name, desc, signature, exceptions);
    }
}
Also used : Type(org.objectweb.asm.Type) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 62 with Type

use of org.objectweb.asm.Type in project hudson-2.x by hudson.

the class SubClassGenerator method generate.

public <T> Class<? extends T> generate(Class<T> base, String name) {
    //?
    ClassWriter cw = new ClassWriter(false, false);
    cw.visit(49, ACC_PUBLIC, name.replace('.', '/'), null, Type.getInternalName(base), null);
    for (Constructor c : base.getDeclaredConstructors()) {
        Class[] et = c.getExceptionTypes();
        String[] exceptions = new String[et.length];
        for (int i = 0; i < et.length; i++) exceptions[i] = Type.getInternalName(et[i]);
        String methodDescriptor = getMethodDescriptor(c);
        MethodVisitor m = cw.visitMethod(c.getModifiers(), "<init>", methodDescriptor, null, exceptions);
        m.visitCode();
        int index = 1;
        m.visitVarInsn(ALOAD, 0);
        for (Class param : c.getParameterTypes()) {
            Type t = Type.getType(param);
            m.visitVarInsn(t.getOpcode(ILOAD), index);
            index += t.getSize();
        }
        m.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(base), "<init>", methodDescriptor);
        m.visitInsn(RETURN);
        m.visitMaxs(index, index);
        m.visitEnd();
    }
    cw.visitEnd();
    byte[] image = cw.toByteArray();
    Class<? extends T> c = defineClass(name, image, 0, image.length).asSubclass(base);
    Hudson h = Hudson.getInstance();
    if (// null only during tests.
    h != null)
        // can't change the field type as it breaks binary compatibility
        ((UberClassLoader) h.pluginManager.uberClassLoader).addNamedClass(name, c);
    return c;
}
Also used : Type(org.objectweb.asm.Type) Constructor(java.lang.reflect.Constructor) Hudson(hudson.model.Hudson) ClassWriter(org.objectweb.asm.ClassWriter) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 63 with Type

use of org.objectweb.asm.Type in project aries by apache.

the class TCCLSetterVisitor method visitEnd.

@Override
public void visitEnd() {
    if (!woven) {
        // if this class wasn't woven, then don't add the synthesized method either.
        super.visitEnd();
        return;
    }
    // Add generated static method
    Set<String> methodNames = new HashSet<String>();
    for (WeavingData wd : weavingData) {
        /* Equivalent to:
             * private static void $$FCCL$$<className>$<methodName>(Class<?> cls) {
             *   Util.fixContextClassLoader("java.util.ServiceLoader", "load", cls, WovenClass.class.getClassLoader());
             * }
             */
        String methodName = getGeneratedMethodName(wd);
        if (methodNames.contains(methodName))
            continue;
        methodNames.add(methodName);
        Method method = new Method(methodName, Type.VOID_TYPE, new Type[] { CLASS_TYPE });
        GeneratorAdapter mv = new GeneratorAdapter(cv.visitMethod(ACC_PRIVATE + ACC_STATIC, methodName, method.getDescriptor(), null, null), ACC_PRIVATE + ACC_STATIC, methodName, method.getDescriptor());
        //Load the strings, method parameter and target
        mv.visitLdcInsn(wd.getClassName());
        mv.visitLdcInsn(wd.getMethodName());
        mv.loadArg(0);
        mv.visitLdcInsn(targetClass);
        //Change the class on the stack into a classloader
        mv.invokeVirtual(CLASS_TYPE, new Method("getClassLoader", CLASSLOADER_TYPE, new Type[0]));
        //Call our util method
        mv.invokeStatic(UTIL_CLASS, new Method("fixContextClassloader", Type.VOID_TYPE, new Type[] { String_TYPE, String_TYPE, CLASS_TYPE, CLASSLOADER_TYPE }));
        mv.returnValue();
        mv.endMethod();
    }
    super.visitEnd();
}
Also used : Type(org.objectweb.asm.Type) WeavingData(org.apache.aries.spifly.WeavingData) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) Method(org.objectweb.asm.commons.Method) HashSet(java.util.HashSet)

Example 64 with Type

use of org.objectweb.asm.Type in project aries by apache.

the class ProxySubclassAdapter method processMethod.

private void processMethod(int access, String name, String desc, String signature, String[] exceptions) {
    LOGGER.debug(Constants.LOG_ENTRY, "processMethod", new Object[] { access, name, desc, signature, exceptions });
    LOGGER.debug("Processing method: {} with descriptor {}", name, desc);
    // identify the target method parameters and return type
    Method currentTransformMethod = new Method(name, desc);
    Type[] targetMethodParameters = currentTransformMethod.getArgumentTypes();
    Type returnType = currentTransformMethod.getReturnType();
    // we create a static field for each method we encounter with a name
    // like method_parm1_parm2...
    StringBuilder methodStaticFieldNameBuilder = new StringBuilder(name);
    // the dots first
    for (Type t : targetMethodParameters) {
        methodStaticFieldNameBuilder.append("_");
        methodStaticFieldNameBuilder.append(t.getClassName().replaceAll("\\[\\]", "Array").replaceAll("\\.", ""));
    }
    String methodStaticFieldName = methodStaticFieldNameBuilder.toString();
    // add a private static field for the method
    cv.visitField(ACC_PRIVATE | ACC_STATIC, methodStaticFieldName, METHOD_TYPE.getDescriptor(), null, null);
    // visit the method using the class writer, delegated through the method
    // visitor and generator
    // modify the method access so that any native methods aren't
    // described as native
    // since they won't be native in proxy form
    // also stop methods being marked synchronized on the proxy as they will
    // be sync
    // on the real object
    int newAccess = access & (~ACC_NATIVE) & (~ACC_SYNCHRONIZED);
    MethodVisitor mv = cv.visitMethod(newAccess, name, desc, signature, exceptions);
    // use a GeneratorAdapter to build the invoke call directly in byte code
    GeneratorAdapter methodAdapter = new GeneratorAdapter(mv, newAccess, name, desc);
    /*
     * Stage 1 creates the bytecode for adding the reflected method of the
     * superclass to a static field in the subclass: private static Method
     * methodName_parm1_parm2... = null; static{ methodName_parm1_parm2... =
     * superClass.getDeclaredMethod(methodName,new Class[]{method args}; }
     * 
     * Stage 2 is to call the ih.invoke(this,methodName_parm1_parm2,args) in
     * the new subclass methods Stage 3 is to cast the return value to the
     * correct type
     */
    /*
     * Stage 1 use superClass.getMethod(methodName,new Class[]{method args}
     * from the Class object on the stack
     */
    // load the static superclass Class onto the stack
    staticAdapter.getStatic(newClassType, currentClassFieldName, CLASS_TYPE);
    // push the method name string arg onto the stack
    staticAdapter.push(name);
    // 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);
        switch(t.getSort()) {
            case Type.BOOLEAN:
                staticAdapter.getStatic(Type.getType(java.lang.Boolean.class), "TYPE", CLASS_TYPE);
                break;
            case Type.BYTE:
                staticAdapter.getStatic(Type.getType(java.lang.Byte.class), "TYPE", CLASS_TYPE);
                break;
            case Type.CHAR:
                staticAdapter.getStatic(Type.getType(java.lang.Character.class), "TYPE", CLASS_TYPE);
                break;
            case Type.DOUBLE:
                staticAdapter.getStatic(Type.getType(java.lang.Double.class), "TYPE", CLASS_TYPE);
                break;
            case Type.FLOAT:
                staticAdapter.getStatic(Type.getType(java.lang.Float.class), "TYPE", CLASS_TYPE);
                break;
            case Type.INT:
                staticAdapter.getStatic(Type.getType(java.lang.Integer.class), "TYPE", CLASS_TYPE);
                break;
            case Type.LONG:
                staticAdapter.getStatic(Type.getType(java.lang.Long.class), "TYPE", CLASS_TYPE);
                break;
            case Type.SHORT:
                staticAdapter.getStatic(Type.getType(java.lang.Short.class), "TYPE", CLASS_TYPE);
                break;
            default:
            case Type.OBJECT:
                staticAdapter.push(t);
                break;
        }
        staticAdapter.arrayStore(CLASS_TYPE);
        index++;
    }
    // invoke the getMethod
    staticAdapter.invokeVirtual(CLASS_TYPE, new Method("getDeclaredMethod", METHOD_TYPE, new Type[] { STRING_TYPE, Type.getType(java.lang.Class[].class) }));
    // store the reflected method in the static field
    staticAdapter.putStatic(newClassType, methodStaticFieldName, METHOD_TYPE);
    /*
     * Stage 2 call the ih.invoke(this,supermethod,parms)
     */
    // load this to get the ih field
    methodAdapter.loadThis();
    // load the invocation handler from the field (the location of the
    // InvocationHandler.invoke)
    methodAdapter.getField(newClassType, IH_FIELD, IH_TYPE);
    // loadThis (the first arg of the InvocationHandler.invoke)
    methodAdapter.loadThis();
    // load the method to invoke (the second arg of the
    // InvocationHandler.invoke)
    methodAdapter.getStatic(newClassType, methodStaticFieldName, METHOD_TYPE);
    // load all the method arguments onto the stack as an object array (the
    // third arg of the InvocationHandler.invoke)
    methodAdapter.loadArgArray();
    // generate the invoke method
    Method invocationHandlerInvokeMethod = new Method("invoke", OBJECT_TYPE, new Type[] { OBJECT_TYPE, METHOD_TYPE, Type.getType(java.lang.Object[].class) });
    // call the invoke method of the invocation handler
    methodAdapter.invokeInterface(IH_TYPE, invocationHandlerInvokeMethod);
    /*
     * Stage 3 the returned object is now on the top of the stack We need to
     * check the type and cast as necessary
     */
    switch(returnType.getSort()) {
        case Type.BOOLEAN:
            methodAdapter.cast(OBJECT_TYPE, Type.getType(Boolean.class));
            methodAdapter.unbox(Type.BOOLEAN_TYPE);
            break;
        case Type.BYTE:
            methodAdapter.cast(OBJECT_TYPE, Type.getType(Byte.class));
            methodAdapter.unbox(Type.BYTE_TYPE);
            break;
        case Type.CHAR:
            methodAdapter.cast(OBJECT_TYPE, Type.getType(Character.class));
            methodAdapter.unbox(Type.CHAR_TYPE);
            break;
        case Type.DOUBLE:
            methodAdapter.cast(OBJECT_TYPE, Type.getType(Double.class));
            methodAdapter.unbox(Type.DOUBLE_TYPE);
            break;
        case Type.FLOAT:
            methodAdapter.cast(OBJECT_TYPE, Type.getType(Float.class));
            methodAdapter.unbox(Type.FLOAT_TYPE);
            break;
        case Type.INT:
            methodAdapter.cast(OBJECT_TYPE, Type.getType(Integer.class));
            methodAdapter.unbox(Type.INT_TYPE);
            break;
        case Type.LONG:
            methodAdapter.cast(OBJECT_TYPE, Type.getType(Long.class));
            methodAdapter.unbox(Type.LONG_TYPE);
            break;
        case Type.SHORT:
            methodAdapter.cast(OBJECT_TYPE, Type.getType(Short.class));
            methodAdapter.unbox(Type.SHORT_TYPE);
            break;
        case Type.VOID:
            methodAdapter.cast(OBJECT_TYPE, Type.getType(Void.class));
            methodAdapter.unbox(Type.VOID_TYPE);
            break;
        default:
        case Type.OBJECT:
            // in this case check the cast and cast the object to the return
            // type
            methodAdapter.checkCast(returnType);
            methodAdapter.cast(OBJECT_TYPE, returnType);
            break;
    }
    // return the (appropriately cast) result of the invocation from the
    // stack
    methodAdapter.returnValue();
    // end the method
    methodAdapter.endMethod();
    LOGGER.debug(Constants.LOG_EXIT, "processMethod");
}
Also used : Method(org.objectweb.asm.commons.Method) MethodVisitor(org.objectweb.asm.MethodVisitor) Type(org.objectweb.asm.Type) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter)

Example 65 with Type

use of org.objectweb.asm.Type in project aries by apache.

the class ProxySubclassAdapter method addClassStaticField.

private void addClassStaticField(String classBinaryName) {
    LOGGER.debug(Constants.LOG_ENTRY, "addClassStaticField", new Object[] { classBinaryName });
    currentClassFieldName = classBinaryName.replaceAll("\\.", "_");
    /*
     * use Class.forName on the superclass so we can reflectively find
     * methods later
     * 
     * produces bytecode for retrieving the superclass and storing in a
     * private static field: private static Class superClass = null; static{
     * superClass = Class.forName(superclass, true, TYPE_BEING_PROXIED.class.getClassLoader()); }
     */
    // add a private static field for the superclass Class
    cv.visitField(ACC_PRIVATE | ACC_STATIC, currentClassFieldName, CLASS_TYPE.getDescriptor(), null, null);
    // push the String arg for the Class.forName onto the stack
    staticAdapter.push(classBinaryName);
    //push the boolean arg for the Class.forName onto the stack
    staticAdapter.push(true);
    //get the classloader
    staticAdapter.push(newClassType);
    staticAdapter.invokeVirtual(CLASS_TYPE, new Method("getClassLoader", CLASSLOADER_TYPE, NO_ARGS));
    // invoke the Class forName putting the Class on the stack
    staticAdapter.invokeStatic(CLASS_TYPE, new Method("forName", CLASS_TYPE, new Type[] { STRING_TYPE, Type.BOOLEAN_TYPE, CLASSLOADER_TYPE }));
    // put the Class in the static field
    staticAdapter.putStatic(newClassType, currentClassFieldName, CLASS_TYPE);
    LOGGER.debug(Constants.LOG_ENTRY, "addClassStaticField");
}
Also used : Type(org.objectweb.asm.Type) Method(org.objectweb.asm.commons.Method)

Aggregations

Type (org.objectweb.asm.Type)185 GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)39 MethodVisitor (org.objectweb.asm.MethodVisitor)34 Method (org.objectweb.asm.commons.Method)28 Label (org.objectweb.asm.Label)27 ClassWriter (org.objectweb.asm.ClassWriter)16 Method (java.lang.reflect.Method)13 ArrayList (java.util.ArrayList)12 ClassReader (org.objectweb.asm.ClassReader)10 AnnotationVisitor (org.objectweb.asm.AnnotationVisitor)9 ClassVisitor (org.objectweb.asm.ClassVisitor)9 ExprString (lucee.transformer.expression.ExprString)8 ModelType (org.gradle.model.internal.type.ModelType)7 LayoutlibDelegate (com.android.tools.layoutlib.annotations.LayoutlibDelegate)6 IOException (java.io.IOException)6 MethodType (java.lang.invoke.MethodType)6 HashMap (java.util.HashMap)6 List (java.util.List)6 LitString (lucee.transformer.expression.literal.LitString)6 PropertyAccessorType (org.gradle.internal.reflect.PropertyAccessorType)6