// File: /workspace/github_c_makefile_star2_O2/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 %rbx
movq %rdi, %rbx
movq 0xb3266(%rip), %rdi     # 0x117da8
addq $0x8, %rdi
callq 0x97ae2
movq 0xb3256(%rip), %rax     # 0x117da8
movq (%rax), %rdi
movq %rbx, %rsi
callq 0x66b16
movq %rax, %r14
movq 0xb3241(%rip), %rdi     # 0x117da8
addq $0x8, %rdi
callq 0x97b12
testq %r14, %r14
je 0x64b81
movq (%r14), %rbx
movq %rbx, %rax
popq %rbx
popq %r14
popq %r15
retq
movq 0xb3228(%rip), %rdi     # 0x117db0
addq $0x8, %rdi
callq 0x97ae2
movq 0xb3218(%rip), %rax     # 0x117db0
movq (%rax), %rdi
movq %rbx, %rsi
callq 0x66bc4
movq %rax, %r14
movq 0xb3203(%rip), %rdi     # 0x117db0
addq $0x8, %rdi
callq 0x97b12
testq %r14, %r14
je 0x64c52
callq *(%r14)
movq %rax, %r14
movq 0x8(%rax), %rdi
cmpq %rbx, %rdi
je 0x64c05
callq 0x6133a
movq %rax, %r15
movq %rbx, %rdi
callq 0x6133a
leaq 0x5cfb3(%rip), %rdi     # 0xc1b98
leaq 0x5c7d2(%rip), %rsi     # 0xc13be
leaq 0x5cfbc(%rip), %rcx     # 0xc1baf
movl $0x8fd, %edx            # imm = 0x8FD
movq %r15, %r8
movq %rax, %r9
xorl %eax, %eax
callq 0x60031
movq %r14, %rdi
callq 0x64785
movq 0xb3194(%rip), %rdi     # 0x117da8
addq $0x8, %rdi
callq 0x97ae2
movq %r14, %rdi
callq 0x64c93
movq 0xb317c(%rip), %rax     # 0x117da8
movq (%rax), %rdi
movq %rbx, %rsi
callq 0x6721a
movq 0xb316a(%rip), %rcx     # 0x117da8
movq (%rcx), %rdi
testb %al, %al
je 0x64c59
movq %rbx, %rsi
callq 0x66b16
movq (%rax), %rbx
jmp 0x64c6d
xorl %ebx, %ebx
jmp 0x64b78
pushq $0x1
popq %rcx
movq %rbx, %rsi
movq %r14, %rdx
callq 0x66bf0
movq %r14, %rbx
xorl %r14d, %r14d
movq 0xb3134(%rip), %rdi     # 0x117da8
addq $0x8, %rdi
callq 0x97b12
testq %r14, %r14
je 0x64b78
movq %r14, %rdi
callq 0x63886
jmp 0x64b78