Example usage for org.objectweb.asm MethodVisitor visitCode

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

Introduction

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

Prototype

public void visitCode() 

Source Link

Document

Starts the visit of the method's code, if any (i.e.

Usage

From source file:one.nio.serial.gen.DelegateGenerator.java

License:Apache License

private static void generateCalcSize(ClassVisitor cv, Class cls, FieldDescriptor[] fds) {
    MethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_FINAL, "calcSize",
            "(Ljava/lang/Object;Lone/nio/serial/CalcSizeStream;)V", null,
            new String[] { "java/io/IOException" });
    mv.visitCode();

    Method writeObjectMethod = JavaInternals.findMethodRecursively(cls, "writeObject",
            ObjectOutputStream.class);
    if (writeObjectMethod != null
            && !Repository.hasOptions(writeObjectMethod.getDeclaringClass(), Repository.SKIP_WRITE_OBJECT)) {
        mv.visitVarInsn(ALOAD, 1);//from ww w.j ava2 s  . com
        mv.visitFieldInsn(GETSTATIC, "one/nio/serial/gen/NullObjectOutputStream", "INSTANCE",
                "Lone/nio/serial/gen/NullObjectOutputStream;");
        emitInvoke(mv, writeObjectMethod);
    }

    int primitiveFieldsSize = 0;

    for (FieldDescriptor fd : fds) {
        Field ownField = fd.ownField();
        Class sourceClass = fd.type().resolve();
        FieldType srcType = FieldType.valueOf(sourceClass);

        if (srcType != FieldType.Object) {
            primitiveFieldsSize += srcType.dataSize;
        } else if (ownField == null) {
            primitiveFieldsSize++; // 1 byte to encode null reference
        } else {
            mv.visitVarInsn(ALOAD, 2);
            mv.visitVarInsn(ALOAD, 1);
            if (fd.parentField() != null)
                emitGetField(mv, fd.parentField());
            emitGetField(mv, ownField);
            emitTypeCast(mv, ownField.getType(), sourceClass);
            mv.visitMethodInsn(INVOKEVIRTUAL, "one/nio/serial/CalcSizeStream", "writeObject",
                    "(Ljava/lang/Object;)V");
        }
    }

    if (primitiveFieldsSize != 0) {
        mv.visitVarInsn(ALOAD, 2);
        mv.visitInsn(DUP);
        mv.visitFieldInsn(GETFIELD, "one/nio/serial/CalcSizeStream", "count", "I");
        emitInt(mv, primitiveFieldsSize);
        mv.visitInsn(IADD);
        mv.visitFieldInsn(PUTFIELD, "one/nio/serial/CalcSizeStream", "count", "I");
    }

    mv.visitInsn(RETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:one.nio.serial.gen.DelegateGenerator.java

License:Apache License

private static void generateWrite(ClassVisitor cv, Class cls, FieldDescriptor[] fds) {
    MethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_FINAL, "write",
            "(Ljava/lang/Object;Lone/nio/serial/DataStream;)V", null, new String[] { "java/io/IOException" });
    mv.visitCode();

    Method writeObjectMethod = JavaInternals.findMethodRecursively(cls, "writeObject",
            ObjectOutputStream.class);
    if (writeObjectMethod != null
            && !Repository.hasOptions(writeObjectMethod.getDeclaringClass(), Repository.SKIP_WRITE_OBJECT)) {
        mv.visitVarInsn(ALOAD, 1);//from   w ww  .  j  a  va 2s.  c  o m
        mv.visitFieldInsn(GETSTATIC, "one/nio/serial/gen/NullObjectOutputStream", "INSTANCE",
                "Lone/nio/serial/gen/NullObjectOutputStream;");
        emitInvoke(mv, writeObjectMethod);
    }

    for (FieldDescriptor fd : fds) {
        Field ownField = fd.ownField();
        Class sourceClass = fd.type().resolve();
        FieldType srcType = FieldType.valueOf(sourceClass);

        mv.visitVarInsn(ALOAD, 2);

        if (ownField == null) {
            mv.visitInsn(FieldType.Void.convertTo(srcType));
        } else {
            mv.visitVarInsn(ALOAD, 1);
            if (fd.parentField() != null)
                emitGetField(mv, fd.parentField());
            emitGetField(mv, ownField);
            emitTypeCast(mv, ownField.getType(), sourceClass);
        }

        mv.visitMethodInsn(INVOKEVIRTUAL, "one/nio/serial/DataStream", srcType.writeMethod(),
                srcType.writeSignature());
    }

    mv.visitInsn(RETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:one.nio.serial.gen.DelegateGenerator.java

License:Apache License

private static void generateRead(ClassVisitor cv, Class cls, FieldDescriptor[] fds, List<Field> defaultFields) {
    MethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_FINAL, "read",
            "(Lone/nio/serial/DataStream;)Ljava/lang/Object;", null,
            new String[] { "java/io/IOException", "java/lang/ClassNotFoundException" });
    mv.visitCode();

    mv.visitVarInsn(ALOAD, 1);/*from www  . j  ava2 s . c  o  m*/
    mv.visitTypeInsn(NEW, Type.getInternalName(cls));
    mv.visitInsn(DUP);
    mv.visitVarInsn(ASTORE, 2);
    mv.visitMethodInsn(INVOKEVIRTUAL, "one/nio/serial/DataStream", "register", "(Ljava/lang/Object;)V");

    ArrayList<Field> parents = new ArrayList<Field>(1);
    for (FieldDescriptor fd : fds) {
        Field ownField = fd.ownField();
        Field parentField = fd.parentField();
        Class sourceClass = fd.type().resolve();
        FieldType srcType = FieldType.valueOf(sourceClass);

        if (parentField != null && !parents.contains(parentField)) {
            parents.add(parentField);
            mv.visitFieldInsn(GETSTATIC, "one/nio/util/JavaInternals", "unsafe", "Lsun/misc/Unsafe;");
            mv.visitVarInsn(ALOAD, 2);
            mv.visitLdcInsn(unsafe.objectFieldOffset(parentField));
            mv.visitTypeInsn(NEW, Type.getInternalName(parentField.getType()));
            mv.visitMethodInsn(INVOKESPECIAL, "sun/misc/Unsafe", "putObject",
                    "(Ljava/lang/Object;JLjava/lang/Object;)V");
        }

        if (ownField == null) {
            mv.visitVarInsn(ALOAD, 1);
            mv.visitMethodInsn(INVOKEVIRTUAL, "one/nio/serial/DataStream", srcType.readMethod(),
                    srcType.readSignature());
            mv.visitInsn(srcType.convertTo(FieldType.Void));
        } else if (Modifier.isFinal(ownField.getModifiers())) {
            FieldType dstType = FieldType.valueOf(ownField.getType());
            mv.visitFieldInsn(GETSTATIC, "one/nio/util/JavaInternals", "unsafe", "Lsun/misc/Unsafe;");
            mv.visitVarInsn(ALOAD, 2);
            if (parentField != null)
                emitGetField(mv, parentField);
            mv.visitLdcInsn(unsafe.objectFieldOffset(ownField));
            mv.visitVarInsn(ALOAD, 1);
            mv.visitMethodInsn(INVOKEVIRTUAL, "one/nio/serial/DataStream", srcType.readMethod(),
                    srcType.readSignature());
            if (srcType == FieldType.Object)
                emitTypeCast(mv, Object.class, sourceClass);
            emitTypeCast(mv, sourceClass, ownField.getType());
            mv.visitMethodInsn(INVOKESPECIAL, "sun/misc/Unsafe", dstType.putMethod(), dstType.putSignature());
        } else {
            mv.visitVarInsn(ALOAD, 2);
            if (parentField != null)
                emitGetField(mv, parentField);
            mv.visitVarInsn(ALOAD, 1);
            mv.visitMethodInsn(INVOKEVIRTUAL, "one/nio/serial/DataStream", srcType.readMethod(),
                    srcType.readSignature());
            if (srcType == FieldType.Object)
                emitTypeCast(mv, Object.class, sourceClass);
            emitTypeCast(mv, sourceClass, ownField.getType());
            emitPutField(mv, ownField);
        }
    }

    if (defaultFields != null && !defaultFields.isEmpty()) {
        for (Field defaultField : defaultFields) {
            String defaultValue = defaultField.getAnnotation(Default.class).value();
            putFieldConstant(mv, defaultField, defaultValue);
        }
    }

    Method readObjectMethod = JavaInternals.findMethodRecursively(cls, "readObject", ObjectInputStream.class);
    if (readObjectMethod != null
            && !Repository.hasOptions(readObjectMethod.getDeclaringClass(), Repository.SKIP_READ_OBJECT)) {
        mv.visitVarInsn(ALOAD, 2);
        mv.visitFieldInsn(GETSTATIC, "one/nio/serial/gen/NullObjectInputStream", "INSTANCE",
                "Lone/nio/serial/gen/NullObjectInputStream;");
        emitInvoke(mv, readObjectMethod);
    }

    mv.visitVarInsn(ALOAD, 2);
    mv.visitInsn(ARETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:one.nio.serial.gen.DelegateGenerator.java

License:Apache License

private static void generateSkip(ClassVisitor cv, FieldDescriptor[] fds) {
    MethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_FINAL, "skip", "(Lone/nio/serial/DataStream;)V", null,
            new String[] { "java/io/IOException", "java/lang/ClassNotFoundException" });
    mv.visitCode();

    int skipSize = 0;

    for (FieldDescriptor fd : fds) {
        Class sourceClass = fd.type().resolve();
        FieldType srcType = FieldType.valueOf(sourceClass);

        if (srcType != FieldType.Object) {
            skipSize += srcType.dataSize;
        } else {/*from   ww w. j a v  a  2s . c om*/
            if (skipSize > 0) {
                mv.visitVarInsn(ALOAD, 1);
                emitInt(mv, skipSize);
                mv.visitMethodInsn(INVOKEVIRTUAL, "one/nio/serial/DataStream", "skipBytes", "(I)I");
                mv.visitInsn(POP);
                skipSize = 0;
            }
            mv.visitVarInsn(ALOAD, 1);
            mv.visitMethodInsn(INVOKEVIRTUAL, "one/nio/serial/DataStream", "readObject",
                    "()Ljava/lang/Object;");
            mv.visitInsn(POP);
        }
    }

    if (skipSize > 0) {
        mv.visitVarInsn(ALOAD, 1);
        emitInt(mv, skipSize);
        mv.visitMethodInsn(INVOKEVIRTUAL, "one/nio/serial/DataStream", "skipBytes", "(I)I");
        mv.visitInsn(POP);
    }

    mv.visitInsn(RETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:one.nio.serial.gen.DelegateGenerator.java

License:Apache License

private static void generateToJson(ClassVisitor cv, FieldDescriptor[] fds) {
    MethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_FINAL, "toJson",
            "(Ljava/lang/Object;Ljava/lang/StringBuilder;)V", null, new String[] { "java/io/IOException" });
    mv.visitCode();

    boolean firstWritten = false;
    mv.visitVarInsn(ALOAD, 2);/*  w w  w .java2 s.  c om*/

    for (FieldDescriptor fd : fds) {
        Field ownField = fd.ownField();
        if (ownField == null) {
            continue;
        }

        String fieldName = "\"" + ownField.getName() + "\":";
        mv.visitLdcInsn(firstWritten ? ',' + fieldName : '{' + fieldName);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
        firstWritten = true;

        Class sourceClass = fd.type().resolve();
        FieldType srcType = FieldType.valueOf(sourceClass);

        mv.visitVarInsn(ALOAD, 1);
        if (fd.parentField() != null)
            emitGetField(mv, fd.parentField());
        emitGetField(mv, ownField);
        emitTypeCast(mv, ownField.getType(), sourceClass);

        switch (srcType) {
        case Object:
            mv.visitMethodInsn(INVOKESTATIC, "one/nio/serial/Json", "appendObject",
                    "(Ljava/lang/StringBuilder;Ljava/lang/Object;)V");
            mv.visitVarInsn(ALOAD, 2);
            break;
        case Char:
            mv.visitMethodInsn(INVOKESTATIC, "one/nio/serial/Json", "appendChar",
                    "(Ljava/lang/StringBuilder;C)V");
            mv.visitVarInsn(ALOAD, 2);
            break;
        default:
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", srcType.appendSignature());
        }
    }

    if (!firstWritten) {
        emitInt(mv, '{');
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(C)Ljava/lang/StringBuilder;");
    }
    emitInt(mv, '}');
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(C)Ljava/lang/StringBuilder;");
    mv.visitInsn(POP);

    mv.visitInsn(RETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:one.nio.serial.gen.StubGenerator.java

License:Apache License

public static Class generateRegular(String className, String superName, FieldDescriptor[] fds) {
    String internalClassName = getStubName(className);

    ClassWriter cv = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    cv.visit(V1_6, ACC_PUBLIC | ACC_FINAL, internalClassName, null, superName,
            new String[] { "java/io/Serializable" });

    MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
    mv.visitCode();
    mv.visitVarInsn(ALOAD, 0);/*from w ww  .j  a  va2 s  .  co  m*/
    mv.visitMethodInsn(INVOKESPECIAL, superName, "<init>", "()V");
    mv.visitInsn(RETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();

    if (fds != null) {
        for (FieldDescriptor fd : fds) {
            String name = fd.name();
            String oldName = null;

            int p = name.indexOf('|');
            if (p >= 0) {
                oldName = name.substring(p + 1);
                name = name.substring(0, p);
            }

            FieldVisitor fv = cv.visitField(ACC_PRIVATE, name, Type.getDescriptor(fd.type().resolve()), null,
                    null);
            if (oldName != null) {
                AnnotationVisitor av = fv.visitAnnotation("Lone/nio/serial/Renamed;", true);
                av.visit("from", oldName);
                av.visitEnd();
            }
            fv.visitEnd();
        }
    }

    cv.visitEnd();
    return INSTANCE.defineClassIfNotExists(internalClassName.replace('/', '.'), cv.toByteArray());
}

From source file:one.nio.serial.gen.StubGenerator.java

License:Apache License

public static Class generateEnum(String className, String[] constants) {
    String internalClassName = getStubName(className);

    ClassWriter cv = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    cv.visit(V1_6, ACC_PUBLIC | ACC_FINAL | ACC_ENUM, internalClassName, null, "java/lang/Enum", null);

    String classDesc = 'L' + internalClassName + ';';
    for (String c : constants) {
        cv.visitField(ACC_PUBLIC | ACC_STATIC | ACC_FINAL, c, classDesc, null, null).visitEnd();
    }/*from  w w w. j ava  2s. c  o m*/

    String arrayDesc = '[' + classDesc;
    cv.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, "$VALUES", arrayDesc, null, null).visitEnd();

    MethodVisitor mv = cv.visitMethod(ACC_PRIVATE, "<init>", "(Ljava/lang/String;I)V", null, null);
    mv.visitCode();
    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitVarInsn(ILOAD, 2);
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Enum", "<init>", "(Ljava/lang/String;I)V");
    mv.visitInsn(RETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();

    mv = cv.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
    mv.visitCode();
    emitInt(mv, constants.length);
    mv.visitTypeInsn(ANEWARRAY, internalClassName);

    for (int i = 0; i < constants.length; i++) {
        mv.visitInsn(DUP);
        emitInt(mv, i);
        mv.visitTypeInsn(NEW, internalClassName);
        mv.visitInsn(DUP);
        mv.visitLdcInsn(constants[i]);
        emitInt(mv, i);
        mv.visitMethodInsn(INVOKESPECIAL, internalClassName, "<init>", "(Ljava/lang/String;I)V");
        mv.visitInsn(DUP);
        mv.visitFieldInsn(PUTSTATIC, internalClassName, constants[i], classDesc);
        mv.visitInsn(AASTORE);
    }

    mv.visitFieldInsn(PUTSTATIC, internalClassName, "$VALUES", arrayDesc);
    mv.visitInsn(RETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();

    mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, "values", "()" + arrayDesc, null, null);
    mv.visitCode();
    mv.visitFieldInsn(GETSTATIC, internalClassName, "$VALUES", arrayDesc);
    mv.visitInsn(ARETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();

    mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, "valueOf", "(Ljava/lang/String;)" + classDesc, null, null);
    mv.visitCode();
    mv.visitLdcInsn(Type.getObjectType(internalClassName));
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Enum", "valueOf",
            "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;");
    mv.visitTypeInsn(CHECKCAST, internalClassName);
    mv.visitInsn(ARETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();

    cv.visitEnd();
    return INSTANCE.defineClassIfNotExists(internalClassName.replace('/', '.'), cv.toByteArray());
}

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  w  w w. ja  v a2 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  .  ja v a 2  s.c  o  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/*w ww. j  a 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);
    }
}