Example usage for org.objectweb.asm MethodVisitor visitLocalVariable

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

Introduction

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

Prototype

public void visitLocalVariable(final String name, final String descriptor, final String signature,
        final Label start, final Label end, final int index) 

Source Link

Document

Visits a local variable declaration.

Usage

From source file:org.simantics.databoard.binding.reflection.AsmBindingClassLoader.java

License:Open Source License

public byte[] createBindingClass(ClassInfo ci, String bindingClassName) {
    //System.out.println("BindingFactory: "+bindingClassName+" (for "+ci.clazz.getClassLoader()+")");
    int count = ci.fields.length;
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
    ClassVisitor cv = cw;//new CheckClassAdapter(cw);

    FieldVisitor fv;/*from  w  w  w  . ja  va2s.  c  o m*/
    MethodVisitor mv;
    AnnotationVisitor av0;

    String className = ci.clazz.getName().replaceAll("\\.", "/");
    bindingClassName = bindingClassName.replaceAll("\\.", "/");
    Object[] classNameX = new Object[] { className };
    String signature = "L" + bindingClassName + ";";

    // Constructor
    String superClass = "org/simantics/databoard/binding/reflection/ClassBinding";
    cv.visit(V1_6, ACC_PUBLIC + ACC_SUPER, bindingClassName, null, superClass, null);

    // Constructor
    {
        mv = cv.visitMethod(ACC_PUBLIC, "<init>", "(Lorg/simantics/databoard/type/RecordType;)V", null,
                new String[] { "org/simantics/databoard/binding/error/BindingConstructionException" });

        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitLdcInsn(Type.getType("L" + className + ";"));
        mv.visitMethodInsn(INVOKESPECIAL, superClass, "<init>", "(Ljava/lang/Class;)V");

        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitFieldInsn(PUTFIELD, bindingClassName, "type", "Lorg/simantics/databoard/type/Datatype;");

        Label l2 = new Label();
        mv.visitLabel(l2);
        mv.visitInsn(RETURN);

        Label l3 = new Label();
        mv.visitLabel(l3);
        mv.visitLocalVariable("this", signature, null, l0, l3, 0);
        mv.visitLocalVariable("type", "Lorg/simantics/databoard/type/RecordType;", null, l0, l3, 1);
        mv.visitMaxs(2, 2);
        mv.visitEnd();
    }

    // getComponent
    {
        mv = cv.visitMethod(ACC_PUBLIC, "getComponent", "(Ljava/lang/Object;I)Ljava/lang/Object;", null,
                new String[] { "org/simantics/databoard/binding/error/BindingException" });
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitTypeInsn(CHECKCAST, className);
        mv.visitVarInsn(ASTORE, 3);
        Label l1 = new Label();
        mv.visitLabel(l1);

        Label caseLabels[] = createFieldLabels(ci);
        Label elseLabel = new Label();

        if (count > 0) {
            // Switch
            mv.visitVarInsn(ILOAD, 2);
            mv.visitTableSwitchInsn(0, count - 1, elseLabel, caseLabels);

            // case i: x.field = value[i]
            for (int i = 0; i < count; i++) {
                Label label = caseLabels[i];
                Field field = ci.fields[i];
                String fieldName = field.getName();
                Class<?> fieldClass = ci.fields[i].getType();
                String typeDescriptor = toTypeDescriptor(fieldClass);

                Method getter = ci.getters[i];
                boolean useGetter = ((field.getModifiers() & Modifier.PUBLIC) == 0) && getter != null;

                mv.visitLabel(label);
                if (i == 0) {
                    mv.visitFrame(Opcodes.F_APPEND, 1, classNameX, 0, null);
                } else {
                    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                }

                // Read instance argument
                mv.visitVarInsn(ALOAD, 3);

                if (useGetter) {
                    // call getField
                    mv.visitMethodInsn(INVOKEVIRTUAL, className, getter.getName(), "()" + typeDescriptor);
                } else {
                    // Read field
                    mv.visitFieldInsn(GETFIELD, className, fieldName, typeDescriptor);
                }

                // Box 
                box(mv, fieldClass);

                mv.visitInsn(ARETURN);
            }

        }

        mv.visitLabel(elseLabel);
        if (count > 0) {
            mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        }
        mv.visitTypeInsn(NEW, "org/simantics/databoard/binding/error/BindingException");
        mv.visitInsn(DUP);
        mv.visitLdcInsn("Illegal field index");
        mv.visitMethodInsn(INVOKESPECIAL, "org/simantics/databoard/binding/error/BindingException", "<init>",
                "(Ljava/lang/String;)V");
        mv.visitInsn(ATHROW);

        // End 
        Label l19 = new Label();
        mv.visitLabel(l19);
        mv.visitLocalVariable("this", "L" + className + ";", null, l0, l19, 0);
        mv.visitLocalVariable("obj", "Ljava/lang/Object;", null, l0, l19, 1);
        mv.visitLocalVariable("index", "I", null, l0, l19, 2);
        //mv.visitLocalVariable("x", "Lorg/simantics/databoard/binding/reflection/MyClass;", null, l1, l19, 3);
        mv.visitMaxs(3, 4);
        mv.visitEnd();
    }

    // Create
    {
        mv = cv.visitMethod(ACC_PUBLIC + ACC_VARARGS, "create", "([Ljava/lang/Object;)Ljava/lang/Object;", null,
                new String[] { "org/simantics/databoard/binding/error/BindingException" });
        if (ci.beanConstructor != null) {
            mv.visitCode();
            Label l0 = new Label();
            mv.visitLabel(l0);
            mv.visitTypeInsn(NEW, className);
            mv.visitInsn(DUP);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKESPECIAL, className, "<init>",
                    "(Lorg/simantics/databoard/binding/Binding;)V");
            mv.visitVarInsn(ASTORE, 2);
            Label l1 = new Label();
            mv.visitLabel(l1);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitVarInsn(ALOAD, 2);
            mv.visitVarInsn(ALOAD, 1);
            mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "setComponents",
                    "(Ljava/lang/Object;[Ljava/lang/Object;)V");
            Label l2 = new Label();
            mv.visitLabel(l2);
            mv.visitVarInsn(ALOAD, 2);
            mv.visitInsn(ARETURN);
            Label l3 = new Label();
            mv.visitLabel(l3);
            mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l3, 0);
            mv.visitLocalVariable("values", "[Ljava/lang/Object;", null, l0, l3, 1);
            //mv.visitLocalVariable("x", "L"+className+";", null, l1, l3, 2);
            mv.visitMaxs(3, 3);
            mv.visitEnd();
        } else if (ci.argsConstructor != null) {
            mv.visitCode();
            Label l0 = new Label();
            mv.visitLabel(l0);
            mv.visitTypeInsn(NEW, className);
            mv.visitInsn(DUP);

            String constArgsDescriptor = "(";
            Class<?>[] args = ci.argsConstructor.getParameterTypes();
            for (int i = 0; i < count; i++) {
                Label label = new Label();
                Class<?> field = args[i];
                String fieldName = field.getName();
                Method getter = ci.getters[i];
                Class<?> fieldClass = ci.fields[i].getType();
                Class<?> boxClass = getBoxClass(fieldClass);
                String typeDescriptor = toTypeDescriptor(fieldClass);
                String boxTypeDescriptor = toTypeDescriptor(boxClass);
                constArgsDescriptor += typeDescriptor;

                mv.visitLabel(label);
                mv.visitVarInsn(ALOAD, 1);
                if (i < 6) {
                    mv.visitInsn(ICONST_0 + i);
                } else {
                    mv.visitIntInsn(BIPUSH, i);
                }

                mv.visitInsn(AALOAD);
                mv.visitTypeInsn(CHECKCAST, toClassCanonicalName(boxClass));
                unbox(mv, fieldClass);
            }

            Label l17 = new Label();
            mv.visitLabel(l17);
            constArgsDescriptor += ")V";
            mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", constArgsDescriptor);
            mv.visitInsn(ARETURN);
            Label l18 = new Label();
            mv.visitLabel(l18);
            mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l18, 0);
            mv.visitLocalVariable("values", "[Ljava/lang/Object;", null, l0, l18, 1);
            mv.visitMaxs(21, 2);
            mv.visitEnd();

        } else {
            mv.visitCode();
            Label l0 = new Label();
            mv.visitLabel(l0);
            mv.visitTypeInsn(NEW, className);
            mv.visitInsn(DUP);
            mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "()V");
            mv.visitVarInsn(ASTORE, 2);
            Label l1 = new Label();
            mv.visitLabel(l1);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitVarInsn(ALOAD, 2);
            mv.visitVarInsn(ALOAD, 1);
            mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "setComponents",
                    "(Ljava/lang/Object;[Ljava/lang/Object;)V");
            Label l2 = new Label();
            mv.visitLabel(l2);
            mv.visitVarInsn(ALOAD, 2);
            mv.visitInsn(ARETURN);
            Label l3 = new Label();
            mv.visitLabel(l3);
            mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l3, 0);
            mv.visitLocalVariable("values", "[Ljava/lang/Object;", null, l0, l3, 1);
            //mv.visitLocalVariable("x", "L"+className+";", null, l1, l3, 2);
            mv.visitMaxs(3, 3);
            mv.visitEnd();
        }
    }

    // CreatePartial
    mv = cv.visitMethod(ACC_PUBLIC, "createPartial", "()Ljava/lang/Object;", null,
            new String[] { "org/simantics/databoard/binding/error/BindingException" });
    if (ci.beanConstructor != null) {
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitTypeInsn(NEW, className);
        mv.visitInsn(DUP);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "(Lorg/simantics/databoard/binding/Binding;)V");
        mv.visitInsn(ARETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l1, 0);
        mv.visitMaxs(3, 1);
        mv.visitEnd();
    } else if (ci.noArgsConstructor != null) {
        // return new MyClass();
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitTypeInsn(NEW, className);
        mv.visitInsn(DUP);
        mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "()V");
        mv.visitInsn(ARETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l1, 0);
        mv.visitMaxs(2, 1);
        mv.visitEnd();
    } else {
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitIntInsn(BIPUSH, count);
        mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
        mv.visitVarInsn(ASTORE, 1);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitInsn(ICONST_0);
        mv.visitVarInsn(ISTORE, 2);
        Label l2 = new Label();
        mv.visitLabel(l2);
        Label l3 = new Label();
        mv.visitJumpInsn(GOTO, l3);
        Label l4 = new Label();
        mv.visitLabel(l4);
        mv.visitFrame(Opcodes.F_APPEND, 2, new Object[] { "[Ljava/lang/Object;", Opcodes.INTEGER }, 0, null);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, bindingClassName, "componentBindings",
                "[Lorg/simantics/databoard/binding/Binding;");
        mv.visitVarInsn(ILOAD, 2);
        mv.visitInsn(AALOAD);
        mv.visitVarInsn(ASTORE, 3);
        Label l5 = new Label();
        mv.visitLabel(l5);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitVarInsn(ILOAD, 2);
        mv.visitVarInsn(ALOAD, 3);
        mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/Binding", "createDefault",
                "()Ljava/lang/Object;");
        mv.visitInsn(AASTORE);
        Label l6 = new Label();
        mv.visitLabel(l6);
        mv.visitIincInsn(2, 1);
        mv.visitLabel(l3);
        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        mv.visitVarInsn(ILOAD, 2);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitInsn(ARRAYLENGTH);
        mv.visitJumpInsn(IF_ICMPLT, l4);
        Label l7 = new Label();
        mv.visitLabel(l7);
        mv.visitLineNumber(109, l7);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "create",
                "([Ljava/lang/Object;)Ljava/lang/Object;");
        mv.visitInsn(ARETURN);
        Label l8 = new Label();
        mv.visitLabel(l8);
        mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, l8, 0);
        mv.visitLocalVariable("values", "[Ljava/lang/Object;", null, l1, l8, 1);
        mv.visitLocalVariable("i", "I", null, l2, l7, 2);
        mv.visitLocalVariable("fb", "Lorg/simantics/databoard/binding/Binding;", null, l5, l6, 3);
        mv.visitMaxs(3, 4);
        mv.visitEnd();
    }

    // setComponent
    {
        mv = cv.visitMethod(ACC_PUBLIC, "setComponent", "(Ljava/lang/Object;ILjava/lang/Object;)V", null,
                new String[] { "org/simantics/databoard/binding/error/BindingException" });
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitTypeInsn(CHECKCAST, className);
        mv.visitVarInsn(ASTORE, 4);
        Label endLabel = new Label();
        Label l1 = new Label();
        mv.visitLabel(l1);

        Label elseLabel = new Label();
        Label labels[] = new Label[count];
        for (int i = 0; i < count; i++)
            labels[i] = new Label();

        if (count > 0) {
            mv.visitVarInsn(ILOAD, 2);
            mv.visitTableSwitchInsn(0, count - 1, elseLabel, labels);

            for (int i = 0; i < count; i++) {
                Label label = labels[i];
                mv.visitLabel(label);
                Field field = ci.fields[i];
                String fieldName = field.getName();
                Class<?> fieldClass = ci.fields[i].getType();
                Class<?> boxClass = getBoxClass(fieldClass);
                String typeDescriptor = toTypeDescriptor(fieldClass);
                String boxTypeDescriptor = toTypeDescriptor(boxClass);

                Method setter = ci.setters[i];
                Class<?> setterClass = setter != null ? setter.getParameterTypes()[0] : null;
                boolean useSetter = ((field.getModifiers() & Modifier.PUBLIC) == 0) && setter != null;

                if (i == 0) {
                    mv.visitFrame(Opcodes.F_APPEND, 1, classNameX, 0, null);
                } else {
                    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                }
                mv.visitVarInsn(ALOAD, 4);
                mv.visitVarInsn(ALOAD, 3);
                mv.visitTypeInsn(CHECKCAST, toClassCanonicalName(boxClass));

                if (useSetter) {
                    unbox(mv, setterClass);
                    mv.visitMethodInsn(INVOKEVIRTUAL, className, setter.getName(), "(" + typeDescriptor + ")V");
                } else {
                    unbox(mv, fieldClass);
                    mv.visitFieldInsn(PUTFIELD, className, field.getName(), typeDescriptor);
                }
                mv.visitInsn(RETURN);
            }
        }

        mv.visitLabel(elseLabel);
        mv.visitLineNumber(178, elseLabel);
        if (count > 0) {
            mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        }
        mv.visitTypeInsn(NEW, "org/simantics/databoard/binding/error/BindingException");
        mv.visitInsn(DUP);
        mv.visitLdcInsn("Illegal field index");
        mv.visitMethodInsn(INVOKESPECIAL, "org/simantics/databoard/binding/error/BindingException", "<init>",
                "(Ljava/lang/String;)V");
        mv.visitInsn(ATHROW);

        mv.visitLabel(endLabel);
        mv.visitLocalVariable("this", "L" + bindingClassName + ";", null, l0, endLabel, 0);
        mv.visitLocalVariable("obj", "Ljava/lang/Object;", null, l0, endLabel, 1);
        mv.visitLocalVariable("index", "I", null, l0, endLabel, 2);
        mv.visitLocalVariable("value", "Ljava/lang/Object;", null, l0, endLabel, 3);
        //mv.visitLocalVariable("x", "L"+className+";", null, l1, endLabel, 4);
        mv.visitMaxs(3, 5);
        mv.visitEnd();
    }

    // IsImmutable
    {
        mv = cv.visitMethod(ACC_PUBLIC, "isImmutable", "()Z", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitInsn(ICONST_0);
        mv.visitInsn(IRETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", "L" + className + ";", null, l0, l1, 0);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }

    // IsInstance
    {
        mv = cv.visitMethod(ACC_PUBLIC, "isInstance", "(Ljava/lang/Object;)Z", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitTypeInsn(INSTANCEOF, className);
        mv.visitInsn(IRETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", "L" + className + ";", null, l0, l1, 0);
        mv.visitLocalVariable("obj", "Ljava/lang/Object;", null, l0, l1, 1);
        mv.visitMaxs(1, 2);
        mv.visitEnd();
    }

    // SetComponents
    {
        mv = cv.visitMethod(ACC_PUBLIC + ACC_VARARGS, "setComponents",
                "(Ljava/lang/Object;[Ljava/lang/Object;)V", null,
                new String[] { "org/simantics/databoard/binding/error/BindingException" });
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitTypeInsn(CHECKCAST, className);
        mv.visitVarInsn(ASTORE, 3);
        Label firstLabel = l0;

        for (int i = 0; i < count; i++) {
            Label label = new Label();
            if (firstLabel == l0)
                firstLabel = label;
            Field field = ci.fields[i];
            String fieldName = field.getName();
            Class<?> fieldClass = ci.fields[i].getType();
            Class<?> boxClass = getBoxClass(fieldClass);
            String typeDescriptor = toTypeDescriptor(fieldClass);
            String boxTypeDescriptor = toTypeDescriptor(boxClass);

            Method setter = ci.setters[i];
            Class<?> setterClass = setter != null ? setter.getParameterTypes()[0] : null;
            boolean useSetter = ((field.getModifiers() & Modifier.PUBLIC) == 0) && setter != null;

            mv.visitLabel(label);
            mv.visitVarInsn(ALOAD, 3);
            mv.visitVarInsn(ALOAD, 2);
            if (i < 6) {
                mv.visitInsn(ICONST_0 + i);
            } else {
                mv.visitIntInsn(BIPUSH, i);
            }
            mv.visitInsn(AALOAD);
            mv.visitTypeInsn(CHECKCAST, toClassCanonicalName(boxClass));

            if (useSetter) {
                unbox(mv, setterClass);
                mv.visitMethodInsn(INVOKEVIRTUAL, className, setter.getName(), "(" + typeDescriptor + ")V");
            } else {
                unbox(mv, fieldClass);
                mv.visitFieldInsn(PUTFIELD, className, field.getName(), typeDescriptor);
            }

        }
        Label l17 = new Label();
        mv.visitLabel(l17);
        mv.visitInsn(RETURN);
        Label endLabel = new Label();
        mv.visitLabel(endLabel);
        mv.visitLocalVariable("this", "L" + className + ";", null, l0, endLabel, 0);
        mv.visitLocalVariable("obj", "Ljava/lang/Object;", null, l0, endLabel, 1);
        mv.visitLocalVariable("value", "[Ljava/lang/Object;", null, l0, endLabel, 2);
        //mv.visitLocalVariable("x", "Lorg/simantics/databoard/binding/reflection/MyClass;", null, firstLabel, endLabel, 3);
        mv.visitMaxs(3, 4);
        mv.visitEnd();
    }

    // Add primitive setters
    {
        addGetSetPrimitive(ci, cv, "Boolean", "Z", bindingClassName);
        addGetSetPrimitive(ci, cv, "Byte", "B", bindingClassName);
        addGetSetPrimitive(ci, cv, "Int", "I", bindingClassName);
        addGetSetPrimitive(ci, cv, "Long", "J", bindingClassName);
        addGetSetPrimitive(ci, cv, "Float", "F", bindingClassName);
        addGetSetPrimitive(ci, cv, "Double", "D", bindingClassName);
    }

    cv.visitEnd();
    return cw.toByteArray();
}

From source file:org.simantics.databoard.tests.testASM.java

License:Open Source License

public static byte[] dump() throws Exception {
    ClassWriter cw = new ClassWriter(0);
    FieldVisitor fv;//from   w w  w.ja va 2 s.  c  o m
    MethodVisitor mv;
    AnnotationVisitor av0;

    cw.visit(V1_6, ACC_SUPER, "org/simantics/data/Virhe", null, "java/lang/Object", null);

    cw.visitSource("testASM.java", null);

    {
        mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitLineNumber(157, l0);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
        mv.visitInsn(RETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", "Lorg/simantics/data/Virhe;", null, l0, l1, 0);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }
    cw.visitEnd();

    return cw.toByteArray();
}

From source file:org.simantics.databoard.tests.testASM.java

License:Open Source License

void createImpl(String className, Class<?> interfaze, ClassWriter cw) {
    FieldVisitor fv;/*from   w  ww  .ja  v a 2s. c  o  m*/
    MethodVisitor mv;
    AnnotationVisitor av0;

    java.lang.reflect.Method[] methods = interfaze.getMethods();
    Arrays.sort(methods, MethodInterfaceUtil.methodComparator);

    String classResourceName = className.replaceAll("\\.", "/");
    String classTypeDescriptor = "L" + classResourceName + ";";
    String interfaceResourceName = classResourceName.substring(0, classResourceName.length() - 5);
    String interfaceTypeDescriptor = "L" + interfaceResourceName + ";";

    cw.visit(V1_6, ACC_SUPER | ACC_PUBLIC, classResourceName, null, "java/lang/Object",
            new String[] { interfaceResourceName });

    // Imports
    Set<Class<?>> imports = new HashSet<Class<?>>();
    imports.add(AsyncResult.class);
    imports.add(ExecutionError.class);
    imports.add(Method.class);
    imports.add(interfaze);

    for (java.lang.reflect.Method m : methods) {
        for (Class<?> clazz : m.getExceptionTypes()) {
            imports.add(clazz);
        }
        for (Class<?> clazz : m.getParameterTypes()) {
            imports.add(clazz);
        }
        imports.add(m.getReturnType());
    }

    for (Class<?> clazz : imports) {
        if (clazz.isPrimitive())
            continue;
        String name = clazz.getName();
        if (name.startsWith("java.lang"))
            continue;
        String resourceName = name.replaceAll("\\.", "/");
        String outerName = resourceName.contains("$") ? resourceName.substring(0, resourceName.indexOf('$'))
                : null;
        String className_ = clazz.isArray()
                ? clazz.getSimpleName().substring(0, clazz.getSimpleName().length() - 2)
                : clazz.getSimpleName();
        int access = ACC_PUBLIC + ACC_STATIC + (clazz.isInterface() ? ACC_INTERFACE + ACC_ABSTRACT : 0);
        //         System.out.printf("name=%s, outerName=%s, innerName=%s\n", resourceName, outerName, className_);
        cw.visitInnerClass(resourceName, outerName, className_, access);
    }

    // Fields
    {
        fv = cw.visitField(ACC_FINAL + ACC_STATIC, "interfaze", "Ljava/lang/Class;", "Ljava/lang/Class<*>;",
                null);
        fv.visitEnd();
    }
    {
        fv = cw.visitField(ACC_FINAL + ACC_STATIC, "bindings",
                "[Lorg/simantics/databoard/method/MethodBinding;", null, null);
        fv.visitEnd();
    }
    {
        fv = cw.visitField(0, "mi", "Lorg/simantics/data/session/MethodInterface;", null, null);
        fv.visitEnd();
    }
    {
        fv = cw.visitField(0, "methods", "[Lorg/simantics/data/session/MethodInterface$Method;", null, null);
        fv.visitEnd();
    }

    // Init class - static {}
    {
        mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitLdcInsn(Type.getType(interfaceTypeDescriptor));
        mv.visitFieldInsn(PUTSTATIC, classResourceName, "interfaze", "Ljava/lang/Class;");
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitFieldInsn(GETSTATIC, classResourceName, "interfaze", "Ljava/lang/Class;");
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethods", "()[Ljava/lang/reflect/Method;");
        mv.visitVarInsn(ASTORE, 0);
        Label l2 = new Label();
        mv.visitLabel(l2);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETSTATIC, "org/simantics/data/network/MethodInterfaceUtil", "methodComparator",
                "Ljava/util/Comparator;");
        mv.visitMethodInsn(INVOKESTATIC, "java/util/Arrays", "sort",
                "([Ljava/lang/Object;Ljava/util/Comparator;)V");
        Label l3 = new Label();
        mv.visitLabel(l3);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitInsn(ARRAYLENGTH);
        mv.visitTypeInsn(ANEWARRAY, "org/simantics/databoard/method/MethodBinding");
        mv.visitFieldInsn(PUTSTATIC, classResourceName, "bindings",
                "[Lorg/simantics/databoard/method/MethodBinding;");
        Label l4 = new Label();
        mv.visitLabel(l4);
        mv.visitInsn(ICONST_0);
        mv.visitVarInsn(ISTORE, 1);
        Label l5 = new Label();
        mv.visitLabel(l5);
        Label l6 = new Label();
        mv.visitJumpInsn(GOTO, l6);
        Label l7 = new Label();
        mv.visitLabel(l7);
        mv.visitFrame(Opcodes.F_APPEND, 2, new Object[] { "[Ljava/lang/reflect/Method;", Opcodes.INTEGER }, 0,
                null);
        mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings",
                "[Lorg/simantics/databoard/method/MethodBinding;");
        mv.visitVarInsn(ILOAD, 1);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ILOAD, 1);
        mv.visitInsn(AALOAD);
        mv.visitMethodInsn(INVOKESTATIC, "org/simantics/databoard/DataTypes", "getMethodBinding",
                "(Ljava/lang/reflect/Method;)Lorg/simantics/databoard/method/MethodBinding;");
        mv.visitInsn(AASTORE);
        Label l8 = new Label();
        mv.visitLabel(l8);
        mv.visitIincInsn(1, 1);
        mv.visitLabel(l6);
        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        mv.visitVarInsn(ILOAD, 1);
        mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings",
                "[Lorg/simantics/databoard/method/MethodBinding;");
        mv.visitInsn(ARRAYLENGTH);
        mv.visitJumpInsn(IF_ICMPLT, l7);
        Label l9 = new Label();
        mv.visitLabel(l9);
        mv.visitInsn(RETURN);
        Label l10 = new Label();
        mv.visitLabel(l10);
        mv.visitLocalVariable("methods", "[Ljava/lang/reflect/Method;", null, l2, l10, 0);
        mv.visitLocalVariable("i", "I", null, l5, l9, 1);
        mv.visitMaxs(4, 2);
        mv.visitEnd();
    }

    // Constructor
    {
        mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Lorg/simantics/data/session/MethodInterface;)V", null,
                new String[] { "org/simantics/data/error/MethodNotSupportedException" });
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitFieldInsn(PUTFIELD, classResourceName, "mi", "Lorg/simantics/data/session/MethodInterface;");
        Label l2 = new Label();
        mv.visitLabel(l2);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings",
                "[Lorg/simantics/databoard/method/MethodBinding;");
        mv.visitInsn(ARRAYLENGTH);
        mv.visitTypeInsn(ANEWARRAY, "org/simantics/data/session/MethodInterface$Method");
        mv.visitFieldInsn(PUTFIELD, classResourceName, "methods",
                "[Lorg/simantics/data/session/MethodInterface$Method;");
        Label l3 = new Label();
        mv.visitLabel(l3);
        mv.visitInsn(ICONST_0);
        mv.visitVarInsn(ISTORE, 2);
        Label l4 = new Label();
        mv.visitLabel(l4);
        Label l5 = new Label();
        mv.visitJumpInsn(GOTO, l5);
        Label l6 = new Label();
        mv.visitLabel(l6);
        mv.visitFrame(Opcodes.F_FULL, 3, new Object[] { classResourceName,
                "org/simantics/data/session/MethodInterface", Opcodes.INTEGER }, 0, new Object[] {});
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, classResourceName, "methods",
                "[Lorg/simantics/data/session/MethodInterface$Method;");
        mv.visitVarInsn(ILOAD, 2);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings",
                "[Lorg/simantics/databoard/method/MethodBinding;");
        mv.visitVarInsn(ILOAD, 2);
        mv.visitInsn(AALOAD);
        mv.visitMethodInsn(INVOKEINTERFACE, "org/simantics/data/session/MethodInterface", "getMethod",
                "(Lorg/simantics/databoard/method/MethodBinding;)Lorg/simantics/data/session/MethodInterface$Method;");
        mv.visitInsn(AASTORE);
        Label l7 = new Label();
        mv.visitLabel(l7);
        mv.visitIincInsn(2, 1);
        mv.visitLabel(l5);
        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        mv.visitVarInsn(ILOAD, 2);
        mv.visitFieldInsn(GETSTATIC, classResourceName, "bindings",
                "[Lorg/simantics/databoard/method/MethodBinding;");
        mv.visitInsn(ARRAYLENGTH);
        mv.visitJumpInsn(IF_ICMPLT, l6);
        Label l8 = new Label();
        mv.visitLabel(l8);
        mv.visitInsn(RETURN);
        Label l9 = new Label();
        mv.visitLabel(l9);
        mv.visitLocalVariable("this", classTypeDescriptor, null, l0, l9, 0);
        mv.visitLocalVariable("mi", "Lorg/simantics/data/session/MethodInterface;", null, l0, l9, 1);
        mv.visitLocalVariable("i", "I", null, l4, l8, 2);
        mv.visitMaxs(5, 3);
        mv.visitEnd();
    }

    // Method
    int methodNumber = 0;
    for (java.lang.reflect.Method m : methods) {
        String typeDescription = "";
        Class<?>[] params = m.getParameterTypes();
        for (int i = 0; i < params.length; i++) {
            if (i > 0)
                typeDescription += ";";
            typeDescription += classToTypeDescriptor(params[i]);
        }
        typeDescription = "(" + typeDescription + ")" + classToTypeDescriptor(m.getReturnType());
        System.out.println(typeDescription + " " + m.getName());

        Class<?>[] exceptions = m.getExceptionTypes();
        String[] exceptionResourceNames = new String[exceptions.length];
        for (int i = 0; i < exceptionResourceNames.length; i++) {
            exceptionResourceNames[i] = exceptions[i].getName().replaceAll("\\.", "/");
        }

        // Registers
        // 0 - this
        // 1..argRegs args
        // argRegs+1 - method
        // argRegs+2 - args (the array)
        // argRegs+3 - AsyncResult
        // argRegs+4 - e
        // argRegs+5 - ExecutionError.cause
        // argRegs+6 - e

        int argRegs = 0;
        for (int i = 0; i < params.length; i++) {
            Class<?> clazz = params[i];
            argRegs++;
            if (clazz == long.class || clazz == float.class || clazz == Double.class)
                argRegs++;
        }

        mv = cw.visitMethod(ACC_PUBLIC, m.getName(), typeDescription, null, exceptionResourceNames);
        mv.visitCode();
        Label l0 = new Label();
        Label l1 = new Label();
        Label l2 = new Label();
        mv.visitTryCatchBlock(l0, l1, l2, "org/simantics/data/session/MethodInterface$ExecutionError");
        Label l3 = new Label();
        mv.visitTryCatchBlock(l0, l1, l3, "java/lang/InterruptedException");
        Label l4 = new Label();
        mv.visitLabel(l4);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, classResourceName, "methods",
                "[Lorg/simantics/data/session/MethodInterface$Method;");
        // Method m and puts into register 
        mv.visitLdcInsn(Integer.valueOf(methodNumber));
        mv.visitInsn(AALOAD);
        mv.visitVarInsn(ASTORE, argRegs + 1);
        Label l5 = new Label();
        mv.visitLabel(l5);
        mv.visitLdcInsn(Integer.valueOf(params.length));
        mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");

        int register = 1; // argument register   
        for (int i = 0; i < params.length; i++) {
            Class<?> clazz = params[i];
            mv.visitInsn(DUP);
            mv.visitLdcInsn(Integer.valueOf(i));

            if (clazz == byte.class) {
                mv.visitVarInsn(ILOAD, register++);
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;");
            } else if (clazz == char.class) {
                mv.visitVarInsn(ILOAD, register++);
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;");
            } else if (clazz == boolean.class) {
                mv.visitVarInsn(ILOAD, register++);
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;");
            } else if (clazz == byte.class) {
                mv.visitVarInsn(ILOAD, register++);
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;");
            } else if (clazz == int.class) {
                mv.visitVarInsn(ILOAD, register++);
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
            } else if (clazz == long.class) {
                mv.visitVarInsn(LLOAD, register);
                register += 2;
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(F)Ljava/lang/Long;");
            } else if (clazz == float.class) {
                mv.visitVarInsn(FLOAD, register);
                register += 2;
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;");
            } else if (clazz == Double.class) {
                mv.visitVarInsn(DLOAD, register);
                register += 2;
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;");
            } else {
                // Push argument to stack 
                mv.visitVarInsn(ALOAD, register++);
            }
            mv.visitInsn(AASTORE);
        }

        // Store args to argRegs+2
        mv.visitVarInsn(ASTORE, argRegs + 2);
        Label l6 = new Label();
        mv.visitLabel(l6);
        mv.visitVarInsn(ALOAD, argRegs + 1 /* m */);
        mv.visitVarInsn(ALOAD, argRegs + 2 /*args*/);
        mv.visitMethodInsn(INVOKEINTERFACE, "org/simantics/data/session/MethodInterface$Method", "invoke",
                "(Ljava/lang/Object;)Lorg/simantics/data/session/MethodInterface$AsyncResult;");
        mv.visitVarInsn(ASTORE, argRegs + 3);
        mv.visitLabel(l0);
        mv.visitVarInsn(ALOAD, argRegs + 3);
        mv.visitMethodInsn(INVOKEINTERFACE, "org/simantics/data/session/MethodInterface$AsyncResult",
                "waitForResponse", "()Ljava/lang/Object;");
        // TODO Return typecase result
        Class<?> returnType = m.getReturnType();

        if (returnType == void.class) {
            mv.visitInsn(POP);
            mv.visitInsn(RETURN);
        } else if (returnType == int.class) {
            mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I");
            mv.visitLabel(l1);
            mv.visitInsn(IRETURN);
        } else if (returnType == byte.class) {
            mv.visitTypeInsn(CHECKCAST, "java/lang/Byte");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "B()");
            mv.visitLabel(l1);
            mv.visitInsn(IRETURN);
        } else if (returnType == char.class) {
            mv.visitTypeInsn(CHECKCAST, "java/lang/Character");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C");
            mv.visitLabel(l1);
            mv.visitInsn(IRETURN);
        } else if (returnType == boolean.class) {
            mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z");
            mv.visitLabel(l1);
            mv.visitInsn(IRETURN);
        } else if (returnType == short.class) {
            mv.visitTypeInsn(CHECKCAST, "java/lang/Short");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S");
            mv.visitLabel(l1);
            mv.visitInsn(IRETURN);
        } else if (returnType == long.class) {
            mv.visitTypeInsn(CHECKCAST, "java/lang/Long");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J");
            mv.visitLabel(l1);
            mv.visitInsn(LRETURN);
        } else if (returnType == double.class) {
            mv.visitTypeInsn(CHECKCAST, "java/lang/Double");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D");
            mv.visitLabel(l1);
            mv.visitInsn(DRETURN);
        } else if (returnType == float.class) {
            mv.visitTypeInsn(CHECKCAST, "java/lang/Float");
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F");
            mv.visitLabel(l1);
            mv.visitInsn(FRETURN);
        } else {
            // Object
            mv.visitTypeInsn(CHECKCAST, returnType.getName().replaceAll("\\.", "/"));
            mv.visitLabel(l1);
            mv.visitInsn(ARETURN);
        }

        // Handle exceptions
        mv.visitLabel(l2);
        mv.visitFrame(Opcodes.F_FULL, argRegs + 4,
                new Object[] { classResourceName, "java/lang/Integer",
                        "org/simantics/data/session/MethodInterface$Method", "[Ljava/lang/Object;",
                        "org/simantics/data/session/MethodInterface$AsyncResult" },
                1, new Object[] { "org/simantics/data/session/MethodInterface$ExecutionError" });
        mv.visitVarInsn(ASTORE, argRegs + 4);
        Label l7 = new Label();
        mv.visitLabel(l7);
        mv.visitVarInsn(ALOAD, argRegs + 4);
        mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/data/session/MethodInterface$ExecutionError",
                "getError", "()Ljava/lang/Object;");
        mv.visitVarInsn(ASTORE, argRegs + 5); // argRegs+5 <- ExecutionError.cause

        Class<?>[] exceptionClasses = m.getExceptionTypes();
        Label nextException[] = new Label[exceptionClasses.length];
        for (int i = 0; i < exceptionClasses.length; i++) {
            Class<?> exceptionClass = exceptionClasses[i];
            String exceptionClassResourceName = exceptionClass.getName().replaceAll("\\.", "/");
            nextException[i] = new Label();
            // If instanceof MyException
            Label l8 = new Label();
            mv.visitLabel(l8);
            mv.visitVarInsn(ALOAD, argRegs + 5); // Cause
            mv.visitTypeInsn(INSTANCEOF, exceptionClassResourceName);
            mv.visitJumpInsn(IFEQ, nextException[i]); // If not, go to ExecutionError
            // If so, throw it
            mv.visitVarInsn(ALOAD, argRegs + 5); // e
            mv.visitTypeInsn(CHECKCAST, exceptionClassResourceName);
            mv.visitInsn(ATHROW);
            mv.visitLabel(nextException[i]);
        }

        // ExecutionError
        mv.visitFrame(
                Opcodes.F_APPEND, argRegs + 1, new Object[] {
                        "org/simantics/data/session/MethodInterface$ExecutionError", "java/lang/Object" },
                0, null);
        mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
        mv.visitInsn(DUP);
        mv.visitVarInsn(ALOAD, argRegs + 4);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/Throwable;)V");
        mv.visitInsn(ATHROW);

        // InteruptedException
        mv.visitLabel(l3);
        mv.visitFrame(Opcodes.F_FULL, argRegs + 4,
                new Object[] { classResourceName, "java/lang/Integer",
                        "org/simantics/data/session/MethodInterface$Method", "[Ljava/lang/Object;",
                        "org/simantics/data/session/MethodInterface$AsyncResult" },
                1, new Object[] { "java/lang/InterruptedException" });
        mv.visitVarInsn(ASTORE, argRegs + 4);
        Label l10 = new Label();
        mv.visitLabel(l10);
        mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
        mv.visitInsn(DUP);
        mv.visitVarInsn(ALOAD, argRegs + 4);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/Throwable;)V");
        mv.visitInsn(ATHROW);

        Label l11 = new Label();
        mv.visitLabel(l11);
        mv.visitLocalVariable("this", classTypeDescriptor, null, l4, l11, 0);
        //      mv.visitLocalVariable("arg1", "Ljava/lang/Integer;", null, l4, l11, 1);
        register = 1;
        for (int i = 0; i < params.length; i++) {
            Class<?> clazz = params[i];
            mv.visitLocalVariable("arg" + (i + 1), classToTypeDescriptor(clazz), null, l4, l11, register);
            register++;
            if (clazz == long.class || clazz == float.class || clazz == Double.class)
                argRegs++;
        }
        mv.visitLocalVariable("m", "Lorg/simantics/data/session/MethodInterface$Method;", null, l5, l11,
                argRegs + 1);
        mv.visitLocalVariable("args", "[Ljava/lang/Object;", null, l6, l11, argRegs + 2);
        mv.visitLocalVariable("result", "Lorg/simantics/data/session/MethodInterface$AsyncResult;", null, l0,
                l11, argRegs + 3);
        mv.visitLocalVariable("e", "Lorg/simantics/data/session/MethodInterface$ExecutionError;", null, l7, l3,
                argRegs + 4);
        mv.visitLocalVariable("cause", "Ljava/lang/Object;", null, l7, l3, argRegs + 5);
        mv.visitLocalVariable("e", "Ljava/lang/InterruptedException;", null, l10, l11, argRegs + 4);
        mv.visitMaxs(argRegs + 3, argRegs + 6);
        mv.visitEnd();
        methodNumber++;
    }

    cw.visitEnd();
}

From source file:org.spongepowered.despector.emitter.bytecode.type.BytecodeMethodEntryEmitter.java

License:Open Source License

@Override
public boolean emit(BytecodeEmitterContext ctx, MethodEntry ast) {
    int acc = 0;// w w  w.  j  a v  a2  s .com
    switch (ast.getAccessModifier()) {
    case PUBLIC:
        acc |= ACC_PUBLIC;
        break;
    case PRIVATE:
        acc |= ACC_PRIVATE;
        break;
    case PROTECTED:
        acc |= ACC_PROTECTED;
        break;
    default:
    }
    if (ast.isStatic()) {
        acc |= ACC_STATIC;
    }
    if (ast.isAbstract()) {
        acc |= ACC_ABSTRACT;
    }
    if (ast.isBridge()) {
        acc |= ACC_BRIDGE;
    }
    if (ast.isDeprecated()) {
        acc |= ACC_DEPRECATED;
    }
    if (ast.isFinal()) {
        acc |= ACC_FINAL;
    }
    if (ast.isNative()) {
        acc |= ACC_NATIVE;
    }
    if (ast.isStrictFp()) {
        acc |= ACC_STRICT;
    }
    if (ast.isSynchronized()) {
        acc |= ACC_SYNCHRONIZED;
    }
    if (ast.isSynthetic()) {
        acc |= ACC_SYNTHETIC;
    }
    if (ast.isVarargs()) {
        acc |= ACC_VARARGS;
    }
    MethodVisitor mv = ctx.getClassWriter().visitMethod(acc, ast.getName(), ast.getDescription(), null, null);
    ctx.setMethodVisitor(mv);
    mv.visitCode();
    Label start = new Label();
    mv.visitLabel(start);
    ctx.resetMaxs();
    for (Statement stmt : ast.getInstructions().getStatements()) {
        ctx.emitStatement(stmt);
    }
    Label end = new Label();
    mv.visitLabel(end);

    // TODO the indices we have for locals are in terms of the ir list and
    // are therefore useless now
    int maxLocal = 0;
    for (LocalInstance local : ast.getLocals().getAllInstances()) {
        if (local.getType().getDescriptor().startsWith("L")) {
            mv.visitLocalVariable(local.getName(), local.getType().getDescriptor(), local.getType().toString(),
                    start, end, local.getIndex());
        } else {
            mv.visitLocalVariable(local.getName(), local.getType().getDescriptor(), null, start, end,
                    local.getIndex());
        }
        maxLocal = Math.max(maxLocal, local.getIndex() + 1);
    }
    mv.visitMaxs(ctx.getMaxs(), maxLocal);
    mv.visitEnd();
    return true;
}

From source file:org.spongepowered.eventimplgen.factory.FactoryInterfaceGenerator.java

License:MIT License

private static void generateRealImpl(ClassWriter cw, CtType<?> event, String eventName, List<Property> params) {
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, EventImplGenTask.generateMethodName(event),
            getDescriptor(event, params), null, null);

    Label start = new Label();
    Label end = new Label();

    mv.visitCode();//from  w w  w.  j  a  v a2 s .  co m

    mv.visitLabel(start);

    mv.visitTypeInsn(NEW, eventName);
    mv.visitInsn(DUP);

    int[] slots = new int[params.size()];

    for (int i = 0, slot = 0; i < params.size(); i++, slot++) {
        Property param = params.get(i);
        slots[i] = slot;
        Type type = Type.getType(ClassGenerator.getTypeDescriptor(param.getType()));
        mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), slot); // Parameters start at slot 0 for static methods

        if (type.getSize() > 1) {
            slot++; // Skip over unusable following slot
        }
    }
    mv.visitMethodInsn(INVOKESPECIAL, eventName, "<init>", getDescriptor(null, params), false);

    mv.visitInsn(ARETURN);
    mv.visitLabel(end);

    for (int i = 0; i < params.size(); i++) {
        Property property = params.get(i);
        mv.visitLocalVariable(property.getName(), ClassGenerator.getTypeDescriptor(property.getType()), null,
                start, end, slots[i]);
        mv.visitParameter(property.getName(), 0);
    }

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

From source file:org.spongepowered.test.ast.LambdaTest.java

License:Open Source License

@Test
public void testLambda() {
    TestMethodBuilder builder = new TestMethodBuilder("test_mth", "()V");
    MethodVisitor mv = builder.getGenerator();
    Label start = new Label();
    mv.visitLabel(start);//from  w  w  w  .j  a v a  2s.c om
    if (TestHelper.IS_ECLIPSE) {
        mv.visitInvokeDynamicInsn("run", "()Ljava/lang/Runnable;", new Handle(H_INVOKESTATIC,
                "java/lang/invoke/LambdaMetafactory", "metafactory",
                "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"),
                new Object[] { Type.getType("()V"),
                        new Handle(H_INVOKESTATIC, "org/spongepowered/test/ast/LambdaTest", "lambda$0", "()V"),
                        Type.getType("()V") });
    } else {
        // javac adds an extra decoration to the lambda method name with the
        // name of the calling method
        mv.visitInvokeDynamicInsn("run", "()Ljava/lang/Runnable;", new Handle(H_INVOKESTATIC,
                "java/lang/invoke/LambdaMetafactory", "metafactory",
                "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"),
                new Object[] { Type.getType("()V"), new Handle(H_INVOKESTATIC,
                        "org/spongepowered/test/ast/LambdaTest", "lambda$test_lambda$0", "()V"),
                        Type.getType("()V") });
    }
    mv.visitVarInsn(ASTORE, 1);
    Label l1 = new Label();
    mv.visitLabel(l1);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(INVOKEINTERFACE, "java/lang/Runnable", "run", "()V", true);
    mv.visitInsn(RETURN);
    Label end = new Label();
    mv.visitLabel(end);
    mv.visitLocalVariable("this", "Lorg/spongepowered/test/ast/LambdaTest;", null, start, end, 0);
    mv.visitLocalVariable("r", "Ljava/lang/Runnable;", null, l1, end, 1);

    String insn = TestHelper.getAsString(builder.finish(), "test_mth");
    String good = "Runnable r = () -> System.out.println(\"Hello World\");\n" + "r.run();";
    Assert.assertEquals(good, insn);
}

From source file:org.spongepowered.test.ast.LambdaTest.java

License:Open Source License

@Test
public void testConsumer() {
    TestMethodBuilder builder = new TestMethodBuilder("test_mth", "()V");
    MethodVisitor mv = builder.getGenerator();
    Label start = new Label();
    mv.visitLabel(start);//from  w ww .  j av a  2 s  .c  om
    if (TestHelper.IS_ECLIPSE) {
        mv.visitInvokeDynamicInsn("accept", "()Ljava/util/function/Consumer;", new Handle(H_INVOKESTATIC,
                "java/lang/invoke/LambdaMetafactory", "metafactory",
                "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"),
                new Object[] {
                        Type.getType("(Ljava/lang/Object;)V"), new Handle(H_INVOKESTATIC,
                                "org/spongepowered/test/ast/LambdaTest", "lambda$1", "(Ljava/lang/Object;)V"),
                        Type.getType("(Ljava/lang/Object;)V") });
    } else {
        // javac adds an extra decoration to the lambda method name with the
        // name of the calling method
        mv.visitInvokeDynamicInsn("accept", "()Ljava/util/function/Consumer;", new Handle(H_INVOKESTATIC,
                "java/lang/invoke/LambdaMetafactory", "metafactory",
                "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"),
                new Object[] { Type.getType("(Ljava/lang/Object;)V"),
                        new Handle(H_INVOKESTATIC, "org/spongepowered/test/ast/LambdaTest",
                                "lambda$test_consumer$1", "(Ljava/lang/Object;)V"),
                        Type.getType("(Ljava/lang/Object;)V") });
    }
    mv.visitVarInsn(ASTORE, 1);
    Label l1 = new Label();
    mv.visitLabel(l1);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitInsn(ACONST_NULL);
    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/function/Consumer", "accept", "(Ljava/lang/Object;)V", true);
    mv.visitInsn(RETURN);
    Label end = new Label();
    mv.visitLabel(end);
    mv.visitLocalVariable("this", "Lorg/spongepowered/test/ast/LambdaTest;", null, start, end, 0);
    mv.visitLocalVariable("r", "Ljava/util/function/Consumer;",
            "Ljava/util/function/Consumer<Ljava/lang/Object;>;", l1, end, 1);

    String insn = TestHelper.getAsString(builder.finish(), "test_mth");
    String good = "java.util.function.Consumer<Object> r = (obj) -> System.out.println(\"Hello World\");\n"
            + "r.accept(null);";
    Assert.assertEquals(good, insn);
}

From source file:org.spongepowered.test.ast.LambdaTest.java

License:Open Source License

@Test
public void testProducer() {
    TestMethodBuilder builder = new TestMethodBuilder("test_mth", "()V");
    MethodVisitor mv = builder.getGenerator();
    Label start = new Label();
    mv.visitLabel(start);/* www.  ja  va2  s. c  o m*/
    if (TestHelper.IS_ECLIPSE) {
        mv.visitInvokeDynamicInsn("call", "()Ljava/util/concurrent/Callable;", new Handle(H_INVOKESTATIC,
                "java/lang/invoke/LambdaMetafactory", "metafactory",
                "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"),
                new Object[] {
                        Type.getType("()Ljava/lang/Object;"), new Handle(H_INVOKESTATIC,
                                "org/spongepowered/test/ast/LambdaTest", "lambda$2", "()Ljava/lang/Object;"),
                        Type.getType("()Ljava/lang/Object;") });
    } else {
        // javac adds an extra decoration to the lambda method name with the
        // name of the calling method
        mv.visitInvokeDynamicInsn("call", "()Ljava/util/concurrent/Callable;", new Handle(H_INVOKESTATIC,
                "java/lang/invoke/LambdaMetafactory", "metafactory",
                "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"),
                new Object[] { Type.getType("()Ljava/lang/Object;"),
                        new Handle(H_INVOKESTATIC, "org/spongepowered/test/ast/LambdaTest",
                                "lambda$test_producer$2", "()Ljava/lang/Object;"),
                        Type.getType("()Ljava/lang/Object;") });
    }
    mv.visitVarInsn(ASTORE, 1);
    Label l1 = new Label();
    mv.visitLabel(l1);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/concurrent/Callable", "call", "()Ljava/lang/Object;", true);
    mv.visitInsn(POP);
    mv.visitInsn(RETURN);
    Label end = new Label();
    mv.visitLabel(end);
    mv.visitLocalVariable("this", "Lorg/spongepowered/test/ast/LambdaTest;", null, start, end, 0);
    mv.visitLocalVariable("r", "Ljava/util/concurrent/Callable;",
            "Ljava/util/concurrent/Callable<Ljava/lang/Object;>;", l1, end, 1);

    String insn = TestHelper.getAsString(builder.finish(), "test_mth");
    String good = "java.util.concurrent.Callable<Object> r = () -> null;\n" + "r.call();";
    Assert.assertEquals(good, insn);
}

From source file:org.spongepowered.test.ast.LambdaTest.java

License:Open Source License

@Test
public void testMethodRef() {
    TestMethodBuilder builder = new TestMethodBuilder("test_mth", "(Ljava/lang/Runnable;)V");
    MethodVisitor mv = builder.getGenerator();
    Label start = new Label();
    mv.visitLabel(start);/*from  w  ww .j  a  va  2s  . c  om*/
    mv.visitVarInsn(ALOAD, 1);
    mv.visitInvokeDynamicInsn("run", "(Ljava/lang/Runnable;)Ljava/lang/Runnable;", new Handle(H_INVOKESTATIC,
            "java/lang/invoke/LambdaMetafactory", "metafactory",
            "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"),
            new Object[] { Type.getType("()V"),
                    new Handle(H_INVOKEINTERFACE, "java/lang/Runnable", "run", "()V"), Type.getType("()V") });
    mv.visitVarInsn(ASTORE, 2);
    Label l1 = new Label();
    mv.visitLabel(l1);
    mv.visitVarInsn(ALOAD, 2);
    mv.visitMethodInsn(INVOKEINTERFACE, "java/lang/Runnable", "run", "()V", true);
    mv.visitInsn(RETURN);
    Label end = new Label();
    mv.visitLabel(end);
    mv.visitLocalVariable("this", "Lorg/spongepowered/test/ast/LambdaTest;", null, start, end, 0);
    mv.visitLocalVariable("r", "Ljava/lang/Runnable;", null, start, end, 1);
    mv.visitLocalVariable("a", "Ljava/lang/Runnable;", null, l1, end, 2);

    String insn = TestHelper.getAsString(builder.finish(), "test_mth");
    String good = "Runnable a = r::run;\n" + "a.run();";
    Assert.assertEquals(good, insn);
}

From source file:org.spongepowered.test.ast.LambdaTest.java

License:Open Source License

@Test
public void testMethodRefJavac() {
    // apparently javac chooses it add a call to r.getClass() before the
    // method ref
    TestMethodBuilder builder = new TestMethodBuilder("test_mth", "(Ljava/lang/Runnable;)V");
    MethodVisitor mv = builder.getGenerator();
    Label start = new Label();
    mv.visitLabel(start);/*  w  w w.ja  v a2 s  . c  o m*/
    mv.visitVarInsn(ALOAD, 1);
    mv.visitInsn(DUP);
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
    mv.visitInsn(POP);
    mv.visitInvokeDynamicInsn("run", "(Ljava/lang/Runnable;)Ljava/lang/Runnable;", new Handle(H_INVOKESTATIC,
            "java/lang/invoke/LambdaMetafactory", "metafactory",
            "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"),
            new Object[] { Type.getType("()V"),
                    new Handle(H_INVOKEINTERFACE, "java/lang/Runnable", "run", "()V"), Type.getType("()V") });
    mv.visitVarInsn(ASTORE, 2);
    Label l1 = new Label();
    mv.visitLabel(l1);
    mv.visitVarInsn(ALOAD, 2);
    mv.visitMethodInsn(INVOKEINTERFACE, "java/lang/Runnable", "run", "()V", true);
    mv.visitInsn(RETURN);
    Label end = new Label();
    mv.visitLabel(end);
    mv.visitLocalVariable("this", "Lorg/spongepowered/test/ast/LambdaTest;", null, start, end, 0);
    mv.visitLocalVariable("r", "Ljava/lang/Runnable;", null, start, end, 1);
    mv.visitLocalVariable("a", "Ljava/lang/Runnable;", null, l1, end, 2);

    String insn = TestHelper.getAsString(builder.finish(), "test_mth");
    String good = "r.getClass();\n" + "Runnable a = r::run;\n" + "a.run();";
    Assert.assertEquals(good, insn);
}