Example usage for org.objectweb.asm MethodVisitor visitLabel

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

Introduction

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

Prototype

public void visitLabel(final Label label) 

Source Link

Document

Visits a label.

Usage

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  va  2s  .  c  om*/
        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//ww  w. java 2s . co m
 * @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>writeUInt16Null].</code>
 *
 * @param required true if the field is required, otherwise false.
 * @param mv the method visitor, not null.
 * @see #generateEncodeValue//from www.j  ava  2  s .com
 */
protected void generateEncodeCharacterValue(boolean required, MethodVisitor mv) {
    if (required) {
        mv.visitInsn(I2S);
        mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeUInt16",
                "(Lcom/cinnober/msgcodec/io/ByteSink;S)V", false);
    } else {
        Label nullLabel = new Label();
        mv.visitInsn(DUP);
        mv.visitJumpInsn(IFNULL, nullLabel);
        unbox(mv, Character.class);
        mv.visitInsn(I2S);
        box(mv, Short.class);
        mv.visitLabel(nullLabel);
        mv.visitTypeInsn(CHECKCAST, Type.getInternalName(Short.class));
        mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeUInt16Null",
                "(Lcom/cinnober/msgcodec/io/ByteSink;Ljava/lang/Short;)V", false);
    }
}

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

License:Open Source License

protected void generateEncodeRefValue(GroupDef refGroup, boolean required, LocalVariable nextVar,
        MethodVisitor mv, String genClassInternalName, int outputStreamVar, TypeDef.Reference type,
        boolean javaClassCodec) throws IllegalArgumentException {
    if (refGroup != null) {
        Object refGroupType = refGroup.getGroupType();
        String refGroupDescriptor = getTypeDescriptor(refGroupType, javaClassCodec);
        if (required) {
            int instanceVar = nextVar.next();
            mv.visitVarInsn(ASTORE, instanceVar);
            mv.visitVarInsn(ALOAD, 0); // this
            mv.visitInsn(SWAP); // this and out
            mv.visitVarInsn(ALOAD, instanceVar);
            mv.visitMethodInsn(INVOKEVIRTUAL, genClassInternalName, "writeStaticGroup_" + refGroup.getName(),
                    "(Lcom/cinnober/msgcodec/io/ByteSink;" + refGroupDescriptor + ")V", false);
        } else {//from   w  w w .  j  a  v  a  2s .  c  o m
            int instanceVar = nextVar.next();
            mv.visitInsn(DUP);
            Label nonNullLabel = new Label();
            Label endLabel = new Label();
            mv.visitJumpInsn(IFNONNULL, nonNullLabel);
            // null
            mv.visitInsn(POP);
            mv.visitInsn(ICONST_0); // false
            mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writePresenceByte",
                    "(Lcom/cinnober/msgcodec/io/ByteSink;Z)V", false);
            mv.visitJumpInsn(GOTO, endLabel);

            // not null
            mv.visitLabel(nonNullLabel);
            // PENDING: mv.visitFrame?
            mv.visitVarInsn(ASTORE, instanceVar);
            mv.visitInsn(ICONST_1); // true
            mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writePresenceByte",
                    "(Lcom/cinnober/msgcodec/io/ByteSink;Z)V", false);
            mv.visitVarInsn(ALOAD, 0); // this
            mv.visitVarInsn(ALOAD, outputStreamVar);
            mv.visitVarInsn(ALOAD, instanceVar);
            mv.visitMethodInsn(INVOKEVIRTUAL, genClassInternalName, "writeStaticGroup_" + refGroup.getName(),
                    "(Lcom/cinnober/msgcodec/io/ByteSink;" + refGroupDescriptor + ")V", false);
            mv.visitLabel(endLabel);
            // PENDING: mv.visitFrame?
        }
    } else {
        throw new IllegalArgumentException("Illegal reference: " + type);
    }
}

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

License:Open Source License

protected void generateEncodeSequenceValue(Class<?> javaClass, LocalVariable nextVar, MethodVisitor mv,
        boolean required, int outputStreamVar, Class<?> componentJavaClass, TypeDef type, Schema schema,
        String genClassInternalName, String fieldIdentifier, String debugValueLabel, boolean javaClassCodec)
        throws IllegalArgumentException {

    // PENDING: merge the two if-cases, and reuse common code blocks (see generateDecodeSquenceValue)
    if (javaClass.isArray()) {
        int sequenceVar = nextVar.next();
        mv.visitInsn(DUP);//from   w  ww.j  a va  2s  .c  o m
        mv.visitVarInsn(ASTORE, sequenceVar);
        int lengthVar = nextVar.next();
        Label endLabel = new Label();
        if (required) {
            mv.visitInsn(ARRAYLENGTH);
            mv.visitInsn(DUP);
            mv.visitVarInsn(ISTORE, lengthVar);
            mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeUInt32",
                    "(Lcom/cinnober/msgcodec/io/ByteSink;I)V", false);
        } else {
            Label nonNullLabel = new Label();
            mv.visitInsn(DUP);
            mv.visitJumpInsn(IFNONNULL, nonNullLabel);
            // null
            mv.visitInsn(POP);
            mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeNull",
                    "(Lcom/cinnober/msgcodec/io/ByteSink;)V", false);
            mv.visitJumpInsn(GOTO, endLabel);
            // not null
            mv.visitLabel(nonNullLabel);
            // PENDING: mv.visitFrame?
            mv.visitInsn(ARRAYLENGTH);
            mv.visitInsn(DUP);
            mv.visitVarInsn(ISTORE, lengthVar);
            mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeUInt32",
                    "(Lcom/cinnober/msgcodec/io/ByteSink;I)V", false);
        }
        // for loop
        int loopVar = nextVar.next();
        mv.visitInsn(ICONST_0);
        mv.visitVarInsn(ISTORE, loopVar);
        Label loopLabel = new Label();
        mv.visitLabel(loopLabel);
        // PENDING: mv.visitFrame?
        mv.visitVarInsn(ILOAD, loopVar);
        mv.visitVarInsn(ILOAD, lengthVar);
        mv.visitJumpInsn(IF_ICMPGE, endLabel);
        mv.visitVarInsn(ALOAD, outputStreamVar);
        mv.visitVarInsn(ALOAD, sequenceVar);
        mv.visitVarInsn(ILOAD, loopVar);
        if (componentJavaClass == byte.class || componentJavaClass == boolean.class) {
            mv.visitInsn(BALOAD);
        } else if (componentJavaClass == short.class) {
            mv.visitInsn(SALOAD);
        } else if (componentJavaClass == int.class) {
            mv.visitInsn(IALOAD);
        } else if (componentJavaClass == long.class) {
            mv.visitInsn(LALOAD);
        } else if (componentJavaClass == float.class) {
            mv.visitInsn(FALOAD);
        } else if (componentJavaClass == double.class) {
            mv.visitInsn(DALOAD);
        } else if (componentJavaClass == char.class) {
            mv.visitInsn(CALOAD);
        } else {
            mv.visitInsn(AALOAD);
            mv.visitTypeInsn(CHECKCAST, Type.getInternalName(componentJavaClass));
        }

        // encode the element
        TypeDef.Sequence seqType = (TypeDef.Sequence) type;
        generateEncodeValue(mv, outputStreamVar, nextVar, true, seqType.getComponentType(), componentJavaClass,
                null, schema, genClassInternalName, fieldIdentifier, debugValueLabel + ".component",
                javaClassCodec);

        mv.visitIincInsn(loopVar, 1);
        mv.visitJumpInsn(GOTO, loopLabel);
        mv.visitLabel(endLabel);
        // PENDING: mv.visitFrame?

    } else if (javaClass == List.class) {
        int sequenceVar = nextVar.next();
        mv.visitInsn(DUP);
        mv.visitVarInsn(ASTORE, sequenceVar);
        int lengthVar = nextVar.next();
        Label endLabel = new Label();
        if (required) {
            mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "size", "()I", true);
            mv.visitInsn(DUP);
            mv.visitVarInsn(ISTORE, lengthVar);
            mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeUInt32",
                    "(Lcom/cinnober/msgcodec/io/ByteSink;I)V", false);
        } else {
            Label nonNullLabel = new Label();
            mv.visitInsn(DUP);
            mv.visitJumpInsn(IFNONNULL, nonNullLabel);
            // null
            mv.visitInsn(POP);
            mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeNull",
                    "(Lcom/cinnober/msgcodec/io/ByteSink;)V", false);
            mv.visitJumpInsn(GOTO, endLabel);
            // not null
            mv.visitLabel(nonNullLabel);
            // PENDING: mv.visitFrame?
            mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "size", "()I", true);
            mv.visitInsn(DUP);
            mv.visitVarInsn(ISTORE, lengthVar);
            mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeUInt32",
                    "(Lcom/cinnober/msgcodec/io/ByteSink;I)V", false);
        }
        // for loop, using iterator
        int iteratorVar = nextVar.next();
        mv.visitVarInsn(ALOAD, sequenceVar);
        mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "iterator", "()Ljava/util/Iterator;", true);
        mv.visitVarInsn(ASTORE, iteratorVar);
        Label loopLabel = new Label();
        mv.visitLabel(loopLabel);
        // PENDING: mv.visitFrame?
        mv.visitVarInsn(ALOAD, iteratorVar);
        mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z", true);
        mv.visitJumpInsn(IFEQ, endLabel);
        mv.visitVarInsn(ALOAD, outputStreamVar);
        mv.visitVarInsn(ALOAD, iteratorVar);
        mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true);
        if (componentJavaClass.isPrimitive()) {
            mv.visitTypeInsn(CHECKCAST, Type.getInternalName(box(componentJavaClass)));
            unbox(mv, componentJavaClass);
        } else {
            mv.visitTypeInsn(CHECKCAST, Type.getInternalName(componentJavaClass));
        }

        // encode the element
        TypeDef.Sequence seqType = (TypeDef.Sequence) type;
        generateEncodeValue(mv, outputStreamVar, nextVar, true, seqType.getComponentType(), componentJavaClass,
                null, schema, genClassInternalName, fieldIdentifier, debugValueLabel + ".component",
                javaClassCodec);

        mv.visitJumpInsn(GOTO, loopLabel);
        mv.visitLabel(endLabel);
        // PENDING: mv.visitFrame?
    } else {
        throw new IllegalArgumentException("Illegal sequence javaClass: " + javaClass);
    }
}

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

License:Open Source License

protected void generateEncodeTimeValue(TypeDef.Time type, Class<?> javaClass, boolean required,
        MethodVisitor mv) throws RuntimeException {
    if (javaClass == long.class || javaClass == Long.class) {
        generateEncodeInt64Value(required, mv);
    } else if (javaClass == int.class || javaClass == Integer.class) {
        generateEncodeInt32Value(required, mv);
    } else if (javaClass == Date.class) {

        Label nullLabel = new Label();
        Label endLabel = new Label();
        if (!required) {
            mv.visitInsn(DUP);/*from w w  w .  j a  v  a 2  s  .co m*/
            mv.visitJumpInsn(IFNULL, nullLabel);
        }

        // not null
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/Date", "getTime", "()J", false);
        // handle differences in UNIT and EPOCH
        long epochOffset = DateUtil.getEpochOffset(type.getEpoch());
        long timeInMillis = DateUtil.getTimeInMillis(type.getUnit());
        // wireTime = (dateTime - epochOffset) / timeUnitInMillis);
        if (epochOffset != 0) {
            mv.visitLdcInsn(epochOffset);
            mv.visitInsn(LSUB);
        }
        if (timeInMillis != 1) {
            mv.visitLdcInsn(timeInMillis);
            mv.visitInsn(LDIV);
        }
        box(mv, long.class);
        mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeInt64Null",
                "(Lcom/cinnober/msgcodec/io/ByteSink;Ljava/lang/Long;)V", false);

        if (!required) {
            mv.visitJumpInsn(GOTO, endLabel);
            mv.visitLabel(nullLabel);
            mv.visitInsn(POP);
            mv.visitInsn(ACONST_NULL);
            mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeInt64Null",
                    "(Lcom/cinnober/msgcodec/io/ByteSink;Ljava/lang/Long;)V", false);
            mv.visitLabel(endLabel);
        }
    } else {
        throw new IllegalArgumentException("Illegal time javaClass: " + javaClass);
    }
}

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

License:Open Source License

protected void generateEncodeEnumValue(TypeDef.Enum enumType, String genClassInternalName,
        String fieldIdentifier, LocalVariable nextVar, Class<?> javaClass, boolean required, MethodVisitor mv,
        String debugValueLabel) throws IllegalArgumentException {

    Label writeValueLabel = new Label();

    // Make sure that no unsupported javaClass is used for an enum
    if (javaClass != int.class && javaClass != Integer.class && (javaClass == null || !javaClass.isEnum())) {
        throw new IllegalArgumentException("Illegal enum javaClass: " + javaClass);
    }//from   ww w . jav  a2 s .  com

    // If null do not look it up
    if (!required) {
        Label lookupIdLabel = new Label();
        mv.visitInsn(DUP);
        mv.visitJumpInsn(IFNONNULL, lookupIdLabel);

        // null
        mv.visitInsn(POP);
        mv.visitInsn(ACONST_NULL);
        mv.visitJumpInsn(GOTO, writeValueLabel);

        // not null
        mv.visitLabel(lookupIdLabel);
    }

    // SymbolMapping
    if (required && !javaClass.isEnum()) {
        box(mv, int.class);
    }
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, genClassInternalName, "symbolMapping_" + fieldIdentifier,
            "Lcom/cinnober/msgcodec/SymbolMapping;");
    mv.visitInsn(SWAP);
    mv.visitMethodInsn(INVOKEINTERFACE, "com/cinnober/msgcodec/SymbolMapping", "getId",
            "(Ljava/lang/Object;)Ljava/lang/Integer;", true);

    // Write the value
    mv.visitLabel(writeValueLabel);
    if (required) {
        unbox(mv, Integer.class); // TODO: Should null check before this and throw exception since there was no mapping
    }
    generateEncodeInt32Value(required, mv);

    //        if (javaClass.isEnum()) {
    //            Label endLabel = new Label();
    //            if (!required) {
    //                Label nonNullLabel = new Label();
    //                mv.visitInsn(DUP);
    //                mv.visitJumpInsn(IFNONNULL, nonNullLabel);
    //                // null
    //                mv.visitInsn(POP);
    //                mv.visitInsn(ACONST_NULL);
    //                mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeInt32Null",
    //                        "(Lcom/cinnober/msgcodec/io/ByteSink;Ljava/lang/Integer;)V", false);
    //                mv.visitJumpInsn(GOTO, endLabel);
    //                // not null
    //                mv.visitLabel(nonNullLabel);
    //            }
    //            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Enum", "ordinal", "()I", false);
    //            //switch
    //            EnumSymbols enumSymbols = new EnumSymbols(enumType, javaClass);
    //            Enum[] enumValues = ((Class<Enum>)javaClass).getEnumConstants();
    //            int[] ordinals = new int[enumValues.length];
    //            Label[] labels = new Label[enumValues.length];
    //            for (int i=0; i<enumValues.length; i++) {
    //                ordinals[i] = i;
    //                labels[i] = new Label();
    //            }
    //            Label defaultLabel = new Label();
    //            Label writeLabel = new Label();
    //            int symbolIdVar = nextVar.next();
    //            mv.visitLookupSwitchInsn(defaultLabel, ordinals, labels);
    //            for (int i=0; i<enumValues.length; i++) {
    //                mv.visitLabel(labels[i]);
    //                Symbol symbol = enumSymbols.getSymbol(enumValues[i]);
    //                if (symbol != null) {
    //                    mv.visitLdcInsn(symbol.getId());
    //                    mv.visitJumpInsn(GOTO, writeLabel);
    //                } else {
    //                    mv.visitLdcInsn(debugValueLabel);
    //                    mv.visitVarInsn(ALOAD, symbolIdVar);
    //                    mv.visitMethodInsn(INVOKESTATIC, baseclassIName, "unmappableEnumSymbolValue",
    //                            "(Ljava/lang/String;Ljava/lang/Enum;)Ljava/lang/IllegalArgumentException;", false);
    //                    mv.visitInsn(ATHROW);
    //                }
    //            }
    //            mv.visitLabel(defaultLabel);
    //            mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
    //            mv.visitInsn(DUP);
    //            mv.visitLdcInsn("Should not happen: reached generated switch default case for value " + debugValueLabel);
    //            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V", false);
    //            mv.visitInsn(ATHROW);
    //
    //            // write
    //            mv.visitLabel(writeLabel);
    //            if (!required) {
    //                box(mv, int.class);
    //            }
    //            generateEncodeInt32Value(required, mv);
    //            // end
    //            mv.visitLabel(endLabel);
    //        } else if (javaClass == int.class || javaClass == Integer.class) {
    //            generateEncodeInt32Value(required, mv);
    //        } else {
    //            throw new IllegalArgumentException("Illegal enum javaClass: " + javaClass);
    //        }
}

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

License:Open Source License

/**
 * Generate value decoding using the blink input.
 *
 * <p>Defaults to <code>readUInt16[Null].</code>
 *
 * @param required true if the field is required, otherwise false.
 * @param mv the method visitor, not null.
 * @see #generateDecodeValue/*from www  .  j a  va  2 s.c om*/
 */
protected void generateDecodeCharacterValue(boolean required, MethodVisitor mv) {
    if (required) {
        mv.visitMethodInsn(INVOKESTATIC, blinkInputIName, "readUInt16",
                "(Lcom/cinnober/msgcodec/io/ByteSource;)S", false);
        mv.visitInsn(I2C);
    } else {
        mv.visitMethodInsn(INVOKESTATIC, blinkInputIName, "readUInt16Null",
                "(Lcom/cinnober/msgcodec/io/ByteSource;)Ljava/lang/Short;", false);
        Label nullLabel = new Label();
        mv.visitInsn(DUP);
        mv.visitJumpInsn(IFNULL, nullLabel);
        unbox(mv, Short.class);
        mv.visitInsn(I2C);
        box(mv, Character.class);
        mv.visitLabel(nullLabel);
        mv.visitTypeInsn(CHECKCAST, Type.getInternalName(Character.class));
    }
}

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

License:Open Source License

protected void generateDecodeTimeValue(TypeDef.Time type, Class<?> javaClass, boolean required,
        MethodVisitor mv, LocalVariable nextVar) throws IllegalArgumentException {
    if (javaClass == long.class || javaClass == Long.class) {
        generateDecodeInt64Value(required, mv);
    } else if (javaClass == int.class || javaClass == Integer.class) {
        generateDecodeInt32Value(required, mv);
    } else if (javaClass == Date.class) {

        int timeVar = nextVar.next();
        nextVar.next(); // note: 2 variable slots
        Label endLabel = new Label();
        if (required) {
            generateDecodeInt64Value(true, mv);
        } else {//from  w  w  w  .j  a v  a  2 s . c om
            generateDecodeInt64Value(false, mv);
            mv.visitInsn(DUP);
            Label nonNullLabel = new Label();
            mv.visitJumpInsn(IFNONNULL, nonNullLabel);
            // null
            mv.visitTypeInsn(CHECKCAST, "java/util/Date");
            mv.visitJumpInsn(GOTO, endLabel);
            // not null
            mv.visitLabel(nonNullLabel);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false);
        }

        mv.visitVarInsn(LSTORE, timeVar);
        mv.visitTypeInsn(NEW, "java/util/Date");
        mv.visitInsn(DUP);
        mv.visitVarInsn(LLOAD, timeVar);
        // handle differences in UNIT and EPOCH
        long epochOffset = DateUtil.getEpochOffset(type.getEpoch());
        long timeInMillis = DateUtil.getTimeInMillis(type.getUnit());
        // dateTime = wireTime * timeUnitInMillis + epochOffset;
        if (timeInMillis != 1) {
            mv.visitLdcInsn(timeInMillis);
            mv.visitInsn(LMUL);
        }
        if (epochOffset != 0) {
            mv.visitLdcInsn(epochOffset);
            mv.visitInsn(LADD);
        }

        mv.visitMethodInsn(INVOKESPECIAL, "java/util/Date", "<init>", "(J)V", false);

        if (!required) {
            // end
            mv.visitLabel(endLabel);
        }
    } else {
        throw new IllegalArgumentException("Illegal time javaClass: " + javaClass);
    }
}

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

License:Open Source License

/**
 * @see #generateDecodeInt32Value(boolean, org.objectweb.asm.MethodVisitor) 
 *//* w  w  w .ja  v  a2s . c o m*/
protected void generateDecodeEnumValue(boolean required, MethodVisitor mv, TypeDef type,
        String genClassInternalName, String fieldIdentifier, LocalVariable nextVar, Class<?> javaClass,
        String debugValueLabel) throws IllegalArgumentException {

    Label endLabel = new Label();
    if (required) {
        generateDecodeInt32Value(true, mv);
        box(mv, Integer.class);
    } else {
        generateDecodeInt32Value(false, mv);
        mv.visitInsn(DUP);
        mv.visitJumpInsn(IFNULL, endLabel);

        //            Label nonNullLabel = new Label();
        //            mv.visitJumpInsn(IFNONNULL, nonNullLabel);
        //            mv.visitTypeInsn(CHECKCAST, Type.getInternalName(javaClass));
        //            mv.visitJumpInsn(GOTO, endLabel);

        // not null
        //            mv.visitLabel(nonNullLabel);
        //            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false); // unbox(mv, Integer.class);
    }

    // SymbolMapping
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, genClassInternalName, "symbolMapping_" + fieldIdentifier,
            "Lcom/cinnober/msgcodec/SymbolMapping;");
    mv.visitInsn(SWAP);
    mv.visitMethodInsn(INVOKEINTERFACE, "com/cinnober/msgcodec/SymbolMapping", "lookup",
            "(Ljava/lang/Integer;)Ljava/lang/Object;", true);

    //        // switch
    //        TypeDef.Enum enumType = (TypeDef.Enum) type;
    //        List<Symbol> symbols = enumType.getSymbols();
    //        int numSymbols = symbols.size();
    //        int[] ids = new int[numSymbols];
    //        Label[] labels = new Label[numSymbols];
    //        for (int i=0; i<numSymbols; i++) {
    //            ids[i] = symbols.get(i).getId();
    //            labels[i] = new Label();
    //        }
    //        Label defaultLabel = new Label();
    //        int symbolIdVar = nextVar.next();
    //        mv.visitInsn(DUP);
    //        mv.visitVarInsn(ISTORE, symbolIdVar);
    //        EnumSymbols enumSymbols = null;
    //        if (javaClass.isEnum()) {
    //            enumSymbols = new EnumSymbols(enumType, javaClass);
    //        }
    //        mv.visitLookupSwitchInsn(defaultLabel, ids, labels);
    //        for (int i=0; i<numSymbols; i++) {
    //            boolean addGotoEnd = true;
    //            mv.visitLabel(labels[i]);
    //            if (javaClass.isEnum()) {
    //                Enum enumValue = enumSymbols.getEnum(ids[i]);
    //                if (enumValue != null) {
    //                    //mv.visitLdcInsn(Type.getType(javaClass));
    //                    mv.visitFieldInsn(GETSTATIC, Type.getInternalName(javaClass),
    //                            enumValue.name(),
    //                            Type.getDescriptor(javaClass));
    //                } else {
    //                    mv.visitLdcInsn(debugValueLabel);
    //                    mv.visitLdcInsn(ids[i]);
    //                    mv.visitLdcInsn(Type.getType(javaClass));
    //                    mv.visitMethodInsn(INVOKESTATIC, baseclassIName, "unmappableEnumSymbolId",
    //                            "(Ljava/lang/String;ILjava/lang/Class;)Lcom/cinnober/msgcodec/DecodeException;", false);
    //                    mv.visitInsn(ATHROW);
    //                    addGotoEnd = false;
    //                }
    //            } else if (javaClass == int.class || javaClass == Integer.class) {
    //                mv.visitLdcInsn(ids[i]);
    //                if (!required) {
    //                    box(mv, Integer.class);
    //                }
    //            } else {
    //                throw new IllegalArgumentException("Illegal enum javaClass: " + javaClass);
    //            }
    //            if (addGotoEnd) {
    //                mv.visitJumpInsn(GOTO, endLabel);
    //            }
    //        }
    //        mv.visitLabel(defaultLabel);
    //        mv.visitLdcInsn(debugValueLabel);
    //        mv.visitVarInsn(ILOAD, symbolIdVar);
    //        mv.visitMethodInsn(INVOKESTATIC, baseclassIName, "unknownEnumSymbol",
    //                "(Ljava/lang/String;I)Lcom/cinnober/msgcodec/DecodeException;", false);
    //        mv.visitInsn(ATHROW);

    // end
    mv.visitLabel(endLabel);

    if (!javaClass.isEnum()) {
        mv.visitTypeInsn(CHECKCAST, Type.getInternalName(Integer.class));
        if (required) {
            unbox(mv, Integer.class);
        }
    } else {
        mv.visitTypeInsn(CHECKCAST, Type.getInternalName(javaClass));
    }
}