Example usage for org.objectweb.asm MethodVisitor visitLabel

List of usage examples for org.objectweb.asm MethodVisitor visitLabel

Introduction

In this page you can find the example usage for org.objectweb.asm MethodVisitor visitLabel.

Prototype

public void visitLabel(final Label label) 

Source Link

Document

Visits a label.

Usage

From source file:net.wpm.reflectasm.ClassAccess.java

License:Open Source License

private static void insertInvoke(ClassWriter cw, String classNameInternal, List<Method> methods) {
    MethodVisitor mv;
    mv = cw.visitMethod(ACC_PUBLIC + ACC_VARARGS, "invoke",
            "(Ljava/lang/Object;I[Ljava/lang/Object;)Ljava/lang/Object;", null, null);
    mv.visitCode();//from  w  w  w  .j  a v  a2  s  .  com

    int n = methods.size();

    if (n != 0) {
        mv.visitVarInsn(ILOAD, 2);
        Label[] labels = new Label[n];
        for (int i = 0; i < n; i++)
            labels[i] = new Label();
        Label defaultLabel = new Label();
        mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);

        StringBuilder buffer = new StringBuilder(128);
        for (int i = 0; i < n; i++) {
            Method method = methods.get(i);
            boolean isInterface = method.getDeclaringClass().isInterface();
            boolean isStatic = isStatic(method.getModifiers());

            mv.visitLabel(labels[i]);
            if (i == 0)
                mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { classNameInternal }, 0, null);
            else
                mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);

            if (!isStatic) {
                mv.visitVarInsn(ALOAD, 1);
                mv.visitTypeInsn(CHECKCAST, classNameInternal);
            }

            buffer.setLength(0);
            buffer.append('(');

            String methodName = method.getName();
            Class<?>[] paramTypes = method.getParameterTypes();
            Class<?> returnType = method.getReturnType();
            for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
                mv.visitVarInsn(ALOAD, 3);
                mv.visitIntInsn(BIPUSH, paramIndex);
                mv.visitInsn(AALOAD);
                Type paramType = Type.getType(paramTypes[paramIndex]);
                unbox(mv, paramType);
                buffer.append(paramType.getDescriptor());
            }

            buffer.append(')');
            buffer.append(Type.getDescriptor(returnType));
            final int inv = isInterface ? INVOKEINTERFACE : (isStatic ? INVOKESTATIC : INVOKEVIRTUAL);
            mv.visitMethodInsn(inv, classNameInternal, methodName, buffer.toString(), isInterface);

            final Type retType = Type.getType(returnType);
            box(mv, retType);
            mv.visitInsn(ARETURN);
        }

        mv.visitLabel(defaultLabel);
        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    }
    mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException");
    mv.visitInsn(DUP);
    mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
    mv.visitInsn(DUP);
    mv.visitLdcInsn("Method not found: ");
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false);
    mv.visitVarInsn(ILOAD, 2);
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;",
            false);
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V",
            false);
    mv.visitInsn(ATHROW);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:net.wpm.reflectasm.ClassAccess.java

License:Open Source License

static private void insertSetObject(ClassWriter cw, String classNameInternal, List<Field> fields) {
    int maxStack = 6;
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "set", "(Ljava/lang/Object;ILjava/lang/Object;)V", null,
            null);/*from www  .ja  v  a  2  s .co m*/
    mv.visitCode();
    mv.visitVarInsn(ILOAD, 2);

    if (!fields.isEmpty()) {
        maxStack--;
        Label[] labels = new Label[fields.size()];
        for (int i = 0, n = labels.length; i < n; i++)
            labels[i] = new Label();
        Label defaultLabel = new Label();
        mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);

        for (int i = 0, n = labels.length; i < n; i++) {
            Field field = fields.get(i);
            Type fieldType = Type.getType(field.getType());
            boolean st = isStatic(field.getModifiers());

            mv.visitLabel(labels[i]);
            mv.visitFrame(F_SAME, 0, null, 0, null);
            if (!st) {
                mv.visitVarInsn(ALOAD, 1);
                mv.visitTypeInsn(CHECKCAST, classNameInternal);
            }
            mv.visitVarInsn(ALOAD, 3);

            unbox(mv, fieldType);

            mv.visitFieldInsn(st ? PUTSTATIC : PUTFIELD, classNameInternal, field.getName(),
                    fieldType.getDescriptor());
            mv.visitInsn(RETURN);
        }

        mv.visitLabel(defaultLabel);
        mv.visitFrame(F_SAME, 0, null, 0, null);
    }
    mv = insertThrowExceptionForFieldNotFound(mv);
    mv.visitMaxs(maxStack, 4);
    mv.visitEnd();
}

From source file:net.wpm.reflectasm.ClassAccess.java

License:Open Source License

static private void insertGetObject(ClassWriter cw, String classNameInternal, List<Field> fields) {
    int maxStack = 6;
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "get", "(Ljava/lang/Object;I)Ljava/lang/Object;", null, null);
    mv.visitCode();//w w  w .  j a  v a  2 s  .  c om
    mv.visitVarInsn(ILOAD, 2);

    if (!fields.isEmpty()) {
        maxStack--;
        Label[] labels = new Label[fields.size()];
        for (int i = 0, n = labels.length; i < n; i++)
            labels[i] = new Label();
        Label defaultLabel = new Label();
        mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);

        for (int i = 0, n = labels.length; i < n; i++) {
            Field field = fields.get(i);
            mv.visitLabel(labels[i]);
            mv.visitFrame(F_SAME, 0, null, 0, null);
            if (isStatic(field.getModifiers())) {
                mv.visitFieldInsn(GETSTATIC, classNameInternal, field.getName(),
                        Type.getDescriptor(field.getType()));
            } else {
                mv.visitVarInsn(ALOAD, 1);
                mv.visitTypeInsn(CHECKCAST, classNameInternal);
                mv.visitFieldInsn(GETFIELD, classNameInternal, field.getName(),
                        Type.getDescriptor(field.getType()));
            }
            Type fieldType = Type.getType(field.getType());
            box(mv, fieldType);
            mv.visitInsn(ARETURN);
        }
        mv.visitLabel(defaultLabel);
        mv.visitFrame(F_SAME, 0, null, 0, null);
    }
    insertThrowExceptionForFieldNotFound(mv);
    mv.visitMaxs(maxStack, 3);
    mv.visitEnd();
}

From source file:net.wpm.reflectasm.ClassAccess.java

License:Open Source License

static private void insertSetPrimitive(ClassWriter cw, String classNameInternal, List<Field> fields,
        Type primitiveType, String setterMethodName, int loadValueInstruction) {
    int maxStack = 6;
    int maxLocals = 5;
    final String typeNameInternal = primitiveType.getDescriptor();
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, setterMethodName,
            "(Ljava/lang/Object;I" + typeNameInternal + ")V", null, null);
    mv.visitCode();/*from www .  j  a  va  2 s.  c  o  m*/
    mv.visitVarInsn(ILOAD, 2);

    if (!fields.isEmpty()) {
        maxStack--;
        Label[] labels = new Label[fields.size()];
        Label labelForInvalidTypes = new Label();
        boolean hasAnyBadTypeLabel = false;
        for (int i = 0, n = labels.length; i < n; i++) {
            if (Type.getType(fields.get(i).getType()).equals(primitiveType))
                labels[i] = new Label();
            else {
                labels[i] = labelForInvalidTypes;
                hasAnyBadTypeLabel = true;
            }
        }
        Label defaultLabel = new Label();
        mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);

        for (int i = 0, n = labels.length; i < n; i++) {
            if (!labels[i].equals(labelForInvalidTypes)) {
                Field field = fields.get(i);
                mv.visitLabel(labels[i]);
                mv.visitFrame(F_SAME, 0, null, 0, null);
                if (isStatic(field.getModifiers())) {
                    mv.visitVarInsn(loadValueInstruction, 3);
                    mv.visitFieldInsn(PUTSTATIC, classNameInternal, field.getName(), typeNameInternal);
                } else {
                    mv.visitVarInsn(ALOAD, 1);
                    mv.visitTypeInsn(CHECKCAST, classNameInternal);
                    mv.visitVarInsn(loadValueInstruction, 3);
                    mv.visitFieldInsn(PUTFIELD, classNameInternal, field.getName(), typeNameInternal);
                }
                mv.visitInsn(RETURN);
            }
        }
        // Rest of fields: different type
        if (hasAnyBadTypeLabel) {
            mv.visitLabel(labelForInvalidTypes);
            mv.visitFrame(F_SAME, 0, null, 0, null);
            insertThrowExceptionForFieldType(mv, primitiveType.getClassName());
        }
        // Default: field not found
        mv.visitLabel(defaultLabel);
        mv.visitFrame(F_SAME, 0, null, 0, null);
    }
    mv = insertThrowExceptionForFieldNotFound(mv);
    mv.visitMaxs(maxStack, maxLocals);
    mv.visitEnd();
}

From source file:net.wpm.reflectasm.ClassAccess.java

License:Open Source License

static private void insertGetPrimitive(ClassWriter cw, String classNameInternal, List<Field> fields,
        Type primitiveType, String getterMethodName, int returnValueInstruction) {
    int maxStack = 6;
    final String typeNameInternal = primitiveType.getDescriptor();
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, getterMethodName, "(Ljava/lang/Object;I)" + typeNameInternal,
            null, null);/*w  ww. j a  v a 2s .  com*/
    mv.visitCode();
    mv.visitVarInsn(ILOAD, 2);

    if (!fields.isEmpty()) {
        maxStack--;
        Label[] labels = new Label[fields.size()];
        Label labelForInvalidTypes = new Label();
        boolean hasAnyBadTypeLabel = false;
        for (int i = 0, n = labels.length; i < n; i++) {
            if (Type.getType(fields.get(i).getType()).equals(primitiveType))
                labels[i] = new Label();
            else {
                labels[i] = labelForInvalidTypes;
                hasAnyBadTypeLabel = true;
            }
        }
        Label defaultLabel = new Label();
        mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);

        for (int i = 0, n = labels.length; i < n; i++) {
            Field field = fields.get(i);
            if (!labels[i].equals(labelForInvalidTypes)) {
                mv.visitLabel(labels[i]);
                mv.visitFrame(F_SAME, 0, null, 0, null);
                if (isStatic(field.getModifiers())) {
                    mv.visitFieldInsn(GETSTATIC, classNameInternal, field.getName(), typeNameInternal);
                } else {
                    mv.visitVarInsn(ALOAD, 1);
                    mv.visitTypeInsn(CHECKCAST, classNameInternal);
                    mv.visitFieldInsn(GETFIELD, classNameInternal, field.getName(), typeNameInternal);
                }
                mv.visitInsn(returnValueInstruction);
            }
        }
        // Rest of fields: different type
        if (hasAnyBadTypeLabel) {
            mv.visitLabel(labelForInvalidTypes);
            mv.visitFrame(F_SAME, 0, null, 0, null);
            insertThrowExceptionForFieldType(mv, primitiveType.getClassName());
        }
        // Default: field not found
        mv.visitLabel(defaultLabel);
        mv.visitFrame(F_SAME, 0, null, 0, null);
    }
    mv = insertThrowExceptionForFieldNotFound(mv);
    mv.visitMaxs(maxStack, 3);
    mv.visitEnd();

}

From source file:one.nio.http.gen.RequestHandlerGenerator.java

License:Apache License

private void convertArgument(MethodVisitor mv, Class type, boolean needNullCheck) {
    if (type == String.class) {
        return; // nothing to do
    }/*  w  w  w.ja  va 2 s . c o  m*/

    if (type.isPrimitive()) {
        if (type == int.class) {
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "parseInt", "(Ljava/lang/String;)I");
        } else if (type == long.class) {
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "parseLong", "(Ljava/lang/String;)J");
        } else if (type == byte.class) {
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "parseByte", "(Ljava/lang/String;)B");
        } else if (type == short.class) {
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "parseShort", "(Ljava/lang/String;)S");
        } else if (type == float.class) {
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "parseFloat", "(Ljava/lang/String;)F");
        } else if (type == double.class) {
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "parseDouble", "(Ljava/lang/String;)D");
        } else if (type == boolean.class) {
            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "parseBoolean", "(Ljava/lang/String;)Z");
        } else if (type == char.class) {
            mv.visitInsn(ICONST_0);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C");
        }
        return;
    }

    Label isNull = new Label();
    if (needNullCheck) {
        Label nonNull = new Label();
        mv.visitInsn(DUP);
        mv.visitJumpInsn(IFNONNULL, nonNull);
        mv.visitInsn(POP);
        mv.visitInsn(ACONST_NULL);
        mv.visitJumpInsn(GOTO, isNull);
        mv.visitLabel(nonNull);
    }

    if (type == Integer.class) {
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf",
                "(Ljava/lang/String;)Ljava/lang/Integer;");
    } else if (type == Long.class) {
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(Ljava/lang/String;)Ljava/lang/Long;");
    } else if (type == Byte.class) {
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(Ljava/lang/String;)Ljava/lang/Byte;");
    } else if (type == Short.class) {
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(Ljava/lang/String;)Ljava/lang/Short;");
    } else if (type == Float.class) {
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(Ljava/lang/String;)Ljava/lang/Float;");
    } else if (type == Double.class) {
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf",
                "(Ljava/lang/String;)Ljava/lang/Double;");
    } else if (type == Boolean.class) {
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf",
                "(Ljava/lang/String;)Ljava/lang/Boolean;");
    } else {
        throw new IllegalArgumentException("Unsupported argument type: " + type.getName());
    }

    if (needNullCheck) {
        mv.visitLabel(isNull);
    }
}

From source file:org.actorsguildframework.internal.codegenerator.ActorProxyCreator.java

License:Apache License

/**
 * Create or get a MessageCaller implementation for the given method.
 * @param ownerClass the class that owns the message
 * @param method the method to invoke//from ww  w  . j  a v a 2 s  . co m
 * @return the message caller
 * @throws NoSuchMethodException 
 * @throws SecurityException 
 */
@SuppressWarnings("unchecked")
public static Class<MessageCaller<?>> createMessageCaller(Class<?> ownerClass, Method method)
        throws SecurityException, NoSuchMethodException {

    String className = String.format("%s_%s_%d__MESSAGECALLER", ownerClass.getName(), method.getName(),
            getMethodNumber(method));
    String classNameInternal = className.replace('.', '/');
    java.lang.reflect.Type fullReturnType = method.getGenericReturnType();
    if ((!(fullReturnType instanceof ParameterizedType))
            && AsyncResult.class.isAssignableFrom(((Class) ((ParameterizedType) fullReturnType).getRawType())))
        throw new RuntimeException("Something's wrong here: should not be called for such a method");
    String returnSignature = GenericTypeHelper
            .getSignature(((ParameterizedType) fullReturnType).getActualTypeArguments()[0]);

    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
    MethodVisitor mv;

    cw.visit(codeVersion, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER + Opcodes.ACC_SYNTHETIC,
            classNameInternal, "L" + classNameInternal + "<" + returnSignature + ">;",
            "org/actorsguildframework/internal/MessageCaller", null);
    cw.visitSource(null, null);

    {
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "org/actorsguildframework/internal/MessageCaller", "<init>",
                "()V");
        mv.visitInsn(Opcodes.RETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", "L" + classNameInternal + ";", null, l0, l1, 0);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "invoke",
                "(Lorg/actorsguildframework/Actor;[Ljava/lang/Object;)Lorg/actorsguildframework/AsyncResult;",
                "(Lorg/actorsguildframework/Actor;[Ljava/lang/Object;)Lorg/actorsguildframework/AsyncResult<"
                        + returnSignature + ">;",
                null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);

        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(method.getDeclaringClass()) + "__ACTORPROXY");

        int idx = 0;
        for (Class<?> t : method.getParameterTypes()) {
            mv.visitVarInsn(Opcodes.ALOAD, 2);
            mv.visitIntInsn(Opcodes.BIPUSH, idx);
            mv.visitInsn(Opcodes.AALOAD);
            if (t.isPrimitive()) {
                String wrapperDescr = GenerationUtils.getWrapperInternalName(t);
                mv.visitTypeInsn(Opcodes.CHECKCAST, wrapperDescr);
                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, wrapperDescr, t.getName() + "Value",
                        "()" + Type.getDescriptor(t));
            } else {
                if (isArgumentFreezingRequired(method, idx, t)) {
                    mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(SerializableFreezer.class));
                    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(SerializableFreezer.class),
                            "get", Type.getMethodDescriptor(SerializableFreezer.class.getMethod("get")));
                }
                if (!t.equals(Object.class))
                    mv.visitTypeInsn(Opcodes.CHECKCAST, Type.getInternalName(t));
            }
            idx++;
        }
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                Type.getInternalName(method.getDeclaringClass()) + "__ACTORPROXY",
                String.format(SUPER_CALLER_NAME_FORMAT, method.getName()), Type.getMethodDescriptor(method));

        mv.visitInsn(Opcodes.ARETURN);

        Label l2 = new Label();
        mv.visitLabel(l2);
        mv.visitLocalVariable("this", "L" + classNameInternal + ";", null, l0, l2, 0);
        mv.visitLocalVariable("instance", "Lorg/actorsguildframework/Actor;", null, l0, l2, 1);
        mv.visitLocalVariable("arguments", "[Ljava/lang/Object;", null, l0, l2, 2);

        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getMessageName", "()Ljava/lang/String;", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitLdcInsn(method.getName());
        mv.visitInsn(Opcodes.ARETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", "L" + classNameInternal + ";", null, l0, l1, 0);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }
    cw.visitEnd();

    return (Class<MessageCaller<?>>) GenerationUtils.loadClass(className, cw.toByteArray());
}

From source file:org.actorsguildframework.internal.codegenerator.ActorProxyCreator.java

License:Apache License

/**
 * Creates a synchronized delegate method for a message method.
 * @param actorClass the actor class/* w w  w.j av a  2  s. co m*/
 * @param classNameDescriptor the descriptor of the resulting class
 * @param cw the class writer to write to
 * @param method the method being invoked
 * @param simpleDescriptor the descriptor of the method
 * @param genericSignature the generic signature of the method
 * @param isSynchronized true to make the method synchronized, false otherwise
 */
private static void writeSuperProxyMethod(Class<?> actorClass, String classNameDescriptor, ClassWriter cw,
        Method method, String simpleDescriptor, String genericSignature, boolean isSynchronized)
        throws NoSuchMethodException {
    MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC + (isSynchronized ? Opcodes.ACC_SYNCHRONIZED : 0),
            String.format(SUPER_CALLER_NAME_FORMAT, method.getName()), simpleDescriptor, genericSignature,
            null);
    mv.visitCode();
    Label l0 = new Label();
    mv.visitLabel(l0);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    for (int j = 0; j < method.getParameterTypes().length; j++)
        mv.visitVarInsn(Type.getType(method.getParameterTypes()[j]).getOpcode(Opcodes.ILOAD), j + 1);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(actorClass), method.getName(),
            simpleDescriptor);
    mv.visitInsn(Type.getType(method.getReturnType()).getOpcode(Opcodes.IRETURN));
    Label l1 = new Label();
    mv.visitLabel(l1);
    mv.visitLocalVariable("this", classNameDescriptor, null, l0, l1, 0);
    for (int j = 0; j < method.getParameterTypes().length; j++)
        mv.visitLocalVariable("arg" + j, Type.getDescriptor(method.getParameterTypes()[j]),
                GenericTypeHelper.getSignatureIfGeneric(method.getGenericParameterTypes()[j]), l0, l1, j + 1);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:org.actorsguildframework.internal.codegenerator.ActorProxyCreator.java

License:Apache License

/**
 * Creates and loads the actor's proxy class.
 * @param actorClass the Actor class/* ww  w  . ja v a  2  s  . c o m*/
 * @param acd the actor's class descriptor
 * @throws ConfigurationException if the agent is not configured correctly
 */
@SuppressWarnings("unchecked")
private static Class<?> generateProxyClass(Class<?> actorClass, final ActorClassDescriptor acd)
        throws NoSuchMethodException {
    BeanClassDescriptor bcd = acd.getBeanClassDescriptor();

    String className = String.format("%s__ACTORPROXY", actorClass.getName());
    final String classNameInternal = className.replace('.', '/');
    String classNameDescriptor = "L" + classNameInternal + ";";

    final Type actorState = Type
            .getType(acd.getConcurrencyModel().isMultiThreadingCapable() ? MultiThreadedActorState.class
                    : SingleThreadedActorState.class);

    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
    MethodVisitor mv;
    cw.visit(codeVersion, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER + Opcodes.ACC_SYNTHETIC,
            classNameInternal, null, Type.getInternalName(actorClass),
            new String[] { "org/actorsguildframework/internal/ActorProxy" });

    cw.visitSource(null, null);

    {
        for (int i = 0; i < acd.getMessageCount(); i++)
            cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL + Opcodes.ACC_STATIC,
                    String.format(MESSAGE_CALLER_NAME_FORMAT, i),
                    "Lorg/actorsguildframework/internal/MessageCaller;",
                    "Lorg/actorsguildframework/internal/MessageCaller<*>;", null).visitEnd();

        cw.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL, "actorState__ACTORPROXY",
                actorState.getDescriptor(), null, null).visitEnd();
    }

    BeanCreator.writePropFields(bcd, cw);

    {
        mv = cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
        mv.visitCode();

        for (int i = 0; i < acd.getMessageCount(); i++) {
            Class<?> caller = createMessageCaller(acd.getMessage(i).getOwnerClass(),
                    acd.getMessage(i).getMethod());
            String mcName = Type.getInternalName(caller);
            mv.visitTypeInsn(Opcodes.NEW, mcName);
            mv.visitInsn(Opcodes.DUP);
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, mcName, "<init>", "()V");
            mv.visitFieldInsn(Opcodes.PUTSTATIC, classNameInternal,
                    String.format(MESSAGE_CALLER_NAME_FORMAT, i),
                    "Lorg/actorsguildframework/internal/MessageCaller;");
        }
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }

    BeanCreator.writeConstructor(actorClass, bcd, classNameInternal, cw, new BeanCreator.SnippetWriter() {
        @Override
        public void write(MethodVisitor mv) {
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitTypeInsn(Opcodes.NEW, actorState.getInternalName());
            mv.visitInsn(Opcodes.DUP);
            mv.visitVarInsn(Opcodes.ALOAD, 1);
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, actorState.getInternalName(), "<init>",
                    "(Lorg/actorsguildframework/internal/Controller;Lorg/actorsguildframework/Actor;)V");
            mv.visitFieldInsn(Opcodes.PUTFIELD, classNameInternal, "actorState__ACTORPROXY",
                    actorState.getDescriptor());
        }
    });

    BeanCreator.writePropAccessors(bcd, classNameInternal, cw);

    {
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "getState__ACTORPROXYMETHOD",
                "()Lorg/actorsguildframework/internal/ActorState;", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, classNameInternal, "actorState__ACTORPROXY",
                actorState.getDescriptor());
        mv.visitInsn(Opcodes.ARETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", classNameDescriptor, null, l0, l1, 0);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }

    for (int i = 0; i < acd.getMessageCount(); i++) {
        MessageImplDescriptor mid = acd.getMessage(i);
        Method method = mid.getMethod();
        String simpleDescriptor = Type.getMethodDescriptor(method);
        String genericSignature = GenericTypeHelper.getSignature(method);

        writeProxyMethod(classNameInternal, classNameDescriptor, cw, i, actorState, acd.getConcurrencyModel(),
                mid, method, simpleDescriptor, genericSignature);

        writeSuperProxyMethod(actorClass, classNameDescriptor, cw, method, simpleDescriptor, genericSignature,
                !acd.getConcurrencyModel().isMultiThreadingCapable());
    }

    {
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_SYNCHRONIZED, "toString", "()Ljava/lang/String;",
                null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "toString", "()Ljava/lang/String;");
        mv.visitInsn(Opcodes.ARETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", classNameDescriptor, null, l0, l1, 0);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }
    cw.visitEnd();

    try {
        return (Class<? extends ActorProxy>) GenerationUtils.loadClass(className, cw.toByteArray());
    } catch (Exception e) {
        throw new ConfigurationException("Failure loading ActorProxy", e);
    }
}

From source file:org.actorsguildframework.internal.codegenerator.ActorProxyCreator.java

License:Apache License

/**
 * Writes a proxy method for messages.//from w w w .j a v a2s.c o m
 * @param classNameInternal the internal class name
 * @param classNameDescriptor the class name descriptor
 * @param cw the ClassWriter
 * @param index the message index
 * @param type the ActorState type to use
 * @param concurrencyModel the concurrency model of the message
 * @param messageDescriptor the message's descriptor
 * @param method the method to override
 * @param simpleDescriptor a simple descriptor of the message
 * @param genericSignature the signature of the message
 */
private static void writeProxyMethod(String classNameInternal, String classNameDescriptor, ClassWriter cw,
        int index, Type actorState, ConcurrencyModel concurrencyModel, MessageImplDescriptor messageDescriptor,
        Method method, String simpleDescriptor, String genericSignature) throws NoSuchMethodException {
    MethodVisitor mv;
    {
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, method.getName(), simpleDescriptor, genericSignature, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitIntInsn(Opcodes.BIPUSH, method.getParameterTypes().length);
        mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
        for (int j = 0; j < method.getParameterTypes().length; j++) {
            mv.visitInsn(Opcodes.DUP);
            mv.visitIntInsn(Opcodes.BIPUSH, j);
            Class<?> paraType = method.getParameterTypes()[j];
            if (paraType.isPrimitive()) {
                String wrapperClass = GenerationUtils.getWrapperInternalName(paraType);
                Type primType = Type.getType(paraType);
                mv.visitVarInsn(primType.getOpcode(Opcodes.ILOAD), j + 1);
                mv.visitMethodInsn(Opcodes.INVOKESTATIC, wrapperClass, "valueOf",
                        "(" + primType.getDescriptor() + ")" + "L" + wrapperClass + ";");
            } else if (isArgumentFreezingRequired(method, j, paraType)) {
                mv.visitVarInsn(Opcodes.ALOAD, j + 1);
                mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(SerializableFreezer.class),
                        "freeze",
                        Type.getMethodDescriptor(SerializableFreezer.class.getMethod("freeze", Object.class)));
            } else if (paraType.isInterface()) {
                mv.visitVarInsn(Opcodes.ALOAD, j + 1);
                mv.visitInsn(Opcodes.DUP);
                mv.visitTypeInsn(Opcodes.INSTANCEOF, "org/actorsguildframework/Actor");
                Label lEndif = new Label();
                mv.visitJumpInsn(Opcodes.IFNE, lEndif);
                mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(ActorRuntimeException.class));
                mv.visitInsn(Opcodes.DUP);
                mv.visitLdcInsn(String.format(
                        "Argument %d is an non-Serializable interface, but you did not give an Actor. If a message's argument type is an interface that does not extend Serializable, only Actors are acceptable as argument.",
                        j));
                mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(ActorRuntimeException.class),
                        "<init>", "(Ljava/lang/String;)V");
                mv.visitInsn(Opcodes.ATHROW);
                mv.visitLabel(lEndif);
            } else
                mv.visitVarInsn(Opcodes.ALOAD, j + 1);

            mv.visitInsn(Opcodes.AASTORE);
        }
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitVarInsn(Opcodes.ASTORE, method.getParameterTypes().length + 1); // method.getParameterTypes().length+1 ==> 'args' local variable
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, classNameInternal, "actorState__ACTORPROXY",
                actorState.getDescriptor());
        mv.visitFieldInsn(Opcodes.GETSTATIC, classNameInternal,
                String.format(MESSAGE_CALLER_NAME_FORMAT, index),
                "Lorg/actorsguildframework/internal/MessageCaller;");
        mv.visitFieldInsn(Opcodes.GETSTATIC, "org/actorsguildframework/annotations/ThreadUsage",
                messageDescriptor.getThreadUsage().name(),
                "Lorg/actorsguildframework/annotations/ThreadUsage;");
        mv.visitVarInsn(Opcodes.ALOAD, method.getParameterTypes().length + 1);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, actorState.getInternalName(), "queueMessage",
                "(Lorg/actorsguildframework/internal/MessageCaller;Lorg/actorsguildframework/annotations/ThreadUsage;[Ljava/lang/Object;)Lorg/actorsguildframework/internal/AsyncResultImpl;");
        mv.visitInsn(Opcodes.ARETURN);
        Label l4 = new Label();
        mv.visitLabel(l4);
        mv.visitLocalVariable("this", classNameDescriptor, null, l0, l4, 0);
        for (int j = 0; j < method.getParameterTypes().length; j++)
            mv.visitLocalVariable("arg" + j, Type.getDescriptor(method.getParameterTypes()[j]),
                    GenericTypeHelper.getSignatureIfGeneric(method.getGenericParameterTypes()[j]), l0, l4,
                    j + 1);
        mv.visitLocalVariable("args", "[Ljava/lang/Object;", null, l1, l4,
                method.getParameterTypes().length + 1);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }
}