Example usage for org.objectweb.asm Label Label

List of usage examples for org.objectweb.asm Label Label

Introduction

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

Prototype

public Label() 

Source Link

Document

Constructs a new label.

Usage

From source file:com.centimia.orm.jaqu.ext.asm.JaquClassAdapter.java

License:Open Source License

/**
 * Generates the new method body, copy the old to a new method and connect them.
 * the structure of the new method is:<br>
 * <br><b><div style="background:lightgray">
 * <pre>//from w  w w.j  a  v  a  2  s .c o  m
 * public [entityType] [getterName]() {
 *   if ([field] == null) {
 *      try {
 *         if (null == db)
 *            throw new RuntimeException("Cannot initialize 'Relation' outside an open session!!!. Try initializing field directly within the class.");
 *         
 *         [parentType] parent = this.getClass().newInstance();
 *         [entityType] desc = TestB.class.newInstance();
 *         
 *         // get the primary key
 *         Object pk = db.getPrimaryKey(this);
 *         
 *         // get the object
 *         [entityValue] = db.from(desc).innerJoin(parent).on(parent.[entityValue]).is(desc).where(db.getPrimaryKey(parent)).is(pk).selectFirst();
 *      }
 *      catch (Exception e) {
 *         if (e instanceof RuntimeException)
 *            throw (RuntimeException)e;
 *         throw new RuntimeException(e.getMessage(), e);
 *      }
 *   }
 *   return $orig_[getterName]();
 *  }
 * </pre>
 * </div>
 * 
 * @param access
 * @param desc
 * @param exceptions
 * @param name - current method name
 * @param newName - new method name (the orig...)
 * @param fieldName
 */
public void generateLazyRelation(int access, String desc, String[] exceptions, String name, String newName,
        String fieldName) {
    MethodVisitor mv = cv.visitMethod(access, name, desc, null, exceptions);
    String fieldSignature = desc.substring(desc.indexOf(')') + 1);
    String fieldClassName = desc.substring(desc.indexOf(')') + 2, desc.length() - 1);

    mv.visitCode();
    Label l0 = new Label();
    Label l1 = new Label();
    Label l2 = new Label();
    mv.visitTryCatchBlock(l0, l1, l2, "java/lang/Exception");
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, className, fieldName, fieldSignature);
    Label l3 = new Label();
    mv.visitJumpInsn(IFNULL, l3);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, className, fieldName, fieldSignature);
    mv.visitFieldInsn(GETFIELD, fieldClassName, "isLazy", "Z");
    mv.visitJumpInsn(IFEQ, l3);
    mv.visitLabel(l0);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, className, "db", "Lcom/centimia/orm/jaqu/Db;");
    Label l4 = new Label();
    mv.visitJumpInsn(IFNULL, l4);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, className, "db", "Lcom/centimia/orm/jaqu/Db;");
    mv.visitMethodInsn(INVOKEVIRTUAL, "com/centimia/orm/jaqu/Db", "isClosed", "()Z", false);
    Label l5 = new Label();
    mv.visitJumpInsn(IFEQ, l5);
    mv.visitLabel(l4);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
    mv.visitInsn(DUP);
    mv.visitLdcInsn(
            "Cannot initialize 'Relation' outside an open session!!!. Try initializing field directly within the class.");
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V", false);
    mv.visitInsn(ATHROW);
    mv.visitLabel(l5);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "newInstance", "()Ljava/lang/Object;", false);
    mv.visitTypeInsn(CHECKCAST, className);
    mv.visitVarInsn(ASTORE, 1);
    mv.visitLdcInsn(Type.getType(fieldSignature));
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "newInstance", "()Ljava/lang/Object;", false);
    mv.visitTypeInsn(CHECKCAST, fieldClassName);
    mv.visitVarInsn(ASTORE, 2);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, className, "db", "Lcom/centimia/orm/jaqu/Db;");
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKEVIRTUAL, "com/centimia/orm/jaqu/Db", "getPrimaryKey",
            "(Ljava/lang/Object;)Ljava/lang/Object;", false);
    mv.visitVarInsn(ASTORE, 3);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, className, "db", "Lcom/centimia/orm/jaqu/Db;");
    mv.visitVarInsn(ALOAD, 2);
    mv.visitMethodInsn(INVOKEVIRTUAL, "com/centimia/orm/jaqu/Db", "from",
            "(Ljava/lang/Object;)Lcom/centimia/orm/jaqu/QueryInterface;", false);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(INVOKEINTERFACE, "com/centimia/orm/jaqu/QueryInterface", "innerJoin",
            "(Ljava/lang/Object;)Lcom/centimia/orm/jaqu/QueryJoin;", true);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitFieldInsn(GETFIELD, className, fieldName, fieldSignature);
    mv.visitMethodInsn(INVOKEVIRTUAL, "com/centimia/orm/jaqu/QueryJoin", "on",
            "(Ljava/lang/Object;)Lcom/centimia/orm/jaqu/QueryJoinCondition;", false);
    mv.visitVarInsn(ALOAD, 2);
    mv.visitMethodInsn(INVOKEVIRTUAL, "com/centimia/orm/jaqu/QueryJoinCondition", "is",
            "(Ljava/lang/Object;)Lcom/centimia/orm/jaqu/QueryJoinWhere;", false);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, className, "db", "Lcom/centimia/orm/jaqu/Db;");
    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(INVOKEVIRTUAL, "com/centimia/orm/jaqu/Db", "getPrimaryKey",
            "(Ljava/lang/Object;)Ljava/lang/Object;", false);
    mv.visitMethodInsn(INVOKEVIRTUAL, "com/centimia/orm/jaqu/QueryJoinWhere", "where",
            "(Ljava/lang/Object;)Lcom/centimia/orm/jaqu/QueryCondition;", false);
    mv.visitVarInsn(ALOAD, 3);
    mv.visitMethodInsn(INVOKEVIRTUAL, "com/centimia/orm/jaqu/QueryCondition", "is",
            "(Ljava/lang/Object;)Lcom/centimia/orm/jaqu/QueryWhere;", false);
    mv.visitMethodInsn(INVOKEVIRTUAL, "com/centimia/orm/jaqu/QueryWhere", "selectFirst", "()Ljava/lang/Object;",
            false);
    mv.visitTypeInsn(CHECKCAST, fieldClassName);
    mv.visitFieldInsn(PUTFIELD, className, fieldName, fieldSignature);
    mv.visitLabel(l1);
    mv.visitJumpInsn(GOTO, l3);
    mv.visitLabel(l2);
    mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { "java/lang/Exception" });
    mv.visitVarInsn(ASTORE, 1);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitTypeInsn(INSTANCEOF, "java/lang/RuntimeException");
    Label l6 = new Label();
    mv.visitJumpInsn(IFEQ, l6);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitTypeInsn(CHECKCAST, "java/lang/RuntimeException");
    mv.visitInsn(ATHROW);
    mv.visitLabel(l6);
    mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { "java/lang/Exception" }, 0, null);
    mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
    mv.visitInsn(DUP);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Exception", "getMessage", "()Ljava/lang/String;", false);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>",
            "(Ljava/lang/String;Ljava/lang/Throwable;)V", false);
    mv.visitInsn(ATHROW);
    mv.visitLabel(l3);
    mv.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKEVIRTUAL, className, newName, desc, false);
    mv.visitInsn(ARETURN);
    mv.visitMaxs(4, 4);
    mv.visitEnd();
}

From source file:com.changingbits.Builder.java

License:Apache License

private void buildAsm(GeneratorAdapter gen, Node node, int uptoLocal) {

    if (node.outputs != null) {
        //System.out.println("gen outputs=" + node.outputs);
        // Increment any range outputs at the current node:
        for (int range : node.outputs) {
            // Load arg 1 (the int[] answers):
            gen.loadArg(1);//from  www .  j a  va2 s.c o m
            // Load the index we will store to
            gen.loadLocal(uptoLocal, Type.INT_TYPE);
            // The range value we will store:
            gen.push(range);
            // Store it
            gen.arrayStore(Type.INT_TYPE);
            // Increment our upto:
            gen.iinc(uptoLocal, 1);
        }
    }

    if (node.left != null && (node.left.hasOutputs || node.right.hasOutputs)) {
        assert node.left.end + 1 == node.right.start;
        if (node.left.hasOutputs && node.right.hasOutputs) {
            // Recurse on either left or right
            Label labelLeft = new Label();
            Label labelEnd = new Label();
            gen.loadArg(0);
            gen.push(node.left.end);

            gen.ifCmp(Type.LONG_TYPE, GeneratorAdapter.LE, labelLeft);
            buildAsm(gen, node.right, uptoLocal);
            gen.goTo(labelEnd);
            gen.visitLabel(labelLeft);
            buildAsm(gen, node.left, uptoLocal);
            gen.visitLabel(labelEnd);
        } else if (node.left.hasOutputs) {
            // Recurse only on left
            Label labelEnd = new Label();
            gen.loadArg(0);
            gen.push(node.left.end);

            gen.ifCmp(Type.LONG_TYPE, GeneratorAdapter.GT, labelEnd);
            buildAsm(gen, node.left, uptoLocal);
            gen.visitLabel(labelEnd);
        } else {
            // Recurse only on right
            Label labelEnd = new Label();
            gen.loadArg(0);
            gen.push(node.left.end);

            gen.ifCmp(Type.LONG_TYPE, GeneratorAdapter.LE, labelEnd);
            buildAsm(gen, node.right, uptoLocal);
            gen.visitLabel(labelEnd);
        }
    }
}

From source file:com.changingbits.Builder.java

License:Apache License

/** Increments counts as field members (count0, count1,
 *  ...) instead of a this.intArray[0], ... */
private void buildCounterAsm2(GeneratorAdapter gen, Node node, boolean sawOutputs) {

    sawOutputs |= node.outputs != null;/*from  w w  w .  j ava  2 s .c  o m*/

    if (node.left != null) {
        assert node.left.end + 1 == node.right.start;
        // Recurse on either left or right
        Label labelLeft = new Label();
        Label labelEnd = new Label();
        gen.loadArg(0);
        gen.push(node.left.end);

        gen.ifCmp(Type.LONG_TYPE, GeneratorAdapter.LE, labelLeft);
        buildCounterAsm2(gen, node.right, sawOutputs);
        gen.goTo(labelEnd);
        gen.visitLabel(labelLeft);
        buildCounterAsm2(gen, node.left, sawOutputs);
        gen.visitLabel(labelEnd);
    } else if (sawOutputs) {
        // leaf: this.countN++
        gen.loadThis();
        gen.loadThis();
        gen.getField(COMPILED_COUNTER_CLASS2_TYPE, "count" + node.leafIndex, Type.INT_TYPE);
        gen.push(1);
        gen.visitInsn(Opcodes.IADD);
        gen.putField(COMPILED_COUNTER_CLASS2_TYPE, "count" + node.leafIndex, Type.INT_TYPE);
    }
}

From source file:com.changingbits.Builder.java

License:Apache License

private void buildCounterAsm(GeneratorAdapter gen, Node node, boolean sawOutputs) {

    sawOutputs |= node.outputs != null;/*from   w  ww .  j  av  a  2 s  . c o m*/

    if (node.left != null) {
        assert node.left.end + 1 == node.right.start;
        // Recurse on either left or right
        Label labelLeft = new Label();
        Label labelEnd = new Label();
        gen.loadArg(0);
        gen.push(node.left.end);

        gen.ifCmp(Type.LONG_TYPE, GeneratorAdapter.LE, labelLeft);
        buildCounterAsm(gen, node.right, sawOutputs);
        gen.goTo(labelEnd);
        gen.visitLabel(labelLeft);
        buildCounterAsm(gen, node.left, sawOutputs);
        gen.visitLabel(labelEnd);
    } else if (sawOutputs) {
        // leaf: elementaryCounts[node.leafIndex]++
        gen.loadThis();
        gen.getField(BASE_LONG_RANGE_COUNTER_TYPE, "elementaryCounts", INT_ARRAY_TYPE);
        gen.push(node.leafIndex);
        gen.dup2();
        gen.arrayLoad(Type.INT_TYPE);
        gen.push(1);
        gen.visitInsn(Opcodes.IADD);
        gen.arrayStore(Type.INT_TYPE);
    }
}

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

License:Open Source License

protected void generateWriteStaticGroup(Schema schema, ClassVisitor cv, String genClassInternalName,
        boolean javaClassCodec) {
    // method writeStaticGroupWithId - switch
    MethodVisitor mv = cv.visitMethod(ACC_PROTECTED, "writeStaticGroupWithId",
            "(Lcom/cinnober/msgcodec/io/ByteSink;Ljava/lang/Object;)V", null,
            new String[] { "java/io/IOException" });
    int nextVar = 3;
    mv.visitCode();/*from   w w  w . j  av  a  2 s.  c  om*/

    mv.visitVarInsn(ALOAD, 2);
    if (javaClassCodec) {
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
    } else {
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, genClassInternalName, "groupTypeAccessor",
                "Lcom/cinnober/msgcodec/GroupTypeAccessor;");
        mv.visitVarInsn(ALOAD, 2);
        mv.visitMethodInsn(INVOKEINTERFACE, "com/cinnober/msgcodec/GroupTypeAccessor", "getGroupType",
                "(Ljava/lang/Object;)Ljava/lang/Object;", true);
    }
    int groupTypeVar = nextVar++;
    mv.visitInsn(DUP);
    mv.visitVarInsn(ASTORE, groupTypeVar);
    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false);

    // switch on class.hashCode()
    Map<Integer, ObjectHashCodeSwitchCase<Object>> casesByHashCode = new TreeMap<>();
    Map<Integer, Label> labelsByGroupId = new TreeMap<>();
    for (GroupDef group : schema.getGroups()) {
        Object groupType = group.getGroupType();
        int groupHash = groupType.hashCode();
        ObjectHashCodeSwitchCase<Object> hashCase = casesByHashCode.get(groupHash);
        if (hashCase == null) {
            hashCase = new ObjectHashCodeSwitchCase<>(groupHash);
            casesByHashCode.put(hashCase.hashCode, hashCase);
        }
        hashCase.add(groupType);
    }

    Label unknownHashLabel = new Label();
    {
        int[] caseValues = new int[casesByHashCode.size()];
        int i = 0;
        for (int hashCode : casesByHashCode.keySet()) {
            caseValues[i++] = hashCode;
        }
        Label[] caseLabels = new Label[casesByHashCode.size()];
        i = 0;
        for (ObjectHashCodeSwitchCase<Object> hashCase : casesByHashCode.values()) {
            caseLabels[i++] = hashCase.label;
        }
        mv.visitLookupSwitchInsn(unknownHashLabel, caseValues, caseLabels);
    }
    for (ObjectHashCodeSwitchCase<Object> hashCase : casesByHashCode.values()) {
        mv.visitLabel(hashCase.label);
        mv.visitFrame(F_SAME, 0, null, 0, null);
        for (ObjectSwitchCase<Object> classCase : hashCase.cases) {
            GroupDef group = schema.getGroup(classCase.object);
            int groupId = schema.getGroup(classCase.object).getId();
            if (groupId != -1) {
                labelsByGroupId.put(groupId, classCase.label);
            }

            mv.visitVarInsn(ALOAD, groupTypeVar);
            if (javaClassCodec) {
                mv.visitLdcInsn(getJavaType(classCase.object));
                mv.visitJumpInsn(IF_ACMPEQ, classCase.label);
            } else {
                mv.visitVarInsn(ALOAD, 0);
                mv.visitFieldInsn(GETFIELD, genClassInternalName, "groupType_" + group.getName(),
                        "Ljava/lang/Object;");
                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", false);
                mv.visitJumpInsn(IFNE, classCase.label); // IFNE = if not false
            }
        }
    }
    // Default case for class hashcode switch, do lookup using schema.getGroup(Object)
    {
        Label unknownGroupIdLabel = new Label();
        mv.visitLabel(unknownHashLabel);
        mv.visitFrame(F_SAME, 0, null, 0, null);
        Label[] groupIdLabels = new Label[labelsByGroupId.size()];
        int[] groupIds = new int[groupIdLabels.length];

        {
            int i = 0;
            for (Entry<Integer, Label> entry : labelsByGroupId.entrySet()) {
                groupIds[i] = entry.getKey();
                groupIdLabels[i] = new Label();
                i++;
            }
        }

        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, genClassInternalName, "schema", "Lcom/cinnober/msgcodec/Schema;");

        mv.visitVarInsn(ALOAD, groupTypeVar);
        mv.visitMethodInsn(INVOKEVIRTUAL, SCHEMA_INAME, "getGroup",
                "(Ljava/lang/Object;)Lcom/cinnober/msgcodec/GroupDef;", false);

        // check for null result from getGroup
        Label noGroupDefLabel = new Label();
        mv.visitInsn(DUP);
        mv.visitJumpInsn(IFNULL, noGroupDefLabel);

        mv.visitMethodInsn(INVOKEVIRTUAL, GROUPDEF_INAME, "getId", "()I", false);

        // Switch on the group id
        mv.visitLookupSwitchInsn(unknownHashLabel, groupIds, groupIdLabels);

        // Cases for the group ids
        for (int i = 0; i < groupIds.length; i++) {
            mv.visitLabel(groupIdLabels[i]);
            mv.visitFrame(F_SAME, 0, null, 0, null);
            mv.visitJumpInsn(GOTO, labelsByGroupId.get(groupIds[i]));
        }

        mv.visitLabel(noGroupDefLabel);
        mv.visitFrame(F_SAME, 0, null, 0, null);
        mv.visitInsn(POP);

        // Throw exception if there is no match on class or group id
        mv.visitLabel(unknownGroupIdLabel);
        mv.visitFrame(F_SAME, 0, null, 0, null);
        mv.visitVarInsn(ALOAD, groupTypeVar);
        mv.visitMethodInsn(INVOKESTATIC, baseclassIName, "unknownGroupType",
                "(Ljava/lang/Object;)Ljava/lang/IllegalArgumentException;", false);
        mv.visitInsn(ATHROW);
    }

    // Generate the labeled calls to group writer methods
    for (ObjectHashCodeSwitchCase<Object> hashCase : casesByHashCode.values()) {
        for (ObjectSwitchCase<Object> classCase : hashCase.cases) {
            Object groupType = classCase.object;
            GroupDef group = schema.getGroup(groupType);
            String groupDescriptor = getTypeDescriptor(groupType, javaClassCodec);
            mv.visitLabel(classCase.label);
            mv.visitFrame(F_SAME, 0, null, 0, null);
            mv.visitVarInsn(ALOAD, 0); // this
            mv.visitVarInsn(ALOAD, 1); // out
            mv.visitVarInsn(ALOAD, 2); // obj
            if (javaClassCodec) {
                mv.visitTypeInsn(CHECKCAST, getTypeInternalName(groupType, javaClassCodec));
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, genClassInternalName, "writeStaticGroupWithId_" + group.getName(),
                    "(Lcom/cinnober/msgcodec/io/ByteSink;" + groupDescriptor + ")V", false);
            mv.visitInsn(RETURN);
        }
    }

    mv.visitMaxs(4, nextVar);
    mv.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();/*  w  ww.j av  a  2  s  . co  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 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  w w  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 ww w. j  a  va 2 s  .com*/
 * @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 ww w.j a v  a 2  s . c  o m
 */
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 {/*  w ww.  j a v a2  s  .  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);
    }
}