Example usage for org.objectweb.asm MethodVisitor visitEnd

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

Introduction

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

Prototype

public void visitEnd() 

Source Link

Document

Visits the end of the method.

Usage

From source file:kr.debop4j.core.reflect.ConstructorAccess.java

License:Apache License

/** inner ?  */
static void insertNewInstanceInner(ClassWriter cw, String classNameInternal,
        String enclosingClassNameInternal) {
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "newInstance", "(Ljava/lang/Object;)Ljava/lang/Object;", null,
            null);/* w w w  .ja  va 2s  .  com*/
    mv.visitCode();
    if (enclosingClassNameInternal != null) {
        mv.visitTypeInsn(NEW, classNameInternal);
        mv.visitInsn(DUP);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitTypeInsn(CHECKCAST, enclosingClassNameInternal);
        mv.visitInsn(DUP);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
        mv.visitInsn(POP);
        mv.visitMethodInsn(INVOKESPECIAL, classNameInternal, "<init>",
                "(L" + enclosingClassNameInternal + ";)V");
        mv.visitInsn(ARETURN);
        mv.visitMaxs(4, 2);
    } else {
        mv.visitTypeInsn(NEW, "java/lang/UnsupportedOperationException");
        mv.visitInsn(DUP);
        mv.visitLdcInsn("Not an inner class.");
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/UnsupportedOperationException", "<init>",
                "(Ljava/lang/String;)V");
        mv.visitInsn(ATHROW);
        mv.visitMaxs(3, 2);
    }
    mv.visitEnd();
}

From source file:kr.debop4j.core.reflect.FieldAccess.java

License:Apache License

static private void insertConstructor(ClassWriter cw) {
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
    mv.visitCode();//from w  ww.  j av  a  2 s .  co m
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESPECIAL, ReflectConsts.FIELD_ACCESS_PATH, "<init>", "()V");
    mv.visitInsn(RETURN);
    mv.visitMaxs(1, 1);
    mv.visitEnd();
}

From source file:kr.debop4j.core.reflect.FieldAccess.java

License:Apache License

static private void insertSetObject(ClassWriter cw, String classNameInternal, List<Field> fields) {
    int maxStack = 6;
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "set", "(Ljava/lang/Object;ILjava/lang/Object;)V", null,
            null);//from ww  w.jav  a 2 s  .  c  om
    mv.visitCode();
    mv.visitVarInsn(ILOAD, 2);

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

        for (int i = 0, n = labels.length; i < n; i++) {
            Field field = fields.get(i);
            Type fieldType = Type.getType(field.getType());

            mv.visitLabel(labels[i]);
            mv.visitFrame(F_SAME, 0, null, 0, null);
            mv.visitVarInsn(ALOAD, 1);
            mv.visitTypeInsn(CHECKCAST, classNameInternal);
            mv.visitVarInsn(ALOAD, 3);

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

            mv.visitFieldInsn(PUTFIELD, classNameInternal, field.getName(), fieldType.getDescriptor());
            mv.visitInsn(RETURN);
        }

        mv.visitLabel(defaultLabel);
        mv.visitFrame(F_SAME, 0, null, 0, null);
    }
    mv = insertThrowExceptionForFieldNotFound(mv);
    mv.visitMaxs(maxStack, 4);
    mv.visitEnd();
}

From source file:kr.debop4j.core.reflect.FieldAccess.java

License:Apache License

static private void insertGetObject(ClassWriter cw, String classNameInternal, List<Field> fields) {
    int maxStack = 6;
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "get", "(Ljava/lang/Object;I)Ljava/lang/Object;", null, null);
    mv.visitCode();/*from w w  w. j  a  v a 2s.c  om*/
    mv.visitVarInsn(ILOAD, 2);

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

        for (int i = 0, n = labels.length; i < n; i++) {
            Field field = fields.get(i);

            mv.visitLabel(labels[i]);
            mv.visitFrame(F_SAME, 0, null, 0, null);
            mv.visitVarInsn(ALOAD, 1);
            mv.visitTypeInsn(CHECKCAST, classNameInternal);
            mv.visitFieldInsn(GETFIELD, classNameInternal, field.getName(),
                    Type.getDescriptor(field.getType()));

            Type fieldType = Type.getType(field.getType());

            switch (fieldType.getSort()) {
            case Type.BOOLEAN:
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;");
                break;
            case Type.BYTE:
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;");
                break;
            case Type.CHAR:
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;");
                break;
            case Type.SHORT:
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;");
                break;
            case Type.INT:
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
                break;
            case Type.FLOAT:
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;");
                break;
            case Type.LONG:
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;");
                break;
            case Type.DOUBLE:
                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;");
                break;
            default:
            }

            mv.visitInsn(ARETURN);
        }

        mv.visitLabel(defaultLabel);
        mv.visitFrame(F_SAME, 0, null, 0, null);
    }
    insertThrowExceptionForFieldNotFound(mv);
    mv.visitMaxs(maxStack, 3);
    mv.visitEnd();
}

From source file:kr.debop4j.core.reflect.FieldAccess.java

License:Apache License

static private void insertGetString(ClassWriter cw, String classNameInternal, List<Field> fields) {
    int maxStack = 6;
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "getString", "(Ljava/lang/Object;I)Ljava/lang/String;", null,
            null);/*from w  w  w .  j  a va 2s  .co m*/
    mv.visitCode();
    mv.visitVarInsn(ILOAD, 2);

    if (!fields.isEmpty()) {
        maxStack--;
        Label[] labels = new Label[fields.size()];
        Label labelForInvalidTypes = new Label();
        boolean hasAnyBadTypeLabel = false;
        for (int i = 0, n = labels.length; i < n; i++) {
            if (fields.get(i).getType().equals(String.class))
                labels[i] = new Label();
            else {
                labels[i] = labelForInvalidTypes;
                hasAnyBadTypeLabel = true;
            }
        }
        Label defaultLabel = new Label();
        mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);

        for (int i = 0, n = labels.length; i < n; i++) {
            if (!labels[i].equals(labelForInvalidTypes)) {
                mv.visitLabel(labels[i]);
                mv.visitFrame(F_SAME, 0, null, 0, null);
                mv.visitVarInsn(ALOAD, 1);
                mv.visitTypeInsn(CHECKCAST, classNameInternal);
                mv.visitFieldInsn(GETFIELD, classNameInternal, fields.get(i).getName(), "Ljava/lang/String;");
                mv.visitInsn(ARETURN);
            }
        }
        // Rest of fields: different type
        if (hasAnyBadTypeLabel) {
            mv.visitLabel(labelForInvalidTypes);
            mv.visitFrame(F_SAME, 0, null, 0, null);
            insertThrowExceptionForFieldType(mv, "String");
        }
        // Default: field not found
        mv.visitLabel(defaultLabel);
        mv.visitFrame(F_SAME, 0, null, 0, null);
    }
    insertThrowExceptionForFieldNotFound(mv);
    mv.visitMaxs(maxStack, 3);
    mv.visitEnd();
}

From source file:kr.debop4j.core.reflect.FieldAccess.java

License:Apache License

static private void insertSetPrimitive(ClassWriter cw, String classNameInternal, List<Field> fields,
        Type primitiveType) {/* w w  w.  j  a v a2  s.  c  om*/
    int maxStack = 6;
    int maxLocals = 4; // See correction below for LLOAD and DLOAD
    final String setterMethodName;
    final String typeNameInternal = primitiveType.getDescriptor();
    final int loadValueInstruction;
    switch (primitiveType.getSort()) {
    case Type.BOOLEAN:
        setterMethodName = "setBoolean";
        loadValueInstruction = ILOAD;
        break;
    case Type.BYTE:
        setterMethodName = "setByte";
        loadValueInstruction = ILOAD;
        break;
    case Type.CHAR:
        setterMethodName = "setChar";
        loadValueInstruction = ILOAD;
        break;
    case Type.SHORT:
        setterMethodName = "setShort";
        loadValueInstruction = ILOAD;
        break;
    case Type.INT:
        setterMethodName = "setInt";
        loadValueInstruction = ILOAD;
        break;
    case Type.FLOAT:
        setterMethodName = "setFloat";
        loadValueInstruction = FLOAD;
        break;
    case Type.LONG:
        setterMethodName = "setLong";
        loadValueInstruction = LLOAD;
        maxLocals++; // (LLOAD and DLOAD actually load two slots)
        break;
    case Type.DOUBLE:
        setterMethodName = "setDouble";
        loadValueInstruction = DLOAD; // (LLOAD and DLOAD actually load two slots)
        maxLocals++;
        break;
    default:
        setterMethodName = "set";
        loadValueInstruction = ALOAD;
        break;
    }
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, setterMethodName,
            "(Ljava/lang/Object;I" + typeNameInternal + ")V", null, null);
    mv.visitCode();
    mv.visitVarInsn(ILOAD, 2);

    if (!fields.isEmpty()) {
        maxStack--;
        Label[] labels = new Label[fields.size()];
        Label labelForInvalidTypes = new Label();
        boolean hasAnyBadTypeLabel = false;
        for (int i = 0, n = labels.length; i < n; i++) {
            if (Type.getType(fields.get(i).getType()).equals(primitiveType))
                labels[i] = new Label();
            else {
                labels[i] = labelForInvalidTypes;
                hasAnyBadTypeLabel = true;
            }
        }
        Label defaultLabel = new Label();
        mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);

        for (int i = 0, n = labels.length; i < n; i++) {
            if (!labels[i].equals(labelForInvalidTypes)) {
                mv.visitLabel(labels[i]);
                mv.visitFrame(F_SAME, 0, null, 0, null);
                mv.visitVarInsn(ALOAD, 1);
                mv.visitTypeInsn(CHECKCAST, classNameInternal);
                mv.visitVarInsn(loadValueInstruction, 3);
                mv.visitFieldInsn(PUTFIELD, classNameInternal, fields.get(i).getName(), typeNameInternal);
                mv.visitInsn(RETURN);
            }
        }
        // Rest of fields: different type
        if (hasAnyBadTypeLabel) {
            mv.visitLabel(labelForInvalidTypes);
            mv.visitFrame(F_SAME, 0, null, 0, null);
            insertThrowExceptionForFieldType(mv, primitiveType.getClassName());
        }
        // Default: field not found
        mv.visitLabel(defaultLabel);
        mv.visitFrame(F_SAME, 0, null, 0, null);
    }
    mv = insertThrowExceptionForFieldNotFound(mv);
    mv.visitMaxs(maxStack, maxLocals);
    mv.visitEnd();
}

From source file:kr.debop4j.core.reflect.FieldAccess.java

License:Apache License

static private void insertGetPrimitive(ClassWriter cw, String classNameInternal, List<Field> fields,
        Type primitiveType) {//ww w. j  av  a 2 s. co  m
    int maxStack = 6;
    final String getterMethodName;
    final String typeNameInternal = primitiveType.getDescriptor();
    final int returnValueInstruction;
    switch (primitiveType.getSort()) {
    case Type.BOOLEAN:
        getterMethodName = "getBoolean";
        returnValueInstruction = IRETURN;
        break;
    case Type.BYTE:
        getterMethodName = "getByte";
        returnValueInstruction = IRETURN;
        break;
    case Type.CHAR:
        getterMethodName = "getChar";
        returnValueInstruction = IRETURN;
        break;
    case Type.SHORT:
        getterMethodName = "getShort";
        returnValueInstruction = IRETURN;
        break;
    case Type.INT:
        getterMethodName = "getInt";
        returnValueInstruction = IRETURN;
        break;
    case Type.FLOAT:
        getterMethodName = "getFloat";
        returnValueInstruction = FRETURN;
        break;
    case Type.LONG:
        getterMethodName = "getLong";
        returnValueInstruction = LRETURN;
        break;
    case Type.DOUBLE:
        getterMethodName = "getDouble";
        returnValueInstruction = DRETURN;
        break;
    default:
        getterMethodName = "get";
        returnValueInstruction = ARETURN;
        break;
    }
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, getterMethodName, "(Ljava/lang/Object;I)" + typeNameInternal,
            null, null);
    mv.visitCode();
    mv.visitVarInsn(ILOAD, 2);

    if (!fields.isEmpty()) {
        maxStack--;
        Label[] labels = new Label[fields.size()];
        Label labelForInvalidTypes = new Label();
        boolean hasAnyBadTypeLabel = false;
        for (int i = 0, n = labels.length; i < n; i++) {
            if (Type.getType(fields.get(i).getType()).equals(primitiveType))
                labels[i] = new Label();
            else {
                labels[i] = labelForInvalidTypes;
                hasAnyBadTypeLabel = true;
            }
        }
        Label defaultLabel = new Label();
        mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);

        for (int i = 0, n = labels.length; i < n; i++) {
            Field field = fields.get(i);
            if (!labels[i].equals(labelForInvalidTypes)) {
                mv.visitLabel(labels[i]);
                mv.visitFrame(F_SAME, 0, null, 0, null);
                mv.visitVarInsn(ALOAD, 1);
                mv.visitTypeInsn(CHECKCAST, classNameInternal);
                mv.visitFieldInsn(GETFIELD, classNameInternal, field.getName(), typeNameInternal);
                mv.visitInsn(returnValueInstruction);
            }
        }
        // Rest of fields: different type
        if (hasAnyBadTypeLabel) {
            mv.visitLabel(labelForInvalidTypes);
            mv.visitFrame(F_SAME, 0, null, 0, null);
            insertThrowExceptionForFieldType(mv, primitiveType.getClassName());
        }
        // Default: field not found
        mv.visitLabel(defaultLabel);
        mv.visitFrame(F_SAME, 0, null, 0, null);
    }
    mv = insertThrowExceptionForFieldNotFound(mv);
    mv.visitMaxs(maxStack, 3);
    mv.visitEnd();
}

From source file:kr.debop4j.core.reflect.MethodAccess.java

License:Apache License

/**
 *  ? ? ??   MethodAccess ./*from   w ww. j  a v  a  2  s .c om*/
 *
 * @param type 
 * @return the method access
 */
public static MethodAccess get(final Class type) {
    Guard.shouldNotBeNull(type, "type");

    List<Method> methods = Lists.newArrayList();
    Class nextClass = type;
    while (nextClass != Object.class) {
        Method[] declaredMethods = nextClass.getDeclaredMethods();
        for (Method method : declaredMethods) {
            int modifiers = method.getModifiers();
            if (Modifier.isStatic(modifiers))
                continue;
            if (Modifier.isPrivate(modifiers))
                continue;
            methods.add(method);
        }
        nextClass = nextClass.getSuperclass();
    }

    Class[][] parameterTypes = new Class[methods.size()][];
    String[] methodNames = new String[methods.size()];
    for (int i = 0, size = methodNames.length; i < size; i++) {
        Method method = methods.get(i);
        methodNames[i] = method.getName();
        parameterTypes[i] = method.getParameterTypes();
    }

    String className = type.getName();
    String accessClassName = className + "MethodAccess";
    if (accessClassName.startsWith("java."))
        accessClassName = ReflectConsts.BASE_PACKAGE + "." + accessClassName;

    Class accessClass;
    AccessClassLoader loader = AccessClassLoader.get(type);

    synchronized (loader) {
        try {
            accessClass = loader.loadClass(accessClassName);
        } catch (ClassNotFoundException ignored) {
            String accessClassNameInternal = accessClassName.replace('.', '/');
            String classNameInternal = className.replace('.', '/');

            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
            MethodVisitor mv;
            cw.visit(V1_1, ACC_PUBLIC + ACC_SUPER, accessClassNameInternal, null,
                    ReflectConsts.METHOD_ACCESS_PATH, null);
            {
                mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
                mv.visitCode();
                mv.visitVarInsn(ALOAD, 0);
                mv.visitMethodInsn(INVOKESPECIAL, ReflectConsts.METHOD_ACCESS_PATH, "<init>", "()V");
                mv.visitInsn(RETURN);
                mv.visitMaxs(0, 0);
                mv.visitEnd();
            }
            {
                mv = cw.visitMethod(ACC_PUBLIC + ACC_VARARGS, "invoke",
                        "(Ljava/lang/Object;I[Ljava/lang/Object;)Ljava/lang/Object;", null, null);
                mv.visitCode();

                if (!methods.isEmpty()) {
                    mv.visitVarInsn(ALOAD, 1);
                    mv.visitTypeInsn(CHECKCAST, classNameInternal);
                    mv.visitVarInsn(ASTORE, 4);

                    mv.visitVarInsn(ILOAD, 2);
                    Label[] labels = new Label[methods.size()];
                    for (int i = 0, n = labels.length; 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, n = labels.length; 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);

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

                        Method method = methods.get(i);
                        Class[] paramTypes = method.getParameterTypes();
                        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]);
                            switch (paramType.getSort()) {
                            case Type.BOOLEAN:
                                mv.visitTypeInsn(CHECKCAST, "java/lang/Boolean");
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z");
                                break;
                            case Type.BYTE:
                                mv.visitTypeInsn(CHECKCAST, "java/lang/Byte");
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B");
                                break;
                            case Type.CHAR:
                                mv.visitTypeInsn(CHECKCAST, "java/lang/Character");
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C");
                                break;
                            case Type.SHORT:
                                mv.visitTypeInsn(CHECKCAST, "java/lang/Short");
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S");
                                break;
                            case Type.INT:
                                mv.visitTypeInsn(CHECKCAST, "java/lang/Integer");
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I");
                                break;
                            case Type.FLOAT:
                                mv.visitTypeInsn(CHECKCAST, "java/lang/Float");
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F");
                                break;
                            case Type.LONG:
                                mv.visitTypeInsn(CHECKCAST, "java/lang/Long");
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J");
                                break;
                            case Type.DOUBLE:
                                mv.visitTypeInsn(CHECKCAST, "java/lang/Double");
                                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D");
                                break;
                            case Type.ARRAY:
                                mv.visitTypeInsn(CHECKCAST, paramType.getDescriptor());
                                break;
                            case Type.OBJECT:
                                mv.visitTypeInsn(CHECKCAST, paramType.getInternalName());
                                break;
                            }
                            buffer.append(paramType.getDescriptor());
                        }

                        buffer.append(')');
                        buffer.append(Type.getDescriptor(method.getReturnType()));
                        mv.visitMethodInsn(INVOKEVIRTUAL, classNameInternal, method.getName(),
                                buffer.toString());

                        switch (Type.getType(method.getReturnType()).getSort()) {
                        case Type.VOID:
                            mv.visitInsn(ACONST_NULL);
                            break;
                        case Type.BOOLEAN:
                            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", "valueOf",
                                    "(Z)Ljava/lang/Boolean;");
                            break;
                        case Type.BYTE:
                            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf",
                                    "(B)Ljava/lang/Byte;");
                            break;
                        case Type.CHAR:
                            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", "valueOf",
                                    "(C)Ljava/lang/Character;");
                            break;
                        case Type.SHORT:
                            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf",
                                    "(S)Ljava/lang/Short;");
                            break;
                        case Type.INT:
                            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf",
                                    "(I)Ljava/lang/Integer;");
                            break;
                        case Type.FLOAT:
                            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf",
                                    "(F)Ljava/lang/Float;");
                            break;
                        case Type.LONG:
                            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf",
                                    "(J)Ljava/lang/Long;");
                            break;
                        case Type.DOUBLE:
                            mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf",
                                    "(D)Ljava/lang/Double;");
                            break;
                        }

                        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");
                mv.visitVarInsn(ILOAD, 2);
                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                        "(I)Ljava/lang/StringBuilder;");
                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString",
                        "()Ljava/lang/String;");
                mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>",
                        "(Ljava/lang/String;)V");
                mv.visitInsn(ATHROW);
                mv.visitMaxs(0, 0);
                mv.visitEnd();
            }
            cw.visitEnd();
            byte[] data = cw.toByteArray();
            accessClass = loader.defineClass(accessClassName, data);
        }
    }

    try {
        MethodAccess access = (MethodAccess) accessClass.newInstance();
        access.methodNames = methodNames;
        access.parameterTypes = parameterTypes;

        return access;
    } catch (Exception ex) {
        throw new RuntimeException("Error constructing method access class=[" + accessClassName + "]", ex);
    }
}

From source file:lapin.comp.asm.ASMByteCodeGenerator.java

License:Open Source License

private void generateClassInitializer(Env env) {
    MethodVisitor mv = _cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);

    // field for SELF (static field)
    mv.visitCode();//from   w  w w.j  a v  a  2  s.c om
    mv.visitInsn(Opcodes.ACONST_NULL);
    mv.visitFieldInsn(Opcodes.PUTSTATIC, toInternalName(super.classInfo.classname()), "SELF",
            toTypeDescriptor(super.classInfo.classname()));
    mv.visitInsn(Opcodes.RETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:lapin.comp.asm.ASMByteCodeGenerator.java

License:Open Source License

private void generateConstructor(Env env) {
    /*//from  w  w w.  ja  v a  2 s . c  o  m
     * local variables (reserved)
     * 0: this
     * 1: env
     */
    MethodVisitor mv = _cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>",
            //"(Llapin/lang/Env;)V",
            Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_ENV }), null, null);

    mv.visitCode();
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitLdcInsn(super.classInfo.name().pname());
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "lapin/function/CompiledExpr", "<init>",
            //"(Ljava/lang/String;)V");
            Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { TYPE_STRING }));

    Iterator it;

    // fields for constants
    it = constTable.keySet().iterator();
    while (it.hasNext()) {
        Object key = it.next(); // key: object (const)
        String val = Data.string(constTable.get(key));
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitLdcInsn(Printer.prin1ToString(key, env));
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "lapin/function/CompiledExpr", "toSexp",
                Type.getMethodDescriptor(TYPE_OBJECT, new Type[] { TYPE_STRING, TYPE_ENV }));
        mv.visitFieldInsn(Opcodes.PUTFIELD, toInternalName(super.classInfo.classname()), val,
                TYPE_OBJECT.getDescriptor());
    }

    // fields for vars
    it = varTable.keySet().iterator();
    while (it.hasNext()) {
        Object key = it.next(); // key: symbol (var)
        String val = Data.string(varTable.get(key));
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitLdcInsn(Printer.prin1ToString(key, env));
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "lapin/function/CompiledExpr", "toSexp",
                Type.getMethodDescriptor(TYPE_OBJECT, new Type[] { TYPE_STRING, TYPE_ENV }));
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "lapin/lang/Data", "symbol",
                Type.getMethodDescriptor(TYPE_SYMBOL, new Type[] { TYPE_OBJECT }));
        mv.visitFieldInsn(Opcodes.PUTFIELD, toInternalName(super.classInfo.classname()), val,
                TYPE_SYMBOL.getDescriptor());
    }

    // fields for lambdaLists
    it = llTable.keySet().iterator();
    while (it.hasNext()) {
        Object key = it.next(); // key: lambdaList
        String val = Data.string(llTable.get(key));
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitLdcInsn(Printer.prin1ToString(Data.lambdaList(key).params(), env));
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "lapin/function/CompiledExpr", "toLambdaList",
                Type.getMethodDescriptor(TYPE_LAMBDA_LIST, new Type[] { TYPE_STRING, TYPE_ENV }));
        mv.visitFieldInsn(Opcodes.PUTFIELD, toInternalName(super.classInfo.classname()), val,
                TYPE_LAMBDA_LIST.getDescriptor());
    }

    // field for SELF (static field)
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.PUTSTATIC, toInternalName(super.classInfo.classname()), "SELF",
            toTypeDescriptor(super.classInfo.classname()));
    mv.visitInsn(Opcodes.RETURN);

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