List of usage examples for org.objectweb.asm MethodVisitor visitMethodInsn
public void visitMethodInsn(final int opcode, final String owner, final String name, final String descriptor, final boolean isInterface)
From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java
License:Open Source License
protected void generateWriteStaticGroupForType(Schema schema, ClassVisitor cv, String genClassInternalName, boolean javaClassCodec) { for (GroupDef group : schema.getGroups()) { Object groupType = group.getGroupType(); String groupDescriptor = getTypeDescriptor(groupType, javaClassCodec); MethodVisitor writemv = cv.visitMethod(ACC_PRIVATE, "writeStaticGroup_" + group.getName(), "(Lcom/cinnober/msgcodec/io/ByteSink;" + groupDescriptor + ")V", null, new String[] { "java/io/IOException" }); writemv.visitCode();/*from ww w . j a v a 2 s . com*/ LocalVariable nextWriteVar = new LocalVariable(3); // write fields of super group if (group.getSuperGroup() != null) { GroupDef superGroup = schema.getGroup(group.getSuperGroup()); Object superGroupType = superGroup.getGroupType(); String superGroupDescriptor = getTypeDescriptor(superGroupType, javaClassCodec); writemv.visitVarInsn(ALOAD, 0); writemv.visitVarInsn(ALOAD, 1); writemv.visitVarInsn(ALOAD, 2); writemv.visitMethodInsn(INVOKEVIRTUAL, genClassInternalName, "writeStaticGroup_" + superGroup.getName(), "(Lcom/cinnober/msgcodec/io/ByteSink;" + superGroupDescriptor + ")V", false); } // fields for (FieldDef field : group.getFields()) { writemv.visitVarInsn(ALOAD, 1); // output stream Class<?> javaClass = field.getJavaClass(); Accessor<?, ?> accessor = field.getAccessor(); if (accessor.getClass() == CreateAccessor.class) { if (field.getType().getType() == TypeDef.Type.REFERENCE) { if (field.isRequired()) { writemv.visitInsn(ICONST_0); generateEncodeInt32Value(true, writemv); } else { writemv.visitInsn(ACONST_NULL); generateEncodeInt32Value(false, writemv); } continue; } } if (isPublicFieldAccessor(accessor)) { Field f = ((FieldAccessor) accessor).getField(); writemv.visitVarInsn(ALOAD, 2); writemv.visitFieldInsn(GETFIELD, Type.getInternalName(f.getDeclaringClass()), f.getName(), Type.getDescriptor(f.getType())); if (!f.getType().equals(field.getJavaClass())) { // this can happen when the field is a generic type variable in a super-class. writemv.visitTypeInsn(CHECKCAST, Type.getInternalName(javaClass)); } } else { writemv.visitVarInsn(ALOAD, 0); writemv.visitFieldInsn(GETFIELD, genClassInternalName, "accessor_" + group.getName() + "_" + field.getName(), "Lcom/cinnober/msgcodec/Accessor;"); writemv.visitVarInsn(ALOAD, 2); // instance writemv.visitMethodInsn(INVOKEINTERFACE, "com/cinnober/msgcodec/Accessor", "getValue", "(Ljava/lang/Object;)Ljava/lang/Object;", true); if (javaClass.isPrimitive()) { writemv.visitTypeInsn(CHECKCAST, Type.getInternalName(box(javaClass))); unbox(writemv, javaClass); } else { writemv.visitTypeInsn(CHECKCAST, Type.getInternalName(javaClass)); } } // the output stream and the value is now on the stack generateEncodeValue(writemv, 1, nextWriteVar, field.isRequired(), field.getType(), javaClass, field.getComponentJavaClass(), schema, genClassInternalName, group.getName() + "_" + field.getName(), group.getName() + "." + field.getName(), javaClassCodec); } // end write writemv.visitInsn(RETURN); writemv.visitMaxs(4, nextWriteVar.get()); writemv.visitEnd(); } }
From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java
License:Open Source License
protected void generateReadStaticGroup(Schema schema, ClassVisitor cv, String genClassInternalName, boolean javaClassCodec) { MethodVisitor mv = cv.visitMethod(ACC_PROTECTED, "readStaticGroup", "(ILcom/cinnober/msgcodec/io/ByteSource;)Ljava/lang/Object;", null, new String[] { "java/io/IOException" }); int nextVar = 3; mv.visitCode();//from ww w.j av a 2 s . c o m Map<Integer, Label> labelsByGroupId = new TreeMap<>(); for (GroupDef group : schema.getGroups()) { if (group.getId() != -1) { labelsByGroupId.put(group.getId(), new Label()); } } mv.visitVarInsn(ILOAD, 1); // group id Label unknownGroupIdLabel = new Label(); { int[] caseValues = new int[labelsByGroupId.size()]; int i = 0; for (int groupId : labelsByGroupId.keySet()) { caseValues[i++] = groupId; } Label[] caseLabels = labelsByGroupId.values().toArray(new Label[labelsByGroupId.size()]); mv.visitLookupSwitchInsn(unknownGroupIdLabel, caseValues, caseLabels); } for (Map.Entry<Integer, Label> caseEntry : labelsByGroupId.entrySet()) { GroupDef group = schema.getGroup(caseEntry.getKey().intValue()); Object groupType = group.getGroupType(); String groupDescriptor = getTypeDescriptor(groupType, javaClassCodec); mv.visitLabel(caseEntry.getValue()); mv.visitFrame(F_SAME, 0, null, 0, null); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, genClassInternalName, "readStaticGroup_" + group.getName(), "(Lcom/cinnober/msgcodec/io/ByteSource;)" + groupDescriptor, false); mv.visitInsn(ARETURN); } // default case mv.visitLabel(unknownGroupIdLabel); mv.visitFrame(F_SAME, 0, null, 0, null); mv.visitVarInsn(ILOAD, 1); mv.visitMethodInsn(INVOKESTATIC, baseclassIName, "unknownGroupId", "(I)Lcom/cinnober/msgcodec/DecodeException;", false); mv.visitInsn(ATHROW); mv.visitMaxs(2, nextVar); mv.visitEnd(); }
From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java
License:Open Source License
protected void generateReadStaticGroupForTypeAndCreate(Schema schema, ClassVisitor cv, String genClassInternalName, boolean javaClassCodec) { for (GroupDef group : schema.getGroups()) { Object groupType = group.getGroupType(); String groupDescriptor = getTypeDescriptor(groupType, javaClassCodec); String groupInternalName = getTypeInternalName(groupType, javaClassCodec); MethodVisitor readmv = cv.visitMethod(ACC_PRIVATE, "readStaticGroup_" + group.getName(), "(Lcom/cinnober/msgcodec/io/ByteSource;)" + groupDescriptor, null, new String[] { "java/io/IOException" }); readmv.visitCode();/*from www .j a v a2 s .c om*/ int nextReadVar = 2; Factory<?> factory = group.getFactory(); if (isPublicConstructorFactory(factory)) { // read, create instance readmv.visitTypeInsn(NEW, groupInternalName); readmv.visitInsn(DUP); readmv.visitMethodInsn(INVOKESPECIAL, groupInternalName, "<init>", "()V", false); } else { // read, create instance readmv.visitVarInsn(ALOAD, 0); // this readmv.visitFieldInsn(GETFIELD, genClassInternalName, "factory_" + group.getName(), "Lcom/cinnober/msgcodec/Factory;"); readmv.visitMethodInsn(INVOKEINTERFACE, "com/cinnober/msgcodec/Factory", "newInstance", "()Ljava/lang/Object;", true); if (javaClassCodec) { readmv.visitTypeInsn(CHECKCAST, groupInternalName); } } final int readInstanceVar = nextReadVar++; readmv.visitVarInsn(ASTORE, readInstanceVar); readmv.visitVarInsn(ALOAD, 0); readmv.visitVarInsn(ALOAD, 1); readmv.visitVarInsn(ALOAD, readInstanceVar); readmv.visitMethodInsn(INVOKEVIRTUAL, genClassInternalName, "readStaticGroup_" + group.getName(), "(Lcom/cinnober/msgcodec/io/ByteSource;" + groupDescriptor + ")V", false); // end read readmv.visitVarInsn(ALOAD, readInstanceVar); readmv.visitInsn(ARETURN); readmv.visitMaxs(4, nextReadVar); readmv.visitEnd(); } }
From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java
License:Open Source License
protected void generateReadStaticGroupForType(final Schema schema, ClassVisitor cv, final String genClassInternalName, final boolean javaClassCodec) { for (final GroupDef group : schema.getGroups()) { Object groupType = group.getGroupType(); String groupDescriptor = getTypeDescriptor(groupType, javaClassCodec); final MethodVisitor mv = cv.visitMethod(ACC_PRIVATE, "readStaticGroup_" + group.getName(), "(Lcom/cinnober/msgcodec/io/ByteSource;" + groupDescriptor + ")V", null, new String[] { "java/io/IOException" }); mv.visitCode();/*from ww w.j a v a 2 s .c o m*/ final LocalVariable nextVar = new LocalVariable(3); // read fields of super group if (group.getSuperGroup() != null) { GroupDef superGroup = schema.getGroup(group.getSuperGroup()); Object superGroupType = superGroup.getGroupType(); String superGroupDescriptor = getTypeDescriptor(superGroupType, javaClassCodec); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL, genClassInternalName, "readStaticGroup_" + superGroup.getName(), "(Lcom/cinnober/msgcodec/io/ByteSource;" + superGroupDescriptor + ")V", false); } // fields for (final FieldDef field : group.getFields()) { final Class<?> javaClass = field.getJavaClass(); Runnable readValue = () -> { Label tryStart = new Label(); Label tryEnd = new Label(); Label tryCatch = new Label(); Label tryAfter = new Label(); mv.visitTryCatchBlock(tryStart, tryEnd, tryCatch, "java/lang/Exception"); mv.visitLabel(tryStart); mv.visitVarInsn(ALOAD, 1); // input stream generateDecodeValue(mv, 1, nextVar, field.isRequired(), field.getType(), javaClass, field.getComponentJavaClass(), schema, genClassInternalName, group.getName() + "_" + field.getName(), group.getName() + "." + field.getName(), javaClassCodec); mv.visitLabel(tryEnd); mv.visitJumpInsn(GOTO, tryAfter); mv.visitLabel(tryCatch); int caughtExVar = nextVar.next(); mv.visitVarInsn(ASTORE, caughtExVar); mv.visitTypeInsn(NEW, "com/cinnober/msgcodec/blink/FieldDecodeException"); mv.visitInsn(DUP); mv.visitLdcInsn(field.getName()); mv.visitVarInsn(ALOAD, caughtExVar); mv.visitMethodInsn(INVOKESPECIAL, "com/cinnober/msgcodec/blink/FieldDecodeException", "<init>", "(Ljava/lang/String;Ljava/lang/Throwable;)V", false); mv.visitInsn(ATHROW); mv.visitLabel(tryAfter); }; Accessor<?, ?> accessor = field.getAccessor(); if (isPublicFieldAccessor(accessor)) { Field f = ((FieldAccessor) accessor).getField(); mv.visitVarInsn(ALOAD, 2); // instance // value readValue.run(); // store mv.visitFieldInsn(PUTFIELD, Type.getInternalName(f.getDeclaringClass()), f.getName(), Type.getDescriptor(f.getType())); } else if (accessor.getClass() == CreateAccessor.class) { mv.visitVarInsn(ALOAD, 2); // instance Label tryStart = new Label(); Label tryEnd = new Label(); Label tryCatch = new Label(); Label tryAfter = new Label(); mv.visitTryCatchBlock(tryStart, tryEnd, tryCatch, "java/lang/Exception"); mv.visitLabel(tryStart); mv.visitVarInsn(ALOAD, 1); // input stream generateDecodeDummy(mv, 1, nextVar, field.isRequired(), field.getType(), javaClass, field.getComponentJavaClass(), schema, genClassInternalName, group.getName() + "." + field.getName(), javaClassCodec); mv.visitInsn(POP); mv.visitLabel(tryEnd); mv.visitJumpInsn(GOTO, tryAfter); mv.visitLabel(tryCatch); int caughtExVar = nextVar.next(); mv.visitVarInsn(ASTORE, caughtExVar); mv.visitTypeInsn(NEW, "com/cinnober/msgcodec/blink/FieldDecodeException"); mv.visitInsn(DUP); mv.visitLdcInsn(field.getName()); mv.visitVarInsn(ALOAD, caughtExVar); mv.visitMethodInsn(INVOKESPECIAL, "com/cinnober/msgcodec/blink/FieldDecodeException", "<init>", "(Ljava/lang/String;Ljava/lang/Throwable;)V", false); mv.visitInsn(ATHROW); mv.visitLabel(tryAfter); mv.visitInsn(POP); } else { // accessor mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, genClassInternalName, "accessor_" + group.getName() + "_" + field.getName(), "Lcom/cinnober/msgcodec/Accessor;"); // instance mv.visitVarInsn(ALOAD, 2); // instance // value readValue.run(); if (javaClass.isPrimitive()) { box(mv, javaClass); } // store mv.visitMethodInsn(INVOKEINTERFACE, "com/cinnober/msgcodec/Accessor", "setValue", "(Ljava/lang/Object;Ljava/lang/Object;)V", true); } } mv.visitInsn(RETURN); mv.visitMaxs(6, nextVar.get()); mv.visitEnd(); } }
From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java
License:Open Source License
/** * Generate instructions to encode the specified value type. * The values on the stack are; the output stream and the value to be encoded. * After this call these values are expected to be consumed. * * @param mv the method visitor, open for code instructions. * @param outputStreamVar the variable instance that contains the output stream. * @param nextVar the next variable//from w w w . ja v a2s .c om * @param required true if the field is required, otherwise false. * @param type the field type * @param javaClass the field java class * @param componentJavaClass the field component java class, or null if not a sequence type * @param schema the protocol schema, not null * @param genClassInternalName the internal name of the generated class */ protected void generateEncodeValue(MethodVisitor mv, int outputStreamVar, LocalVariable nextVar, boolean required, TypeDef type, Class<?> javaClass, Class<?> componentJavaClass, Schema schema, String genClassInternalName, String fieldIdentifier, String debugValueLabel, boolean javaClassCodec) { type = schema.resolveToType(type, false); GroupDef refGroup = schema.resolveToGroup(type); if (javaClass.isPrimitive() && !required) { box(mv, javaClass); } else if (!javaClass.isPrimitive() && required) { mv.visitInsn(DUP); Label notNullLabel = new Label(); mv.visitJumpInsn(IFNONNULL, notNullLabel); mv.visitInsn(POP); // output stream mv.visitLdcInsn(debugValueLabel); mv.visitMethodInsn(INVOKESTATIC, baseclassIName, "missingRequiredValue", "(Ljava/lang/String;)Ljava/lang/IllegalArgumentException;", false); mv.visitInsn(ATHROW); mv.visitLabel(notNullLabel); unbox(mv, javaClass); } switch (type.getType()) { case INT8: generateEncodeInt8Value(required, mv); break; case UINT8: generateEncodeUInt8Value(required, mv); break; case CHAR: generateEncodeCharacterValue(required, mv); break; case INT16: generateEncodeInt16Value(required, mv); break; case UINT16: generateEncodeUInt16Value(required, mv); break; case INT32: generateEncodeInt32Value(required, mv); break; case UINT32: generateEncodeUInt32Value(required, mv); break; case INT64: generateEncodeInt64Value(required, mv); break; case UINT64: generateEncodeUInt64Value(required, mv); break; case FLOAT32: generateEncodeFloat32Value(required, mv); break; case FLOAT64: generateEncodeFloat64Value(required, mv); break; case BIGINT: generateEncodeBigIntValue(required, mv); break; case DECIMAL: generateEncodeDecimalValue(required, mv); break; case BIGDECIMAL: generateEncodeBigDecimalValue(required, mv); break; case STRING: generateEncodeStringValue((TypeDef.StringUnicode) type, required, mv); break; case BINARY: generateEncodeBinaryValue((TypeDef.Binary) type, required, mv); break; case BOOLEAN: generateEncodeBooleanValue(required, mv); break; case ENUM: generateEncodeEnumValue((TypeDef.Enum) type, genClassInternalName, fieldIdentifier, nextVar, javaClass, required, mv, debugValueLabel); break; case TIME: generateEncodeTimeValue((TypeDef.Time) type, javaClass, required, mv); break; case SEQUENCE: generateEncodeSequenceValue(javaClass, nextVar, mv, required, outputStreamVar, componentJavaClass, type, schema, genClassInternalName, fieldIdentifier, debugValueLabel, javaClassCodec); break; case REFERENCE: generateEncodeRefValue(refGroup, required, nextVar, mv, genClassInternalName, outputStreamVar, (TypeDef.Reference) type, javaClassCodec); break; case DYNAMIC_REFERENCE: generateEncodeDynRefValue(nextVar, mv, required); break; default: throw new RuntimeException("Unhandled case: " + type.getType()); } }
From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java
License:Open Source License
/** * Generate value encoding using the blink output. * * <p>Defaults to <code>writeBoolean[Null].</code> * * @param required true if the field is required, otherwise false. * @param mv the method visitor, not null. * @see #generateEncodeValue//from ww w .j a v a 2s .c o m */ protected void generateEncodeBooleanValue(boolean required, MethodVisitor mv) { if (required) { mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeBoolean", "(Lcom/cinnober/msgcodec/io/ByteSink;Z)V", false); } else { mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeBooleanNull", "(Lcom/cinnober/msgcodec/io/ByteSink;Ljava/lang/Boolean;)V", false); } }
From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java
License:Open Source License
/** * Generate value encoding using the blink output. * * <p>Defaults to <code>writeBinary[Null].</code> * * @param required true if the field is required, otherwise false. * @param mv the method visitor, not null. * @see #generateEncodeValue// w w w . j a va 2 s . c o m */ protected void generateEncodeBinaryValue(TypeDef.Binary type, boolean required, MethodVisitor mv) { if (required) { mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeBinary", "(Lcom/cinnober/msgcodec/io/ByteSink;[B)V", false); } else { mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeBinaryNull", "(Lcom/cinnober/msgcodec/io/ByteSink;[B)V", false); } }
From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java
License:Open Source License
/** * Generate value encoding using the blink output. * * <p>Defaults to <code>writeStringUTF8[Null].</code> * * @param required true if the field is required, otherwise false. * @param mv the method visitor, not null. * @see #generateEncodeValue// w ww . j av a 2 s. c om */ protected void generateEncodeStringValue(TypeDef.StringUnicode type, boolean required, MethodVisitor mv) { if (required) { mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeStringUTF8", "(Lcom/cinnober/msgcodec/io/ByteSink;Ljava/lang/String;)V", false); } else { mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeStringUTF8Null", "(Lcom/cinnober/msgcodec/io/ByteSink;Ljava/lang/String;)V", false); } }
From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java
License:Open Source License
/** * Generate value encoding using the blink output. * * <p>Defaults to <code>writeBigDecimal[Null].</code> * * @param required true if the field is required, otherwise false. * @param mv the method visitor, not null. * @see #generateEncodeValue// w w w . j ava 2 s . c o m */ protected void generateEncodeBigDecimalValue(boolean required, MethodVisitor mv) { if (required) { mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeBigDecimal", "(Lcom/cinnober/msgcodec/io/ByteSink;Ljava/math/BigDecimal;)V", false); } else { mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeBigDecimalNull", "(Lcom/cinnober/msgcodec/io/ByteSink;Ljava/math/BigDecimal;)V", false); } }
From source file:com.cinnober.msgcodec.blink.BaseByteCodeGenerator.java
License:Open Source License
/** * Generate value encoding using the blink output. * * <p>Defaults to <code>writeDecimal[Null].</code> * * @param required true if the field is required, otherwise false. * @param mv the method visitor, not null. * @see #generateEncodeValue/*from w w w . jav a 2s. co m*/ */ protected void generateEncodeDecimalValue(boolean required, MethodVisitor mv) { if (required) { mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeDecimal", "(Lcom/cinnober/msgcodec/io/ByteSink;Ljava/math/BigDecimal;)V", false); } else { mv.visitMethodInsn(INVOKESTATIC, blinkOutputIName, "writeDecimalNull", "(Lcom/cinnober/msgcodec/io/ByteSink;Ljava/math/BigDecimal;)V", false); } }