Example usage for org.objectweb.asm Opcodes F_APPEND

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

Introduction

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

Prototype

int F_APPEND

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

Click Source Link

Document

A compressed frame where locals are the same as the locals in the previous frame, except that additional 1-3 locals are defined, and with an empty stack.

Usage

From source file:net.sourceforge.cobertura.instrument.pass3.TestUnitCodeProvider.java

License:GNU General Public License

/**
 * Generates://  w  ww.  j  a v  a2 s .  com
 *   public static void __cobertura_init()
 *   {
 *     if (__cobertura_counters == null)
 *       {
 *         __cobertura_counters = new TestUnitInformationHolder[class.length];
 *       }
 *       TouchCollector.registerClass("mypackage/HelloWorld");
 *   }
 */
public void generateCINITmethod(MethodVisitor mv, String className, int counters_cnt) {
    mv.visitFieldInsn(Opcodes.GETSTATIC, className, COBERTURA_COUNTERS_FIELD_NAME,
            COBERTURA_COUNTERS_FIELD_TYPE);
    Label l1 = new Label();
    mv.visitJumpInsn(Opcodes.IFNONNULL, l1);
    mv.visitLdcInsn(counters_cnt);
    mv.visitTypeInsn(Opcodes.ANEWARRAY, Type.getInternalName(TestUnitInformationHolder.class));
    mv.visitFieldInsn(Opcodes.PUTSTATIC, className, COBERTURA_COUNTERS_FIELD_NAME,
            COBERTURA_COUNTERS_FIELD_TYPE);

    mv.visitInsn(ICONST_0);
    mv.visitVarInsn(ISTORE, 1);
    Label l11 = new Label();
    mv.visitLabel(l11);
    Label l2 = new Label();
    mv.visitJumpInsn(GOTO, l2);
    Label l3 = new Label();
    mv.visitLabel(l3);
    mv.visitLineNumber(24, l3);
    mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { Opcodes.INTEGER }, 0, null);
    mv.visitFieldInsn(GETSTATIC, className, COBERTURA_COUNTERS_FIELD_NAME, COBERTURA_COUNTERS_FIELD_TYPE);
    mv.visitVarInsn(ILOAD, 1);
    mv.visitTypeInsn(NEW, "net/sourceforge/cobertura/coveragedata/TestUnitInformationHolder");
    mv.visitInsn(DUP);
    mv.visitMethodInsn(INVOKESPECIAL, "net/sourceforge/cobertura/coveragedata/TestUnitInformationHolder",
            "<init>", "()V");
    mv.visitInsn(AASTORE);
    Label l4 = new Label();
    mv.visitLabel(l4);
    mv.visitLineNumber(23, l4);
    mv.visitIincInsn(1, 1);
    mv.visitLabel(l2);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitVarInsn(ILOAD, 1);
    mv.visitFieldInsn(GETSTATIC, className, COBERTURA_COUNTERS_FIELD_NAME, COBERTURA_COUNTERS_FIELD_TYPE);
    mv.visitInsn(ARRAYLENGTH);
    mv.visitJumpInsn(IF_ICMPLT, l3);

    mv.visitLabel(l1);

    generateRegisterClass(mv, className);
}

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

License:Open Source License

private static void insertNewInstance(ClassWriter cw, String classNameInternal, ClassInfo info) {
    MethodVisitor mv;//from   w  w w  . java2  s .c  o m
    mv = cw.visitMethod(ACC_PUBLIC + ACC_VARARGS, "newInstance", "(I[Ljava/lang/Object;)Ljava/lang/Object;",
            null, null);
    mv.visitCode();

    int n = info.constructorModifiers.length;

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

        StringBuilder buffer = new StringBuilder(128);
        for (int i = 0; i < n; i++) {
            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.visitTypeInsn(NEW, classNameInternal);
            mv.visitInsn(DUP);

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

            Class<?>[] paramTypes = info.constructorParameterTypes[i];
            for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
                mv.visitVarInsn(ALOAD, 2);
                mv.visitIntInsn(BIPUSH, paramIndex);
                mv.visitInsn(AALOAD);
                Type paramType = Type.getType(paramTypes[paramIndex]);
                unbox(mv, paramType);
                buffer.append(paramType.getDescriptor());
            }
            buffer.append(")V");
            mv.visitMethodInsn(INVOKESPECIAL, classNameInternal, "<init>", buffer.toString(), false);
            mv.visitInsn(ARETURN);
        }
        mv.visitLabel(defaultLabel);
        mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    }
    mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException");
    mv.visitInsn(DUP);
    mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
    mv.visitInsn(DUP);
    mv.visitLdcInsn("Constructor not found: ");
    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.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V",
            false);
    mv.visitInsn(ATHROW);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

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

License:Open Source License

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

    int n = methods.size();

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

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

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

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

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

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

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

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

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

From source file:org.glassfish.pfl.tf.tools.enhancer.SimpleMethodTracer.java

License:Open Source License

private String getFrameType(int type) {
    switch (type) {
    case Opcodes.F_APPEND:
        return "APPEND";
    case Opcodes.F_CHOP:
        return "CHOP";
    case Opcodes.F_FULL:
        return "FULL";
    case Opcodes.F_NEW:
        return "NEW";
    case Opcodes.F_SAME:
        return "SAME";
    case Opcodes.F_SAME1:
        return "SAME1";
    }/*from   www. j a  v a  2 s  . c  om*/
    return "BAD_FRAME_TYPE";
}

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   www  .j  a v  a  2s . c  o  m
        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.kjots.json.object.JsonObjectGeneratorBase.java

License:Apache License

/**
 * Generate a get Java primitive property method.
 *
 * @param classVisitor The class visitor.
 * @param jsonObjectImplType The type of the JSON object implementation.
 * @param method The method./*from  ww w . j  a  va2 s  . co m*/
 * @param propertyName The name of the property.
 * @param jsonPrimitiveType The type of the JSON primitive.
 * @param javaPrimitiveType The type of the Java primitive.
 */
private void generateGetJavaPrimitivePropertyMethod(ClassVisitor classVisitor, Type jsonObjectImplType,
        Method method, String propertyName, Type jsonPrimitiveType, Type javaPrimitiveType) {
    MethodVisitor methodVisitor = classVisitor.visitMethod(ACC_PUBLIC + ACC_FINAL, method, null, null);

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

    methodVisitor.visitCode();

    methodVisitor.visitLabel(start);
    methodVisitor.visitVarInsn(ALOAD, 0);
    methodVisitor.visitLdcInsn(propertyName);
    methodVisitor.visitMethodInsn(INVOKEVIRTUAL, jsonObjectImplType,
            this.getGetJsonPrimitivePropertyMethod(jsonPrimitiveType));
    methodVisitor.visitVarInsn(ASTORE, 1);
    methodVisitor.visitVarInsn(ALOAD, 1);
    methodVisitor.visitJumpInsn(IFNULL, l0);
    methodVisitor.visitVarInsn(ALOAD, 1);
    methodVisitor.visitMethodInsn(INVOKEVIRTUAL, jsonPrimitiveType,
            this.getToJavaPrimitiveMethod(javaPrimitiveType));
    methodVisitor.visitJumpInsn(GOTO, l1);
    methodVisitor.visitLabel(l0);
    methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] { jsonPrimitiveType }, 0, null);
    methodVisitor.visitInsn(this.getDefaultConstOpcode(javaPrimitiveType));
    methodVisitor.visitLabel(l1);
    methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1,
            new Object[] { this.getStackElement(javaPrimitiveType) });
    methodVisitor.visitInsn(javaPrimitiveType.getOpcode(IRETURN));
    methodVisitor.visitLabel(end);

    methodVisitor.visitLocalVariable("this", jsonObjectImplType, null, start, end, 0);
    methodVisitor.visitLocalVariable("_" + propertyName, jsonPrimitiveType, null, start, end, 1);
    methodVisitor.visitMaxs(2, 2);

    methodVisitor.visitEnd();
}

From source file:org.kjots.json.object.JsonObjectGeneratorBase.java

License:Apache License

/**
 * Generate a get Java character primitive property method.
 *
 * @param classVisitor The class visitor.
 * @param jsonObjectImplType The type of the JSON object implementation.
 * @param method The method.//w w  w .j a va2s .c om
 * @param propertyName The name of the property.
 */
private void generateGetJavaCharacterPrimitivePropertyMethod(ClassVisitor classVisitor, Type jsonObjectImplType,
        Method method, String propertyName) {
    Type jsonStringPrimitiveType = Type.getType(String.class);

    MethodVisitor methodVisitor = classVisitor.visitMethod(ACC_PUBLIC + ACC_FINAL, method, null, null);

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

    methodVisitor.visitCode();

    methodVisitor.visitLabel(start);
    methodVisitor.visitVarInsn(ALOAD, 0);
    methodVisitor.visitLdcInsn(propertyName);
    methodVisitor.visitMethodInsn(INVOKEVIRTUAL, jsonObjectImplType,
            this.getGetJsonPrimitivePropertyMethod(jsonStringPrimitiveType));
    methodVisitor.visitVarInsn(ASTORE, 1);
    methodVisitor.visitVarInsn(ALOAD, 1);
    methodVisitor.visitJumpInsn(IFNULL, l0);
    methodVisitor.visitVarInsn(ALOAD, 1);
    methodVisitor.visitMethodInsn(INVOKEVIRTUAL, jsonStringPrimitiveType,
            new Method("isEmpty", Type.BOOLEAN_TYPE, new Type[] {}));
    methodVisitor.visitJumpInsn(IFNE, l0);
    methodVisitor.visitVarInsn(ALOAD, 1);
    methodVisitor.visitInsn(ICONST_0);
    methodVisitor.visitMethodInsn(INVOKEVIRTUAL, jsonStringPrimitiveType,
            new Method("charAt", Type.CHAR_TYPE, new Type[] { Type.INT_TYPE }));
    methodVisitor.visitJumpInsn(GOTO, l1);
    methodVisitor.visitLabel(l0);
    methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] { jsonStringPrimitiveType }, 0, null);
    methodVisitor.visitInsn(ICONST_0);
    methodVisitor.visitLabel(l1);
    methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { Opcodes.INTEGER });
    methodVisitor.visitInsn(IRETURN);
    methodVisitor.visitLabel(end);

    methodVisitor.visitLocalVariable("this", jsonObjectImplType, null, start, end, 0);
    methodVisitor.visitLocalVariable("_" + propertyName, jsonStringPrimitiveType, null, start, end, 1);
    methodVisitor.visitMaxs(2, 2);

    methodVisitor.visitEnd();
}

From source file:org.kjots.json.object.JsonObjectGeneratorBase.java

License:Apache License

/**
 * Generate a get composite JSON object property method.
 *
 * @param classVisitor The class visitor.
 * @param jsonObjectImplType The type of the JSON object implementation.
 * @param method The method./*from   w w  w.java 2  s  . co m*/
 * @param propertyName The name of the property.
 * @param jsonObjectType The type of the JSON object.
 * @param elementType The type of the element.
 */
private void generateGetCompositeJsonObjectPropertyMethod(ClassVisitor classVisitor, Type jsonObjectImplType,
        Method method, String propertyName, Type jsonObjectType, Type elementType) {
    MethodVisitor methodVisitor = classVisitor.visitMethod(ACC_PUBLIC + ACC_FINAL, method, null, null);

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

    methodVisitor.visitCode();

    methodVisitor.visitLabel(start);
    methodVisitor.visitVarInsn(ALOAD, 0);
    methodVisitor.visitLdcInsn(propertyName);
    methodVisitor.visitLdcInsn(jsonObjectType);
    methodVisitor.visitMethodInsn(INVOKEVIRTUAL, jsonObjectImplType, this.getGetJsonObjectPropertyMethod());
    methodVisitor.visitTypeInsn(CHECKCAST, jsonObjectType);
    methodVisitor.visitVarInsn(ASTORE, 1);
    methodVisitor.visitVarInsn(ALOAD, 1);
    methodVisitor.visitJumpInsn(IFNULL, l0);
    methodVisitor.visitVarInsn(ALOAD, 1);
    methodVisitor.visitLdcInsn(elementType);
    methodVisitor.visitMethodInsn(INVOKEINTERFACE, jsonObjectType,
            this.getCastCompositeJsonObjectElementMethod(jsonObjectType));
    methodVisitor.visitJumpInsn(GOTO, l1);
    methodVisitor.visitLabel(l0);
    methodVisitor.visitFrame(Opcodes.F_APPEND, 1, new Object[] { jsonObjectType }, 0, null);
    methodVisitor.visitInsn(ACONST_NULL);
    methodVisitor.visitLabel(l1);
    methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { jsonObjectType });
    methodVisitor.visitInsn(ARETURN);
    methodVisitor.visitLabel(end);

    methodVisitor.visitLocalVariable("this", jsonObjectImplType, null, start, end, 0);
    methodVisitor.visitLocalVariable("_" + propertyName, jsonObjectType, null, start, end, 1);
    methodVisitor.visitMaxs(3, 2);

    methodVisitor.visitEnd();
}

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 ww  w . ja  v  a  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  ww w .  ja  v a  2 s  .  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();

}