Search in sources :

Example 1 with INVOKESPECIAL

use of org.apache.xbean.asm9.Opcodes.INVOKESPECIAL in project openwebbeans by apache.

the class AbstractMetaDataDiscoveryTest method createBean.

private void createBean(final JarOutputStream outputStream, final String resource, final Class<?> itf) throws IOException {
    outputStream.putNextEntry(new JarEntry(resource));
    final ClassWriter writer = new ClassWriter(COMPUTE_FRAMES);
    // make it count for annotated mode
    writer.visitAnnotation(Type.getDescriptor(ApplicationScoped.class), true).visitEnd();
    writer.visit(V1_8, ACC_PUBLIC + ACC_SUPER, resource.substring(0, resource.length() - ".class".length()), null, Type.getInternalName(Object.class), itf == null ? null : new String[] { Type.getInternalName(itf) });
    writer.visitSource(resource.replace(".class", ".java"), null);
    final MethodVisitor constructor = writer.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
    constructor.visitCode();
    constructor.visitVarInsn(ALOAD, 0);
    constructor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
    constructor.visitInsn(RETURN);
    constructor.visitMaxs(1, 1);
    constructor.visitEnd();
    writer.visitEnd();
    outputStream.write(writer.toByteArray());
    outputStream.closeEntry();
}
Also used : JarEntry(java.util.jar.JarEntry) ClassWriter(org.apache.xbean.asm9.ClassWriter) MethodVisitor(org.apache.xbean.asm9.MethodVisitor)

Example 2 with INVOKESPECIAL

use of org.apache.xbean.asm9.Opcodes.INVOKESPECIAL in project component-runtime by Talend.

the class ProxyGenerator method delegateMethod.

private void delegateMethod(final ClassWriter cw, final Method method, final String proxyClassFileName, final int methodIndex) {
    final Class<?> returnType = method.getReturnType();
    final Class<?>[] parameterTypes = method.getParameterTypes();
    final Class<?>[] exceptionTypes = method.getExceptionTypes();
    final int modifiers = method.getModifiers();
    if (Modifier.isFinal(modifiers) || Modifier.isStatic(modifiers)) {
        throw new IllegalStateException("It's not possible to proxy a final or static method: " + method.getDeclaringClass().getName() + " " + method.getName());
    }
    // push the method definition
    int modifier = modifiers & (ACC_PUBLIC | ACC_PROTECTED | ACC_VARARGS);
    MethodVisitor mv = cw.visitMethod(modifier, method.getName(), Type.getMethodDescriptor(method), null, null);
    mv.visitCode();
    // push try/catch block, to catch declared exceptions, and to catch java.lang.Throwable
    final Label l0 = new Label();
    final Label l1 = new Label();
    final Label l2 = new Label();
    if (exceptionTypes.length > 0) {
        mv.visitTryCatchBlock(l0, l1, l2, "java/lang/reflect/InvocationTargetException");
    }
    // push try code
    mv.visitLabel(l0);
    final String classNameToOverride = method.getDeclaringClass().getName().replace('.', '/');
    mv.visitLdcInsn(Type.getType("L" + classNameToOverride + ";"));
    // the following code generates the bytecode for this line of Java:
    // Method method = <proxy>.class.getMethod("add", new Class[] { <array of function argument classes> });
    // get the method name to invoke, and push to stack
    mv.visitLdcInsn(method.getName());
    // create the Class[]
    createArrayDefinition(mv, parameterTypes.length, Class.class);
    int length = 1;
    // push parameters into array
    for (int i = 0; i < parameterTypes.length; i++) {
        // keep copy of array on stack
        mv.visitInsn(DUP);
        Class<?> parameterType = parameterTypes[i];
        // push number onto stack
        pushIntOntoStack(mv, i);
        if (parameterType.isPrimitive()) {
            String wrapperType = getWrapperType(parameterType);
            mv.visitFieldInsn(GETSTATIC, wrapperType, "TYPE", "Ljava/lang/Class;");
        } else {
            mv.visitLdcInsn(Type.getType(parameterType));
        }
        mv.visitInsn(AASTORE);
        if (Long.TYPE.equals(parameterType) || Double.TYPE.equals(parameterType)) {
            length += 2;
        } else {
            length++;
        }
    }
    // the following code generates bytecode equivalent to:
    // return ((<returntype>) invocationHandler.invoke(this, {methodIndex}, new Object[] { <function arguments
    // }))[.<primitive>Value()];
    final Label l4 = new Label();
    mv.visitLabel(l4);
    mv.visitVarInsn(ALOAD, 0);
    // get the invocationHandler field from this class
    mv.visitFieldInsn(GETFIELD, proxyClassFileName, FIELD_INTERCEPTOR_HANDLER, Type.getDescriptor(InterceptorHandler.class));
    // add the Method from the static array as first parameter
    mv.visitFieldInsn(GETSTATIC, proxyClassFileName, FIELD_INTERCEPTED_METHODS, Type.getDescriptor(Method[].class));
    // push the methodIndex of the current method
    if (methodIndex < 128) {
        mv.visitIntInsn(BIPUSH, methodIndex);
    } else if (methodIndex < 32267) {
        // for methods > 127 we need to push a short number as index
        mv.visitIntInsn(SIPUSH, methodIndex);
    } else {
        throw new IllegalStateException("Sorry, we only support Classes with 2^15 methods...");
    }
    // and now load the Method from the array
    mv.visitInsn(AALOAD);
    // prepare the parameter array as Object[] and store it on the stack
    pushMethodParameterArray(mv, parameterTypes);
    // invoke the invocationHandler
    mv.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(InterceptorHandler.class), "invoke", "(Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;", true);
    // cast the result
    mv.visitTypeInsn(CHECKCAST, getCastType(returnType));
    if (returnType.isPrimitive() && (!Void.TYPE.equals(returnType))) {
        // get the primitive value
        mv.visitMethodInsn(INVOKEVIRTUAL, getWrapperType(returnType), getPrimitiveMethod(returnType), "()" + Type.getDescriptor(returnType), false);
    }
    // push return
    mv.visitLabel(l1);
    if (!Void.TYPE.equals(returnType)) {
        mv.visitInsn(getReturnInsn(returnType));
    } else {
        mv.visitInsn(POP);
        mv.visitInsn(RETURN);
    }
    // catch InvocationTargetException
    if (exceptionTypes.length > 0) {
        mv.visitLabel(l2);
        mv.visitVarInsn(ASTORE, length);
        Label l5 = new Label();
        mv.visitLabel(l5);
        for (int i = 0; i < exceptionTypes.length; i++) {
            Class<?> exceptionType = exceptionTypes[i];
            mv.visitLdcInsn(Type.getType("L" + exceptionType.getCanonicalName().replace('.', '/') + ";"));
            mv.visitVarInsn(ALOAD, length);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/InvocationTargetException", "getCause", "()Ljava/lang/Throwable;", false);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", false);
            final Label l6 = new Label();
            mv.visitJumpInsn(IFEQ, l6);
            final Label l7 = new Label();
            mv.visitLabel(l7);
            mv.visitVarInsn(ALOAD, length);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/reflect/InvocationTargetException", "getCause", "()Ljava/lang/Throwable;", false);
            mv.visitTypeInsn(CHECKCAST, getCastType(exceptionType));
            mv.visitInsn(ATHROW);
            mv.visitLabel(l6);
            if (i == (exceptionTypes.length - 1)) {
                mv.visitTypeInsn(NEW, "java/lang/reflect/UndeclaredThrowableException");
                mv.visitInsn(DUP);
                mv.visitVarInsn(ALOAD, length);
                mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/UndeclaredThrowableException", "<init>", "(Ljava/lang/Throwable;)V", false);
                mv.visitInsn(ATHROW);
            }
        }
    }
    // finish this method
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}
Also used : InterceptorHandler(org.talend.sdk.component.api.service.interceptor.InterceptorHandler) Label(org.apache.xbean.asm9.Label) MethodVisitor(org.apache.xbean.asm9.MethodVisitor)

Example 3 with INVOKESPECIAL

use of org.apache.xbean.asm9.Opcodes.INVOKESPECIAL in project component-runtime by Talend.

the class ProxyGenerator method createConstructor.

private String createConstructor(final ClassWriter cw, final Class<?> classToProxy, final String classFileName, final String proxyClassFileName, final Constructor<?> constructor, final boolean withInterceptors) {
    try {
        Constructor superDefaultCt;
        String parentClassFileName;
        String[] exceptions = null;
        if (classToProxy.isInterface()) {
            parentClassFileName = Type.getInternalName(Object.class);
            superDefaultCt = Object.class.getConstructor();
        } else {
            parentClassFileName = classFileName;
            if (constructor == null) {
                superDefaultCt = classToProxy.getConstructor();
            } else {
                superDefaultCt = constructor;
                Class<?>[] exceptionTypes = constructor.getExceptionTypes();
                exceptions = exceptionTypes.length == 0 ? null : new String[exceptionTypes.length];
                for (int i = 0; i < exceptionTypes.length; i++) {
                    exceptions[i] = Type.getInternalName(exceptionTypes[i]);
                }
            }
        }
        final String descriptor = Type.getConstructorDescriptor(superDefaultCt);
        final MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", descriptor, null, exceptions);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        if (constructor != null) {
            for (int i = 1; i <= constructor.getParameterTypes().length; i++) {
                mv.visitVarInsn(ALOAD, i);
            }
        }
        mv.visitMethodInsn(INVOKESPECIAL, parentClassFileName, "<init>", descriptor, false);
        if (withInterceptors) {
            mv.visitVarInsn(ALOAD, 0);
            mv.visitInsn(ACONST_NULL);
            mv.visitFieldInsn(PUTFIELD, proxyClassFileName, FIELD_INTERCEPTOR_HANDLER, Type.getDescriptor(InterceptorHandler.class));
        }
        mv.visitInsn(RETURN);
        mv.visitMaxs(-1, -1);
        mv.visitEnd();
        return parentClassFileName;
    } catch (final NoSuchMethodException e) {
        throw new IllegalStateException(e);
    }
}
Also used : InterceptorHandler(org.talend.sdk.component.api.service.interceptor.InterceptorHandler) Constructor(java.lang.reflect.Constructor) AllArgsConstructor(lombok.AllArgsConstructor) MethodVisitor(org.apache.xbean.asm9.MethodVisitor)

Example 4 with INVOKESPECIAL

use of org.apache.xbean.asm9.Opcodes.INVOKESPECIAL in project tomee by apache.

the class DynamicSubclass method visitConstructor.

private static MethodVisitor visitConstructor(final ClassWriter cw, final String proxyClassFileName, final String classFileName, final Constructor<?> constructor) {
    final String descriptor = Type.getConstructorDescriptor(constructor);
    final String[] exceptions = new String[constructor.getExceptionTypes().length];
    for (int i = 0; i < exceptions.length; i++) {
        exceptions[i] = Type.getInternalName(constructor.getExceptionTypes()[i]);
    }
    final MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", descriptor, null, exceptions);
    mv.visitCode();
    mv.visitVarInsn(ALOAD, 0);
    int index = 1;
    for (final Type type : Type.getArgumentTypes(descriptor)) {
        mv.visitVarInsn(type.getOpcode(ILOAD), index);
        index += size(type);
    }
    mv.visitMethodInsn(INVOKESPECIAL, classFileName, "<init>", descriptor, false);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(PUTFIELD, proxyClassFileName, "this$handler", "Ljava/lang/reflect/InvocationHandler;");
    mv.visitInsn(RETURN);
    mv.visitMaxs(2, 1);
    return mv;
}
Also used : Type(org.apache.xbean.asm9.Type) MethodVisitor(org.apache.xbean.asm9.MethodVisitor)

Example 5 with INVOKESPECIAL

use of org.apache.xbean.asm9.Opcodes.INVOKESPECIAL in project tomee by apache.

the class MakeTxLookup method createNewHibernateStrategy.

private static void createNewHibernateStrategy(final File basedir, final String target, final String abstractJtaPlatformPackage) throws Exception {
    final ClassWriter cw = new ClassWriter(0);
    MethodVisitor mv;
    cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, target.replace('.', '/'), null, abstractJtaPlatformPackage + "/AbstractJtaPlatform", null);
    {
        mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, abstractJtaPlatformPackage + "/AbstractJtaPlatform", "<init>", "()V", false);
        mv.visitInsn(RETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(ACC_PROTECTED, "locateTransactionManager", "()Ljakarta/transaction/TransactionManager;", null, null);
        mv.visitCode();
        mv.visitMethodInsn(INVOKESTATIC, "org/apache/openejb/OpenEJB", "getTransactionManager", "()Ljakarta/transaction/TransactionManager;", false);
        mv.visitInsn(ARETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(ACC_PROTECTED, "locateUserTransaction", "()Ljakarta/transaction/UserTransaction;", null, null);
        mv.visitCode();
        final Label l0 = new Label();
        final Label l1 = new Label();
        final Label l2 = new Label();
        mv.visitTryCatchBlock(l0, l1, l2, "javax/naming/NamingException");
        mv.visitLabel(l0);
        mv.visitMethodInsn(INVOKESTATIC, "org/apache/openejb/loader/SystemInstance", "get", "()Lorg/apache/openejb/loader/SystemInstance;", false);
        mv.visitLdcInsn(Type.getType("Lorg/apache/openejb/spi/ContainerSystem;"));
        mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/openejb/loader/SystemInstance", "getComponent", "(Ljava/lang/Class;)Ljava/lang/Object;", false);
        mv.visitTypeInsn(CHECKCAST, "org/apache/openejb/spi/ContainerSystem");
        mv.visitMethodInsn(INVOKEINTERFACE, "org/apache/openejb/spi/ContainerSystem", "getJNDIContext", "()Ljavax/naming/Context;", true);
        mv.visitLdcInsn("comp/UserTransaction");
        mv.visitMethodInsn(INVOKEINTERFACE, "javax/naming/Context", "lookup", "(Ljava/lang/String;)Ljava/lang/Object;", true);
        mv.visitTypeInsn(CHECKCAST, "jakarta/transaction/UserTransaction");
        mv.visitLabel(l1);
        mv.visitInsn(ARETURN);
        mv.visitLabel(l2);
        mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "javax/naming/NamingException" });
        mv.visitVarInsn(ASTORE, 1);
        mv.visitInsn(ACONST_NULL);
        mv.visitInsn(ARETURN);
        mv.visitMaxs(2, 2);
        mv.visitEnd();
    }
    cw.visitEnd();
    write(basedir, cw, target.replace('.', '/'));
}
Also used : Label(org.apache.xbean.asm9.Label) ClassWriter(org.apache.xbean.asm9.ClassWriter) MethodVisitor(org.apache.xbean.asm9.MethodVisitor)

Aggregations

MethodVisitor (org.apache.xbean.asm9.MethodVisitor)20 ClassWriter (org.apache.xbean.asm9.ClassWriter)9 Label (org.apache.xbean.asm9.Label)6 ZipEntry (java.util.zip.ZipEntry)3 AnnotationVisitor (org.apache.xbean.asm9.AnnotationVisitor)3 Type (org.apache.xbean.asm9.Type)2 InterceptorHandler (org.talend.sdk.component.api.service.interceptor.InterceptorHandler)2 File (java.io.File)1 FileOutputStream (java.io.FileOutputStream)1 IOException (java.io.IOException)1 Constructor (java.lang.reflect.Constructor)1 Field (java.lang.reflect.Field)1 JarEntry (java.util.jar.JarEntry)1 JarOutputStream (java.util.jar.JarOutputStream)1 AllArgsConstructor (lombok.AllArgsConstructor)1 ProxyGenerationException (org.apache.openejb.util.proxy.ProxyGenerationException)1 ClassReader (org.apache.xbean.asm9.ClassReader)1 Processor (org.talend.sdk.component.api.processor.Processor)1 Action (org.talend.sdk.component.api.service.Action)1