Example usage for org.objectweb.asm MethodVisitor visitMaxs

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

Introduction

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

Prototype

public void visitMaxs(final int maxStack, final int maxLocals) 

Source Link

Document

Visits the maximum stack size and the maximum number of local variables of the method.

Usage

From source file:com.github.javalbert.bytecode.utils.AsmUtils.java

License:Apache License

public static void visitDefaultConstructor(ClassWriter cw, String classTypeDescriptor) {
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
    mv.visitCode();/*from   w ww .j a va 2  s  .c o  m*/
    Label l0 = new Label();
    mv.visitLabel(l0);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
    mv.visitInsn(RETURN);
    Label l1 = new Label();
    mv.visitLabel(l1);
    mv.visitLocalVariable("this", classTypeDescriptor, null, l0, l1, 0);
    mv.visitMaxs(1, 1);
    mv.visitEnd();
}

From source file:com.github.megatronking.stringfog.plugin.StringFogClassVisitor.java

License:Apache License

@Override
public void visitEnd() {
    if (!mIgnoreClass && !isClInitExists && !mStaticFinalFields.isEmpty()) {
        MethodVisitor mv = super.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
        mv.visitCode();//from  w w w . j a v  a2 s  .co  m
        // Here init static final fields.
        for (ClassStringField field : mStaticFinalFields) {
            if (!canEncrypted(field.value)) {
                continue;
            }
            String originValue = field.value;
            String encryptValue = mStringFogImpl.encrypt(originValue, mKey);
            mMappingPrinter.output(getJavaClassName(), originValue, encryptValue);
            mv.visitLdcInsn(encryptValue);
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, mFogClassName, "decrypt",
                    "(Ljava/lang/String;)Ljava/lang/String;", false);
            mv.visitFieldInsn(Opcodes.PUTSTATIC, mClassName, field.name, ClassStringField.STRING_DESC);
        }
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(1, 0);
        mv.visitEnd();
    }
    super.visitEnd();
}

From source file:com.github.rgcjonas.kuemmelgtr.core.Compiler.java

License:Open Source License

public static byte[] compileFunc(TokenSource<RPNToken> source, String variable) throws ParsingError {
    // initialize class
    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);

    writer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "com/github/rgcjonas/kuemmelgtr/jit/BogusName", null,
            CompiledClassBase.class.getName().replace('.', '/'),
            new String[] { Evaluator.Function.class.getName().replace('.', '/') });

    // create constructor
    MethodVisitor construct = writer.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
    construct.visitCode();/*  ww w .j av  a2  s  . c o  m*/
    construct.visitVarInsn(Opcodes.ALOAD, 0);
    construct.visitMethodInsn(Opcodes.INVOKESPECIAL, CompiledClassBase.class.getName().replace('.', '/'),
            "<init>", "()V");
    construct.visitInsn(Opcodes.RETURN);
    construct.visitMaxs(0, 0);
    construct.visitEnd();

    MethodVisitor method = writer.visitMethod(Opcodes.ACC_PUBLIC, "evaluate", "(D)D", null,
            new String[] { "com/github/rgcjonas/kuemmelgtr/core/RuntimeError" });

    compileCommon(source, method, variable);

    writer.visitEnd();
    return writer.toByteArray();
}

From source file:com.github.rgcjonas.kuemmelgtr.core.Compiler.java

License:Open Source License

public static byte[] compileBasic(TokenSource<RPNToken> source) throws ParsingError {
    // initialize class
    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);

    writer.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "com/github/rgcjonas/kuemmelgtr/jit/BogusName", null,
            CompiledClassBase.class.getName().replace('.', '/'),
            new String[] { Evaluator.Basic.class.getName().replace('.', '/') });

    // create constructor
    MethodVisitor construct = writer.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
    construct.visitCode();/*from   ww w . j  a v a2  s  .  c o m*/
    construct.visitVarInsn(Opcodes.ALOAD, 0);
    construct.visitMethodInsn(Opcodes.INVOKESPECIAL, CompiledClassBase.class.getName().replace('.', '/'),
            "<init>", "()V");
    construct.visitInsn(Opcodes.RETURN);
    construct.visitMaxs(0, 0);
    construct.visitEnd();

    MethodVisitor method = writer.visitMethod(Opcodes.ACC_PUBLIC, "evaluate", "()D", null,
            new String[] { "com/github/rgcjonas/kuemmelgtr/core/ParsingError",
                    "com/github/rgcjonas/kuemmelgtr/core/RuntimeError" });

    compileCommon(source, method, null);

    writer.visitEnd();
    return writer.toByteArray();
}

From source file:com.github.rgcjonas.kuemmelgtr.core.Compiler.java

License:Open Source License

private static void compileCommon(TokenSource<RPNToken> source, MethodVisitor method, String variable)
        throws ParsingError {
    method.visitCode();//  w  w w  .j ava  2  s .  c  om

    // we now can compile our token stream
    int currentStackSize = 0; // we keep track of the current stack size to throw errors if we encounter an invalid instruction
    RPNToken t;
    while ((t = source.nextToken()) != null) {
        if (t instanceof RPNToken.Operand) {
            // we push it onto the stack
            method.visitLdcInsn(((RPNToken.Operand) t).getValue());
            currentStackSize++;
        } else if (t instanceof RPNToken.Operator) {
            RPNToken.Operator op = (RPNToken.Operator) t;

            if (currentStackSize < op.getNumOperands())
                throw new ParsingError(t.getSrcLine(), t.getSrcColumn(), "Missing operand(s)");

            switch (op.getName()) {
            case "_add":
                method.visitInsn(Opcodes.DADD);
                currentStackSize--;
                break;
            case "_mult":
                method.visitInsn(Opcodes.DMUL);
                currentStackSize--;
                break;
            case "_sub":
                method.visitInsn(Opcodes.DSUB);
                currentStackSize--;
                break;
            case "_div":
                method.visitInsn(Opcodes.DDIV);
                currentStackSize--;
                break;
            case "_pow":
                method.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Math", "pow", "(DD)D");
                currentStackSize--;
                break;
            default:
                //HACK: support every function in java/lang/Math. Will be way more performant than any lookup-and-evaluate
                //TODO: implement more functions inline
                if (currentStackSize < 1)
                    throw new ParsingError(t.getSrcLine(), t.getSrcColumn(), "Missing operand");
                try {
                    Method meth = Math.class.getDeclaredMethod(op.getName(), double.class); // just check if it's available and hope it returns a double
                    if (meth.getReturnType() != double.class)
                        throw new NoSuchMethodException(); // we don't want to blow up at runtime, do we?

                    method.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Math", op.getName(), "(D)D");
                } catch (NoSuchMethodException e) {
                    // we do not give up. The method may be available at runtime.
                    method.visitVarInsn(Opcodes.ALOAD, 0);
                    method.visitInsn(Opcodes.DUP_X2); // swap the this pointer and double
                    method.visitInsn(Opcodes.POP);
                    method.visitLdcInsn(op.getName());
                    method.visitLdcInsn((int) op.getSrcLine());
                    method.visitLdcInsn((int) op.getSrcColumn());
                    method.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                            CompiledClassBase.class.getName().replace('.', '/'), "resolveAndEvaluateFunction",
                            "(DLjava/lang/String;II)D");
                }
            }
        } else if (t instanceof RPNToken.VariableRecall) {
            // maybe, maybe the variable is an argument we can load
            if (variable != null && ((RPNToken.VariableRecall) t).getName().equalsIgnoreCase(variable)) {
                method.visitVarInsn(Opcodes.DLOAD, 1);
            } else {
                // we let our parent class do the hard work
                method.visitVarInsn(Opcodes.ALOAD, 0);
                method.visitLdcInsn(((RPNToken.VariableRecall) t).getName());
                method.visitLdcInsn(t.getSrcLine());
                method.visitLdcInsn(t.getSrcColumn());
                method.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                        CompiledClassBase.class.getName().replace('.', '/'), "getVariable",
                        "(Ljava/lang/String;II)D");
            }
            currentStackSize++;
        } else if (t instanceof RPNToken.VariableAssignment) {
            // also defer to our parent class
            // we do not give up. The method may be available at runtime.
            method.visitVarInsn(Opcodes.ALOAD, 0);
            method.visitInsn(Opcodes.DUP_X2); // swap the this pointer and double
            method.visitInsn(Opcodes.POP);
            method.visitLdcInsn(((RPNToken.VariableAssignment) t).getVariableName());
            method.visitLdcInsn(t.getSrcLine());
            method.visitLdcInsn(t.getSrcColumn());
            method.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CompiledClassBase.class.getName().replace('.', '/'),
                    "setVariable", "(DLjava/lang/String;II)D");
        } else {
            throw new ParsingError(t.getSrcLine(), t.getSrcColumn(), "Unknown instruction: " + t);
        }
    }

    if (currentStackSize != 1)
        throw new ParsingError(0, 0, "Expected stack to be one value, found " + currentStackSize);

    method.visitInsn(Opcodes.DRETURN);

    method.visitMaxs(0, 0);
    method.visitEnd();
}

From source file:com.github.wolf480pl.mias4j.MakeTestBuryUninitialized.java

License:Open Source License

public static byte[] dump() throws Exception {

    ClassWriter cw = new ClassWriter(0);
    FieldVisitor fv;/*from   w ww .  ja  va  2s  .  co  m*/
    MethodVisitor mv;
    AnnotationVisitor av0;

    cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, "Test3", null, "java/lang/Object", null);

    {
        mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(I)V", null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitLdcInsn("hey");
        mv.visitVarInsn(ILOAD, 1);
        mv.visitInsn(ICONST_1);
        mv.visitInsn(IADD);
        mv.visitMethodInsn(INVOKESTATIC, "Test3", "say", "(Ljava/lang/Object;I)I", false);
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
        mv.visitTypeInsn(NEW, "java/util/LinkedList");
        mv.visitInsn(DUP);
        mv.visitMethodInsn(INVOKESPECIAL, "java/util/LinkedList", "<init>", "()V", false);
        mv.visitMethodInsn(INVOKESPECIAL, "Test3", "<init>", "(Ljava/lang/Integer;Ljava/util/List;)V", false);
        mv.visitLdcInsn("hey1");
        mv.visitInsn(ICONST_1);
        mv.visitTypeInsn(NEW, "java/util/Date");
        mv.visitInsn(DUP_X2);

        mv.visitMethodInsn(INVOKESPECIAL, "java/util/Date", "<init>", "()V", false);
        mv.visitInsn(POP2);

        mv.visitInsn(ICONST_0);
        mv.visitMethodInsn(INVOKESTATIC, "Test3", "say", "(Ljava/lang/Object;I)I", false);
        mv.visitInsn(POP);
        mv.visitInsn(RETURN);
        mv.visitMaxs(4, 2);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/Integer;Ljava/util/List;)V",
                "(Ljava/lang/Integer;Ljava/util/List<Ljava/lang/Integer;>;)V", null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
        mv.visitVarInsn(ALOAD, 2);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z", true);
        mv.visitInsn(POP);
        mv.visitInsn(RETURN);
        mv.visitMaxs(2, 3);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
        mv.visitCode();
        mv.visitTypeInsn(NEW, "Test3");
        mv.visitIntInsn(BIPUSH, 10);
        mv.visitMethodInsn(INVOKESPECIAL, "Test3", "<init>", "(I)V", false);
        mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
        mv.visitLdcInsn("byebye");
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
        mv.visitInsn(RETURN);
        mv.visitMaxs(2, 1);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(ACC_PRIVATE + ACC_STATIC, "say", "(Ljava/lang/Object;I)I", null, null);
        mv.visitCode();
        mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/Object;)V", false);
        mv.visitVarInsn(ILOAD, 1);
        mv.visitInsn(IRETURN);
        mv.visitMaxs(2, 2);
        mv.visitEnd();
    }
    cw.visitEnd();

    return cw.toByteArray();
}

From source file:com.github.wolf480pl.mias4j.MakeTestDynamic.java

License:Open Source License

public static byte[] dump() throws Exception {

    ClassWriter cw = new ClassWriter(0);
    FieldVisitor fv;/*from  w  w  w  . j a v a 2s  .  c  o m*/
    MethodVisitor mv;
    AnnotationVisitor av0;

    cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, "TestDynamic", null, "java/lang/Object", null);

    cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup",
            ACC_PUBLIC + ACC_FINAL + ACC_STATIC);

    {
        mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
        mv.visitInsn(RETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "bootstrap",
                "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;",
                null, new String[] { "java/lang/NoSuchMethodException", "java/lang/IllegalAccessException" });
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitLdcInsn(Type.getType("LTestDynamic;"));
        mv.visitLdcInsn("sayHi");
        mv.visitVarInsn(ALOAD, 3);
        mv.visitLdcInsn(Type.getType("LTestDynamic;"));
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandles$Lookup", "findSpecial",
                "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Class;)Ljava/lang/invoke/MethodHandle;",
                false);
        mv.visitVarInsn(ASTORE, 4);
        mv.visitTypeInsn(NEW, "java/lang/invoke/ConstantCallSite");
        mv.visitInsn(DUP);
        mv.visitVarInsn(ALOAD, 4);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/invoke/ConstantCallSite", "<init>",
                "(Ljava/lang/invoke/MethodHandle;)V", false);
        mv.visitInsn(ARETURN);
        mv.visitMaxs(5, 5);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
        mv.visitCode();
        mv.visitTypeInsn(NEW, "TestDynamic");
        mv.visitInsn(DUP);
        mv.visitMethodInsn(INVOKESPECIAL, "TestDynamic", "<init>", "()V", false);
        mv.visitVarInsn(ASTORE, 1);
        mv.visitVarInsn(ALOAD, 1);
        // mv.visitMethodInsn(INVOKESPECIAL, "TestDynamic", "sayHi", "()V", false);
        mv.visitInvokeDynamicInsn("sayHi", "(LTestDynamic;)V", new Handle(H_INVOKESTATIC, "TestDynamic",
                "bootstrap",
                "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"),
                Type.getMethodType("()V"));
        mv.visitInsn(RETURN);
        mv.visitMaxs(2, 2);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(ACC_PRIVATE, "sayHi", "()V", null, null);
        mv.visitCode();
        mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
        mv.visitLdcInsn("hi");
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
        mv.visitInsn(RETURN);
        mv.visitMaxs(2, 1);
        mv.visitEnd();
    }
    cw.visitEnd();

    return cw.toByteArray();
}

From source file:com.github.wolf480pl.mias4j.MakeTestMH.java

License:Open Source License

public static byte[] dump() throws Exception {

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

    cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, "TestMH", null, "java/lang/Object", null);

    cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup",
            ACC_PUBLIC + ACC_FINAL + ACC_STATIC);

    {//from w w w  .  j av a 2  s.  c  o  m
        mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
        mv.visitInsn(RETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
        mv.visitCode();
        Label l0 = new Label();
        Label l1 = new Label();
        Label l2 = new Label();
        mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Throwable");
        mv.visitLabel(l0);
        /*mv.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodHandles", "lookup", "()Ljava/lang/invoke/MethodHandles$Lookup;", false);
        mv.visitLdcInsn(Type.getType("Ljava/io/PrintStream;"));
        mv.visitLdcInsn("println");
        mv.visitFieldInsn(GETSTATIC, "java/lang/Void", "TYPE", "Ljava/lang/Class;");
        mv.visitLdcInsn(Type.getType("Ljava/lang/String;"));
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodType", "methodType", "(Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/invoke/MethodType;", false);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandles$Lookup", "findVirtual", "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;", false);*/
        mv.visitLdcInsn(new Handle(H_INVOKEVIRTUAL, "java/io/PrintStream", "println",
                Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String.class))));
        mv.visitVarInsn(ASTORE, 1);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
        mv.visitLdcInsn("hey");
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invoke",
                "(Ljava/io/PrintStream;Ljava/lang/String;)V", false);
        mv.visitLabel(l1);
        Label l3 = new Label();
        mv.visitJumpInsn(GOTO, l3);
        mv.visitLabel(l2);
        mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" });
        mv.visitVarInsn(ASTORE, 1);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Throwable", "printStackTrace", "()V", false);
        mv.visitLabel(l3);
        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        mv.visitInsn(RETURN);
        mv.visitMaxs(5, 2);
        mv.visitEnd();
    }
    cw.visitEnd();

    return cw.toByteArray();
}

From source file:com.gmail.socraticphoenix.nebula.event.wrappers.BytecodeEventListenerGeneration.java

License:Open Source License

public static List<EventListenerWrapper> of(Object listener) {
    List<Class> cachedListeners = BytecodeEventListenerGeneration.listenerCache.get(listener.getClass());
    List<EventListenerWrapper> wrappers = new ArrayList<>();

    if (cachedListeners != null) {
        cachedListeners.forEach(c -> {
            try {
                wrappers.add((EventListenerWrapper) c.getConstructor(Object.class).newInstance(listener));
            } catch (InstantiationException | IllegalAccessException | NoSuchMethodException
                    | InvocationTargetException e) {

            }/*from w w w . j a va 2s  .  com*/
        });
    } else {
        try {
            Type listenerType = Type.getType(listener.getClass());
            Map<String, ClassWriter> classes = new LinkedHashMap<>();
            Map<String, String> binaryNames = new LinkedHashMap<>();

            List<Method> methods = new ArrayList<>();
            for (Method method : listener.getClass().getDeclaredMethods()) {
                if (method.isAnnotationPresent(EventListener.class)) {
                    EventListenerWrapper.verify(method, listener);
                    methods.add(method);
                }
            }

            for (Method method : methods) {
                int event = BytecodeEventListenerGeneration.isolateEvent(method);
                int eventVarIndex = event + 1;
                int[] jumpTable = BytecodeEventListenerGeneration.jumpTable(eventVarIndex,
                        method.getParameters());

                Parameter eventParam = method.getParameters()[event];
                Class eventClass = eventParam.getType();
                Type eventType = Type.getType(eventClass);

                String name = BytecodeEventListenerGeneration.name(method);
                ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
                classes.put(name, writer);

                String internalName = BytecodeEventListenerGeneration.listener(
                        method.getAnnotation(EventListener.class), eventClass, listener, method, writer);
                binaryNames.put(name, internalName.replace('/', '.'));

                if (!eventType.equals(BytecodeEventListenerGeneration.eventType)) {
                    MethodVisitor handleDelegateMethod = writer.visitMethod(ACC_PUBLIC | ACC_FINAL, "handle",
                            Type.getMethodDescriptor(Type.VOID_TYPE, BytecodeEventListenerGeneration.eventType),
                            null, null);
                    handleDelegateMethod.visitCode();
                    handleDelegateMethod.visitVarInsn(ALOAD, 0);
                    handleDelegateMethod.visitVarInsn(ALOAD, 1);
                    BytecodeEventListenerGeneration.checkCast(eventType, handleDelegateMethod);
                    handleDelegateMethod.visitMethodInsn(INVOKEVIRTUAL, internalName, "handle",
                            Type.getMethodDescriptor(Type.VOID_TYPE, eventType), false);
                    handleDelegateMethod.visitInsn(RETURN);
                    handleDelegateMethod.visitMaxs(0, 0);
                    handleDelegateMethod.visitEnd();
                }

                MethodVisitor handleMethod = writer.visitMethod(ACC_PUBLIC | ACC_FINAL, "handle",
                        Type.getMethodDescriptor(Type.VOID_TYPE, eventType), null, null);
                handleMethod.visitCode();
                if (method.isAnnotationPresent(Exclude.class)) {
                    BytecodeEventListenerGeneration.exclude(method.getAnnotation(Exclude.class), 1,
                            handleMethod);
                } else if (method.isAnnotationPresent(Include.class)) {
                    BytecodeEventListenerGeneration.include(method.getAnnotation(Include.class), 1,
                            handleMethod);
                }

                if (method.isAnnotationPresent(Cancelled.class)) {
                    BytecodeEventListenerGeneration.cancelled(method.getAnnotation(Cancelled.class), 1,
                            eventClass, handleMethod);
                }

                for (int i = 0; i < method.getParameters().length; i++) {
                    Parameter parameter = method.getParameters()[i];
                    JavaSourceFilledGenerics generics = parameter
                            .getParameterizedType() instanceof ParameterizedType
                                    ? JavaSourceFilledGenerics
                                            .of((ParameterizedType) parameter.getParameterizedType())
                                    : JavaSourceFilledGenerics.empty();
                    int var = i + 1;
                    Annotation annotation = BytecodeEventListenerGeneration.isolateAnnotation(parameter);
                    if (annotation instanceof AllCauses) {
                        AllCauses allCauses = (AllCauses) annotation;
                        Class clazz = generics.getFilled().isEmpty() ? Object.class
                                : generics.getFilled().get(0).type().getRepresented().orElse(Object.class);
                        BytecodeEventListenerGeneration.allCauses(allCauses, clazz, jumpTable[var], 1,
                                handleMethod);
                    } else if (annotation instanceof AllContexts) {
                        AllContexts allContexts = (AllContexts) annotation;

                        JavaSourceNamespace.Filled target = generics.getFilled().isEmpty()
                                ? JavaSourceNamespace.of(Object.class).fill()
                                : generics.getFilled().get(0).type();
                        Class clazz = target.getRepresented().orElse(Object.class);

                        if (!allContexts.value()) {
                            BytecodeEventListenerGeneration.allContexts(allContexts, false, parameter.getType(),
                                    jumpTable[var], 1, handleMethod);
                        } else if (clazz == Pair.class) {
                            Class a = target.getFilledGenerics().getFilled().isEmpty() ? Object.class
                                    : target.getFilledGenerics().getFilled().get(0).type().getRepresented()
                                            .orElse(Object.class);
                            Class b = target.getFilledGenerics().getFilled().size() <= 1 ? Object.class
                                    : target.getFilledGenerics().getFilled().get(1).type().getRepresented()
                                            .orElse(Object.class);
                            if (a == String.class) {
                                BytecodeEventListenerGeneration.allContexts(allContexts, true, b,
                                        jumpTable[var], 1, handleMethod);
                            } else {
                                BytecodeEventListenerGeneration.allContexts(allContexts, false,
                                        parameter.getType(), jumpTable[var], 1, handleMethod);
                            }
                        } else {
                            BytecodeEventListenerGeneration.allContexts(allContexts, false, parameter.getType(),
                                    jumpTable[var], 1, handleMethod);
                        }
                    } else if (annotation instanceof FirstCause) {
                        FirstCause firstCause = (FirstCause) annotation;
                        BytecodeEventListenerGeneration.firstCause(firstCause, parameter.getType(),
                                jumpTable[var], 1, handleMethod);
                    } else if (annotation instanceof FirstContext) {
                        FirstContext firstContext = (FirstContext) annotation;
                        if (!firstContext.value()) {
                            BytecodeEventListenerGeneration.firstContext(firstContext, false,
                                    parameter.getType(), jumpTable[var], 1, handleMethod);
                        } else if (parameter.getType() == Pair.class) {
                            Class a = generics.getFilled().isEmpty() ? Object.class
                                    : generics.getFilled().get(0).type().getRepresented().orElse(Object.class);
                            Class b = generics.getFilled().size() <= 1 ? Object.class
                                    : generics.getFilled().get(1).type().getRepresented().orElse(Object.class);
                            if (a == String.class) {
                                BytecodeEventListenerGeneration.firstContext(firstContext, true, b,
                                        jumpTable[var], 1, handleMethod);
                            } else {
                                BytecodeEventListenerGeneration.firstContext(firstContext, false,
                                        parameter.getType(), jumpTable[var], 1, handleMethod);
                            }
                        } else {
                            BytecodeEventListenerGeneration.firstContext(firstContext, false,
                                    parameter.getType(), jumpTable[var], 1, handleMethod);
                        }
                    } else if (annotation instanceof LastCause) {
                        LastCause lastCause = (LastCause) annotation;
                        BytecodeEventListenerGeneration.lastCause(lastCause, parameter.getType(),
                                jumpTable[var], 1, handleMethod);
                    } else if (annotation instanceof LastContext) {
                        LastContext lastContext = (LastContext) annotation;
                        if (!lastContext.value()) {
                            BytecodeEventListenerGeneration.lastContext(lastContext, false, parameter.getType(),
                                    jumpTable[var], 1, handleMethod);
                        } else if (parameter.getType() == Pair.class) {
                            Class a = generics.getFilled().isEmpty() ? Object.class
                                    : generics.getFilled().get(0).type().getRepresented().orElse(Object.class);
                            Class b = generics.getFilled().size() <= 1 ? Object.class
                                    : generics.getFilled().get(1).type().getRepresented().orElse(Object.class);
                            if (a == String.class) {
                                BytecodeEventListenerGeneration.lastContext(lastContext, true, b,
                                        jumpTable[var], 1, handleMethod);
                            } else {
                                BytecodeEventListenerGeneration.lastContext(lastContext, false,
                                        parameter.getType(), jumpTable[var], 1, handleMethod);
                            }
                        } else {
                            BytecodeEventListenerGeneration.lastContext(lastContext, false, parameter.getType(),
                                    jumpTable[var], 1, handleMethod);
                        }
                    } else if (annotation instanceof GetContext) {
                        GetContext getContext = (GetContext) annotation;
                        BytecodeEventListenerGeneration.getContext(getContext, parameter.getName(),
                                parameter.getType(), jumpTable[var], 1, handleMethod);
                    } else if (annotation instanceof Get) {
                        Get get = (Get) annotation;
                        BytecodeEventListenerGeneration.get(get, parameter, eventClass, jumpTable[var], 1,
                                handleMethod);
                    }
                }

                handleMethod.visitVarInsn(ALOAD, 0);
                handleMethod.visitFieldInsn(GETFIELD, internalName, "listener", listenerType.getDescriptor());
                for (int i = 0; i < method.getParameters().length; i++) {
                    handleMethod.visitVarInsn(ALOAD, jumpTable[i + 1]);
                }
                handleMethod.visitMethodInsn(INVOKEVIRTUAL, listenerType.getInternalName(), method.getName(),
                        Type.getType(method).getDescriptor(), false);
                handleMethod.visitInsn(RETURN);
                handleMethod.visitMaxs(0, 0);
                handleMethod.visitEnd();
            }

            List<Class> cache = BytecodeEventListenerGeneration.listenerCache.get(listener.getClass());
            if (cache == null) {
                cache = new ArrayList<>();
                BytecodeEventListenerGeneration.listenerCache.put(listener.getClass(), cache);
            }

            for (Map.Entry<String, ClassWriter> finished : classes.entrySet()) {
                ClassWriter visitor = finished.getValue();
                visitor.visitEnd();

                byte[] clazz = visitor.toByteArray();
                Class eventListenerClass = EventListenerClassLoader.INSTANCE
                        .defineClass(binaryNames.get(finished.getKey()), clazz);
                cache.add(eventListenerClass);
                EventListenerWrapper instance = (EventListenerWrapper) eventListenerClass
                        .getConstructor(listener.getClass()).newInstance(listener);
                wrappers.add(instance);
            }

        } catch (NoSuchMethodException | InstantiationException | InvocationTargetException
                | IllegalAccessException e) {

        }
    }

    return wrappers;
}

From source file:com.gmail.socraticphoenix.nebula.event.wrappers.BytecodeEventListenerGeneration.java

License:Open Source License

public static String listener(EventListener eventListener, Class eventClass, Object listener, Method method,
        ClassVisitor visitor) {//w  w w  .  jav a  2s .  c  om
    Type listenerType = Type.getType(listener.getClass());
    Type eventType = Type.getType(eventClass);
    String internalImplName = listenerType.getInternalName() + "$listener$" + method.getName() + "$"
            + BytecodeEventListenerGeneration.index++;

    visitor.visit(V1_8, ACC_PUBLIC | ACC_SYNTHETIC | ACC_FINAL, internalImplName, null,
            BytecodeEventListenerGeneration.objectType.getInternalName(),
            new String[] { BytecodeEventListenerGeneration.eventWrapperType.getInternalName() });
    visitor.visitField(ACC_PRIVATE | ACC_FINAL, "listener", listenerType.getDescriptor(), null, null)
            .visitEnd();

    MethodVisitor constructor = visitor.visitMethod(ACC_PUBLIC, "<init>",
            Type.getMethodDescriptor(Type.VOID_TYPE, listenerType), null, null);
    constructor.visitParameter("listener", ACC_FINAL);
    constructor.visitCode();
    constructor.visitVarInsn(ALOAD, 0);
    constructor.visitMethodInsn(INVOKESPECIAL, BytecodeEventListenerGeneration.objectType.getInternalName(),
            "<init>", Type.getMethodDescriptor(Type.VOID_TYPE), false);
    constructor.visitVarInsn(ALOAD, 0);
    constructor.visitVarInsn(ALOAD, 1);
    constructor.visitFieldInsn(PUTFIELD, internalImplName, "listener", listenerType.getDescriptor());
    constructor.visitInsn(RETURN);
    constructor.visitMaxs(0, 0);
    constructor.visitEnd();

    MethodVisitor priority = visitor.visitMethod(ACC_PUBLIC | ACC_FINAL, "priority",
            BytecodeEventListenerGeneration.priorityMethod.getDescriptor(), null, null);
    priority.visitCode();
    priority.visitLdcInsn(eventListener.value());
    priority.visitInsn(IRETURN);
    priority.visitMaxs(0, 0);
    priority.visitEnd();

    MethodVisitor getListener = visitor.visitMethod(ACC_PUBLIC | ACC_FINAL, "listener",
            BytecodeEventListenerGeneration.listenerMethod.getDescriptor(), null, null);
    getListener.visitVarInsn(ALOAD, 0);
    getListener.visitFieldInsn(GETFIELD, internalImplName, "listener", listenerType.getDescriptor());
    getListener.visitInsn(ARETURN);
    getListener.visitMaxs(0, 0);
    getListener.visitEnd();

    MethodVisitor event = visitor.visitMethod(ACC_PUBLIC | ACC_FINAL, "mainEvent",
            BytecodeEventListenerGeneration.mainEventMethod.getDescriptor(), null, null);
    event.visitCode();
    event.visitLdcInsn(eventType);
    event.visitInsn(ARETURN);
    event.visitMaxs(0, 0);
    event.visitEnd();

    return internalImplName;
}