private void visitObjectArrayPropertyAccessorRead()

in lightning-core/src/main/java/org/apache/directmemory/lightning/internal/generator/BytecodeMarshallerGenerator.java [413:504]


    private void visitObjectArrayPropertyAccessorRead( MethodVisitor mv, String className,
                                                       PropertyDescriptor propertyDescriptor )
    {
        Class<?> propertyType = propertyDescriptor.getType();

        // Load this to method stack
        mv.visitVarInsn( ALOAD, 0 );

        // Read PropertyAccessor from field
        mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "accessor", propertyDescriptor ),
                           PROPERTYACCESSOR_CLASS_DESCRIPTOR );
        mv.visitTypeInsn( CHECKCAST, ARRAYPROPERTYACCESSOR_CLASS_INTERNAL_TYPE );
        mv.visitVarInsn( ASTORE, 8 );

        // Load property type
        mv.visitVarInsn( ALOAD, 8 );
        mv.visitInsn( DUP );
        mv.visitMethodInsn( INVOKEINTERFACE, PROPERTYACCESSOR_CLASS_INTERNAL_TYPE, "getType",
                            OBJECT_GET_CLASS_SIGNATURE );
        mv.visitVarInsn( ASTORE, 5 );

        // Load value to method stack
        mv.visitVarInsn( ALOAD, 1 );

        // Save array to stack position 6
        visitPropertyAccessorValueRead( propertyType, mv );
        mv.visitTypeInsn( CHECKCAST, Type.getType( propertyType ).getInternalName() );
        mv.visitVarInsn( ASTORE, 6 );

        // Save length to stream
        mv.visitVarInsn( ALOAD, 3 );
        mv.visitVarInsn( ALOAD, 6 );
        mv.visitInsn( ARRAYLENGTH );
        mv.visitMethodInsn( INVOKEINTERFACE, TARGET_CLASS_INTERNAL_TYPE, "writeInt", "(I)V" );

        // Loop over every element in array
        Label forLoopEnd = new Label();
        Label forLoopStart = new Label();
        mv.visitInsn( ICONST_0 );
        mv.visitVarInsn( ISTORE, 7 );
        mv.visitJumpInsn( GOTO, forLoopEnd );
        mv.visitLabel( forLoopStart );

        // Load this to method stack
        mv.visitVarInsn( ALOAD, 0 );

        // Load property marshaller on stack
        mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "marshaller", propertyDescriptor ),
                           MARSHALLER_CLASS_DESCRIPTOR );

        // Load PropertyAccessor to method stack
        mv.visitVarInsn( ALOAD, 8 );

        // Load array to method stack
        mv.visitVarInsn( ALOAD, 6 );

        // Load index to method stack
        mv.visitVarInsn( ILOAD, 7 );

        // Get value from array
        mv.visitMethodInsn( INVOKEINTERFACE, ARRAYPROPERTYACCESSOR_CLASS_INTERNAL_TYPE, "readObject",
                            PROPERTY_ACCESSOR_ARRAY_READ_OBJECT_SIGNATURE );
        mv.visitTypeInsn( CHECKCAST, Type.getType( propertyType.getComponentType() ).getInternalName() );

        // If type is primitive add some "autoboxing" magic
        if ( propertyType.getComponentType().isPrimitive() )
        {
            visitWrapperAutoboxing( propertyType.getComponentType(), mv );
        }

        // Load type to method stack
        mv.visitVarInsn( ALOAD, 0 );
        mv.visitFieldInsn( GETFIELD, className, toFinalFieldName( "component", propertyDescriptor ),
                           CHEATINGPROPERTYDESCRIPTOR_CLASS_DESCRIPTOR );

        // Load DataOutput to method stack
        mv.visitVarInsn( ALOAD, 3 );

        // Load SerializationContext to method stack
        mv.visitVarInsn( ALOAD, 4 );

        // Call Marshaller#marshall on properties marshaller
        mv.visitMethodInsn( INVOKEINTERFACE, MARSHALLER_CLASS_INTERNAL_TYPE, "marshall", MARSHALLER_MARSHALL_SIGNATURE );

        // Test if loop ends
        mv.visitIincInsn( 7, 1 );
        mv.visitLabel( forLoopEnd );
        mv.visitVarInsn( ILOAD, 7 );
        mv.visitVarInsn( ALOAD, 6 );
        mv.visitInsn( ARRAYLENGTH );
        mv.visitJumpInsn( IF_ICMPLT, forLoopStart );
    }