Example usage for org.objectweb.asm MethodVisitor visitMethodInsn

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

Introduction

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

Prototype

public void visitMethodInsn(final int opcode, final String owner, final String name, final String descriptor,
        final boolean isInterface) 

Source Link

Document

Visits a method instruction.

Usage

From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java

License:Open Source License

protected void generateWriteStaticGroupForType(Schema schema, ClassVisitor cv, String genClassInternalName,
        boolean javaClassCodec) {
    for (GroupDef group : schema.getGroups()) {
        Object groupType = group.getGroupType();
        String groupDescriptor = getTypeDescriptor(groupType, javaClassCodec);
        MethodVisitor writemv = cv.visitMethod(ACC_PRIVATE, "writeStaticGroup_" + group.getName(),
                "(Lcom/cinnober/msgcodec/io/ByteSink;" + groupDescriptor + ")V", null,
                new String[] { "java/io/IOException" });
        writemv.visitCode();/*from ww  w .  j a  v a  2  s  .  com*/
        LocalVariable nextWriteVar = new LocalVariable(3);

        // write fields of super group
        if (group.getSuperGroup() != null) {
            GroupDef superGroup = schema.getGroup(group.getSuperGroup());
            Object superGroupType = superGroup.getGroupType();
            String superGroupDescriptor = getTypeDescriptor(superGroupType, javaClassCodec);
            writemv.visitVarInsn(ALOAD, 0);
            writemv.visitVarInsn(ALOAD, 1);
            writemv.visitVarInsn(ALOAD, 2);
            writemv.visitMethodInsn(INVOKEVIRTUAL, genClassInternalName,
                    "writeStaticGroup_" + superGroup.getName(),
                    "(Lcom/cinnober/msgcodec/io/ByteSink;" + superGroupDescriptor + ")V", false);
        }

        // fields
        for (FieldDef field : group.getFields()) {

            writemv.visitVarInsn(ALOAD, 1); // output stream

            Class<?> javaClass = field.getJavaClass();
            Accessor<?, ?> accessor = field.getAccessor();

            if (accessor.getClass() == CreateAccessor.class) {
                if (field.getType().getType() == TypeDef.Type.REFERENCE) {
                    if (field.isRequired()) {
                        writemv.visitInsn(ICONST_0);
                        generateEncodeInt32Value(true, writemv);
                    } else {
                        writemv.visitInsn(ACONST_NULL);
                        generateEncodeInt32Value(false, writemv);
                    }
                    continue;
                }
            }

            if (isPublicFieldAccessor(accessor)) {
                Field f = ((FieldAccessor) accessor).getField();
                writemv.visitVarInsn(ALOAD, 2);
                writemv.visitFieldInsn(GETFIELD, Type.getInternalName(f.getDeclaringClass()), f.getName(),
                        Type.getDescriptor(f.getType()));
                if (!f.getType().equals(field.getJavaClass())) {
                    // this can happen when the field is a generic type variable in a super-class.
                    writemv.visitTypeInsn(CHECKCAST, Type.getInternalName(javaClass));
                }
            } else {
                writemv.visitVarInsn(ALOAD, 0);
                writemv.visitFieldInsn(GETFIELD, genClassInternalName,
                        "accessor_" + group.getName() + "_" + field.getName(),
                        "Lcom/cinnober/msgcodec/Accessor;");
                writemv.visitVarInsn(ALOAD, 2); // instance
                writemv.visitMethodInsn(INVOKEINTERFACE, "com/cinnober/msgcodec/Accessor", "getValue",
                        "(Ljava/lang/Object;)Ljava/lang/Object;", true);
                if (javaClass.isPrimitive()) {
                    writemv.visitTypeInsn(CHECKCAST, Type.getInternalName(box(javaClass)));
                    unbox(writemv, javaClass);
                } else {
                    writemv.visitTypeInsn(CHECKCAST, Type.getInternalName(javaClass));
                }
            }
            // the output stream and the value is now on the stack
            generateEncodeValue(writemv, 1, nextWriteVar, field.isRequired(), field.getType(), javaClass,
                    field.getComponentJavaClass(), schema, genClassInternalName,
                    group.getName() + "_" + field.getName(), group.getName() + "." + field.getName(),
                    javaClassCodec);
        }

        // end write
        writemv.visitInsn(RETURN);
        writemv.visitMaxs(4, nextWriteVar.get());
        writemv.visitEnd();
    }
}

From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java

License:Open Source License

protected void generateReadStaticGroup(Schema schema, ClassVisitor cv, String genClassInternalName,
        boolean javaClassCodec) {
    MethodVisitor mv = cv.visitMethod(ACC_PROTECTED, "readStaticGroup",
            "(ILcom/cinnober/msgcodec/io/ByteSource;)Ljava/lang/Object;", null,
            new String[] { "java/io/IOException" });
    int nextVar = 3;
    mv.visitCode();//from   ww w.j av  a 2 s .  c o  m

    Map<Integer, Label> labelsByGroupId = new TreeMap<>();
    for (GroupDef group : schema.getGroups()) {
        if (group.getId() != -1) {
            labelsByGroupId.put(group.getId(), new Label());
        }
    }
    mv.visitVarInsn(ILOAD, 1); // group id
    Label unknownGroupIdLabel = new Label();
    {
        int[] caseValues = new int[labelsByGroupId.size()];
        int i = 0;
        for (int groupId : labelsByGroupId.keySet()) {
            caseValues[i++] = groupId;
        }
        Label[] caseLabels = labelsByGroupId.values().toArray(new Label[labelsByGroupId.size()]);
        mv.visitLookupSwitchInsn(unknownGroupIdLabel, caseValues, caseLabels);
    }

    for (Map.Entry<Integer, Label> caseEntry : labelsByGroupId.entrySet()) {
        GroupDef group = schema.getGroup(caseEntry.getKey().intValue());
        Object groupType = group.getGroupType();
        String groupDescriptor = getTypeDescriptor(groupType, javaClassCodec);

        mv.visitLabel(caseEntry.getValue());
        mv.visitFrame(F_SAME, 0, null, 0, null);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 2);
        mv.visitMethodInsn(INVOKEVIRTUAL, genClassInternalName, "readStaticGroup_" + group.getName(),
                "(Lcom/cinnober/msgcodec/io/ByteSource;)" + groupDescriptor, false);
        mv.visitInsn(ARETURN);
    }
    // default case
    mv.visitLabel(unknownGroupIdLabel);
    mv.visitFrame(F_SAME, 0, null, 0, null);
    mv.visitVarInsn(ILOAD, 1);
    mv.visitMethodInsn(INVOKESTATIC, baseclassIName, "unknownGroupId",
            "(I)Lcom/cinnober/msgcodec/DecodeException;", false);
    mv.visitInsn(ATHROW);
    mv.visitMaxs(2, nextVar);
    mv.visitEnd();
}

From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java

License:Open Source License

protected void generateReadStaticGroupForTypeAndCreate(Schema schema, ClassVisitor cv,
        String genClassInternalName, boolean javaClassCodec) {
    for (GroupDef group : schema.getGroups()) {
        Object groupType = group.getGroupType();
        String groupDescriptor = getTypeDescriptor(groupType, javaClassCodec);
        String groupInternalName = getTypeInternalName(groupType, javaClassCodec);
        MethodVisitor readmv = cv.visitMethod(ACC_PRIVATE, "readStaticGroup_" + group.getName(),
                "(Lcom/cinnober/msgcodec/io/ByteSource;)" + groupDescriptor, null,
                new String[] { "java/io/IOException" });
        readmv.visitCode();/*from www .j  a v  a2  s  .c  om*/
        int nextReadVar = 2;

        Factory<?> factory = group.getFactory();
        if (isPublicConstructorFactory(factory)) {
            // read, create instance
            readmv.visitTypeInsn(NEW, groupInternalName);
            readmv.visitInsn(DUP);
            readmv.visitMethodInsn(INVOKESPECIAL, groupInternalName, "<init>", "()V", false);
        } else {
            // read, create instance
            readmv.visitVarInsn(ALOAD, 0); // this
            readmv.visitFieldInsn(GETFIELD, genClassInternalName, "factory_" + group.getName(),
                    "Lcom/cinnober/msgcodec/Factory;");
            readmv.visitMethodInsn(INVOKEINTERFACE, "com/cinnober/msgcodec/Factory", "newInstance",
                    "()Ljava/lang/Object;", true);
            if (javaClassCodec) {
                readmv.visitTypeInsn(CHECKCAST, groupInternalName);
            }
        }
        final int readInstanceVar = nextReadVar++;
        readmv.visitVarInsn(ASTORE, readInstanceVar);

        readmv.visitVarInsn(ALOAD, 0);
        readmv.visitVarInsn(ALOAD, 1);
        readmv.visitVarInsn(ALOAD, readInstanceVar);
        readmv.visitMethodInsn(INVOKEVIRTUAL, genClassInternalName, "readStaticGroup_" + group.getName(),
                "(Lcom/cinnober/msgcodec/io/ByteSource;" + groupDescriptor + ")V", false);

        // end read
        readmv.visitVarInsn(ALOAD, readInstanceVar);
        readmv.visitInsn(ARETURN);
        readmv.visitMaxs(4, nextReadVar);
        readmv.visitEnd();
    }
}

From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java

License:Open Source License

protected void generateReadStaticGroupForType(final Schema schema, ClassVisitor cv,
        final String genClassInternalName, final boolean javaClassCodec) {
    for (final GroupDef group : schema.getGroups()) {
        Object groupType = group.getGroupType();
        String groupDescriptor = getTypeDescriptor(groupType, javaClassCodec);
        final MethodVisitor mv = cv.visitMethod(ACC_PRIVATE, "readStaticGroup_" + group.getName(),
                "(Lcom/cinnober/msgcodec/io/ByteSource;" + groupDescriptor + ")V", null,
                new String[] { "java/io/IOException" });
        mv.visitCode();/*from  ww w.j  a  v a  2  s  .c o m*/
        final LocalVariable nextVar = new LocalVariable(3);

        // read fields of super group
        if (group.getSuperGroup() != null) {
            GroupDef superGroup = schema.getGroup(group.getSuperGroup());
            Object superGroupType = superGroup.getGroupType();
            String superGroupDescriptor = getTypeDescriptor(superGroupType, javaClassCodec);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitVarInsn(ALOAD, 1);
            mv.visitVarInsn(ALOAD, 2);
            mv.visitMethodInsn(INVOKEVIRTUAL, genClassInternalName, "readStaticGroup_" + superGroup.getName(),
                    "(Lcom/cinnober/msgcodec/io/ByteSource;" + superGroupDescriptor + ")V", false);
        }

        // fields
        for (final FieldDef field : group.getFields()) {
            final Class<?> javaClass = field.getJavaClass();

            Runnable readValue = () -> {
                Label tryStart = new Label();
                Label tryEnd = new Label();
                Label tryCatch = new Label();
                Label tryAfter = new Label();
                mv.visitTryCatchBlock(tryStart, tryEnd, tryCatch, "java/lang/Exception");

                mv.visitLabel(tryStart);
                mv.visitVarInsn(ALOAD, 1); // input stream
                generateDecodeValue(mv, 1, nextVar, field.isRequired(), field.getType(), javaClass,
                        field.getComponentJavaClass(), schema, genClassInternalName,
                        group.getName() + "_" + field.getName(), group.getName() + "." + field.getName(),
                        javaClassCodec);
                mv.visitLabel(tryEnd);
                mv.visitJumpInsn(GOTO, tryAfter);
                mv.visitLabel(tryCatch);
                int caughtExVar = nextVar.next();
                mv.visitVarInsn(ASTORE, caughtExVar);
                mv.visitTypeInsn(NEW, "com/cinnober/msgcodec/blink/FieldDecodeException");
                mv.visitInsn(DUP);
                mv.visitLdcInsn(field.getName());
                mv.visitVarInsn(ALOAD, caughtExVar);
                mv.visitMethodInsn(INVOKESPECIAL, "com/cinnober/msgcodec/blink/FieldDecodeException", "<init>",
                        "(Ljava/lang/String;Ljava/lang/Throwable;)V", false);
                mv.visitInsn(ATHROW);
                mv.visitLabel(tryAfter);
            };

            Accessor<?, ?> accessor = field.getAccessor();
            if (isPublicFieldAccessor(accessor)) {
                Field f = ((FieldAccessor) accessor).getField();
                mv.visitVarInsn(ALOAD, 2); // instance
                // value
                readValue.run();
                // store
                mv.visitFieldInsn(PUTFIELD, Type.getInternalName(f.getDeclaringClass()), f.getName(),
                        Type.getDescriptor(f.getType()));
            } else if (accessor.getClass() == CreateAccessor.class) {
                mv.visitVarInsn(ALOAD, 2); // instance

                Label tryStart = new Label();
                Label tryEnd = new Label();
                Label tryCatch = new Label();
                Label tryAfter = new Label();
                mv.visitTryCatchBlock(tryStart, tryEnd, tryCatch, "java/lang/Exception");

                mv.visitLabel(tryStart);
                mv.visitVarInsn(ALOAD, 1); // input stream

                generateDecodeDummy(mv, 1, nextVar, field.isRequired(), field.getType(), javaClass,
                        field.getComponentJavaClass(), schema, genClassInternalName,
                        group.getName() + "." + field.getName(), javaClassCodec);

                mv.visitInsn(POP);

                mv.visitLabel(tryEnd);
                mv.visitJumpInsn(GOTO, tryAfter);
                mv.visitLabel(tryCatch);
                int caughtExVar = nextVar.next();
                mv.visitVarInsn(ASTORE, caughtExVar);
                mv.visitTypeInsn(NEW, "com/cinnober/msgcodec/blink/FieldDecodeException");
                mv.visitInsn(DUP);
                mv.visitLdcInsn(field.getName());
                mv.visitVarInsn(ALOAD, caughtExVar);
                mv.visitMethodInsn(INVOKESPECIAL, "com/cinnober/msgcodec/blink/FieldDecodeException", "<init>",
                        "(Ljava/lang/String;Ljava/lang/Throwable;)V", false);
                mv.visitInsn(ATHROW);
                mv.visitLabel(tryAfter);

                mv.visitInsn(POP);
            } else {
                // accessor
                mv.visitVarInsn(ALOAD, 0);
                mv.visitFieldInsn(GETFIELD, genClassInternalName,
                        "accessor_" + group.getName() + "_" + field.getName(),
                        "Lcom/cinnober/msgcodec/Accessor;");
                // instance
                mv.visitVarInsn(ALOAD, 2); // instance
                // value
                readValue.run();
                if (javaClass.isPrimitive()) {
                    box(mv, javaClass);
                }
                // store
                mv.visitMethodInsn(INVOKEINTERFACE, "com/cinnober/msgcodec/Accessor", "setValue",
                        "(Ljava/lang/Object;Ljava/lang/Object;)V", true);
            }
        }

        mv.visitInsn(RETURN);
        mv.visitMaxs(6, nextVar.get());
        mv.visitEnd();
    }
}

From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java

License:Open Source License

/**
 * Generate instructions to encode the specified value type.
 * The values on the stack are; the output stream and the value to be encoded.
 * After this call these values are expected to be consumed.
 *
 * @param mv the method visitor, open for code instructions.
 * @param outputStreamVar the variable instance that contains the output stream.
 * @param nextVar the next variable//from w  w w  . ja v  a2s .c  om
 * @param required true if the field is required, otherwise false.
 * @param type the field type
 * @param javaClass the field java class
 * @param componentJavaClass the field component java class, or null if not a sequence type
 * @param schema the protocol schema, not null
 * @param genClassInternalName the internal name of the generated class
 */
protected void generateEncodeValue(MethodVisitor mv, int outputStreamVar, LocalVariable nextVar,
        boolean required, TypeDef type, Class<?> javaClass, Class<?> componentJavaClass, Schema schema,
        String genClassInternalName, String fieldIdentifier, String debugValueLabel, boolean javaClassCodec) {

    type = schema.resolveToType(type, false);
    GroupDef refGroup = schema.resolveToGroup(type);

    if (javaClass.isPrimitive() && !required) {
        box(mv, javaClass);
    } else if (!javaClass.isPrimitive() && required) {
        mv.visitInsn(DUP);
        Label notNullLabel = new Label();
        mv.visitJumpInsn(IFNONNULL, notNullLabel);
        mv.visitInsn(POP); // output stream
        mv.visitLdcInsn(debugValueLabel);
        mv.visitMethodInsn(INVOKESTATIC, baseclassIName, "missingRequiredValue",
                "(Ljava/lang/String;)Ljava/lang/IllegalArgumentException;", false);
        mv.visitInsn(ATHROW);
        mv.visitLabel(notNullLabel);
        unbox(mv, javaClass);
    }
    switch (type.getType()) {
    case INT8:
        generateEncodeInt8Value(required, mv);
        break;
    case UINT8:
        generateEncodeUInt8Value(required, mv);
        break;
    case CHAR:
        generateEncodeCharacterValue(required, mv);
        break;
    case INT16:
        generateEncodeInt16Value(required, mv);
        break;
    case UINT16:
        generateEncodeUInt16Value(required, mv);
        break;
    case INT32:
        generateEncodeInt32Value(required, mv);
        break;
    case UINT32:
        generateEncodeUInt32Value(required, mv);
        break;
    case INT64:
        generateEncodeInt64Value(required, mv);
        break;
    case UINT64:
        generateEncodeUInt64Value(required, mv);
        break;
    case FLOAT32:
        generateEncodeFloat32Value(required, mv);
        break;
    case FLOAT64:
        generateEncodeFloat64Value(required, mv);
        break;
    case BIGINT:
        generateEncodeBigIntValue(required, mv);
        break;
    case DECIMAL:
        generateEncodeDecimalValue(required, mv);
        break;
    case BIGDECIMAL:
        generateEncodeBigDecimalValue(required, mv);
        break;
    case STRING:
        generateEncodeStringValue((TypeDef.StringUnicode) type, required, mv);
        break;
    case BINARY:
        generateEncodeBinaryValue((TypeDef.Binary) type, required, mv);
        break;
    case BOOLEAN:
        generateEncodeBooleanValue(required, mv);
        break;
    case ENUM:
        generateEncodeEnumValue((TypeDef.Enum) type, genClassInternalName, fieldIdentifier, nextVar, javaClass,
                required, mv, debugValueLabel);
        break;
    case TIME:
        generateEncodeTimeValue((TypeDef.Time) type, javaClass, required, mv);
        break;
    case SEQUENCE:
        generateEncodeSequenceValue(javaClass, nextVar, mv, required, outputStreamVar, componentJavaClass, type,
                schema, genClassInternalName, fieldIdentifier, debugValueLabel, javaClassCodec);
        break;
    case REFERENCE:
        generateEncodeRefValue(refGroup, required, nextVar, mv, genClassInternalName, outputStreamVar,
                (TypeDef.Reference) type, javaClassCodec);
        break;
    case DYNAMIC_REFERENCE:
        generateEncodeDynRefValue(nextVar, mv, required);
        break;
    default:
        throw new RuntimeException("Unhandled case: " + type.getType());
    }
}

From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java

License:Open Source License

/**
 * Generate value encoding using the blink output.
 *
 * <p>Defaults to <code>writeBoolean[Null].</code>
 *
 * @param required true if the field is required, otherwise false.
 * @param mv the method visitor, not null.
 * @see #generateEncodeValue//from   ww  w .j  a v  a 2s  .c o m
 */
protected void generateEncodeBooleanValue(boolean required, MethodVisitor mv) {
    if (required) {
        mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeBoolean",
                "(Lcom/cinnober/msgcodec/io/ByteSink;Z)V", false);
    } else {
        mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeBooleanNull",
                "(Lcom/cinnober/msgcodec/io/ByteSink;Ljava/lang/Boolean;)V", false);
    }
}

From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java

License:Open Source License

/**
 * Generate value encoding using the blink output.
 *
 * <p>Defaults to <code>writeBinary[Null].</code>
 *
 * @param required true if the field is required, otherwise false.
 * @param mv the method visitor, not null.
 * @see #generateEncodeValue//  w w w . j  a  va  2  s . c o  m
 */
protected void generateEncodeBinaryValue(TypeDef.Binary type, boolean required, MethodVisitor mv) {
    if (required) {
        mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeBinary",
                "(Lcom/cinnober/msgcodec/io/ByteSink;[B)V", false);
    } else {
        mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeBinaryNull",
                "(Lcom/cinnober/msgcodec/io/ByteSink;[B)V", false);
    }
}

From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java

License:Open Source License

/**
 * Generate value encoding using the blink output.
 *
 * <p>Defaults to <code>writeStringUTF8[Null].</code>
 *
 * @param required true if the field is required, otherwise false.
 * @param mv the method visitor, not null.
 * @see #generateEncodeValue//  w ww  .  j av a 2  s. c om
 */
protected void generateEncodeStringValue(TypeDef.StringUnicode type, boolean required, MethodVisitor mv) {
    if (required) {
        mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeStringUTF8",
                "(Lcom/cinnober/msgcodec/io/ByteSink;Ljava/lang/String;)V", false);
    } else {
        mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeStringUTF8Null",
                "(Lcom/cinnober/msgcodec/io/ByteSink;Ljava/lang/String;)V", false);
    }
}

From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java

License:Open Source License

/**
 * Generate value encoding using the blink output.
 *
 * <p>Defaults to <code>writeBigDecimal[Null].</code>
 *
 * @param required true if the field is required, otherwise false.
 * @param mv the method visitor, not null.
 * @see #generateEncodeValue//  w w  w .  j ava  2 s . c o  m
 */
protected void generateEncodeBigDecimalValue(boolean required, MethodVisitor mv) {
    if (required) {
        mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeBigDecimal",
                "(Lcom/cinnober/msgcodec/io/ByteSink;Ljava/math/BigDecimal;)V", false);
    } else {
        mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeBigDecimalNull",
                "(Lcom/cinnober/msgcodec/io/ByteSink;Ljava/math/BigDecimal;)V", false);
    }
}

From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java

License:Open Source License

/**
 * Generate value encoding using the blink output.
 *
 * <p>Defaults to <code>writeDecimal[Null].</code>
 *
 * @param required true if the field is required, otherwise false.
 * @param mv the method visitor, not null.
 * @see #generateEncodeValue/*from   w w w .  jav a  2s.  co  m*/
 */
protected void generateEncodeDecimalValue(boolean required, MethodVisitor mv) {
    if (required) {
        mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeDecimal",
                "(Lcom/cinnober/msgcodec/io/ByteSink;Ljava/math/BigDecimal;)V", false);
    } else {
        mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeDecimalNull",
                "(Lcom/cinnober/msgcodec/io/ByteSink;Ljava/math/BigDecimal;)V", false);
    }
}