// File: /workspace/github_c_makefile_star2_O2/johsteffens[P]beth/lib/bcore/bcore_spect_via.c
// Function: bcore_via_s_create_from_self
static bcore_via_s* bcore_via_s_create_from_self( const bcore_self_s* self )
{
    assert( self != NULL );

    bcore_via_s* o = bcore_inst_t_create( entypeof( "bcore_via_s" ) );
    o->header.p_type  = typeof( "bcore_via_s" );
    o->header.o_type  = self->type;
    o->is_leaf = bcore_type_is_leaf( self->type );

    const bcore_inst_s* inst_p = bcore_inst_s_get_typed( self->type );
    o->inst_p = inst_p;
    o->via_call_p = bcore_via_call_spect_s_get_typed( self->type );

    o->vitem_arr = NULL;
    uz_t vitem_arr_size  = 0;
    uz_t vitem_arr_space = 0;

    uz_t items_size = bcore_self_s_items_size( self );
    for( uz_t i = 0; i < items_size; i++ )
    {
        const bcore_self_item_s* self_item = bcore_self_s_get_item( self, i );

        if( self_item->flags.f_hidden ) continue; // hidden items are not accessible in via
        if( self_item->flags.f_const  ) continue; // constants are not accessible in via

        // self-aware type is not directly accessible in via but can be queried from flag 'is_aware'
        if( i == 0 && self_item->type == TYPEOF_aware_t )
        {
            o->is_aware = true;
            continue;
        }

        const bcore_inst_item_s* inst_item = bcore_inst_s_get_item_from_self_item( inst_p, self_item );

        if( inst_item && inst_item->no_trace ) continue; // instance no-trace items (private, external, ...) are not accessible in via

        bcore_vitem_s vitem;
        bcore_memzero( &vitem, sizeof( bcore_vitem_s ) );
        vitem.name = self_item->name;
        vitem.caps = self_item->caps;
        vitem.offs = inst_item ? inst_item->offset : 0;
        vitem.flags = self_item->flags;

        switch( vitem.caps )
        {
            case BCORE_CAPS_SOLID_STATIC:
            case BCORE_CAPS_LINK_STATIC:
            {
                vitem.type = self_item->type;
            }
            break;

            case BCORE_CAPS_LINK_TYPED:
            case BCORE_CAPS_LINK_AWARE:
                vitem.type = 0;
                break;

            case BCORE_CAPS_ARRAY_DYN_SOLID_STATIC:
                vitem.type = bcore_array_dyn_solid_static_type_of( self_item->type );
                break;

            case BCORE_CAPS_ARRAY_DYN_SOLID_TYPED:
                vitem.type = typeof( "bcore_array_dyn_solid_typed_s" );
                break;

            case BCORE_CAPS_ARRAY_DYN_LINK_STATIC:
                vitem.type = bcore_array_dyn_link_static_type_of( self_item->type );
                break;

            case BCORE_CAPS_ARRAY_DYN_LINK_TYPED:
                vitem.type = typeof( "bcore_array_dyn_link_typed_s" );
                break;

            case BCORE_CAPS_ARRAY_DYN_LINK_AWARE:
                vitem.type = typeof( "bcore_array_dyn_link_aware_s" );
                break;

            case BCORE_CAPS_ARRAY_FIX_SOLID_STATIC:
                vitem.type = bcore_array_fix_solid_static_type_of( self_item->type, self_item->array_fix_size );
                break;

            case BCORE_CAPS_ARRAY_FIX_LINK_STATIC:
                vitem.type = bcore_array_fix_link_static_type_of( self_item->type, self_item->array_fix_size );
                break;

            case BCORE_CAPS_ARRAY_FIX_LINK_AWARE:
                vitem.type = bcore_array_fix_link_aware_type_of( self_item->array_fix_size );
                break;

            case BCORE_CAPS_EXTERNAL_FUNC:
                continue; // external items are (currently) not accessible in via
                break;

            default:
                ERR( "Unexpected caps '%s'", bcore_flect_caps_e_sc( vitem.caps ) );
                break;
        }

        if( vitem.type )
        {
            if( vitem.type == o->header.o_type )
            {
                vitem.via_p = o;
            }
            else
            {
                vitem.via_p = bcore_via_s_get_typed( vitem.type );
            }
        }

        // explicit setter, getter
        {

            bcore_life_s* l = bcore_life_s_create();
            vitem.fp_get = ( bcore_fp_get )bcore_self_s_try_external_fp( self, typeof( "bcore_fp_get" ), typeof( st_s_createf_l( l, "get_%s", ifnameof( vitem.name ) )->sc ) );
            vitem.fp_set = ( bcore_fp_set )bcore_self_s_try_external_fp( self, typeof( "bcore_fp_set" ), typeof( st_s_createf_l( l, "set_%s", ifnameof( vitem.name ) )->sc ) );
            if( vitem.flags.f_shell )
            {
                if( !vitem.fp_get ) ERR( "Object '%s' has shell '%s' but no function 'get_%s'.", ifnameof( o->header.o_type ), ifnameof( vitem.name ), ifnameof( vitem.name ) );
                if( !vitem.fp_set ) ERR( "Object '%s' has shell '%s' but no function 'set_%s'.", ifnameof( o->header.o_type ), ifnameof( vitem.name ), ifnameof( vitem.name ) );
            }
            bcore_life_s_discard( l );
        }

        if( vitem_arr_size == vitem_arr_space )
        {
            o->vitem_arr = bcore_un_alloc( sizeof( bcore_vitem_s ), o->vitem_arr, vitem_arr_space, vitem_arr_space > 0 ? vitem_arr_space * 2 : 1, &vitem_arr_space );
        }
        o->vitem_arr[ vitem_arr_size++ ] = vitem;
    }

    o->size = vitem_arr_size;

    return o;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %rdi, %rbx
leaq 0x386de(%rip), %rdi     # 0xc4e8a
callq 0x7227a
testq %rax, %rax
je 0x8c7cc
movq %rax, %rdi
callq 0x8a9c0
movq %rax, %rdi
callq *0xa8(%rax)
movq %rax, %r14
jmp 0x8c7cf
xorl %r14d, %r14d
leaq 0x386b4(%rip), %rdi     # 0xc4e8a
callq 0x8bb9f
movq %rax, (%r14)
movq 0x8(%rbx), %rdi
movq %rdi, 0x8(%r14)
callq 0x73359
movb %al, 0x28(%r14)
movq 0x8(%rbx), %rdi
callq 0x8a9c0
movq %rax, 0x60(%rsp)
movq %rax, 0x10(%r14)
movq 0x8(%rbx), %r15
leaq 0x874a4(%rip), %rdi     # 0x113cb0
movq %r15, %rsi
callq 0x8cbda
movq %r14, %r13
movq %rax, %r14
testq %rax, %rax
jne 0x8c846
movabsq $-0x220988275314685e, %rdi # imm = 0xDDF677D8ACEB97A2
movq %r15, %rsi
callq 0x79b94
movq %rax, %r14
leaq 0x87475(%rip), %rdi     # 0x113cb0
movq %r15, %rsi
movq %rax, %rdx
callq 0x98d4b
movq %r14, 0x18(%r13)
andq $0x0, 0x30(%r13)
leaq 0x58(%rsp), %rax
andq $0x0, (%rax)
movq %rbx, %rdi
callq 0x6389b
xorl %r12d, %r12d
xorl %ebp, %ebp
movq %r13, %r14
movq %rax, %r13
movq %rax, 0x10(%rsp)
cmpq %r12, %r13
je 0x8cbc4
movq %rbx, %rdi
movq %r12, %rsi
callq 0x638ac
testb $0x14, 0x14(%rax)
jne 0x8cbbc
movq %rax, %r15
testq %r12, %r12
jne 0x8c8af
movabsq $-0x388c46b188de83fe, %rax # imm = 0xC773B94E77217C02
cmpq %rax, (%r15)
jne 0x8c8af
movb $0x1, 0x29(%r14)
jmp 0x8cbbc
movq %r14, %r13
movq 0x60(%rsp), %rdi
movq %r15, %rsi
callq 0x833ca
movq %rax, %r14
testq %rax, %rax
je 0x8c8db
cmpb $0x0, 0x28(%r14)
je 0x8c8db
movq %r13, %r14
movq 0x10(%rsp), %r13
jmp 0x8cbbc
leaq 0x18(%rsp), %rdi
pushq $0x38
popq %rsi
callq 0x6028b
movq 0x8(%r15), %rax
movq %rax, 0x20(%rsp)
movl 0x10(%r15), %edi
movl %edi, 0x28(%rsp)
testq %r14, %r14
je 0x8c903
movq (%r14), %rax
jmp 0x8c905
xorl %eax, %eax
movq %r13, %r14
movq %rax, 0x30(%rsp)
movl 0x14(%r15), %eax
movl %eax, 0x2c(%rsp)
leal -0x1(%rdi), %eax
cmpl $0xd, %eax
ja 0x8c97f
leaq 0x3ccb8(%rip), %rcx     # 0xc95dc
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq (%r15), %rax
jmp 0x8c9c9
andq $0x0, 0x18(%rsp)
jmp 0x8c9ed
movq (%r15), %rdi
movq 0x18(%r15), %rsi
callq 0x7c936
jmp 0x8c9c9
movq (%r15), %rdi
callq 0x7c909
jmp 0x8c9c9
leaq 0x3563a(%rip), %rdi     # 0xc1f99
jmp 0x8c9c4
movq 0x18(%r15), %rdi
callq 0x7c945
jmp 0x8c9c9
movq (%r15), %rdi
callq 0x7c918
jmp 0x8c9c9
leaq 0x35658(%rip), %rdi     # 0xc1fd5
jmp 0x8c9c4
callq 0x610e5
leaq 0x3d024(%rip), %rdi     # 0xc99af
leaq 0x3ccad(%rip), %rsi     # 0xc963f
movl $0x268, %edx            # imm = 0x268
leaq 0x3d15c(%rip), %rcx     # 0xc9afa
movq %rax, %r8
xorl %eax, %eax
callq 0x60031
movq 0x18(%rsp), %rax
jmp 0x8c9ce
movq (%r15), %rdi
movq 0x18(%r15), %rsi
callq 0x7c927
jmp 0x8c9c9
leaq 0x3562e(%rip), %rdi     # 0xc1ff2
callq 0x8bb9f
movq %rax, 0x18(%rsp)
testq %rax, %rax
je 0x8c9ed
cmpq 0x8(%r14), %rax
jne 0x8c9e0
movq %r14, 0x38(%rsp)
jmp 0x8c9ed
movq %rax, %rdi
callq 0x8cc32
movq %rax, 0x38(%rsp)
xorl %eax, %eax
callq 0x717ac
movq %rax, %r15
leaq 0x34f29(%rip), %rdi     # 0xc1927
callq 0x8bb9f
movq %rax, %r14
movq 0x20(%rsp), %rdi
callq 0x8aa10
movq %r15, %rdi
leaq 0x3d0f5(%rip), %rsi     # 0xc9b0f
movq %rax, %rdx
xorl %eax, %eax
callq 0x8ede9
movq 0x8(%rax), %rdi
callq 0x8bb9f
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rdx
callq 0x6449c
movq %rax, 0x40(%rsp)
leaq 0x34ed3(%rip), %rdi     # 0xc191a
callq 0x8bb9f
movq %rax, %r14
movq 0x20(%rsp), %rdi
callq 0x8aa10
movq %r15, %rdi
leaq 0x3d0b3(%rip), %rsi     # 0xc9b16
movq %rax, %rdx
xorl %eax, %eax
callq 0x8ede9
movq 0x8(%rax), %rdi
callq 0x8bb9f
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rdx
callq 0x6449c
movq %rax, 0x48(%rsp)
testb $0x2, 0x2c(%rsp)
je 0x8cb4a
cmpq $0x0, 0x40(%rsp)
jne 0x8caf3
movq 0x8(%r13), %rdi
callq 0x8aa10
movq %rax, 0x50(%rsp)
movq 0x20(%rsp), %rdi
callq 0x8aa10
movq %rax, %r14
movq 0x20(%rsp), %rdi
callq 0x8aa10
movq %rax, (%rsp)
leaq 0x3cee3(%rip), %rdi     # 0xc99af
leaq 0x3cb6c(%rip), %rsi     # 0xc963f
movl $0x280, %edx            # imm = 0x280
leaq 0x3d03e(%rip), %rcx     # 0xc9b1d
movq 0x50(%rsp), %r8
movq %r14, %r9
xorl %eax, %eax
callq 0x60031
movq 0x48(%rsp), %rax
testq %rax, %rax
jne 0x8cb4a
movq 0x8(%r13), %rdi
callq 0x8aa10
movq %rax, 0x50(%rsp)
movq 0x20(%rsp), %rdi
callq 0x8aa10
movq %rax, %r14
movq 0x20(%rsp), %rdi
callq 0x8aa10
movq %rax, (%rsp)
leaq 0x3ce87(%rip), %rdi     # 0xc99af
leaq 0x3cb10(%rip), %rsi     # 0xc963f
movl $0x281, %edx            # imm = 0x281
leaq 0x3d017(%rip), %rcx     # 0xc9b52
movq 0x50(%rsp), %r8
movq %r14, %r9
xorl %eax, %eax
callq 0x60031
movq %r15, %rdi
callq 0x717c7
movq %r13, %r14
movq 0x30(%r13), %rax
cmpq 0x58(%rsp), %rbp
jne 0x8cb89
leaq (,%rbp,2), %rcx
testq %rbp, %rbp
pushq $0x1
popq %rdx
cmoveq %rdx, %rcx
pushq $0x38
popq %rdi
movq %rax, %rsi
movq %rbp, %rdx
leaq 0x58(%rsp), %r8
callq 0x60263
movq %rax, 0x30(%r14)
movq 0x10(%rsp), %r13
imulq $0x38, %rbp, %rcx
incq %rbp
movq 0x48(%rsp), %rdx
movq %rdx, 0x30(%rax,%rcx)
movups 0x18(%rsp), %xmm0
movups 0x28(%rsp), %xmm1
movups 0x38(%rsp), %xmm2
movups %xmm2, 0x20(%rax,%rcx)
movups %xmm1, 0x10(%rax,%rcx)
movups %xmm0, (%rax,%rcx)
incq %r12
jmp 0x8c870
movq %rbp, 0x20(%r14)
movq %r14, %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq