// File: /workspace/github_c_makefile_star2_O3/johsteffens[P]beth/lib/bcore/bcore_spect_inst.c
// Function: down_generic
static void down_generic( const bcore_inst_s* p, vd_t o )
{
#ifdef RTCHECKS
    assert( o != NULL );
    if( p->aware ) verify_aware_type( p->header.o_type, o, __func__ );
#endif // RTCHECKS
    for( uz_t i = 0; i < p->body->size; i++ )
    {
        const bcore_inst_item_s* inst_item = &p->body->data[ i ];
        if( inst_item->no_trace ) continue;

        const bcore_self_item_s* self_item = inst_item->self_item;
        vd_t item_obj = ( u0_t* )o + inst_item->offset;

        switch( self_item->caps )
        {
            case BCORE_CAPS_SOLID_STATIC:
            {
                const bcore_inst_s* inst_p = inst_item->inst_p;
                if( !inst_p->down_flat ) inst_p->down( inst_p, item_obj );
            }
            break;

            case BCORE_CAPS_LINK_STATIC:
            {
                bcore_link_static_s* s = item_obj;
                if( s->link )
                {
                    const bcore_inst_s* inst_p = inst_item->inst_p;
                    inst_p->discard( inst_p, s->link );
                }
            }
            break;

            case BCORE_CAPS_LINK_TYPED:
            {
                bcore_link_typed_s* s = item_obj;
                if( s->link ) bcore_inst_t_discard( s->type, s->link );
            }
            break;

            case BCORE_CAPS_LINK_AWARE:
            {
                bcore_link_aware_s* s = item_obj;
                if( s->link ) bcore_inst_a_discard( s->link );
            }
            break;

            case BCORE_CAPS_POINTER:
            {
                // nothing to do
            }
            break;

            case BCORE_CAPS_ARRAY_DYN_SOLID_STATIC:
            {
                bcore_array_dyn_solid_static_s* s = item_obj;
                if( s->space ) // space == 0 means array does not own data
                {
                    const bcore_inst_s* inst_p = inst_item->inst_p;
                    if( !inst_p->down_flat )
                    {
                        bcore_release_arg_arr( ( fp_t )inst_p->down, inst_p, s->data, s->size, inst_p->size );
                    }
                    else
                    {
                        bcore_free( s->data );
                    }
                    s->data = NULL;
                    s->space = 0;
                }
            }
            break;

            case BCORE_CAPS_ARRAY_DYN_SOLID_TYPED:
            {
                bcore_array_dyn_solid_typed_s* s = item_obj;
                if( s->space ) // space == 0 means array does not own data
                {
                    const bcore_inst_s* inst_p = bcore_inst_s_get_typed( s->type );
                    if( !inst_p->down_flat )
                    {
                        bcore_release_arg_arr( ( fp_t )inst_p->down, inst_p, s->data, s->size, inst_p->size );
                    }
                    else
                    {
                        bcore_free( s->data );
                    }
                    s->data = NULL;
                    s->space = 0;
                }
            }
            break;

            case BCORE_CAPS_ARRAY_DYN_LINK_STATIC:
            {
                bcore_array_dyn_link_static_s* s = item_obj;
                if( s->space ) // space == 0 means array does not own data
                {
                    const bcore_inst_s* inst_p = inst_item->inst_p;
                    for( uz_t i = 0; i < s->size; i++ ) inst_p->discard( inst_p, s->data[ i ] );
                    bcore_free( s->data );
                    s->data = NULL;
                    s->space = 0;
                }
            }
            break;

            case BCORE_CAPS_ARRAY_DYN_LINK_TYPED:
            {
                bcore_array_dyn_link_typed_s* s = item_obj;
                if( s->space ) // space == 0 means array does not own data
                {
                    const bcore_inst_s* inst_p = bcore_inst_s_get_typed( s->type );
                    for( uz_t i = 0; i < s->size; i++ ) inst_p->discard( inst_p, s->data[ i ] );
                    bcore_free( s->data );
                    s->data = NULL;
                    s->space = 0;
                }
            }
            break;

            case BCORE_CAPS_ARRAY_DYN_LINK_AWARE:
            {
                bcore_array_dyn_link_aware_s* s = item_obj;
                if( s->space ) // space == 0 means array does not own data
                {
                    for( uz_t i = 0; i < s->size; i++ ) bcore_inst_a_discard( s->data[ i ] );
                    bcore_free( s->data );
                    s->data = NULL;
                    s->space = 0;
                }
            }
            break;

            case BCORE_CAPS_ARRAY_FIX_SOLID_STATIC:
            {
                const bcore_inst_s* inst_p = inst_item->inst_p;
                if( !inst_p->down_flat )
                {
                    uz_t arr_size = bcore_inst_item_s_array_fix_size( inst_item );
                    uz_t element_size = inst_p->size;
                    for( uz_t i = 0; i < arr_size; i++ )
                    {
                        vd_t obj = ( u0_t* )item_obj + element_size * i;
                        inst_p->down( inst_p, obj );
                    }
                }
            }
            break;

            case BCORE_CAPS_ARRAY_FIX_LINK_STATIC:
            {
                const bcore_inst_s* inst_p = inst_item->inst_p;
                uz_t arr_size = bcore_inst_item_s_array_fix_size( inst_item );
                vd_t* arr = item_obj;
                for( uz_t i = 0; i < arr_size; i++ )
                {
                    bcore_inst_p_discard( inst_p, arr[ i ] );
                    arr[ i ] = NULL;
                }
            }
            break;

            case BCORE_CAPS_ARRAY_FIX_LINK_AWARE:
            {
                uz_t arr_size = bcore_inst_item_s_array_fix_size( inst_item );
                vd_t* arr = item_obj;
                for( uz_t i = 0; i < arr_size; i++ )
                {
                    bcore_inst_a_discard( arr[ i ] );
                    arr[ i ] = NULL;
                }
            }
            break;

            default:
            {
                ERR_fa( "Unhandled nesting '#<sc_t>'", bcore_flect_caps_e_sc( self_item->caps ) );
            }
        }
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, (%rsp)
movq %rdi, 0x10(%rsp)
movq 0x10(%rdi), %rax
cmpq $0x0, 0x8(%rax)
je 0xfb0c1
xorl %r12d, %r12d
movq (%rax), %rax
leaq (%r12,%r12,2), %rcx
shlq $0x4, %rcx
cmpb $0x0, 0x28(%rax,%rcx)
je 0xfaa90
incq %r12
movq 0x10(%rsp), %rax
movq 0x10(%rax), %rax
cmpq 0x8(%rax), %r12
jb 0xfaa67
jmp 0xfb0c1
addq %rcx, %rax
movq 0x18(%rax), %rcx
movl 0x10(%rcx), %edi
leal -0x1(%rdi), %edx
cmpl $0xc, %edx
ja 0xfaeb4
movq (%rax), %r13
addq (%rsp), %r13
leaq 0x4f684(%rip), %rsi     # 0x14a138
movslq (%rsi,%rdx,4), %rdx
addq %rsi, %rdx
jmpq *%rdx
movq 0x20(%rax), %rdi
cmpb $0x0, 0x2a(%rdi)
jne 0xfaa79
movq %r13, %rsi
callq *0x88(%rdi)
jmp 0xfaa79
movq 0x18(%rcx), %rbx
testq %rbx, %rbx
je 0xfaa79
movq 0x20(%rax), %r15
xorl %r14d, %r14d
movq (%r13,%r14,8), %rsi
testq %rsi, %rsi
je 0xfaaf6
movq %r15, %rdi
callq *0xb8(%r15)
movq $0x0, (%r13,%r14,8)
incq %r14
cmpq %r14, %rbx
jne 0xfaae2
jmp 0xfaa79
movq (%r13), %r13
testq %r13, %r13
je 0xfaa79
movq (%r13), %rbp
movl 0xa1945(%rip), %eax     # 0x19c468
cltq
leaq (%rax,%rax,2), %rax
leaq 0xa1938(%rip), %rdx     # 0x19c468
movq 0x20(%rdx,%rax,8), %rcx
movq 0x18(%rdx,%rax,8), %rdx
andq %rbp, %rdx
shlq $0x4, %rdx
leaq (%rcx,%rdx), %rax
movq (%rcx,%rdx), %rdx
movl $0x8, %ecx
cmpq %rbp, %rdx
je 0xfab7d
movq 0x10(%rax), %rdx
movl $0x18, %ecx
cmpq %rbp, %rdx
je 0xfab7d
movq 0x20(%rax), %rdx
movl $0x28, %ecx
cmpq %rbp, %rdx
je 0xfab7d
movq 0x30(%rax), %rdx
movl $0x38, %ecx
cmpq %rbp, %rdx
jne 0xfab86
movq (%rax,%rcx), %r15
testq %r15, %r15
jne 0xfabad
movabsq $0x782b96602f424981, %rdi # imm = 0x782B96602F424981
movq %rbp, %rsi
callq 0xe9bc5
movq %rax, %r15
leaq 0xa18c6(%rip), %rdi     # 0x19c468
movq %rbp, %rsi
movq %rax, %rdx
callq 0x115fac
movq %r15, %rdi
movq %r13, %rsi
jmp 0xfae3b
movq 0x18(%rcx), %rax
movq %rax, 0x8(%rsp)
testq %rax, %rax
je 0xfaa79
xorl %r14d, %r14d
movq (%r13,%r14,8), %rbp
testq %rbp, %rbp
je 0xfac7b
movq (%rbp), %r15
movl 0xa1883(%rip), %eax     # 0x19c468
cltq
leaq (%rax,%rax,2), %rax
leaq 0xa1876(%rip), %rdx     # 0x19c468
movq 0x20(%rdx,%rax,8), %rcx
movq 0x18(%rdx,%rax,8), %rdx
andq %r15, %rdx
shlq $0x4, %rdx
leaq (%rcx,%rdx), %rax
movq (%rcx,%rdx), %rdx
movl $0x8, %ecx
cmpq %r15, %rdx
je 0xfac3f
movq 0x10(%rax), %rdx
movl $0x18, %ecx
cmpq %r15, %rdx
je 0xfac3f
movq 0x20(%rax), %rdx
movl $0x28, %ecx
cmpq %r15, %rdx
je 0xfac3f
movq 0x30(%rax), %rdx
movl $0x38, %ecx
cmpq %r15, %rdx
jne 0xfac48
movq (%rax,%rcx), %rbx
testq %rbx, %rbx
jne 0xfac6f
movabsq $0x782b96602f424981, %rdi # imm = 0x782B96602F424981
movq %r15, %rsi
callq 0xe9bc5
movq %rax, %rbx
leaq 0xa1804(%rip), %rdi     # 0x19c468
movq %r15, %rsi
movq %rax, %rdx
callq 0x115fac
movq %rbx, %rdi
movq %rbp, %rsi
callq *0xb8(%rbx)
movq $0x0, (%r13,%r14,8)
incq %r14
cmpq %r14, 0x8(%rsp)
jne 0xfabcd
jmp 0xfaa79
cmpq $0x0, 0x10(%r13)
je 0xfaa79
movq 0x8(%r13), %rax
testq %rax, %rax
je 0xfb0a9
xorl %r14d, %r14d
movq (%r13), %rcx
movq (%rcx,%r14,8), %rbp
testq %rbp, %rbp
je 0xfad67
movq (%rbp), %r15
movl 0xa179b(%rip), %eax     # 0x19c468
cltq
leaq (%rax,%rax,2), %rax
leaq 0xa178e(%rip), %rdx     # 0x19c468
movq 0x20(%rdx,%rax,8), %rcx
movq 0x18(%rdx,%rax,8), %rdx
andq %r15, %rdx
shlq $0x4, %rdx
leaq (%rcx,%rdx), %rax
movq (%rcx,%rdx), %rdx
movl $0x8, %ecx
cmpq %r15, %rdx
je 0xfad27
movq 0x10(%rax), %rdx
movl $0x18, %ecx
cmpq %r15, %rdx
je 0xfad27
movq 0x20(%rax), %rdx
movl $0x28, %ecx
cmpq %r15, %rdx
je 0xfad27
movq 0x30(%rax), %rdx
movl $0x38, %ecx
cmpq %r15, %rdx
jne 0xfad30
movq (%rax,%rcx), %rbx
testq %rbx, %rbx
jne 0xfad57
movabsq $0x782b96602f424981, %rdi # imm = 0x782B96602F424981
movq %r15, %rsi
callq 0xe9bc5
movq %rax, %rbx
leaq 0xa171c(%rip), %rdi     # 0x19c468
movq %r15, %rsi
movq %rax, %rdx
callq 0x115fac
movq %rbx, %rdi
movq %rbp, %rsi
callq *0xb8(%rbx)
movq 0x8(%r13), %rax
incq %r14
cmpq %rax, %r14
jb 0xfacb2
jmp 0xfb0a9
movq (%r13), %rsi
testq %rsi, %rsi
je 0xfaa79
movq 0x20(%rax), %rdi
callq *0xb8(%rdi)
jmp 0xfaa79
movq (%r13), %rbp
testq %rbp, %rbp
je 0xfaa79
movq 0x8(%r13), %r13
movl 0xa16bd(%rip), %eax     # 0x19c468
cltq
leaq (%rax,%rax,2), %rax
leaq 0xa16b0(%rip), %rdx     # 0x19c468
movq 0x20(%rdx,%rax,8), %rcx
movq 0x18(%rdx,%rax,8), %rdx
andq %r13, %rdx
shlq $0x4, %rdx
leaq (%rcx,%rdx), %rax
movq (%rcx,%rdx), %rdx
movl $0x8, %ecx
cmpq %r13, %rdx
je 0xfae05
movq 0x10(%rax), %rdx
movl $0x18, %ecx
cmpq %r13, %rdx
je 0xfae05
movq 0x20(%rax), %rdx
movl $0x28, %ecx
cmpq %r13, %rdx
je 0xfae05
movq 0x30(%rax), %rdx
movl $0x38, %ecx
cmpq %r13, %rdx
jne 0xfae0e
movq (%rax,%rcx), %r15
testq %r15, %r15
jne 0xfae35
movabsq $0x782b96602f424981, %rdi # imm = 0x782B96602F424981
movq %r13, %rsi
callq 0xe9bc5
movq %rax, %r15
leaq 0xa163e(%rip), %rdi     # 0x19c468
movq %r13, %rsi
movq %rax, %rdx
callq 0x115fac
movq %r15, %rdi
movq %rbp, %rsi
callq *0xb8(%r15)
jmp 0xfaa79
cmpq $0x0, 0x10(%r13)
je 0xfaa79
cmpq $0x0, 0x8(%r13)
je 0xfb0a9
movq 0x20(%rax), %r15
xorl %ebx, %ebx
movq (%r13), %rax
movq (%rax,%rbx,8), %rsi
movq %r15, %rdi
callq *0xb8(%r15)
incq %rbx
cmpq 0x8(%r13), %rbx
jb 0xfae63
jmp 0xfb0a9
cmpq $0x0, 0x10(%r13)
je 0xfaa79
movq 0x20(%rax), %rsi
cmpb $0x0, 0x2a(%rsi)
jne 0xfb0a9
movq 0x18(%rsi), %r8
movq 0x88(%rsi), %rdi
movq (%r13), %rdx
movq 0x8(%r13), %rcx
jmp 0xfafa2
callq 0xbf808
leaq 0x4f96d(%rip), %rdi     # 0x14a82d
leaq 0x4f2f7(%rip), %rsi     # 0x14a1be
movl $0x237, %edx            # imm = 0x237
leaq 0x4f93e(%rip), %rcx     # 0x14a811
movq %rax, %r8
xorl %eax, %eax
callq 0xbe6f9
jmp 0xfaa79
cmpq $0x0, 0x10(%r13)
je 0xfaa79
movq 0x18(%r13), %rbp
movl 0xa1571(%rip), %eax     # 0x19c468
cltq
leaq (%rax,%rax,2), %rax
leaq 0xa1564(%rip), %rdx     # 0x19c468
movq 0x20(%rdx,%rax,8), %rcx
movq 0x18(%rdx,%rax,8), %rdx
andq %rbp, %rdx
shlq $0x4, %rdx
leaq (%rcx,%rdx), %rax
movq (%rcx,%rdx), %rdx
movl $0x8, %ecx
cmpq %rbp, %rdx
je 0xfaf51
movq 0x10(%rax), %rdx
movl $0x18, %ecx
cmpq %rbp, %rdx
je 0xfaf51
movq 0x20(%rax), %rdx
movl $0x28, %ecx
cmpq %rbp, %rdx
je 0xfaf51
movq 0x30(%rax), %rdx
movl $0x38, %ecx
cmpq %rbp, %rdx
jne 0xfaf5a
movq (%rax,%rcx), %r15
testq %r15, %r15
jne 0xfaf81
movabsq $0x782b96602f424981, %rdi # imm = 0x782B96602F424981
movq %rbp, %rsi
callq 0xe9bc5
movq %rax, %r15
leaq 0xa14f2(%rip), %rdi     # 0x19c468
movq %rbp, %rsi
movq %rax, %rdx
callq 0x115fac
cmpb $0x0, 0x2a(%r15)
jne 0xfb0a9
movq 0x18(%r15), %r8
movq 0x88(%r15), %rdi
movq (%r13), %rdx
movq 0x8(%r13), %rcx
movq %r15, %rsi
callq 0xbe7fd
jmp 0xfb0b2
movq 0x20(%rax), %r15
cmpb $0x0, 0x2a(%r15)
jne 0xfaa79
movq 0x18(%rcx), %rbx
testq %rbx, %rbx
je 0xfaa79
movq 0x18(%r15), %r14
movq %r15, %rdi
movq %r13, %rsi
callq *0x88(%r15)
addq %r14, %r13
decq %rbx
jne 0xfafcc
jmp 0xfaa79
cmpq $0x0, 0x10(%r13)
je 0xfaa79
movq 0x18(%r13), %rbp
movl 0xa146d(%rip), %eax     # 0x19c468
cltq
leaq (%rax,%rax,2), %rax
leaq 0xa1460(%rip), %rdx     # 0x19c468
movq 0x20(%rdx,%rax,8), %rcx
movq 0x18(%rdx,%rax,8), %rdx
andq %rbp, %rdx
shlq $0x4, %rdx
leaq (%rcx,%rdx), %rax
movq (%rcx,%rdx), %rdx
movl $0x8, %ecx
cmpq %rbp, %rdx
je 0xfb055
movq 0x10(%rax), %rdx
movl $0x18, %ecx
cmpq %rbp, %rdx
je 0xfb055
movq 0x20(%rax), %rdx
movl $0x28, %ecx
cmpq %rbp, %rdx
je 0xfb055
movq 0x30(%rax), %rdx
movl $0x38, %ecx
cmpq %rbp, %rdx
jne 0xfb05e
movq (%rax,%rcx), %r15
testq %r15, %r15
jne 0xfb085
movabsq $0x782b96602f424981, %rdi # imm = 0x782B96602F424981
movq %rbp, %rsi
callq 0xe9bc5
movq %rax, %r15
leaq 0xa13ee(%rip), %rdi     # 0x19c468
movq %rbp, %rsi
movq %rax, %rdx
callq 0x115fac
cmpq $0x0, 0x8(%r13)
je 0xfb0a9
xorl %ebx, %ebx
movq (%r13), %rax
movq (%rax,%rbx,8), %rsi
movq %r15, %rdi
callq *0xb8(%r15)
incq %rbx
cmpq 0x8(%r13), %rbx
jb 0xfb08e
movq (%r13), %rdi
callq 0xbe7a3
xorl %eax, %eax
movq %rax, (%r13)
movq %rax, 0x10(%r13)
jmp 0xfaa79
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq