// File: /workspace/github_c_makefile_star2_O3/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 0xd6eff(%rip), %rdi     # 0x19bda8
addq $0x8, %rdi
callq 0x1142c9
movq 0xd6eef(%rip), %rax     # 0x19bda8
movq (%rax), %rdi
movq %rbx, %rsi
callq 0xc7708
movq %rax, %r14
movq 0xd6eda(%rip), %rdi     # 0x19bda8
addq $0x8, %rdi
callq 0x1142fb
testq %r14, %r14
je 0xc4eee
movq (%r14), %r14
movq %r14, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
movq 0xd6ebb(%rip), %rdi     # 0x19bdb0
addq $0x8, %rdi
callq 0x1142c9
movq 0xd6eab(%rip), %rax     # 0x19bdb0
movq (%rax), %rdi
movq %rbx, %rsi
callq 0xc77b7
movq %rax, %r14
movq 0xd6e96(%rip), %rdi     # 0x19bdb0
addq $0x8, %rdi
callq 0x1142fb
testq %r14, %r14
je 0xc4ffe
callq *(%r14)
movq %rax, %r14
movq 0x8(%rax), %rdi
cmpq %rbx, %rdi
je 0xc4f87
callq 0xd6ec4
movq %rax, %r15
testq %rax, %rax
leaq 0x837c8(%rip), %r12     # 0x148715
cmoveq %r12, %r15
movq %rbx, %rdi
callq 0xd6ec4
testq %rax, %rax
cmovneq %rax, %r12
leaq 0x7eea1(%rip), %rdi     # 0x143e08
leaq 0x7e6c0(%rip), %rsi     # 0x14362e
leaq 0x7eeaa(%rip), %rcx     # 0x143e1f
movl $0x8fd, %edx            # imm = 0x8FD
movq %r15, %r8
movq %r12, %r9
xorl %eax, %eax
callq 0xbe592
movq %r14, %rdi
callq 0xc4ac0
movq 0xd6e12(%rip), %rdi     # 0x19bda8
addq $0x8, %rdi
callq 0x1142c9
movq 0x8(%r14), %rdi
movq 0x10(%r14), %rsi
callq 0x1168a7
movq 0xd6df5(%rip), %rax     # 0x19bda8
movq (%rax), %rdi
movq %rbx, %rsi
callq 0xc8069
movq 0xd6de3(%rip), %rcx     # 0x19bda8
movq (%rcx), %rdi
movq %rbx, %rsi
testb %al, %al
je 0xc5006
callq 0xc7708
movq (%rax), %rbx
movq 0xd6dca(%rip), %rdi     # 0x19bda8
addq $0x8, %rdi
callq 0x1142fb
leaq -0x1ddd(%rip), %rdi     # 0xc3211
movq %r14, %rsi
callq 0xbe7ee
movq %rbx, %r14
jmp 0xc4edf
xorl %r14d, %r14d
jmp 0xc4edf
movq %r14, %rdx
movl $0x1, %ecx
callq 0xc77e4
movq 0xd6d8e(%rip), %rdi     # 0x19bda8
addq $0x8, %rdi
callq 0x1142fb
jmp 0xc4edf