Example usage for org.objectweb.asm Opcodes F_SAME

List of usage examples for org.objectweb.asm Opcodes F_SAME

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes F_SAME.

Prototype

int F_SAME

To view the source code for org.objectweb.asm Opcodes F_SAME.

Click Source Link

Document

A compressed frame with exactly the same locals as the previous frame and with an empty stack.

Usage

From source file:org.jacoco.core.internal.instr.ProbeVariableInserterTest.java

License:Open Source License

@Test(expected = IllegalStateException.class)
public void testVisitFrameNegative() {
    ProbeVariableInserter i = new ProbeVariableInserter(0, "(J)V", delegate);
    i.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
}

From source file:org.jupiter.common.util.FastMethodAccessor.java

License:Apache License

private static FastMethodAccessor create(Class<?> type) {
    ArrayList<Method> methods = Lists.newArrayList();
    boolean isInterface = type.isInterface();
    if (!isInterface) {
        Class nextClass = type;/*from ww  w.  j  av  a2  s . c  om*/
        while (nextClass != Object.class) {
            addDeclaredMethodsToList(nextClass, methods);
            nextClass = nextClass.getSuperclass();
        }
    } else {
        recursiveAddInterfaceMethodsToList(type, methods);
    }

    int n = methods.size();
    String[] methodNames = new String[n];
    Class<?>[][] parameterTypes_s = new Class[n][];
    Class<?>[] returnTypes = new Class[n];
    for (int i = 0; i < n; i++) {
        Method method = methods.get(i);
        methodNames[i] = method.getName();
        parameterTypes_s[i] = method.getParameterTypes();
        returnTypes[i] = method.getReturnType();
    }

    String className = type.getName();
    String accessorClassName = className + "_FastMethodAccessor";
    String accessorClassNameInternal = accessorClassName.replace('.', '/');
    String classNameInternal = className.replace('.', '/');
    String superClassNameInternal = FastMethodAccessor.class.getName().replace('.', '/');

    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    MethodVisitor mv;
    cw.visit(V1_1, ACC_PUBLIC + ACC_SUPER, accessorClassNameInternal, null, superClassNameInternal, null);

    // ?
    {
        mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, superClassNameInternal, "<init>", "()V", false);
        mv.visitInsn(RETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }

    // : public Object invoke(Object obj, int methodIndex, Object... args);
    {
        mv = cw.visitMethod(ACC_PUBLIC + ACC_VARARGS, "invoke",
                "(Ljava/lang/Object;I[Ljava/lang/Object;)Ljava/lang/Object;", null, null);
        mv.visitCode();

        if (n > 0) {
            // ?? obj  (Class<?> type)
            mv.visitVarInsn(ALOAD, 1);
            mv.visitTypeInsn(CHECKCAST, classNameInternal);
            mv.visitVarInsn(ASTORE, 4);

            // ? switch ?
            mv.visitVarInsn(ILOAD, 2);
            Label[] labels = new Label[n];
            for (int i = 0; i < n; i++) {
                labels[i] = new Label();
            }
            Label defaultLabel = new Label(); // the default handler block
            mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);

            StringBuilder buf = new StringBuilder(128);
            for (int i = 0; i < n; i++) {
                mv.visitLabel(labels[i]);
                if (i == 0) {
                    mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { classNameInternal }, 0, null);
                } else {
                    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                }
                mv.visitVarInsn(ALOAD, 4);

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

                Class<?>[] parameterTypes = parameterTypes_s[i];
                Class<?> returnType = returnTypes[i];
                for (int p_index = 0; p_index < parameterTypes.length; p_index++) {
                    mv.visitVarInsn(ALOAD, 3);
                    mv.visitIntInsn(BIPUSH, p_index);
                    mv.visitInsn(AALOAD);

                    // ?, (?)
                    Type p_type = Type.getType(parameterTypes[p_index]);
                    switch (p_type.getSort()) {
                    case Type.BOOLEAN:
                        mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
                        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
                        break;
                    case Type.BYTE:
                        mv.visitTypeInsn(CHECKCAST, "java/lang/Byte");
                        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false);
                        break;
                    case Type.CHAR:
                        mv.visitTypeInsn(CHECKCAST, "java/lang/Character");
                        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C", false);
                        break;
                    case Type.SHORT:
                        mv.visitTypeInsn(CHECKCAST, "java/lang/Short");
                        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false);
                        break;
                    case Type.INT:
                        mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
                        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
                        break;
                    case Type.FLOAT:
                        mv.visitTypeInsn(CHECKCAST, "java/lang/Float");
                        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false);
                        break;
                    case Type.LONG:
                        mv.visitTypeInsn(CHECKCAST, "java/lang/Long");
                        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false);
                        break;
                    case Type.DOUBLE:
                        mv.visitTypeInsn(CHECKCAST, "java/lang/Double");
                        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false);
                        break;
                    case Type.ARRAY:
                        mv.visitTypeInsn(CHECKCAST, p_type.getDescriptor());
                        break;
                    case Type.OBJECT:
                        mv.visitTypeInsn(CHECKCAST, p_type.getInternalName());
                        break;
                    }
                    buf.append(p_type.getDescriptor());
                }

                buf.append(')').append(Type.getDescriptor(returnType));

                // ??, ???
                if (isInterface) {
                    mv.visitMethodInsn(INVOKEINTERFACE, classNameInternal, methodNames[i], buf.toString(),
                            true);
                } else if (Modifier.isStatic(methods.get(i).getModifiers())) {
                    mv.visitMethodInsn(INVOKESTATIC, classNameInternal, methodNames[i], buf.toString(), false);
                } else {
                    mv.visitMethodInsn(INVOKEVIRTUAL, classNameInternal, methodNames[i], buf.toString(), false);
                }

                Type r_type = Type.getType(returnType);
                switch (r_type.getSort()) {
                case Type.VOID:
                    mv.visitInsn(ACONST_NULL);
                    break;
                case Type.BOOLEAN:
                    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;",
                            false);
                    break;
                case Type.BYTE:
                    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
                    break;
                case Type.CHAR:
                    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf",
                            "(C)Ljava/lang/Character;", false);
                    break;
                case Type.SHORT:
                    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;",
                            false);
                    break;
                case Type.INT:
                    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;",
                            false);
                    break;
                case Type.FLOAT:
                    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;",
                            false);
                    break;
                case Type.LONG:
                    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
                    break;
                case Type.DOUBLE:
                    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;",
                            false);
                    break;
                }
                mv.visitInsn(ARETURN);
            }
            mv.visitLabel(defaultLabel); //  default ??
            mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        }

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

    cw.visitEnd();
    byte[] bytes = cw.toByteArray();

    AccessorClassLoader loader = AccessorClassLoader.get(type);
    Class<?> accessorClass = loader.defineClass(accessorClassName, bytes);
    try {
        FastMethodAccessor accessor = (FastMethodAccessor) accessorClass.newInstance();
        accessor.methodNames = methodNames;
        accessor.parameterTypes_s = parameterTypes_s;
        return accessor;
    } catch (Throwable t) {
        throw new RuntimeException("Error constructing method access class: " + accessorClass, t);
    }
}

From source file:org.lwjglx.autostack.Transformer.java

License:Open Source License

public byte[] transform(ClassLoader loader, final String className, Class<?> classBeingRedefined,
        ProtectionDomain protectionDomain, byte[] classfileBuffer) {
    try {//from  w w w .  ja  v a2 s .co m
        if (className == null || className.startsWith("java/") || className.startsWith("sun/")
                || className.startsWith("jdk/internal/") || className.startsWith("org/lwjgl/"))
            return null;
        for (String pack : packages)
            if (!className.startsWith(pack))
                return null;
        ClassReader cr = new ClassReader(classfileBuffer);
        final Map<String, Integer> stackMethods = new HashMap<String, Integer>();
        // Scan all methods that need auto-stack
        if (debugTransform)
            System.out.println("[autostack] scanning methods in class: " + className.replace('/', '.'));
        cr.accept(new ClassVisitor(ASM7) {
            public MethodVisitor visitMethod(final int access, final String methodName, final String methodDesc,
                    String signature, String[] exceptions) {
                if ((access & (ACC_NATIVE | ACC_ABSTRACT)) != 0) {
                    // Don't try to analyze native or abstract methods.
                    return null;
                }
                MethodVisitor mv = new MethodVisitor(ASM7) {
                    boolean mark, catches, notransform, nostackparam, forcestack;

                    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
                        if ("Lorg/lwjglx/autostack/NoTransform;".equals(desc))
                            notransform = true;
                        else if ("Lorg/lwjglx/autostack/NoStackParam;".equals(desc))
                            nostackparam = true;
                        else if ("Lorg/lwjglx/autostack/UseNewStack;".equals(desc))
                            forcestack = true;
                        return null;
                    }

                    public void visitMethodInsn(int opcode, String owner, String name, String desc,
                            boolean itf) {
                        if (opcode == INVOKESTATIC && !itf && (owner.startsWith("org/lwjgl/")
                                && (name.equals("mallocStack") || name.equals("callocStack"))
                                || owner.equals(MEMORYSTACK) && (name.equals("stackGet")
                                        || name.equals("stackPop") || name.equals("stackPush")
                                        || name.startsWith("stackMalloc") || name.startsWith("stackCalloc")
                                        || name.startsWith("nstackMalloc") || name.startsWith("nstackCalloc")
                                        || name.equals("stackUTF8") || name.equals("stackASCII")
                                        || name.equals("stackUTF16") || name.equals("stackFloats")
                                        || name.equals("stackInts") || name.equals("stackBytes")
                                        || name.equals("stackShorts") || name.equals("stackPointers")
                                        || name.equals("stackLongs")))) {
                            mark = true;
                        }
                    }

                    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
                        catches = true;
                    }

                    public void visitEnd() {
                        int flag = (access & ACC_PRIVATE) != 0 ? 8 : 0;
                        flag |= nostackparam ? 16 : 0;
                        if (mark || notransform || forcestack || nostackparam) {
                            if (notransform) {
                                flag |= 2;
                                if (debugTransform)
                                    System.out.println("[autostack]   will not transform method: "
                                            + className.replace('/', '.') + "." + methodName);
                            } else {
                                if (checkStack)
                                    flag |= 4;
                                flag |= catches ? 1 : 0;
                                if (debugTransform)
                                    System.out.println("[autostack]   will transform method: "
                                            + className.replace('/', '.') + "." + methodName);
                            }
                            stackMethods.put(methodName + methodDesc, Integer.valueOf(flag));
                        }
                    }
                };
                return mv;
            }
        }, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
        if (stackMethods.isEmpty())
            return null;

        // Now, transform all such methods
        if (debugTransform)
            System.out.println("[autostack] transforming methods in class: " + className.replace('/', '.'));
        ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
        cr.accept(new ClassVisitor(ASM7, cw) {
            boolean classDefaultNewStack = defaultNewStack;
            boolean classNoTransform;

            @Override
            public void visit(int version, int access, String name, String signature, String superName,
                    String[] interfaces) {
                cv.visit(version, access, name, signature, superName, interfaces);
                if (!checkStack) {
                    return;
                }
                /* Generate simple synthetic "compare stack pointers and throw if not equal" method */
                MethodVisitor mv = cv.visitMethod(ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, "$checkStack$",
                        "(II)V", null, new String[] { "java/lang/AssertionError" });
                {
                    mv.visitCode();
                    mv.visitVarInsn(ILOAD, 0);
                    mv.visitVarInsn(ILOAD, 1);
                    Label l0 = new Label();
                    mv.visitJumpInsn(IF_ICMPEQ, l0);
                    mv.visitTypeInsn(NEW, "java/lang/IllegalStateException");
                    mv.visitInsn(DUP);
                    mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
                    mv.visitInsn(DUP);
                    mv.visitLdcInsn("Stack pointers differ: ");
                    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>",
                            "(Ljava/lang/String;)V", false);
                    mv.visitVarInsn(ILOAD, 0);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                            "(I)Ljava/lang/StringBuilder;", false);
                    mv.visitLdcInsn(" != ");
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                            "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
                    mv.visitVarInsn(ILOAD, 1);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                            "(I)Ljava/lang/StringBuilder;", false);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString",
                            "()Ljava/lang/String;", false);
                    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalStateException", "<init>",
                            "(Ljava/lang/String;)V", false);
                    mv.visitInsn(ATHROW);
                    mv.visitLabel(l0);
                    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                    mv.visitInsn(RETURN);
                    mv.visitMaxs(5, 2);
                    mv.visitEnd();
                }

                mv = cv.visitMethod(ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, "$checkStackWithThrowable$",
                        "(Ljava/lang/Throwable;II)Ljava/lang/Throwable;", null, null);
                {
                    mv.visitCode();
                    mv.visitVarInsn(ILOAD, 1);
                    mv.visitVarInsn(ILOAD, 2);
                    Label l0 = new Label();
                    mv.visitJumpInsn(IF_ICMPEQ, l0);
                    mv.visitTypeInsn(NEW, "java/lang/IllegalStateException");
                    mv.visitInsn(DUP);
                    mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
                    mv.visitInsn(DUP);
                    mv.visitLdcInsn("Stack pointers differ: ");
                    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>",
                            "(Ljava/lang/String;)V", false);
                    mv.visitVarInsn(ILOAD, 1);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                            "(I)Ljava/lang/StringBuilder;", false);
                    mv.visitLdcInsn(" != ");
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                            "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
                    mv.visitVarInsn(ILOAD, 2);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                            "(I)Ljava/lang/StringBuilder;", false);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString",
                            "()Ljava/lang/String;", false);
                    mv.visitVarInsn(ALOAD, 0);
                    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalStateException", "<init>",
                            "(Ljava/lang/String;Ljava/lang/Throwable;)V", false);
                    mv.visitInsn(ARETURN);
                    mv.visitLabel(l0);
                    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                    mv.visitVarInsn(ALOAD, 0);
                    mv.visitInsn(ARETURN);
                    mv.visitMaxs(5, 3);
                    mv.visitEnd();
                }
            }

            public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
                if ("Lorg/lwjglx/autostack/UseCallerStack;".equals(desc)) {
                    if (debugTransform)
                        System.out.println(
                                "[autostack]   class declares to use caller stack for all methods, unless overridden by method");
                    classDefaultNewStack = false;
                    return null;
                } else if ("Lorg/lwjglx/autostack/UseNewStack;".equals(desc)) {
                    if (debugTransform)
                        System.out.println(
                                "[autostack]   class declares to use new stack for all methods, unless overridden by method");
                    classDefaultNewStack = true;
                    return null;
                } else if ("Lorg/lwjglx/autostack/NoTransform;".equals(desc)) {
                    if (debugTransform)
                        System.out.println("[autostack]   class declares to not transform any methods");
                    classNoTransform = true;
                    return null;
                }
                return cv.visitAnnotation(desc, visible);
            }

            public MethodVisitor visitMethod(final int access, final String name, final String desc,
                    String signature, String[] exceptions) {
                Integer info = stackMethods.get(name + desc);
                if (info == null)
                    return super.visitMethod(access, name, desc, signature, exceptions);
                boolean catches = (info.intValue() & 1) == 1;
                final boolean notransform = classNoTransform || (info.intValue() & 2) == 2;
                if (debugTransform && !notransform)
                    System.out.println(
                            "[autostack]   transform method: " + className.replace('/', '.') + "." + name);
                final boolean memoryStackParam = stackAsParameter && (access & ACC_PRIVATE) != 0
                        && (info.intValue() & 16) == 0;
                MethodVisitor mv;
                final Type[] paramTypes = Type.getArgumentTypes(desc);
                final boolean isStatic = (access & ACC_STATIC) != 0;
                final boolean isConstructor = "<init>".equals(name);
                if (memoryStackParam) {
                    if (debugTransform)
                        System.out.println(
                                "[autostack]     changing signature of method to add additional MemoryStack parameter");

                    // Add additional MemoryStack parameter to the method signature index of the local stays the same
                    int paramEndIndex = desc.indexOf(')');
                    String beforeDesc = desc.substring(0, paramEndIndex);
                    String afterDesc = desc.substring(paramEndIndex);
                    mv = super.visitMethod(access | ACC_SYNTHETIC, name,
                            beforeDesc + "L" + MEMORYSTACK + ";" + afterDesc, signature, exceptions);

                    // Re-introduce the original method which just delegates
                    if (debugTransform)
                        System.out.println("[autostack]     adding delegate method with original signature");
                    MethodVisitor omv = super.visitMethod(access, name, desc, signature, exceptions);
                    omv.visitCode();
                    int param = 0;
                    if (!isStatic) {
                        omv.visitVarInsn(ALOAD, 0);
                        param++;
                    }
                    for (int i = 0; i < paramTypes.length; i++) {
                        omv.visitVarInsn(paramTypes[i].getOpcode(ILOAD), param);
                        param += paramTypes[i].getSize();
                    }
                    omv.visitMethodInsn(INVOKESTATIC, MEMORYSTACK, "stackGet", "()L" + MEMORYSTACK + ";",
                            false);
                    boolean isPrivate = (access & ACC_PRIVATE) != 0;
                    int opcode = isStatic ? INVOKESTATIC : isPrivate ? INVOKESPECIAL : INVOKEVIRTUAL;
                    omv.visitMethodInsn(opcode, className, name,
                            beforeDesc + "L" + MEMORYSTACK + ";" + afterDesc, false);
                    Type retType = Type.getReturnType(desc);
                    omv.visitInsn(retType.getOpcode(IRETURN));
                    omv.visitMaxs(-1, -1);
                    omv.visitEnd();
                } else {
                    mv = super.visitMethod(access, name, desc, signature, exceptions);
                }
                if (catches)
                    mv = new TryCatchBlockSorter(mv, access, name, desc, signature, exceptions);
                mv = new MethodVisitor(ASM7, mv) {
                    Label tryLabel = new Label();
                    Label finallyLabel = new Label();
                    int lastLine = 0;
                    boolean newStack = classDefaultNewStack;
                    int stackVarIndex;
                    int stackPointerVarIndex;
                    int firstAdditionalLocal;
                    int additionalLocals;
                    Object[] replacedLocals;

                    public void visitInsn(int opcode) {
                        if (notransform) {
                            mv.visitInsn(opcode);
                            return;
                        }
                        if (opcode >= IRETURN && opcode <= RETURN && (newStack || checkStack)) {
                            if (debugRuntime && newStack && !checkStack) {
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn("[autostack] restore stack pointer because of return at "
                                        + className.replace('/', '.') + "." + name + ":" + lastLine);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",
                                        "(Ljava/lang/String;)V", false);
                            }
                            if (newStack && !checkStack) {
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitVarInsn(ILOAD, stackPointerVarIndex);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, "setPointer", "(I)V", false);
                            } else if (checkStack) {
                                mv.visitVarInsn(ILOAD, stackPointerVarIndex);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, "getPointer", "()I", false);
                                mv.visitMethodInsn(INVOKESTATIC, className, "$checkStack$", "(II)V", false);
                            }
                        }
                        mv.visitInsn(opcode);
                    }

                    public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
                        if ("Lorg/lwjglx/autostack/UseCallerStack;".equals(desc)) {
                            if (!notransform) {
                                if (debugTransform)
                                    System.out.println("[autostack]     method declares to use caller stack");
                                newStack = false;
                            }
                            return null;
                        } else if ("Lorg/lwjglx/autostack/UseNewStack;".equals(desc)) {
                            if (!notransform) {
                                if (debugTransform)
                                    System.out.println("[autostack]     method declares to use new stack");
                                newStack = true;
                            }
                            return null;
                        } else if ("Lorg/lwjglx/autostack/NoTransform;".equals(desc)) {
                            return null;
                        } else if ("Lorg/lwjglx/autostack/NoStackParam;".equals(desc)) {
                            return null;
                        }
                        return mv.visitAnnotation(desc, visible);
                    }

                    public void visitVarInsn(int opcode, int var) {
                        if (notransform) {
                            mv.visitVarInsn(opcode, var);
                            return;
                        }
                        if (var >= firstAdditionalLocal)
                            var += additionalLocals;
                        mv.visitVarInsn(opcode, var);
                    }

                    public void visitIincInsn(int var, int increment) {
                        if (notransform) {
                            mv.visitIincInsn(var, increment);
                            return;
                        }
                        if (var >= firstAdditionalLocal)
                            var += additionalLocals;
                        mv.visitIincInsn(var, increment);
                    }

                    public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
                        if (notransform) {
                            mv.visitFrame(type, nLocal, local, nStack, stack);
                            return;
                        }
                        if (type == F_FULL) {
                            int noThis = isStatic ? 0 : 1;
                            Object[] locals = new Object[local.length + additionalLocals];
                            if (!isStatic)
                                locals[0] = local[0];
                            int replacementLength = replacedLocals.length;
                            System.arraycopy(replacedLocals, noThis, locals, noThis,
                                    replacementLength - noThis);
                            int len = locals.length - replacementLength;
                            System.arraycopy(local, replacementLength - additionalLocals, locals,
                                    replacementLength, len);
                            mv.visitFrame(type, nLocal + additionalLocals, locals, nStack, stack);
                        } else
                            mv.visitFrame(type, nLocal, local, nStack, stack);
                    }

                    public void visitLocalVariable(String name, String desc, String signature, Label start,
                            Label end, int index) {
                        if (notransform) {
                            mv.visitLocalVariable(name, desc, signature, start, end, index);
                            return;
                        }
                        if (index >= firstAdditionalLocal)
                            index += additionalLocals;
                        mv.visitLocalVariable(name, desc, signature, start, end, index);
                    }

                    private boolean doesNotTakeStackItself(String desc) {
                        return desc.lastIndexOf("L" + MEMORYSTACK + ";)") == -1;
                    }

                    public void visitMethodInsn(int opcode, String owner, String name, String desc,
                            boolean itf) {
                        String completeName = name + desc;
                        Integer info = stackMethods.get(completeName);
                        if (opcode != INVOKESTATIC || notransform) {
                            mv.visitMethodInsn(opcode, owner, name, desc, itf);
                            return;
                        }
                        if (stackAsParameter && info != null && (info.intValue() & 8) != 0
                                && (info.intValue() & 16) == 0) {
                            /* Rewrite invocation to have additional MemoryStack parameter */
                            if (debugTransform)
                                System.out.println(
                                        "[autostack]     rewrite invocation of " + owner.replace('/', '.') + "."
                                                + name + " at line " + lastLine + " --> "
                                                + owner.replace('/', '.') + "." + name + "(..., MemoryStack)");
                            int paramEndIndex = desc.indexOf(')');
                            String beforeDesc = desc.substring(0, paramEndIndex);
                            String afterDesc = desc.substring(paramEndIndex);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                            mv.visitMethodInsn(opcode, owner, name,
                                    beforeDesc + "L" + MEMORYSTACK + ";" + afterDesc, itf);
                            return;
                        }
                        if (owner.startsWith("org/lwjgl/")
                                && (name.equals("mallocStack") || name.equals("callocStack"))
                                && doesNotTakeStackItself(desc)) {
                            if (debugTransform)
                                System.out.println(
                                        "[autostack]     rewrite invocation of " + owner.replace('/', '.') + "."
                                                + name + " at line " + lastLine + " --> aload " + stackVarIndex
                                                + "; invokestatic " + owner.replace('/', '.') + "." + name);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                            int paramEndIndex = desc.indexOf(')');
                            String beforeDesc = desc.substring(0, paramEndIndex);
                            String afterDesc = desc.substring(paramEndIndex);
                            mv.visitMethodInsn(opcode, owner, name,
                                    beforeDesc + "L" + MEMORYSTACK + ";" + afterDesc, false);
                        } else if (owner.equals(MEMORYSTACK) && name.equals("stackGet")) {
                            if (debugTransform)
                                System.out.println("[autostack]     rewrite invocation of "
                                        + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                        + " --> aload " + stackVarIndex);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                        } else if (owner.equals(MEMORYSTACK)
                                && (name.equals("stackPush") || name.equals("stackPop"))) {
                            String newName = "p" + name.substring(6);
                            if (debugTransform)
                                System.out.println("[autostack]     rewrite invocation of "
                                        + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                        + " --> aload " + stackVarIndex + "; invokevirtual "
                                        + MEMORYSTACK.replace('/', '.') + "." + newName);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                            mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                        } else if (owner.equals(MEMORYSTACK)
                                && (name.startsWith("stackMalloc") || name.startsWith("stackCalloc"))) {
                            String newName = name.substring(5, 6).toLowerCase() + name.substring(6);
                            if (debugTransform)
                                System.out.println("[autostack]     rewrite invocation of "
                                        + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                        + " --> aload " + stackVarIndex + "; invokevirtual "
                                        + MEMORYSTACK.replace('/', '.') + "." + newName);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                            mv.visitInsn(SWAP);
                            mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                        } else if (owner.equals(MEMORYSTACK)
                                && (name.startsWith("nstackMalloc") || name.startsWith("nstackCalloc"))) {
                            String newName = "n" + name.substring(6, 7).toLowerCase() + name.substring(7);
                            if (debugTransform)
                                System.out.println("[autostack]     rewrite invocation of "
                                        + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                        + " --> aload " + stackVarIndex + "; invokevirtual "
                                        + MEMORYSTACK.replace('/', '.') + "." + newName);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                            if ("(I)J".equals(desc)) {
                                mv.visitInsn(SWAP);
                            } else {
                                // (II)J
                                mv.visitInsn(DUP_X2);
                                mv.visitInsn(POP);
                            }
                            mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                        } else if (owner.equals(MEMORYSTACK) && (name.equals("stackASCII")
                                || name.equals("stackUTF8") || name.equals("stackUTF16"))) {
                            String newName = name.substring(5);
                            boolean withBoolean = desc.startsWith("(Ljava/lang/CharSequence;Z");
                            if (debugTransform)
                                System.out.println("[autostack]     rewrite invocation of "
                                        + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                        + " --> aload " + stackVarIndex + "; invokevirtual "
                                        + MEMORYSTACK.replace('/', '.') + "." + newName);
                            mv.visitVarInsn(ALOAD, stackVarIndex);
                            if (withBoolean) {
                                mv.visitInsn(DUP_X2);
                                mv.visitInsn(POP);
                            } else {
                                mv.visitInsn(SWAP);
                            }
                            mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                        } else if (owner.equals(MEMORYSTACK)
                                && (name.equals("stackFloats") || name.equals("stackInts")
                                        || name.equals("stackBytes") || name.equals("stackShorts")
                                        || name.equals("stackPointers")
                                                && (desc.startsWith("([Lorg/lwjgl/system/Pointer;")
                                                        || desc.startsWith("(Lorg/lwjgl/system/Pointer;")))) {
                            String newName = name.substring(5, 6).toLowerCase() + name.substring(6);
                            Type[] argTypes = Type.getArgumentTypes(desc);
                            if (argTypes.length == 1 && argTypes[0].getSort() == Type.ARRAY) {
                                if (debugTransform)
                                    System.out.println("[autostack]     rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + " --> aload " + stackVarIndex + "; invokevirtual "
                                            + MEMORYSTACK.replace('/', '.') + "." + newName);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitInsn(SWAP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                            } else if (argTypes.length == 1) {
                                if (debugTransform)
                                    System.out.println("[autostack]     rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + " --> aload " + stackVarIndex + "; invokevirtual "
                                            + MEMORYSTACK.replace('/', '.') + "." + newName);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitInsn(SWAP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                            } else if (argTypes.length == 2) {
                                if (debugTransform)
                                    System.out.println("[autostack]     rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + " --> aload " + stackVarIndex + "; invokevirtual "
                                            + MEMORYSTACK.replace('/', '.') + "." + newName);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitInsn(DUP_X2);
                                mv.visitInsn(POP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                            } else if (argTypes.length == 3) {
                                if (debugTransform)
                                    System.out.println("[autostack]     rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + " --> aload " + stackVarIndex + "; invokevirtual "
                                            + MEMORYSTACK.replace('/', '.') + "." + newName);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitInsn(DUP2_X2);
                                mv.visitInsn(POP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                                mv.visitInsn(SWAP);
                                mv.visitInsn(POP);
                            } else {
                                if (debugTransform)
                                    System.out.println("[autostack]     failed to rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + ". Not yet implemented.");
                                /* Give up. Not possible without an additional local */
                                mv.visitMethodInsn(INVOKESTATIC, MEMORYSTACK, name, desc, itf);
                            }
                        } else if (owner.equals(MEMORYSTACK) && name.equals("stackLongs")) {
                            String newName = name.substring(5, 6).toLowerCase() + name.substring(6);
                            Type[] argTypes = Type.getArgumentTypes(desc);
                            if (argTypes.length == 1 && argTypes[0].getSort() == Type.ARRAY) {
                                if (debugTransform)
                                    System.out.println("[autostack]     rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + " --> aload " + stackVarIndex + "; invokevirtual "
                                            + MEMORYSTACK.replace('/', '.') + "." + newName);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitInsn(SWAP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                            } else if (argTypes.length == 1) {
                                if (debugTransform)
                                    System.out.println("[autostack]     rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + " --> aload " + stackVarIndex + "; invokevirtual "
                                            + MEMORYSTACK.replace('/', '.') + "." + newName);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitInsn(DUP_X2);
                                mv.visitInsn(POP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, newName, desc, itf);
                            } else {
                                if (debugTransform)
                                    System.out.println("[autostack]     failed to rewrite invocation of "
                                            + owner.replace('/', '.') + "." + name + " at line " + lastLine
                                            + ". Not yet implemented.");
                                /* Give up. Not possible without an additional local */
                                mv.visitMethodInsn(INVOKESTATIC, MEMORYSTACK, name, desc, itf);
                            }
                        } else {
                            mv.visitMethodInsn(opcode, owner, name, desc, itf);
                        }
                    }

                    public void visitLineNumber(int line, Label start) {
                        mv.visitLineNumber(line, start);
                        lastLine = line;
                    }

                    public void visitCode() {
                        if (notransform) {
                            mv.visitCode();
                            return;
                        }
                        additionalLocals = newStack || checkStack ? 2 : 1;
                        replacedLocals = new Object[paramTypes.length + additionalLocals + (isStatic ? 0 : 1)];
                        if (!newStack && !checkStack) {
                            replacedLocals[replacedLocals.length - 1] = MEMORYSTACK;
                        } else {
                            replacedLocals[replacedLocals.length - 2] = MEMORYSTACK;
                            replacedLocals[replacedLocals.length - 1] = INTEGER;
                        }
                        if (!isStatic)
                            replacedLocals[0] = isConstructor ? TOP : className;
                        int var = isStatic ? 0 : 1;
                        for (int t = 0, i = var; t < paramTypes.length; t++, i++) {
                            Type type = paramTypes[t];
                            var += type.getSize();
                            switch (type.getSort()) {
                            case Type.INT:
                            case Type.BYTE:
                            case Type.BOOLEAN:
                            case Type.SHORT:
                            case Type.CHAR:
                                replacedLocals[i] = INTEGER;
                                break;
                            case Type.LONG:
                                replacedLocals[i] = LONG;
                                break;
                            case Type.FLOAT:
                                replacedLocals[i] = FLOAT;
                                break;
                            case Type.DOUBLE:
                                replacedLocals[i] = DOUBLE;
                                break;
                            case Type.OBJECT:
                            case Type.ARRAY:
                                replacedLocals[i] = type.getInternalName();
                                break;
                            default:
                                throw new AssertionError("Unhandled parameter type: " + type);
                            }
                        }
                        firstAdditionalLocal = var;
                        stackVarIndex = var;
                        stackPointerVarIndex = var + 1;
                        mv.visitCode();
                        if (newStack && !checkStack || checkStack) {
                            if (!memoryStackParam) {
                                mv.visitMethodInsn(INVOKESTATIC, MEMORYSTACK, "stackGet",
                                        "()L" + MEMORYSTACK + ";", false);
                                mv.visitInsn(DUP);
                                mv.visitVarInsn(ASTORE, stackVarIndex);
                            } else {
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                            }
                            mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, "getPointer", "()I", false);
                            mv.visitVarInsn(ISTORE, stackPointerVarIndex);
                            if (debugRuntime && newStack && !checkStack) {
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn("[autostack] save stack pointer [");
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print",
                                        "(Ljava/lang/String;)V", false);
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitVarInsn(ILOAD, stackPointerVarIndex);
                                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "toString",
                                        "(I)Ljava/lang/String;", false);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print",
                                        "(Ljava/lang/String;)V", false);
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn("] at begin of " + className.replace('/', '.') + "." + name);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",
                                        "(Ljava/lang/String;)V", false);
                            }
                            mv.visitLabel(tryLabel);
                            if (!memoryStackParam)
                                mv.visitFrame(F_APPEND, 2, new Object[] { MEMORYSTACK, INTEGER }, 0, null);
                            else
                                mv.visitFrame(F_APPEND, 1, new Object[] { INTEGER }, 0, null);
                        } else if (!newStack && !checkStack) {
                            if (!memoryStackParam) {
                                mv.visitMethodInsn(INVOKESTATIC, MEMORYSTACK, "stackGet",
                                        "()L" + MEMORYSTACK + ";", false);
                                mv.visitVarInsn(ASTORE, stackVarIndex);
                            }
                            if (debugRuntime) {
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn("[autostack] current stack pointer is [");
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print",
                                        "(Ljava/lang/String;)V", false);
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, "getPointer", "()I", false);
                                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "toString",
                                        "(I)Ljava/lang/String;", false);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print",
                                        "(Ljava/lang/String;)V", false);
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn("] at begin of " + className.replace('/', '.') + "." + name);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",
                                        "(Ljava/lang/String;)V", false);
                            }
                            mv.visitLabel(tryLabel);
                            if (!memoryStackParam)
                                mv.visitFrame(F_APPEND, 1, new Object[] { MEMORYSTACK }, 0, null);
                        }
                    }

                    public void visitMaxs(int maxStack, int maxLocals) {
                        if (notransform) {
                            mv.visitMaxs(maxStack, maxLocals);
                            return;
                        }
                        if (newStack && !checkStack || checkStack) {
                            mv.visitLabel(finallyLabel);
                            mv.visitFrame(F_FULL, replacedLocals.length, replacedLocals, 1,
                                    new Object[] { "java/lang/Throwable" });
                            mv.visitTryCatchBlock(tryLabel, finallyLabel, finallyLabel, null);
                            if (debugRuntime && newStack && !checkStack) {
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn("[autostack] restore stack pointer because of throw [");
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print",
                                        "(Ljava/lang/String;)V", false);
                                mv.visitInsn(DUP);
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitInsn(SWAP);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString",
                                        "()Ljava/lang/String;", false);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print",
                                        "(Ljava/lang/String;)V", false);
                                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out",
                                        "Ljava/io/PrintStream;");
                                mv.visitLdcInsn(
                                        "] at " + className.replace('/', '.') + "." + name + ":" + lastLine);
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",
                                        "(Ljava/lang/String;)V", false);
                            }
                            if (newStack && !checkStack) {
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitVarInsn(ILOAD, stackPointerVarIndex);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, "setPointer", "(I)V", false);
                            }
                            if (checkStack) {
                                mv.visitVarInsn(ILOAD, stackPointerVarIndex);
                                mv.visitVarInsn(ALOAD, stackVarIndex);
                                mv.visitMethodInsn(INVOKEVIRTUAL, MEMORYSTACK, "getPointer", "()I", false);
                                mv.visitMethodInsn(INVOKESTATIC, className, "$checkStackWithThrowable$",
                                        "(Ljava/lang/Throwable;II)Ljava/lang/Throwable;", false);
                            }
                            mv.visitInsn(ATHROW);
                        }
                        mv.visitMaxs(-1, maxLocals + additionalLocals);
                    }
                };
                return mv;
            }
        }, 0);
        byte[] arr = cw.toByteArray();
        if (trace) {
            cr = new ClassReader(arr);
            cr.accept(new TraceClassVisitor(new PrintWriter(System.out)), 0);
        }
        return arr;
    } catch (Throwable t) {
        t.printStackTrace();
        throw new RuntimeException(t);
    }
}

From source file:org.qi4j.runtime.composite.FragmentClassLoader.java

License:Open Source License

public static byte[] generateClass(String name, Class baseClass) throws ClassNotFoundException {
    String classSlash = name.replace('.', '/');
    String baseClassSlash = getInternalName(baseClass);

    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);

    // Class definition start
    cw.visit(jdkVersion, ACC_PUBLIC + ACC_SUPER, classSlash, null, baseClassSlash, null);

    // Composite reference
    {/*from   www.  ja  va 2s .  c o  m*/
        cw.visitField(ACC_PUBLIC, "_instance", "Lorg/qi4j/api/composite/CompositeInvoker;", null, null)
                .visitEnd();
    }

    // Static Method references
    boolean hasProxyMethods = false;
    {
        int idx = 1;
        for (Method method : baseClass.getMethods()) {
            if (isOverridden(method, baseClass)) {
                cw.visitField(ACC_PRIVATE + ACC_STATIC, "m" + idx++, "Ljava/lang/reflect/Method;", null, null)
                        .visitEnd();
                hasProxyMethods = true;
            }
        }
    }

    // Constructors
    for (Constructor constructor : baseClass.getDeclaredConstructors()) {
        if (Modifier.isPublic(constructor.getModifiers()) || Modifier.isProtected(constructor.getModifiers())) {
            String desc = org.objectweb.asm.commons.Method.getMethod(constructor).getDescriptor();
            MethodVisitor cmv = cw.visitMethod(ACC_PUBLIC, "<init>", desc, null, null);
            cmv.visitCode();
            cmv.visitVarInsn(ALOAD, 0);

            int idx = 1;
            for (Class aClass : constructor.getParameterTypes()) {
                final int opcode;
                if (aClass.equals(Integer.TYPE)) {
                    opcode = ILOAD;
                } else if (aClass.equals(Long.TYPE)) {
                    opcode = LLOAD;
                } else if (aClass.equals(Float.TYPE)) {
                    opcode = FLOAD;
                } else if (aClass.equals(Double.TYPE)) {
                    opcode = DLOAD;
                } else {
                    opcode = ALOAD;
                }
                cmv.visitVarInsn(opcode, idx++);
            }

            cmv.visitMethodInsn(INVOKESPECIAL, baseClassSlash, "<init>", desc);
            cmv.visitInsn(RETURN);
            cmv.visitMaxs(idx, idx);
            cmv.visitEnd();
        }
    }

    // Overloaded and unimplemented methods
    if (hasProxyMethods) {
        Method[] methods = baseClass.getMethods();
        int idx = 0;
        List<Label> exceptionLabels = new ArrayList<Label>();
        for (Method method : methods) {
            if (isOverridden(method, baseClass)) {
                idx++;
                String methodName = method.getName();
                String desc = org.objectweb.asm.commons.Method.getMethod(method).getDescriptor();

                String[] exceptions = null;
                {
                    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, methodName, desc, null, exceptions);
                    if (isInternalQi4jMethod(method, baseClass)) {
                        // generate a NoOp method...
                        mv.visitInsn(RETURN);
                    } else {
                        Label endLabel = null; // Use this if return type is void
                        if (method.getExceptionTypes().length > 0) {
                            exceptions = new String[method.getExceptionTypes().length];
                            for (int i = 0; i < method.getExceptionTypes().length; i++) {
                                Class<?> aClass = method.getExceptionTypes()[i];
                                exceptions[i] = getInternalName(aClass);
                            }
                        }
                        mv.visitCode();
                        Label l0 = new Label();
                        Label l1 = new Label();

                        exceptionLabels.clear();
                        for (Class<?> declaredException : method.getExceptionTypes()) {
                            Label ld = new Label();
                            mv.visitTryCatchBlock(l0, l1, ld, getInternalName(declaredException));
                            exceptionLabels.add(ld); // Reuse this further down for the catch
                        }

                        Label lruntime = new Label();
                        mv.visitTryCatchBlock(l0, l1, lruntime, "java/lang/RuntimeException");
                        Label lerror = new Label();
                        mv.visitTryCatchBlock(l0, l1, lerror, "java/lang/Throwable");

                        mv.visitLabel(l0);
                        mv.visitVarInsn(ALOAD, 0);
                        mv.visitFieldInsn(GETFIELD, classSlash, "_instance",
                                "Lorg/qi4j/api/composite/CompositeInvoker;");
                        mv.visitFieldInsn(GETSTATIC, classSlash, "m" + idx, "Ljava/lang/reflect/Method;");

                        int paramCount = method.getParameterTypes().length;
                        int stackIdx = 0;
                        if (paramCount == 0) {
                            // Send in null as parameter
                            mv.visitInsn(ACONST_NULL);
                        } else {
                            insn(mv, paramCount);
                            mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
                            int pidx = 0;
                            for (Class<?> aClass : method.getParameterTypes()) {
                                mv.visitInsn(DUP);
                                insn(mv, pidx++);
                                stackIdx = wrapParameter(mv, aClass, stackIdx + 1);
                                mv.visitInsn(AASTORE);
                            }
                        }

                        // Call method
                        mv.visitMethodInsn(INVOKEINTERFACE, "org/qi4j/api/composite/CompositeInvoker",
                                "invokeComposite",
                                "(Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;");

                        // Return value
                        if (!method.getReturnType().equals(Void.TYPE)) {
                            unwrapResult(mv, method.getReturnType(), l1);
                        } else {
                            mv.visitInsn(POP);
                            mv.visitLabel(l1);
                            endLabel = new Label();
                            mv.visitJumpInsn(GOTO, endLabel);
                        }

                        // Increase stack to beyond method args
                        stackIdx++;

                        // Declared exceptions
                        int exceptionIdx = 0;
                        for (Class<?> aClass : method.getExceptionTypes()) {
                            mv.visitLabel(exceptionLabels.get(exceptionIdx++));
                            mv.visitFrame(Opcodes.F_SAME1, 0, null, 1,
                                    new Object[] { getInternalName(aClass) });
                            mv.visitVarInsn(ASTORE, stackIdx);
                            mv.visitVarInsn(ALOAD, stackIdx);
                            mv.visitInsn(ATHROW);
                        }

                        // RuntimeException and Error catch-all
                        mv.visitLabel(lruntime);
                        mv.visitFrame(Opcodes.F_SAME1, 0, null, 1,
                                new Object[] { "java/lang/RuntimeException" });
                        mv.visitVarInsn(ASTORE, stackIdx);
                        mv.visitVarInsn(ALOAD, stackIdx);
                        mv.visitInsn(ATHROW);

                        mv.visitLabel(lerror);
                        mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" });
                        mv.visitVarInsn(ASTORE, stackIdx);
                        mv.visitVarInsn(ALOAD, stackIdx);
                        mv.visitTypeInsn(CHECKCAST, "java/lang/Error");
                        mv.visitInsn(ATHROW);

                        // Return type = void
                        if (endLabel != null) {
                            mv.visitLabel(endLabel);
                            mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                            mv.visitInsn(RETURN);
                        }

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

                if (!Modifier.isAbstract(method.getModifiers())) {
                    // Add method with _ as prefix
                    MethodVisitor mv;
                    mv = cw.visitMethod(ACC_PUBLIC, "_" + method.getName(), desc, null, exceptions);
                    mv.visitCode();
                    mv.visitVarInsn(ALOAD, 0);

                    // Parameters
                    int stackIdx = 1;
                    for (Class<?> aClass : method.getParameterTypes()) {
                        stackIdx = loadParameter(mv, aClass, stackIdx) + 1;
                    }

                    // Call method
                    mv.visitMethodInsn(INVOKESPECIAL, baseClassSlash, method.getName(), desc);

                    // Return value
                    if (!method.getReturnType().equals(Void.TYPE)) {
                        returnResult(mv, method.getReturnType());
                    } else {
                        mv.visitInsn(RETURN);
                    }

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

        // Class initializer
        {
            MethodVisitor mv;
            mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
            mv.visitCode();
            Label l0 = new Label();
            Label l1 = new Label();
            Label l2 = new Label();
            mv.visitTryCatchBlock(l0, l1, l2, "java/lang/NoSuchMethodException");
            mv.visitLabel(l0);

            // Lookup methods and store in static variables
            int midx = 0;
            for (Method method : methods) {
                if (isOverridden(method, baseClass)) {
                    method.setAccessible(true);
                    Class methodClass;
                    if (Modifier.isAbstract(method.getModifiers())) {
                        methodClass = method.getDeclaringClass();
                    } else {
                        try {
                            methodClass = getInterfaceMethodDeclaration(method, baseClass); // Overridden method lookup
                        } catch (NoSuchMethodException e) {
                            throw new ClassNotFoundException(name, e);
                        }
                    }

                    midx++;

                    mv.visitLdcInsn(Type.getType(methodClass));
                    mv.visitLdcInsn(method.getName());
                    insn(mv, method.getParameterTypes().length);
                    mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");

                    int pidx = 0;
                    for (Class<?> aClass : method.getParameterTypes()) {
                        mv.visitInsn(DUP);
                        insn(mv, pidx++);
                        type(mv, aClass);
                        mv.visitInsn(AASTORE);
                    }

                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod",
                            "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;");
                    mv.visitFieldInsn(PUTSTATIC, classSlash, "m" + midx, "Ljava/lang/reflect/Method;");
                }
            }

            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/NoSuchMethodException" });
            mv.visitVarInsn(ASTORE, 0);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/NoSuchMethodException", "printStackTrace", "()V");
            mv.visitLabel(l3);
            mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
            mv.visitInsn(RETURN);
            mv.visitMaxs(6, 1);
            mv.visitEnd();
        }
    }
    cw.visitEnd();
    return cw.toByteArray();
}

From source file:org.qi4j.runtime.composite.TransientClassLoader.java

License:Open Source License

public static byte[] generateClass(String name, Class baseClass) throws ClassNotFoundException {
    String classSlash = name.replace('.', '/');
    String baseClassSlash = getInternalName(baseClass);

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

    // Class definition start
    cw.visit(jdkVersion, ACC_PUBLIC + ACC_SUPER, classSlash, null, baseClassSlash, null);

    // Composite reference
    {
        fv = cw.visitField(ACC_PUBLIC, "_instance", "Lorg/qi4j/api/composite/CompositeInvoker;", null, null);
        fv.visitEnd();
    }

    // Static Method references
    {
        int idx = 1;
        for (Method method : baseClass.getMethods()) {
            if (isOverloaded(method, baseClass)) {
                fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "m" + idx++, "Ljava/lang/reflect/Method;", null,
                        null);
                fv.visitEnd();
            }
        }
    }

    // Constructors
    for (Constructor constructor : baseClass.getDeclaredConstructors()) {
        if (Modifier.isPublic(constructor.getModifiers()) || Modifier.isProtected(constructor.getModifiers())) {
            String desc = org.objectweb.asm.commons.Method.getMethod(constructor).getDescriptor();
            mv = cw.visitMethod(ACC_PUBLIC, "<init>", desc, null, null);
            mv.visitCode();
            mv.visitVarInsn(ALOAD, 0);

            int idx = 1;
            for (Class aClass : constructor.getParameterTypes()) {
                // TODO Handle other types than objects (?)
                mv.visitVarInsn(ALOAD, idx++);
            }

            mv.visitMethodInsn(INVOKESPECIAL, baseClassSlash, "<init>", desc);
            mv.visitInsn(RETURN);
            mv.visitMaxs(idx, idx);
            mv.visitEnd();
        }
    }

    // Overloaded and unimplemented methods
    Method[] methods = baseClass.getMethods();
    int idx = 0;
    List<Label> exceptionLabels = new ArrayList<Label>();
    for (Method method : methods) {
        if (isOverloaded(method, baseClass)) {
            idx++;
            String methodName = method.getName();
            String desc = org.objectweb.asm.commons.Method.getMethod(method).getDescriptor();

            String[] exceptions = null;
            {
                mv = cw.visitMethod(ACC_PUBLIC, methodName, desc, null, exceptions);
                if (isInternalQi4jMethod(method, baseClass)) {
                    // generate a NoOp method...
                    mv.visitInsn(RETURN);
                } else {
                    Label endLabel = null; // Use this if return type is void
                    if (method.getExceptionTypes().length > 0) {
                        exceptions = new String[method.getExceptionTypes().length];
                        for (int i = 0; i < method.getExceptionTypes().length; i++) {
                            Class<?> aClass = method.getExceptionTypes()[i];
                            exceptions[i] = getInternalName(aClass);
                        }
                    }
                    mv.visitCode();
                    Label l0 = new Label();
                    Label l1 = new Label();

                    exceptionLabels.clear();
                    for (Class<?> declaredException : method.getExceptionTypes()) {
                        Label ld = new Label();
                        mv.visitTryCatchBlock(l0, l1, ld, getInternalName(declaredException));
                        exceptionLabels.add(ld); // Reuse this further down for the catch
                    }

                    Label lruntime = new Label();
                    mv.visitTryCatchBlock(l0, l1, lruntime, "java/lang/RuntimeException");
                    Label lerror = new Label();
                    mv.visitTryCatchBlock(l0, l1, lerror, "java/lang/Throwable");

                    mv.visitLabel(l0);
                    mv.visitVarInsn(ALOAD, 0);
                    mv.visitFieldInsn(GETFIELD, classSlash, "_instance",
                            "Lorg/qi4j/api/composite/CompositeInvoker;");
                    mv.visitFieldInsn(GETSTATIC, classSlash, "m" + idx, "Ljava/lang/reflect/Method;");

                    int paramCount = method.getParameterTypes().length;
                    int stackIdx = 0;
                    if (paramCount == 0) {
                        // Send in null as parameter
                        mv.visitInsn(ACONST_NULL);
                    } else {
                        insn(mv, paramCount);
                        mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
                        int pidx = 0;
                        for (Class<?> aClass : method.getParameterTypes()) {
                            mv.visitInsn(DUP);
                            insn(mv, pidx++);
                            stackIdx = wrapParameter(mv, aClass, stackIdx + 1);
                            mv.visitInsn(AASTORE);
                        }
                    }

                    // Call method
                    mv.visitMethodInsn(INVOKEINTERFACE, "org/qi4j/api/composite/CompositeInvoker",
                            "invokeComposite",
                            "(Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;");

                    // Return value
                    if (!method.getReturnType().equals(Void.TYPE)) {
                        unwrapResult(mv, method.getReturnType(), l1);
                    } else {
                        mv.visitInsn(POP);
                        mv.visitLabel(l1);
                        endLabel = new Label();
                        mv.visitJumpInsn(GOTO, endLabel);
                    }

                    // Increase stack to beyond method args
                    stackIdx++;

                    // Declared exceptions
                    int exceptionIdx = 0;
                    for (Class<?> aClass : method.getExceptionTypes()) {
                        mv.visitLabel(exceptionLabels.get(exceptionIdx++));
                        mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { getInternalName(aClass) });
                        mv.visitVarInsn(ASTORE, stackIdx);
                        mv.visitVarInsn(ALOAD, stackIdx);
                        mv.visitInsn(ATHROW);
                    }

                    // RuntimeException and Error catch-all
                    mv.visitLabel(lruntime);
                    mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/RuntimeException" });
                    mv.visitVarInsn(ASTORE, stackIdx);
                    mv.visitVarInsn(ALOAD, stackIdx);
                    mv.visitInsn(ATHROW);

                    mv.visitLabel(lerror);
                    mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" });
                    mv.visitVarInsn(ASTORE, stackIdx);
                    mv.visitVarInsn(ALOAD, stackIdx);
                    mv.visitTypeInsn(CHECKCAST, "java/lang/Error");
                    mv.visitInsn(ATHROW);

                    // Return type = void
                    if (endLabel != null) {
                        mv.visitLabel(endLabel);
                        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                        mv.visitInsn(RETURN);
                    }

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

            if (!Modifier.isAbstract(method.getModifiers())) {
                // Add method with _ as prefix
                mv = cw.visitMethod(ACC_PUBLIC, "_" + method.getName(), desc, null, exceptions);
                mv.visitCode();
                mv.visitVarInsn(ALOAD, 0);

                // Parameters
                int stackIdx = 1;
                for (Class<?> aClass : method.getParameterTypes()) {
                    stackIdx = loadParameter(mv, aClass, stackIdx) + 1;
                }

                // Call method
                mv.visitMethodInsn(INVOKESPECIAL, baseClassSlash, method.getName(), desc);

                // Return value
                if (!method.getReturnType().equals(Void.TYPE)) {
                    returnResult(mv, method.getReturnType());
                } else {
                    mv.visitInsn(RETURN);
                }

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

    // Class initializer
    {
        mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
        mv.visitCode();
        Label l0 = new Label();
        Label l1 = new Label();
        Label l2 = new Label();
        mv.visitTryCatchBlock(l0, l1, l2, "java/lang/NoSuchMethodException");
        mv.visitLabel(l0);

        // Lookup methods and store in static variables
        int midx = 0;
        for (Method method : methods) {
            if (isOverloaded(method, baseClass)) {
                method.setAccessible(true);
                Class methodClass;
                methodClass = method.getDeclaringClass();

                midx++;

                mv.visitLdcInsn(Type.getType(methodClass));
                mv.visitLdcInsn(method.getName());
                insn(mv, method.getParameterTypes().length);
                mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");

                int pidx = 0;
                for (Class<?> aClass : method.getParameterTypes()) {
                    mv.visitInsn(DUP);
                    insn(mv, pidx++);
                    type(mv, aClass);
                    mv.visitInsn(AASTORE);
                }

                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod",
                        "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;");
                mv.visitFieldInsn(PUTSTATIC, classSlash, "m" + midx, "Ljava/lang/reflect/Method;");
            }
        }

        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/NoSuchMethodException" });
        mv.visitVarInsn(ASTORE, 0);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/NoSuchMethodException", "printStackTrace", "()V");
        mv.visitLabel(l3);
        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        mv.visitInsn(RETURN);
        mv.visitMaxs(6, 1);
        mv.visitEnd();
    }

    cw.visitEnd();

    return cw.toByteArray();
}

From source file:org.qi4j.test.ASMTest.java

License:Open Source License

public static byte[] generateClass() {
    ClassWriter cw = new ClassWriter(0);
    FieldVisitor fv;//from www.  j av a 2  s  . com
    MethodVisitor mv;
    AnnotationVisitor av0;

    cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "org/qi4j/satisfiedBy/SomeMixin_Stub", null,
            "org/qi4j/satisfiedBy/SomeMixin", null);

    {
        fv = cw.visitField(ACC_PUBLIC, "_instance", "Lorg/qi4j/spi/composite/CompositeInvoker;", null, null);
        fv.visitEnd();
    }
    {
        fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "m1", "Ljava/lang/reflect/Method;", null, null);
        fv.visitEnd();
    }
    {
        fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "m2", "Ljava/lang/reflect/Method;", null, null);
        fv.visitEnd();
    }
    {
        fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "m3", "Ljava/lang/reflect/Method;", null, null);
        fv.visitEnd();
    }
    {
        fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "m4", "Ljava/lang/reflect/Method;", null, null);
        fv.visitEnd();
    }
    {
        fv = cw.visitField(ACC_PRIVATE + ACC_STATIC, "m5", "Ljava/lang/reflect/Method;", null, null);
        fv.visitEnd();
    }
    {
        mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, "org/qi4j/satisfiedBy/SomeMixin", "<init>", "()V");
        mv.visitInsn(RETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/String;)V", null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(INVOKESPECIAL, "org/qi4j/satisfiedBy/SomeMixin", "<init>", "(Ljava/lang/String;)V");
        mv.visitInsn(RETURN);
        mv.visitMaxs(2, 2);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(ACC_PUBLIC, "other", "()Ljava/lang/String;", 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.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, "org/qi4j/satisfiedBy/SomeMixin_Stub", "_instance",
                "Lorg/qi4j/spi/composite/CompositeInvoker;");
        mv.visitFieldInsn(GETSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m1", "Ljava/lang/reflect/Method;");
        mv.visitInsn(ACONST_NULL);
        mv.visitMethodInsn(INVOKEINTERFACE, "org/qi4j/spi/composite/CompositeInvoker", "invokeComposite",
                "(Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;");
        mv.visitTypeInsn(CHECKCAST, "java/lang/String");
        mv.visitLabel(l1);
        mv.visitInsn(ARETURN);
        mv.visitLabel(l2);
        mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" });
        mv.visitVarInsn(ASTORE, 1);
        mv.visitTypeInsn(NEW, "java/lang/reflect/UndeclaredThrowableException");
        mv.visitInsn(DUP);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/UndeclaredThrowableException", "<init>",
                "(Ljava/lang/Throwable;)V");
        mv.visitInsn(ATHROW);
        mv.visitMaxs(3, 2);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(ACC_PUBLIC, "foo", "(Ljava/lang/String;I)Ljava/lang/String;", null,
                new String[] { "java/lang/IllegalArgumentException" });
        mv.visitCode();
        Label l0 = new Label();
        Label l1 = new Label();
        Label l2 = new Label();
        mv.visitTryCatchBlock(l0, l1, l2, "java/lang/IllegalArgumentException");
        Label l3 = new Label();
        mv.visitTryCatchBlock(l0, l1, l3, "java/lang/Throwable");
        mv.visitLabel(l0);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, "org/qi4j/satisfiedBy/SomeMixin_Stub", "_instance",
                "Lorg/qi4j/spi/composite/CompositeInvoker;");
        mv.visitFieldInsn(GETSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m2", "Ljava/lang/reflect/Method;");
        mv.visitInsn(ICONST_2);
        mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_1);
        mv.visitVarInsn(ILOAD, 2);
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
        mv.visitInsn(AASTORE);
        mv.visitMethodInsn(INVOKEINTERFACE, "org/qi4j/spi/composite/CompositeInvoker", "invokeComposite",
                "(Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;");
        mv.visitTypeInsn(CHECKCAST, "java/lang/String");
        mv.visitLabel(l1);
        mv.visitInsn(ARETURN);
        mv.visitLabel(l2);
        mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/IllegalArgumentException" });
        mv.visitVarInsn(ASTORE, 3);
        mv.visitVarInsn(ALOAD, 3);
        mv.visitInsn(ATHROW);
        mv.visitLabel(l3);
        mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" });
        mv.visitVarInsn(ASTORE, 3);
        mv.visitTypeInsn(NEW, "java/lang/reflect/UndeclaredThrowableException");
        mv.visitInsn(DUP);
        mv.visitVarInsn(ALOAD, 3);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/UndeclaredThrowableException", "<init>",
                "(Ljava/lang/Throwable;)V");
        mv.visitInsn(ATHROW);
        mv.visitMaxs(6, 4);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(ACC_PUBLIC, "bar", "(DZFCIJSBLjava/lang/Double;[Ljava/lang/Object;[I)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.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, "org/qi4j/satisfiedBy/SomeMixin_Stub", "_instance",
                "Lorg/qi4j/spi/composite/CompositeInvoker;");
        mv.visitFieldInsn(GETSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m3", "Ljava/lang/reflect/Method;");
        mv.visitIntInsn(BIPUSH, 11);
        mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_0);
        mv.visitVarInsn(DLOAD, 1);
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;");
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_1);
        mv.visitVarInsn(ILOAD, 3);
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;");
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_2);
        mv.visitVarInsn(FLOAD, 4);
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;");
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_3);
        mv.visitVarInsn(ILOAD, 5);
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;");
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_4);
        mv.visitVarInsn(ILOAD, 6);
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_5);
        mv.visitVarInsn(LLOAD, 7);
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;");
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitIntInsn(BIPUSH, 6);
        mv.visitVarInsn(ILOAD, 9);
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;");
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitIntInsn(BIPUSH, 7);
        mv.visitVarInsn(ILOAD, 10);
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;");
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitIntInsn(BIPUSH, 8);
        mv.visitVarInsn(ALOAD, 11);
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitIntInsn(BIPUSH, 9);
        mv.visitVarInsn(ALOAD, 12);
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitIntInsn(BIPUSH, 10);
        mv.visitVarInsn(ALOAD, 13);
        mv.visitInsn(AASTORE);
        mv.visitMethodInsn(INVOKEINTERFACE, "org/qi4j/spi/composite/CompositeInvoker", "invokeComposite",
                "(Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;");
        mv.visitInsn(POP);
        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, 14);
        mv.visitTypeInsn(NEW, "java/lang/reflect/UndeclaredThrowableException");
        mv.visitInsn(DUP);
        mv.visitVarInsn(ALOAD, 14);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/UndeclaredThrowableException", "<init>",
                "(Ljava/lang/Throwable;)V");
        mv.visitInsn(ATHROW);
        mv.visitLabel(l3);
        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        mv.visitInsn(RETURN);
        mv.visitMaxs(7, 15);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(ACC_PUBLIC, "multiEx", "(Ljava/lang/String;)V", null,
                new String[] { "org/qi4j/satisfiedBy/Exception1", "org/qi4j/satisfiedBy/Exception2" });
        mv.visitCode();
        Label l0 = new Label();
        Label l1 = new Label();
        Label l2 = new Label();
        mv.visitTryCatchBlock(l0, l1, l2, "org/qi4j/satisfiedBy/Exception1");
        Label l3 = new Label();
        mv.visitTryCatchBlock(l0, l1, l3, "org/qi4j/satisfiedBy/Exception2");
        Label l4 = new Label();
        mv.visitTryCatchBlock(l0, l1, l4, "java/lang/Throwable");
        mv.visitLabel(l0);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, "org/qi4j/satisfiedBy/SomeMixin_Stub", "_instance",
                "Lorg/qi4j/spi/composite/CompositeInvoker;");
        mv.visitFieldInsn(GETSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m4", "Ljava/lang/reflect/Method;");
        mv.visitInsn(ICONST_1);
        mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitInsn(AASTORE);
        mv.visitMethodInsn(INVOKEINTERFACE, "org/qi4j/spi/composite/CompositeInvoker", "invokeComposite",
                "(Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;");
        mv.visitInsn(POP);
        mv.visitLabel(l1);
        Label l5 = new Label();
        mv.visitJumpInsn(GOTO, l5);
        mv.visitLabel(l2);
        mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "org/qi4j/satisfiedBy/Exception1" });
        mv.visitVarInsn(ASTORE, 2);
        mv.visitVarInsn(ALOAD, 2);
        mv.visitInsn(ATHROW);
        mv.visitLabel(l3);
        mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "org/qi4j/satisfiedBy/Exception2" });
        mv.visitVarInsn(ASTORE, 2);
        mv.visitVarInsn(ALOAD, 2);
        mv.visitInsn(ATHROW);
        mv.visitLabel(l4);
        mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" });
        mv.visitVarInsn(ASTORE, 2);
        mv.visitTypeInsn(NEW, "java/lang/reflect/UndeclaredThrowableException");
        mv.visitInsn(DUP);
        mv.visitVarInsn(ALOAD, 2);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/UndeclaredThrowableException", "<init>",
                "(Ljava/lang/Throwable;)V");
        mv.visitInsn(ATHROW);
        mv.visitLabel(l5);
        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        mv.visitInsn(RETURN);
        mv.visitMaxs(6, 3);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(ACC_PUBLIC, "unwrapResult", "()I", 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.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, "org/qi4j/satisfiedBy/SomeMixin_Stub", "_instance",
                "Lorg/qi4j/spi/composite/CompositeInvoker;");
        mv.visitFieldInsn(GETSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m5", "Ljava/lang/reflect/Method;");
        mv.visitInsn(ACONST_NULL);
        mv.visitMethodInsn(INVOKEINTERFACE, "org/qi4j/spi/composite/CompositeInvoker", "invokeComposite",
                "(Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;");
        mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I");
        mv.visitLabel(l1);
        mv.visitInsn(IRETURN);
        mv.visitLabel(l2);
        mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Throwable" });
        mv.visitVarInsn(ASTORE, 1);
        mv.visitTypeInsn(NEW, "java/lang/reflect/UndeclaredThrowableException");
        mv.visitInsn(DUP);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/reflect/UndeclaredThrowableException", "<init>",
                "(Ljava/lang/Throwable;)V");
        mv.visitInsn(ATHROW);
        mv.visitMaxs(3, 2);
        mv.visitEnd();
    }
    {
        mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
        mv.visitCode();
        Label l0 = new Label();
        Label l1 = new Label();
        Label l2 = new Label();
        mv.visitTryCatchBlock(l0, l1, l2, "java/lang/NoSuchMethodException");
        mv.visitLabel(l0);
        mv.visitLdcInsn(Type.getType("Lorg/qi4j/satisfiedBy/Other;"));
        mv.visitLdcInsn("other");
        mv.visitInsn(ICONST_0);
        mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod",
                "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;");
        mv.visitFieldInsn(PUTSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m1", "Ljava/lang/reflect/Method;");
        mv.visitLdcInsn(Type.getType("Lorg/qi4j/satisfiedBy/Other;"));
        mv.visitLdcInsn("foo");
        mv.visitInsn(ICONST_2);
        mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_0);
        mv.visitLdcInsn(Type.getType("Ljava/lang/String;"));
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_1);
        mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;");
        mv.visitInsn(AASTORE);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod",
                "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;");
        mv.visitFieldInsn(PUTSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m2", "Ljava/lang/reflect/Method;");
        mv.visitLdcInsn(Type.getType("Lorg/qi4j/satisfiedBy/Other;"));
        mv.visitLdcInsn("bar");
        mv.visitIntInsn(BIPUSH, 11);
        mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_0);
        mv.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;");
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_1);
        mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;");
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_2);
        mv.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;");
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_3);
        mv.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;");
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_4);
        mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;");
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_5);
        mv.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;");
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitIntInsn(BIPUSH, 6);
        mv.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;");
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitIntInsn(BIPUSH, 7);
        mv.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;");
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitIntInsn(BIPUSH, 8);
        mv.visitLdcInsn(Type.getType("Ljava/lang/Double;"));
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitIntInsn(BIPUSH, 9);
        mv.visitLdcInsn(Type.getType("[Ljava/lang/Object;"));
        mv.visitInsn(AASTORE);
        mv.visitInsn(DUP);
        mv.visitIntInsn(BIPUSH, 10);
        mv.visitLdcInsn(Type.getType("[I"));
        mv.visitInsn(AASTORE);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod",
                "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;");
        mv.visitFieldInsn(PUTSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m3", "Ljava/lang/reflect/Method;");
        mv.visitLdcInsn(Type.getType("Lorg/qi4j/satisfiedBy/Other;"));
        mv.visitLdcInsn("multiEx");
        mv.visitInsn(ICONST_1);
        mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");
        mv.visitInsn(DUP);
        mv.visitInsn(ICONST_0);
        mv.visitLdcInsn(Type.getType("Ljava/lang/String;"));
        mv.visitInsn(AASTORE);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod",
                "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;");
        mv.visitFieldInsn(PUTSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m4", "Ljava/lang/reflect/Method;");
        mv.visitLdcInsn(Type.getType("Lorg/qi4j/satisfiedBy/Other;"));
        mv.visitLdcInsn("unwrapResult");
        mv.visitInsn(ICONST_0);
        mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getMethod",
                "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;");
        mv.visitFieldInsn(PUTSTATIC, "org/qi4j/satisfiedBy/SomeMixin_Stub", "m5", "Ljava/lang/reflect/Method;");
        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/NoSuchMethodException" });
        mv.visitVarInsn(ASTORE, 0);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/NoSuchMethodException", "printStackTrace", "()V");
        mv.visitLabel(l3);
        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        mv.visitInsn(RETURN);
        mv.visitMaxs(6, 1);
        mv.visitEnd();
    }
    cw.visitEnd();

    return cw.toByteArray();
}

From source file:org.qkit.core.asm.adapters.AddCustomGraphicsAdapter.java

License:Open Source License

@Override
public void visitEnd() {
    ClassNode cn = (ClassNode) cv;/*from www . j  a  va 2s .  com*/

    String imgVar = null;
    for (FieldNode f : cn.fields) {
        if (f.desc.contains(Image.class.getName().replace('.', '/')))
            imgVar = f.name;
    }

    MethodNode mm = null, mv = null;

    for (MethodNode m : cn.methods) {
        if (m.name.equals("drawGraphics")) {
            mm = m;
            mv = new MethodNode(ACC_PUBLIC, "drawGraphics", "(ILjava/awt/Graphics;I)V", null, null);
            mv.visitCode();
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKESPECIAL, "RSImageProducer", "method239", "()V");
            mv.visitVarInsn(ALOAD, 0);
            mv.visitFieldInsn(GETFIELD, "RSImageProducer", "anImage320", "Ljava/awt/Image;");
            mv.visitVarInsn(ILOAD, 1);
            mv.visitVarInsn(ILOAD, 3);
            mv.visitMethodInsn(INVOKESTATIC, "RSImageProducer", "render", "(Ljava/awt/Image;II)Z");
            Label l0 = new Label();
            mv.visitJumpInsn(IFEQ, l0);
            mv.visitInsn(RETURN);
            mv.visitLabel(l0);
            mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
            mv.visitVarInsn(ALOAD, 2);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitFieldInsn(GETFIELD, "RSImageProducer", "anImage320", "Ljava/awt/Image;");
            mv.visitVarInsn(ILOAD, 3);
            mv.visitVarInsn(ILOAD, 1);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/awt/Graphics", "drawImage",
                    "(Ljava/awt/Image;IILjava/awt/image/ImageObserver;)Z");
            mv.visitInsn(POP);
            mv.visitInsn(RETURN);
            mv.visitMaxs(5, 4);
            mv.visitEnd();
        }
    }

    cn.methods.remove(mm);
    cn.methods.add(mv);

    System.out.println("          [+M] Added gfx method");

    try {
        cn.accept(next);
    } catch (Exception ez) {
        ez.printStackTrace();
    }

}

From source file:org.simantics.databoard.binding.classfactory.AsmTypeClassFactory.java

License:Open Source License

public Class<?> createRecordClass(RecordType type) throws BindingConstructionException {
    ClassWriter cw = new ClassWriter(0);
    AnnotationVisitor av0;//from   www.ja va  2s.com

    // Create class name
    SignatureVisitor sv = new SignatureVisitor();
    type.accept(sv, null);
    String sig = sv.sb.toString() + "_" + Integer.toHexString(sv.hashcode);

    String hash = Integer.toHexString(type.hashCode());
    String className = "org.simantics.databoard.RecordType_" + sig;
    String classSig = "org/simantics/databoard/RecordType_" + sig;
    Class<?> superClass = makeBean ? Bean.class : Object.class;
    String superType = AsmBindingClassLoader.toClassCanonicalName(superClass);

    cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, classSig, null, superType, null);

    if (type.isReferable()) {
        av0 = cw.visitAnnotation(AsmBindingClassLoader.toTypeDescriptor(Referable.class), true);
        av0.visitEnd();
    }

    for (int i = 0; i < type.getComponentCount(); i++) {
        Component c = type.getComponent(i);
        Datatype fieldType = c.type;
        boolean isOptional = fieldType instanceof OptionalType;
        boolean isIdentifier = type.isIdentifier(i);
        if (isOptional) {
            fieldType = ((OptionalType) fieldType).componentType;
        }
        //         boolean isArray = fieldType instanceof ArrayType;
        //         if ( isArray ) {
        //            fieldType = ((ArrayType) fieldType).componentType;
        //         }
        String fieldName = toJavaFieldName(c.name);
        BindingRequest br = classFactory.getClass(fieldType);

        FieldVisitor fv = cw.visitField(ACC_PUBLIC, fieldName, br.signature,
                br.descriptor.equals(br.signature) ? null : br.descriptor, null);

        // Visit annotations
        if (br.annotations != null && br.annotations.length > 0) {
            for (Annotation a : br.annotations) {

                if (a instanceof Arguments) {
                    Arguments arg = (Arguments) a;
                    av0 = fv.visitAnnotation(AsmBindingClassLoader.toTypeDescriptor(Arguments.class), true);
                    AnnotationVisitor av1 = av0.visitArray("value");
                    for (Class<?> clzz : arg.value()) {
                        av1.visit(null, Type.getType(AsmBindingClassLoader.toTypeDescriptor(clzz)));
                    }
                    av1.visitEnd();
                    av0.visitEnd();
                }

                isIdentifier |= a instanceof Identifier;

                if (a instanceof Length) {
                    Length arg = (Length) a;
                    av0 = fv.visitAnnotation(AsmBindingClassLoader.toTypeDescriptor(Length.class), true);
                    AnnotationVisitor av1 = av0.visitArray("value");
                    for (String s : arg.value())
                        av1.visit(null, s);
                    av1.visitEnd();
                    av0.visitEnd();
                }

                if (a instanceof MIMEType) {
                    MIMEType arg = (MIMEType) a;
                    av0 = fv.visitAnnotation(AsmBindingClassLoader.toTypeDescriptor(MIMEType.class), true);
                    av0.visit("value", arg.value());
                    av0.visitEnd();
                }

                if (a instanceof Name) {
                    Name arg = (Name) a;
                    av0 = fv.visitAnnotation(AsmBindingClassLoader.toTypeDescriptor(Name.class), true);
                    av0.visit("value", arg.value());
                    av0.visitEnd();
                }

                isOptional |= a instanceof Optional;

                if (a instanceof org.simantics.databoard.annotations.Pattern) {
                    org.simantics.databoard.annotations.Pattern arg = (org.simantics.databoard.annotations.Pattern) a;
                    av0 = fv.visitAnnotation(AsmBindingClassLoader
                            .toTypeDescriptor(org.simantics.databoard.annotations.Pattern.class), true);
                    av0.visit("value", arg.value());
                    av0.visitEnd();
                }

                if (a instanceof Range) {
                    Range arg = (Range) a;
                    av0 = fv.visitAnnotation(AsmBindingClassLoader.toTypeDescriptor(Range.class), true);
                    av0.visit("value", arg.value());
                    av0.visitEnd();
                }

                if (a instanceof Unit) {
                    Unit arg = (Unit) a;
                    av0 = fv.visitAnnotation(AsmBindingClassLoader.toTypeDescriptor(Unit.class), true);
                    av0.visit("value", arg.value());
                    av0.visitEnd();
                }
            }
        }

        if (isIdentifier) {
            av0 = fv.visitAnnotation(AsmBindingClassLoader.toTypeDescriptor(Identifier.class), true);
            av0.visitEnd();
        }
        if (isOptional) {
            av0 = fv.visitAnnotation(AsmBindingClassLoader.toTypeDescriptor(Optional.class), true);
            av0.visitEnd();
        }

        fv.visitEnd();
    }

    // Constructor
    {
        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        Label l0 = new Label();

        // super()
        if (!makeBean) {
            mv.visitLabel(l0);
            mv.visitLineNumber(20, l0);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKESPECIAL, superType, "<init>", "()V");
        } else {
            // super( getStaticBinding() )
            mv.visitLabel(l0);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKESTATIC, classSig, "getStaticBinding",
                    "()Lorg/simantics/databoard/binding/Binding;");
            mv.visitMethodInsn(INVOKESPECIAL, "org/simantics/databoard/util/Bean", "<init>",
                    "(Lorg/simantics/databoard/binding/Binding;)V");
        }

        mv.visitInsn(RETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", "L" + classSig + ";", null, l0, l1, 0);
        if (!makeBean) {
            mv.visitMaxs(1, 1);
        } else {
            mv.visitMaxs(2, 1);
        }
        mv.visitEnd();
    }

    // BINDING
    {
        FieldVisitor fv = cw.visitField(ACC_STATIC, "BINDING", "Lorg/simantics/databoard/binding/Binding;",
                null, null);
        fv.visitEnd();

        MethodVisitor mv = cw.visitMethod(ACC_STATIC, "getStaticBinding",
                "()Lorg/simantics/databoard/binding/Binding;", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitFieldInsn(GETSTATIC, classSig, "BINDING", "Lorg/simantics/databoard/binding/Binding;");
        Label l1 = new Label();
        mv.visitJumpInsn(IFNONNULL, l1);
        mv.visitLdcInsn(Type.getType("L" + classSig + ";"));
        mv.visitMethodInsn(INVOKESTATIC, "org/simantics/databoard/Bindings", "getBindingUnchecked",
                "(Ljava/lang/Class;)Lorg/simantics/databoard/binding/Binding;");
        mv.visitFieldInsn(PUTSTATIC, classSig, "BINDING", "Lorg/simantics/databoard/binding/Binding;");
        mv.visitLabel(l1);
        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
        mv.visitFieldInsn(GETSTATIC, classSig, "BINDING", "Lorg/simantics/databoard/binding/Binding;");
        mv.visitInsn(ARETURN);
        mv.visitMaxs(1, 0);
        mv.visitEnd();
    }

    cw.visitEnd();
    byte[] data = cw.toByteArray();
    Class<?> clazz = defineClass(className, data, 0, data.length);
    BindingRequest br = new BindingRequest(clazz);
    return clazz;
}

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 ww  .  ja  va  2  s.  c  om
    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.binding.reflection.AsmBindingClassLoader.java

License:Open Source License

private void addGetSetPrimitive(ClassInfo ci, ClassVisitor cv, String setterName, String signature,
        String bindingClassName) {
    String className = ci.clazz.getName().replaceAll("\\.", "/");

    Label firstLabel = new Label();
    Label secondLabel = new Label();
    Label errorLabel = new Label();
    Label exitLabel = new Label();
    Label lastLabel = new Label();

    boolean oneByte = !signature.equals("J") && !signature.equals("D");

    int c = 0;/*from w w w .  j  ava2s.c  o  m*/
    for (Field f : ci.fields) {
        if (toTypeDescriptor(getPrimitiveClass(f.getType())).equals(signature))
            c++;
    }

    int[] indices = new int[c];
    Label[] caseLabel = new Label[c];

    c = 0;
    for (int i = 0; i < ci.fields.length; i++) {
        Class<?> fieldClass = ci.fields[i].getType();
        fieldClass = getPrimitiveClass(fieldClass);
        String s = toTypeDescriptor(fieldClass);
        if (!s.equals(signature))
            continue;

        indices[c] = i;
        caseLabel[c] = new Label();
        c++;
    }

    //////////////////
    /// Setter
    ///
    MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "set" + setterName, "(Ljava/lang/Object;I" + signature + ")V",
            null, new String[] { "org/simantics/databoard/binding/error/BindingException" });
    mv.visitCode();
    mv.visitLabel(firstLabel);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitTypeInsn(CHECKCAST, className);
    mv.visitVarInsn(ASTORE, oneByte ? 4 : 5);

    mv.visitLabel(secondLabel);
    mv.visitVarInsn(ILOAD, 2);

    // switch
    mv.visitLookupSwitchInsn(errorLabel, indices, caseLabel);

    // case 1:
    if (c > 0) {
        for (int i = 0; i < c; i++) {
            int index = indices[i];
            Method setter = ci.setters[index];
            Field field = ci.fields[index];
            Class<?> fieldClass = field.getType();
            Class<?> setterClass = setter != null ? setter.getParameterTypes()[0] : null;
            boolean useSetter = ((field.getModifiers() & Modifier.PUBLIC) == 0) && setter != null;
            String typeDescriptor = toTypeDescriptor(useSetter ? setterClass : fieldClass);

            mv.visitLabel(caseLabel[i]);
            if (i == 0) {
                mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { className }, 0, null);
            } else {
                mv.visitFrame(Opcodes.F_SAME, 0, new Object[] { className }, 0, null);
            }
            if (signature.equals("F")) {
                mv.visitVarInsn(ALOAD, 4);
                mv.visitVarInsn(FLOAD, 3);
            } else if (signature.equals("D")) {
                mv.visitVarInsn(ALOAD, 5);
                mv.visitVarInsn(DLOAD, 3);
            } else if (signature.equals("J")) {
                mv.visitVarInsn(ALOAD, 5);
                mv.visitVarInsn(LLOAD, 3);
            } else {
                mv.visitVarInsn(ALOAD, 4);
                mv.visitVarInsn(ILOAD, 3);
            }

            if (useSetter) {
                boxTo(mv, setterClass);
                mv.visitMethodInsn(INVOKEVIRTUAL, className, setter.getName(), "(" + typeDescriptor + ")V");
            } else {
                boxTo(mv, fieldClass);
                mv.visitFieldInsn(PUTFIELD, className, field.getName(), typeDescriptor);
            }
            mv.visitJumpInsn(GOTO, exitLabel);
        }
    } else {
        mv.visitInsn(POP);
    }

    // default: (error)
    /*
    mv.visitLabel(errorLabel);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitTypeInsn(NEW, "org/simantics/databoard/binding/error/BindingException");
    mv.visitInsn(DUP);
    mv.visitLdcInsn("Field is not "+setterName);
    mv.visitMethodInsn(INVOKESPECIAL, "org/simantics/databoard/binding/error/BindingException", "<init>", "(Ljava/lang/String;)V");
    mv.visitInsn(ATHROW);
    */

    // default: setComponent
    mv.visitLabel(errorLabel);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitVarInsn(ILOAD, 2);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, bindingClassName, "componentBindings",
            "[Lorg/simantics/databoard/binding/Binding;");
    mv.visitVarInsn(ILOAD, 2);
    mv.visitInsn(AALOAD);
    if (signature.equals("F")) {
        mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/FloatBinding");
        mv.visitVarInsn(FLOAD, 3);
        mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/FloatBinding", "create",
                "(F)Ljava/lang/Object;");
    } else if (signature.equals("D")) {
        mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/DoubleBinding");
        mv.visitVarInsn(DLOAD, 3);
        mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/DoubleBinding", "create",
                "(D)Ljava/lang/Object;");
    } else if (signature.equals("J")) {
        mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/LongBinding");
        mv.visitVarInsn(LLOAD, 3);
        mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/LongBinding", "create",
                "(J)Ljava/lang/Object;");
    } else if (signature.equals("Z")) {
        mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/BooleanBinding");
        mv.visitVarInsn(ILOAD, 3);
        mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/BooleanBinding", "create",
                "(Z)Ljava/lang/Object;");
    } else if (signature.equals("I")) {
        mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/IntBinding");
        mv.visitVarInsn(ILOAD, 3);
        mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/IntBinding", "create",
                "(I)Ljava/lang/Object;");
    } else if (signature.equals("B")) {
        mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/ByteBinding");
        mv.visitVarInsn(ILOAD, 3);
        mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/ByteBinding", "create",
                "(B)Ljava/lang/Object;");
    }
    mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "setComponent",
            "(Ljava/lang/Object;ILjava/lang/Object;)V");

    // return
    mv.visitLabel(exitLabel);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitInsn(RETURN);

    // Something at the end
    mv.visitLabel(lastLabel);
    //       mv.visitLocalVariable("this", "L"+bindingClassName+";", null, firstLabel, lastLabel, 0);
    //       mv.visitLocalVariable("r", "Ljava/lang/Object;", null, firstLabel, lastLabel, 1);
    //       mv.visitLocalVariable("index", "I", null, firstLabel, lastLabel, 2);
    //       mv.visitLocalVariable("z", signature, null, firstLabel, lastLabel, 3);
    //       mv.visitLocalVariable("x", "L"+className+";", null, secondLabel, lastLabel, 4);
    mv.visitMaxs(oneByte ? 5 : 6, oneByte ? 5 : 6);
    mv.visitEnd();

    //////////////////
    /// Getter
    ///
    firstLabel = new Label();
    secondLabel = new Label();
    errorLabel = new Label();
    exitLabel = new Label();
    lastLabel = new Label();
    for (int i = 0; i < c; i++)
        caseLabel[i] = new Label();
    mv = cv.visitMethod(ACC_PUBLIC, "get" + setterName, "(Ljava/lang/Object;I)" + signature, null,
            new String[] { "org/simantics/databoard/binding/error/BindingException" });
    mv.visitCode();
    mv.visitLabel(firstLabel);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitTypeInsn(CHECKCAST, className);
    mv.visitVarInsn(ASTORE, 3);

    mv.visitLabel(secondLabel);
    mv.visitVarInsn(ILOAD, 2);

    // switch
    if (c > 0) {
        mv.visitLookupSwitchInsn(errorLabel, indices, caseLabel);

        // case i:
        for (int i = 0; i < c; i++) {
            int index = indices[i];
            Method getter = ci.getters[index];
            Field field = ci.fields[index];
            Class<?> fieldClass = field.getType();
            Class<?> getterClass = getter != null ? getter.getReturnType() : null;
            boolean useGetter = ((field.getModifiers() & Modifier.PUBLIC) == 0) && getter != null;
            String typeDescriptor = toTypeDescriptor(useGetter ? getterClass : fieldClass);

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

            mv.visitVarInsn(ALOAD, 3);

            if (useGetter) {
                mv.visitMethodInsn(INVOKEVIRTUAL, className, getter.getName(), "()" + typeDescriptor);
                unboxFrom(mv, getterClass);
            } else {
                mv.visitFieldInsn(GETFIELD, className, field.getName(), typeDescriptor);
                unboxFrom(mv, fieldClass);
            }

            if (signature.equals("F")) {
                mv.visitInsn(FRETURN);
            } else if (signature.equals("D")) {
                mv.visitInsn(DRETURN);
            } else if (signature.equals("J")) {
                mv.visitInsn(LRETURN);
            } else {
                mv.visitInsn(IRETURN);
            }
        }
    } else {
        mv.visitInsn(POP);
    }

    // default: (error)
    /*
    mv.visitLabel(errorLabel);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitTypeInsn(NEW, "org/simantics/databoard/binding/error/BindingException");
    mv.visitInsn(DUP);
    mv.visitLdcInsn("Field is not "+setterName);
    mv.visitMethodInsn(INVOKESPECIAL, "org/simantics/databoard/binding/error/BindingException", "<init>", "(Ljava/lang/String;)V");
    mv.visitInsn(ATHROW);
    */

    // default:
    mv.visitLabel(errorLabel);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, bindingClassName, "componentBindings",
            "[Lorg/simantics/databoard/binding/Binding;");
    mv.visitVarInsn(ILOAD, 2);
    mv.visitInsn(AALOAD);
    if (signature.equals("Z")) {
        mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/BooleanBinding");
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitVarInsn(ILOAD, 2);
        mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "getComponent",
                "(Ljava/lang/Object;I)Ljava/lang/Object;");
        mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/BooleanBinding", "getValue_",
                "(Ljava/lang/Object;)Z");
        mv.visitInsn(IRETURN);
    } else if (signature.equals("B")) {
        mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/ByteBinding");
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitVarInsn(ILOAD, 2);
        mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "getComponent",
                "(Ljava/lang/Object;I)Ljava/lang/Object;");
        mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/ByteBinding", "getValue_",
                "(Ljava/lang/Object;)B");
        mv.visitInsn(IRETURN);
    } else if (signature.equals("I")) {
        mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/IntBinding");
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitVarInsn(ILOAD, 2);
        mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "getComponent",
                "(Ljava/lang/Object;I)Ljava/lang/Object;");
        mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/IntBinding", "getValue_",
                "(Ljava/lang/Object;)I");
        mv.visitInsn(IRETURN);
    } else if (signature.equals("J")) {
        mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/LongBinding");
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitVarInsn(ILOAD, 2);
        mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "getComponent",
                "(Ljava/lang/Object;I)Ljava/lang/Object;");
        mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/LongBinding", "getValue_",
                "(Ljava/lang/Object;)J");
        mv.visitInsn(LRETURN);
    } else if (signature.equals("F")) {
        mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/FloatBinding");
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitVarInsn(ILOAD, 2);
        mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "getComponent",
                "(Ljava/lang/Object;I)Ljava/lang/Object;");
        mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/FloatBinding", "getValue_",
                "(Ljava/lang/Object;)F");
        mv.visitInsn(FRETURN);
    } else if (signature.equals("D")) {
        mv.visitTypeInsn(CHECKCAST, "org/simantics/databoard/binding/DoubleBinding");
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitVarInsn(ILOAD, 2);
        mv.visitMethodInsn(INVOKEVIRTUAL, bindingClassName, "getComponent",
                "(Ljava/lang/Object;I)Ljava/lang/Object;");
        mv.visitMethodInsn(INVOKEVIRTUAL, "org/simantics/databoard/binding/DoubleBinding", "getValue_",
                "(Ljava/lang/Object;)D");
        mv.visitInsn(DRETURN);
    }

    // Something at the end
    mv.visitLabel(lastLabel);
    //       mv.visitLocalVariable("this", "Lorg/simantics/databoard/binding/reflection/MyBinding;", null, firstLabel, lastLabel, 0);
    //       mv.visitLocalVariable("r", "Ljava/lang/Object;", null, firstLabel, lastLabel, 1);
    //       mv.visitLocalVariable("index", "I", null, firstLabel, lastLabel, 2);
    //       mv.visitLocalVariable("x", "Lorg/simantics/databoard/binding/reflection/MyClass;", null, secondLabel, lastLabel, 3);
    mv.visitMaxs(4, 4);
    mv.visitEnd();

}