Example usage for org.objectweb.asm MethodVisitor visitEnd

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

Introduction

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

Prototype

public void visitEnd() 

Source Link

Document

Visits the end of the method.

Usage

From source file: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 ww .java  2s. co  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.cinnober.msgcodec.blink.BaseByteCodeGenerator.java

License:Open Source License

protected void generateConstructorAndFields(Schema schema, ClassVisitor cv, String genClassInternalName,
        boolean javaClassCodec) {
    MethodVisitor ctormv;
    ctormv = cv.visitMethod(ACC_PUBLIC, "<init>", "(L" + blinkCodecIName + ";Lcom/cinnober/msgcodec/Schema;)V",
            null, null);/*  w  ww  . j  a  v  a  2 s  . c om*/
    int nextCtorVar = 3;
    ctormv.visitCode();
    ctormv.visitVarInsn(ALOAD, 0);
    ctormv.visitVarInsn(ALOAD, 1);
    ctormv.visitMethodInsn(INVOKESPECIAL, baseclassIName, "<init>", "(L" + blinkCodecIName + ";)V", false);

    // schema field
    FieldVisitor fv = cv.visitField(ACC_PRIVATE + ACC_FINAL, "schema", "Lcom/cinnober/msgcodec/Schema;", null,
            null);
    fv.visitEnd();
    ctormv.visitVarInsn(ALOAD, 0); // this
    ctormv.visitVarInsn(ALOAD, 2); // schema
    ctormv.visitFieldInsn(PUTFIELD, genClassInternalName, "schema", "Lcom/cinnober/msgcodec/Schema;");

    if (!javaClassCodec) {
        // store the group type accessor

        // field
        fv = cv.visitField(ACC_PRIVATE + ACC_FINAL, "groupTypeAccessor",
                "Lcom/cinnober/msgcodec/GroupTypeAccessor;", null, null);
        fv.visitEnd();

        // ctor, init field
        ctormv.visitVarInsn(ALOAD, 0); // this
        ctormv.visitVarInsn(ALOAD, 2); // schema
        ctormv.visitMethodInsn(INVOKEVIRTUAL, "com/cinnober/msgcodec/Schema", "getBinding",
                "()Lcom/cinnober/msgcodec/SchemaBinding;", false);
        ctormv.visitMethodInsn(INVOKEVIRTUAL, "com/cinnober/msgcodec/SchemaBinding", "getGroupTypeAccessor",
                "()Lcom/cinnober/msgcodec/GroupTypeAccessor;", false);
        ctormv.visitFieldInsn(PUTFIELD, genClassInternalName, "groupTypeAccessor",
                "Lcom/cinnober/msgcodec/GroupTypeAccessor;");
    }

    for (GroupDef group : schema.getGroups()) {
        if (!javaClassCodec) {
            // store the group type
            // field
            fv = cv.visitField(ACC_PRIVATE + ACC_FINAL, "groupType_" + group.getName(), "Ljava/lang/Object;",
                    null, null);
            fv.visitEnd();

            // ctor, init field
            ctormv.visitVarInsn(ALOAD, 0); // this
            ctormv.visitVarInsn(ALOAD, 2); // schema
            ctormv.visitLdcInsn(group.getName());
            ctormv.visitMethodInsn(INVOKEVIRTUAL, "com/cinnober/msgcodec/Schema", "getGroup",
                    "(Ljava/lang/String;)Lcom/cinnober/msgcodec/GroupDef;", false);
            ctormv.visitMethodInsn(INVOKEVIRTUAL, "com/cinnober/msgcodec/GroupDef", "getGroupType",
                    "()Ljava/lang/Object;", false);
            ctormv.visitFieldInsn(PUTFIELD, genClassInternalName, "groupType_" + group.getName(),
                    "Ljava/lang/Object;");
        }

        Factory<?> factory = group.getFactory();
        if (isPublicConstructorFactory(factory)) {
            // no factory is needed
        } else {
            // field
            fv = cv.visitField(ACC_PRIVATE + ACC_FINAL, "factory_" + group.getName(),
                    "Lcom/cinnober/msgcodec/Factory;", null, null);
            fv.visitEnd();

            // ctor, init field
            ctormv.visitVarInsn(ALOAD, 0); // this
            ctormv.visitVarInsn(ALOAD, 2); // schema
            ctormv.visitLdcInsn(group.getName());
            ctormv.visitMethodInsn(INVOKEVIRTUAL, "com/cinnober/msgcodec/Schema", "getGroup",
                    "(Ljava/lang/String;)Lcom/cinnober/msgcodec/GroupDef;", false);
            ctormv.visitMethodInsn(INVOKEVIRTUAL, "com/cinnober/msgcodec/GroupDef", "getFactory",
                    "()Lcom/cinnober/msgcodec/Factory;", false);
            ctormv.visitFieldInsn(PUTFIELD, genClassInternalName, "factory_" + group.getName(),
                    "Lcom/cinnober/msgcodec/Factory;");
        }

        for (FieldDef field : group.getFields()) {
            Accessor<?, ?> accessor = field.getAccessor();
            SymbolMapping<?> symbolMapping = field.getBinding().getSymbolMapping();
            TypeDef type = schema.resolveToType(field.getType(), true);
            TypeDef componentType = null;

            if (type.getType() == TypeDef.Type.SEQUENCE) {
                componentType = schema.resolveToType(((TypeDef.Sequence) type).getComponentType(), false);
            }

            if (isPublicFieldAccessor(accessor)) {
                // no accessor needed
            } else {
                // field
                fv = cv.visitField(ACC_PRIVATE + ACC_FINAL,
                        "accessor_" + group.getName() + "_" + field.getName(),
                        "Lcom/cinnober/msgcodec/Accessor;", null, null);
                fv.visitEnd();

                // ctor, init field
                ctormv.visitVarInsn(ALOAD, 0); // this
                ctormv.visitVarInsn(ALOAD, 2); // schema
                ctormv.visitLdcInsn(group.getName());
                ctormv.visitMethodInsn(INVOKEVIRTUAL, "com/cinnober/msgcodec/Schema", "getGroup",
                        "(Ljava/lang/String;)Lcom/cinnober/msgcodec/GroupDef;", false);
                ctormv.visitLdcInsn(field.getName());
                ctormv.visitMethodInsn(INVOKEVIRTUAL, "com/cinnober/msgcodec/GroupDef", "getField",
                        "(Ljava/lang/String;)Lcom/cinnober/msgcodec/FieldDef;", false);
                ctormv.visitMethodInsn(INVOKEVIRTUAL, "com/cinnober/msgcodec/FieldDef", "getAccessor",
                        "()Lcom/cinnober/msgcodec/Accessor;", false);
                ctormv.visitFieldInsn(PUTFIELD, genClassInternalName,
                        "accessor_" + group.getName() + "_" + field.getName(),
                        "Lcom/cinnober/msgcodec/Accessor;");
            }

            if (accessor.getClass() == CreateAccessor.class) {
                // No symbol map needed
            } else if ((type != null && type.getType() == TypeDef.Type.ENUM)
                    || (componentType != null && componentType.getType() == TypeDef.Type.ENUM)) {
                // If there is an enum and we need the symbol map
                Objects.requireNonNull(symbolMapping);

                // Create field
                String symbolMappingFieldName = "symbolMapping_" + group.getName() + "_" + field.getName();

                fv = cv.visitField(ACC_PRIVATE + ACC_FINAL, symbolMappingFieldName,
                        "Lcom/cinnober/msgcodec/SymbolMapping;", null, null);
                fv.visitEnd();

                // Init field in the constructor
                ctormv.visitVarInsn(ALOAD, 0); // this
                ctormv.visitVarInsn(ALOAD, 2); // schema
                ctormv.visitLdcInsn(group.getName());
                ctormv.visitMethodInsn(INVOKEVIRTUAL, "com/cinnober/msgcodec/Schema", "getGroup",
                        "(Ljava/lang/String;)Lcom/cinnober/msgcodec/GroupDef;", false);
                ctormv.visitLdcInsn(field.getName());
                ctormv.visitMethodInsn(INVOKEVIRTUAL, "com/cinnober/msgcodec/GroupDef", "getField",
                        "(Ljava/lang/String;)Lcom/cinnober/msgcodec/FieldDef;", false);
                ctormv.visitMethodInsn(INVOKEVIRTUAL, "com/cinnober/msgcodec/FieldDef", "getBinding",
                        "()Lcom/cinnober/msgcodec/FieldBinding;", false);
                ctormv.visitMethodInsn(INVOKEVIRTUAL, "com/cinnober/msgcodec/FieldBinding", "getSymbolMapping",
                        "()Lcom/cinnober/msgcodec/SymbolMapping;", false);

                ctormv.visitFieldInsn(PUTFIELD, genClassInternalName, symbolMappingFieldName,
                        "Lcom/cinnober/msgcodec/SymbolMapping;");
            }
        }
    }

    ctormv.visitInsn(RETURN);
    ctormv.visitMaxs(3, nextCtorVar);
    ctormv.visitEnd();
}

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 . ja va2  s.  c  o  m

    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 generateWriteStaticGroupForTypeWithId(Schema schema, ClassVisitor cv,
        String genClassInternalName, boolean javaClassCodec) {
    for (GroupDef group : schema.getGroups()) {
        Object groupType = group.getGroupType();
        String groupDescriptor = getTypeDescriptor(groupType, javaClassCodec);
        MethodVisitor mv = cv.visitMethod(ACC_PRIVATE, "writeStaticGroupWithId_" + group.getName(),
                "(Lcom/cinnober/msgcodec/io/ByteSink;" + groupDescriptor + ")V", null,
                new String[] { "java/io/IOException" });
        mv.visitCode();//from  www . j  a v  a  2  s.c  o  m
        int nextWriteidVar = 3;

        if (group.getId() != -1) {
            // write with id
            mv.visitVarInsn(ALOAD, 1); // out
            mv.visitLdcInsn(group.getId());
            mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeUInt32",
                    "(Lcom/cinnober/msgcodec/io/ByteSink;I)V", false);
            mv.visitVarInsn(ALOAD, 0); // this
            mv.visitVarInsn(ALOAD, 1); // out
            mv.visitVarInsn(ALOAD, 2); // obj
            mv.visitMethodInsn(INVOKEVIRTUAL, genClassInternalName, "writeStaticGroup_" + group.getName(),
                    "(Lcom/cinnober/msgcodec/io/ByteSink;" + groupDescriptor + ")V", false);
            mv.visitInsn(RETURN);
        } else {
            // write with id
            mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException");
            mv.visitInsn(DUP);
            mv.visitLdcInsn("No group id");
            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>",
                    "(Ljava/lang/String;)V", false);
            mv.visitInsn(ATHROW);
        }

        // end
        mv.visitMaxs(3, nextWriteidVar);
        mv.visitEnd();
    }
}

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();/* w w  w .java2s.c  o m*/
        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();/*www  .j  a  va  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 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();//  w w  w  . j  a  v  a 2 s. co  m
        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();// www.  j a v  a 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.NativeByteCodeGenerator.java

License:Open Source License

@Override
protected void generateWriteStaticGroupForTypeWithId(Schema schema, ClassVisitor cv,
        String genClassInternalName, boolean javaClassCodec) {
    for (GroupDef group : schema.getGroups()) {
        Object groupType = group.getGroupType();
        String groupDescriptor = getTypeDescriptor(groupType, javaClassCodec);
        MethodVisitor mv = cv.visitMethod(ACC_PRIVATE, "writeStaticGroupWithId_" + group.getName(),
                "(Lcom/cinnober/msgcodec/io/ByteSink;" + groupDescriptor + ")V", null,
                new String[] { "java/io/IOException" });
        mv.visitCode();/*from  w w  w .  j a v a2 s .  co m*/
        int nextWriteidVar = 3;

        if (group.getId() != -1) {
            // write with id
            mv.visitVarInsn(ALOAD, 1); // out
            mv.visitLdcInsn(group.getId() & 0xffffffffL);
            mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeUInt64",
                    "(Lcom/cinnober/msgcodec/io/ByteSink;J)V", false);

            // add extension offset (four zero bytes)
            mv.visitVarInsn(ALOAD, 1); // out
            mv.visitInsn(ICONST_0);
            generateEncodeUInt32Value(true, mv);

            mv.visitVarInsn(ALOAD, 0); // this
            mv.visitVarInsn(ALOAD, 1); // out
            mv.visitVarInsn(ALOAD, 2); // obj
            mv.visitMethodInsn(INVOKEVIRTUAL, genClassInternalName, "writeStaticGroup_" + group.getName(),
                    "(Lcom/cinnober/msgcodec/io/ByteSink;" + groupDescriptor + ")V", false);
            mv.visitInsn(RETURN);
        } else {
            // write with id
            mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException");
            mv.visitInsn(DUP);
            mv.visitLdcInsn("No group id");
            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>",
                    "(Ljava/lang/String;)V", false);
            mv.visitInsn(ATHROW);
        }

        // end
        mv.visitMaxs(3, nextWriteidVar);
        mv.visitEnd();
    }
}

From source file:com.e2info.helloasm.HelloAsmApp.java

License:Open Source License

public static void main(String[] args) throws IOException {
    String name = "HelloAsm";
    int flag = ClassWriter.COMPUTE_MAXS;
    ClassWriter cw = new ClassWriter(flag);
    cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, name, null, "java/lang/Object", null);

    cw.visitSource(name + ".java", null);

    {//from   w w  w  .  j  ava  2 s .  c  o  m
        MethodVisitor mv;
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
        mv.visitInsn(Opcodes.RETURN);
        // we need this call to take effect ClassWriter.COMPUTE_MAXS flag.
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }

    {
        MethodVisitor mv;
        mv = cw.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "main", "([Ljava/lang/String;)V", null,
                null);
        mv.visitCode();
        mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
        mv.visitLdcInsn("hello ASM");
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
        mv.visitInsn(Opcodes.RETURN);
        // we need this call to take effect ClassWriter.COMPUTE_MAXS flag.
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }

    cw.visitEnd();

    // build binary
    byte[] bin = cw.toByteArray();

    // save asm trace for human readable
    {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        new ClassReader(bin).accept(new TraceClassVisitor(pw), 0);
        File f = new File(name + ".txt");
        FileUtils.writeStringToFile(f, sw.toString());
    }

    // save as calss file
    {
        File f = new File(name + ".class");
        FileUtils.writeByteArrayToFile(f, bin);
    }

}