in lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/BytecodeMarshallerGenerator.java [173:300]
private void createConstructor( ClassWriter cw, String className, List<PropertyDescriptor> propertyDescriptors )
{
MethodVisitor mv = cw.visitMethod( ACC_PUBLIC, "<init>", MARSHALLER_CONSTRUCTOR_SIGNATURE, null, null );
mv.visitCode();
// Load this
mv.visitVarInsn( ALOAD, 0 );
// Load first parameter type (Class)
mv.visitVarInsn( ALOAD, 1 );
// Load second parameter type (Map)
mv.visitVarInsn( ALOAD, 2 );
// Load third parameter type (ClassDescriptorAwaySerializer)
mv.visitVarInsn( ALOAD, 3 );
// Load fourth parameter type (ObjenesisSerializer)
mv.visitVarInsn( ALOAD, 4 );
// Call super(Class, Map)
mv.visitMethodInsn( INVOKESPECIAL, SUPER_CLASS_INTERNAL_TYPE, "<init>", MARSHALLER_SUPER_CONSTRUCTOR_SIGNATURE );
// Fill fields with marshallers
for ( int i = 0; i < propertyDescriptors.size(); i++ )
{
PropertyDescriptor propertyDescriptor = propertyDescriptors.get( i );
String fieldName = toFinalFieldName( "marshaller", propertyDescriptor );
mv.visitVarInsn( ALOAD, 0 );
mv.visitVarInsn( ALOAD, 0 );
// Load property type
mv.visitVarInsn( ALOAD, 5 );
mv.visitIntInsn( BIPUSH, i );
mv.visitMethodInsn( INVOKEINTERFACE, LIST_CLASS_INTERNAL_TYPE, "get", "(I)Ljava/lang/Object;" );
// Store PropertyDescriptor
mv.visitTypeInsn( CHECKCAST, PROPERTYDESCRIPTOR_CLASS_INTERNAL_TYPE );
mv.visitFieldInsn( PUTFIELD, className, toFinalFieldName( "descriptor", propertyDescriptor ),
PROPERTYDESCRIPTOR_CLASS_DESCRIPTOR );
if ( propertyDescriptor.getType().isArray()
&& !propertyDescriptor.getType().getComponentType().isPrimitive() )
{
Label labelNonNull = new Label();
// Get type from PropertyAccessor
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "descriptor", propertyDescriptor ),
PROPERTYDESCRIPTOR_CLASS_DESCRIPTOR );
mv.visitMethodInsn( INVOKEINTERFACE, PROPERTYDESCRIPTOR_CLASS_INTERNAL_TYPE, "getType",
"()Ljava/lang/Class;" );
// Get array component type
mv.visitMethodInsn( INVOKEVIRTUAL, CLASS_CLASS_INTERNAL_TYPE, "getComponentType",
CLASS_GET_COMPONENT_TYPE );
mv.visitVarInsn( ASTORE, 9 );
// Generate cheating PropertyDescriptor for component type
mv.visitVarInsn( ALOAD, 0 );
mv.visitTypeInsn( NEW, CHEATINGPROPERTYDESCRIPTOR_CLASS_INTERNAL_TYPE );
mv.visitInsn( DUP );
mv.visitLdcInsn( propertyDescriptor.getPropertyName() + "Element" );
mv.visitVarInsn( ALOAD, 9 );
mv.visitInsn( ACONST_NULL );
mv.visitMethodInsn( INVOKESPECIAL, CHEATINGPROPERTYDESCRIPTOR_CLASS_INTERNAL_TYPE, "<init>",
CHEATINGPROPERTYDESCRIPTOR_CONSTRUCTOR );
mv.visitFieldInsn( PUTFIELD, className, toFinalFieldName( "component", propertyDescriptor ),
CHEATINGPROPERTYDESCRIPTOR_CLASS_DESCRIPTOR );
// Search marshaller by using interal ones
mv.visitVarInsn( ALOAD, 6 );
mv.visitVarInsn( ALOAD, 9 );
mv.visitInsn( ACONST_NULL );
mv.visitMethodInsn( INVOKEINTERFACE, MARSHALLERSTRATEGY_CLASS_INTERNAL_TYPE, "getMarshaller",
MARSHALLERSTRATEGY_GET_MARSHALLER_SIGNATURE );
mv.visitVarInsn( ASTORE, 8 );
mv.visitVarInsn( ALOAD, 8 );
// Search marshaller for property type
mv.visitJumpInsn( IFNONNULL, labelNonNull );
mv.visitVarInsn( ALOAD, 0 );
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "component", propertyDescriptor ),
CHEATINGPROPERTYDESCRIPTOR_CLASS_DESCRIPTOR );
mv.visitMethodInsn( INVOKEVIRTUAL, SUPER_CLASS_INTERNAL_TYPE, "findMarshaller",
MARSHALLER_FIND_MARSHALLER_SIGNATURE );
mv.visitVarInsn( ASTORE, 8 );
// Save marshaller to field
mv.visitLabel( labelNonNull );
mv.visitVarInsn( ALOAD, 0 );
mv.visitVarInsn( ALOAD, 8 );
mv.visitFieldInsn( PUTFIELD, className, toFinalFieldName( "marshaller", propertyDescriptor ),
MARSHALLER_CLASS_DESCRIPTOR );
}
else
{
// Check if marshaller is defined
mv.visitVarInsn( ALOAD, 0 );
mv.visitVarInsn( ALOAD, 0 );
mv.visitVarInsn( ALOAD, 0 );
mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "descriptor", propertyDescriptor ),
PROPERTYDESCRIPTOR_CLASS_DESCRIPTOR );
mv.visitMethodInsn( INVOKEVIRTUAL, SUPER_CLASS_INTERNAL_TYPE, "findMarshaller",
MARSHALLER_FIND_MARSHALLER_SIGNATURE );
mv.visitFieldInsn( PUTFIELD, className, fieldName, MARSHALLER_CLASS_DESCRIPTOR );
}
// Load this to method stack
mv.visitVarInsn( ALOAD, 0 );
mv.visitInsn( DUP );
// Load property accessor
mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "descriptor", propertyDescriptor ),
PROPERTYDESCRIPTOR_CLASS_DESCRIPTOR );
mv.visitMethodInsn( INVOKEINTERFACE, PROPERTYDESCRIPTOR_CLASS_INTERNAL_TYPE, "getPropertyAccessor",
PROPERTY_DESCRIPTOR_GET_PROPERTYACCESSOR_SIGNATURE );
// Save PropertyAccessor to field
mv.visitFieldInsn( PUTFIELD, className, toFinalFieldName( "accessor", propertyDescriptor ),
PROPERTYACCESSOR_CLASS_DESCRIPTOR );
}
mv.visitInsn( RETURN );
mv.visitMaxs( -1, 12 );
mv.visitEnd();
}