// File: /workspace/github_c_makefile_star2_O1/johsteffens[P]beth/lib/bcore/bcore_flect.c
// Function: bcore_flect_try_d_self
bcore_self_s* bcore_flect_try_d_self( tp_t type )
{
    // try reflection registry
    assert( self_map_s_g != NULL );
    bcore_mutex_s_lock( &self_map_s_g->mutex );
    vd_t* p_val = bcore_hmap_u3vd_s_get( self_map_s_g->hmap, type );
    bcore_mutex_s_unlock( &self_map_s_g->mutex );
    if( p_val ) return *p_val;

    // try constructing self by reflection creator
    bcore_self_s* self = NULL;
    assert( creator_map_s_g != NULL );

    bcore_mutex_s_lock( &creator_map_s_g->mutex );
    fp_t* p_func = bcore_hmap_u3vd_s_getf( creator_map_s_g->hmap, type );
    bcore_mutex_s_unlock( &creator_map_s_g->mutex );

    if( p_func )
    {
        self = ( ( bcore_flect_create_self_fp )*p_func )();
        bcore_self_s* discard_self = NULL; // in case multiple threads land here, redundant creations are discarded again

        if( self->type != type )
        {
            ERR( "Type of created reflection '%s' differs from requested type '%s'.\n"
                 "Requested type was probably mapped to the wrong self-creator during registration.\n",
                 ifnameof( self->type ), ifnameof( type ) );
        }

        bcore_self_s_check_integrity( self );

        bcore_mutex_s_lock( &self_map_s_g->mutex );
        bcore_flect_set_trait( self );

        if( bcore_hmap_u3vd_s_exists( self_map_s_g->hmap, type ) )
        {
            // If this reflection has meanwhile been registered by another thread,
            // kill current self and retrieve registered version
            discard_self = self;
            self = *bcore_hmap_u3vd_s_get( self_map_s_g->hmap, type );
        }
        else
        {
            // else: register current self
            bcore_hmap_u3vd_s_set( self_map_s_g->hmap, type, self, true );
        }
        bcore_mutex_s_unlock( &self_map_s_g->mutex );

        if( discard_self ) bcore_self_s_discard( discard_self );
    }

    return self;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0xd9d7d(%rip), %rdi     # 0x1a8da8
addq $0x8, %rdi
callq 0x11f515
movq 0xd9d6d(%rip), %rax     # 0x1a8da8
movq (%rax), %rdi
movq %rbx, %rsi
callq 0xd192d
movq %rax, %r14
movq 0xd9d58(%rip), %rdi     # 0x1a8da8
addq $0x8, %rdi
callq 0x11f547
testq %r14, %r14
je 0xcf070
movq (%r14), %rbx
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
movq 0xd9d39(%rip), %rdi     # 0x1a8db0
addq $0x8, %rdi
callq 0x11f515
movq 0xd9d29(%rip), %rax     # 0x1a8db0
movq (%rax), %rdi
movq %rbx, %rsi
callq 0xd19f6
movq %rax, %r14
movq 0xd9d14(%rip), %rdi     # 0x1a8db0
addq $0x8, %rdi
callq 0x11f547
testq %r14, %r14
je 0xcf15b
callq *(%r14)
movq %rax, %r14
movq 0x8(%rax), %rdi
cmpq %rbx, %rdi
je 0xcf109
callq 0xe0cbc
movq %rax, %r15
testq %rax, %rax
leaq 0x84620(%rip), %r12     # 0x1536ef
cmoveq %r12, %r15
movq %rbx, %rdi
callq 0xe0cbc
testq %rax, %rax
cmovneq %rax, %r12
leaq 0x7fcdf(%rip), %rdi     # 0x14edc8
leaq 0x7f4fe(%rip), %rsi     # 0x14e5ee
leaq 0x7fce8(%rip), %rcx     # 0x14eddf
movl $0x8fd, %edx            # imm = 0x8FD
movq %r15, %r8
movq %r12, %r9
xorl %eax, %eax
callq 0xc80f6
movq %r14, %rdi
callq 0xcec42
movq 0xd9c90(%rip), %rdi     # 0x1a8da8
addq $0x8, %rdi
callq 0x11f515
movq 0x8(%r14), %rdi
movq 0x10(%r14), %rsi
callq 0x121b6d
movq 0xd9c73(%rip), %rax     # 0x1a8da8
movq (%rax), %rdi
movq %rbx, %rsi
callq 0xd2280
movq 0xd9c61(%rip), %rcx     # 0x1a8da8
movq (%rcx), %rdi
movq %rbx, %rsi
testb %al, %al
je 0xcf162
callq 0xd192d
movq (%rax), %rbx
jmp 0xcf175
xorl %ebx, %ebx
jmp 0xcf061
movq %r14, %rdx
movl $0x1, %ecx
callq 0xd1a23
movq %r14, %rbx
xorl %r14d, %r14d
movq 0xd9c2c(%rip), %rdi     # 0x1a8da8
addq $0x8, %rdi
callq 0x11f547
testq %r14, %r14
je 0xcf061
leaq -0x1e9a(%rip), %rdi     # 0xcd2fb
movq %r14, %rsi
callq 0xc8352
jmp 0xcf061