// File: /workspace/github_c_makefile_star2_O3/meaning-matters[P]Except/Except.c
// Function: ExceptFinally
int ExceptFinally(
    Context *   pC)             /* pointer to thread exception context */
{
    Except *    pEx;
    Except      ex;

    if (pC == NULL)
        pC = ExceptGetContext(NULL);

    ex = *(pEx = LifoPop(pC->exStack));
    free(pEx);
    pC->pEx = LifoCount(pC->exStack) ? LifoPeek(pC->exStack, 1) : NULL;

    if (LifoCount(pC->exStack) == 0)
    {
        /* outermost level - default action */

        int     restored = ExceptRestoreHandlers(pC);

        if (ex.state == PENDING)
        {
            if (ex.class == FailedAssertion)
            {
                AssertAction(pC, DO_ABORT, ex.pData, ex.file, ex.line);
            }
            else if (ExceptIsDerived(ex.class, RuntimeException) && restored)
            {
                LifoDestroy(pC->exStack);
                if (MULTI_THREADING)
                {
                    EXCEPT_THREAD_MUTEX_FUNC(1);
                    free(HashRemove(pContextHash, EXCEPT_THREAD_ID_FUNC()));
                    EXCEPT_THREAD_MUTEX_FUNC(0);
                }
                else
                {
                    pC->exStack = NULL;
                }
             
                raise(ex.class->signalNumber);
            }
            else if (ex.class == ReturnEvent)
            {
                LifoDestroy(pC->exStack);
                if (MULTI_THREADING)
                {
                    EXCEPT_THREAD_MUTEX_FUNC(1);
                    free(HashRemove(pContextHash, EXCEPT_THREAD_ID_FUNC()));
                    EXCEPT_THREAD_MUTEX_FUNC(0);
                }
                else
                {
                    pC->exStack = NULL;
                }
                
                LONGJMP(*(JMP_BUF *)ex.pData, 1);
            }
            else
                fprintf(stderr, "%s lost: file \"%s\", line %d.\n",
                        ex.class->name, ex.file, ex.line);
        }
        LifoDestroy(pC->exStack);
        if (MULTI_THREADING)
        {
            EXCEPT_THREAD_MUTEX_FUNC(1);
            free(HashRemove(pContextHash, EXCEPT_THREAD_ID_FUNC()));
            EXCEPT_THREAD_MUTEX_FUNC(0);
        }
        else
        {
            pC->exStack = NULL;
        }
    }
    else     
    {
        /* inner level - propagate */

        if (ex.state == PENDING)
        {
            if (ex.class == ReturnEvent && ex.first)
            {            
                LONGJMP(*(JMP_BUF *)ex.pData, 1);    /* pData is returnBuf */
            }
            else
            {
                ExceptThrow(pC, ex.class, ex.pData, ex.file, ex.line);
            }
        }
    }
            
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
testq %rdi, %rdi
jne 0x1d53
xorl %edi, %edi
callq 0x1710
movq %rax, %rbx
movq 0x8(%rbx), %rdi
callq 0x22af
movl 0x4(%rax), %r13d
movq 0x198(%rax), %r15
movq 0x1a0(%rax), %rcx
movq %rcx, (%rsp)
movq 0x1a8(%rax), %r12
movl 0x1b0(%rax), %ebp
movl 0x1bc(%rax), %r14d
movq %rax, %rdi
callq 0x1040
movq 0x8(%rbx), %rdi
callq 0x2475
testl %eax, %eax
je 0x1dab
movq 0x8(%rbx), %rdi
movl $0x1, %esi
callq 0x2379
jmp 0x1dad
xorl %eax, %eax
movq %rax, (%rbx)
movq 0x8(%rbx), %rdi
callq 0x2475
testl %eax, %eax
je 0x1df6
cmpl $0x1, %r13d
jne 0x1ecc
leaq 0x5432(%rip), %rax      # 0x7200
cmpq %rax, %r15
jne 0x1ddc
testl %r14d, %r14d
jne 0x1f45
movq %rbx, %rdi
movq %r15, %rsi
movq (%rsp), %rdx
movq %r12, %rcx
movl %ebp, %r8d
callq 0x1af1
jmp 0x1ecc
callq 0x18de
cmpl $0x1, %r13d
jne 0x1e94
leaq 0x5314(%rip), %rcx      # 0x7120
cmpq %rcx, %r15
je 0x1e80
leaq 0x5328(%rip), %rcx      # 0x7140
movq %r15, %rsi
movq %rsi, %rdx
cmpq %rcx, %rsi
je 0x1e2c
movq 0x8(%rdx), %rsi
testq %rsi, %rsi
jne 0x1e1b
cmpq %rcx, %rdx
jne 0x1edd
testl %eax, %eax
je 0x1edd
movq 0x8(%rbx), %rdi
callq 0x2190
movl $0x1, %edi
callq 0x175f
movq 0x53e1(%rip), %r14      # 0x7238
callq 0x10f0
movq %r14, %rdi
movl %eax, %esi
callq 0x2870
movq %rax, %rdi
callq 0x1040
xorl %edi, %edi
callq 0x175f
movl 0x18(%r15), %edi
callq 0x1030
jmp 0x1e94
movq %rbx, %rdi
xorl %esi, %esi
movq (%rsp), %rdx
movq %r12, %rcx
movl %ebp, %r8d
callq 0x24a8
movq 0x8(%rbx), %rdi
callq 0x2190
movl $0x1, %edi
callq 0x175f
movq 0x538a(%rip), %rbx      # 0x7238
callq 0x10f0
movq %rbx, %rdi
movl %eax, %esi
callq 0x2870
movq %rax, %rdi
callq 0x1040
xorl %edi, %edi
callq 0x175f
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x531c(%rip), %rax      # 0x7200
cmpq %rax, %r15
je 0x1f0d
movq 0x5108(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
movq 0x10(%r15), %rdx
leaq 0x2201(%rip), %rsi      # 0x40ff
movq %r12, %rcx
movl %ebp, %r8d
xorl %eax, %eax
callq 0x10a0
jmp 0x1e94
movq 0x8(%rbx), %rdi
callq 0x2190
movl $0x1, %edi
callq 0x175f
movq 0x5311(%rip), %rbx      # 0x7238
callq 0x10f0
movq %rbx, %rdi
movl %eax, %esi
callq 0x2870
movq %rax, %rdi
callq 0x1040
xorl %edi, %edi
callq 0x175f
movq (%rsp), %rdi
movl $0x1, %esi
callq 0x1070