// File: /workspace/github_c_makefile_star2_O2/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 0x1cae
xorl %edi, %edi
callq 0x164c
movq %rax, %rbx
movq 0x8(%rbx), %rdi
callq 0x21f6
movl 0x4(%rax), %r14d
movq 0x198(%rax), %r15
movq 0x1a0(%rax), %rcx
movq %rcx, (%rsp)
movq 0x1a8(%rax), %r12
movl 0x1b0(%rax), %ebp
movl 0x1bc(%rax), %r13d
movq %rax, %rdi
callq 0x1040
movq 0x8(%rbx), %rdi
callq 0x23b8
testl %eax, %eax
je 0x1d04
movq 0x8(%rbx), %rdi
pushq $0x1
popq %rsi
callq 0x22be
jmp 0x1d06
xorl %eax, %eax
movq %rax, (%rbx)
movq 0x8(%rbx), %rdi
callq 0x23b8
testl %eax, %eax
je 0x1d4f
cmpl $0x1, %r14d
jne 0x1e18
leaq 0x54d9(%rip), %rax      # 0x7200
cmpq %rax, %r15
jne 0x1d35
testl %r13d, %r13d
jne 0x1e59
movq %rbx, %rdi
movq %r15, %rsi
movq (%rsp), %rdx
movq %r12, %rcx
movl %ebp, %r8d
callq 0x1a40
jmp 0x1e18
callq 0x1830
cmpl $0x1, %r14d
jne 0x1de2
movl %eax, %r13d
leaq 0x53b8(%rip), %rax      # 0x7120
cmpq %rax, %r15
je 0x1dce
leaq 0x53cc(%rip), %rsi      # 0x7140
movq %r15, %rdi
callq 0x1c77
testl %eax, %eax
je 0x1e29
testl %r13d, %r13d
je 0x1e29
movq 0x8(%rbx), %rdi
callq 0x20de
pushq $0x1
popq %rdi
callq 0x1699
movq 0x5493(%rip), %r14      # 0x7238
callq 0x10f0
movq %r14, %rdi
movl %eax, %esi
callq 0x279f
movq %rax, %rdi
callq 0x1040
xorl %edi, %edi
callq 0x1699
movl 0x18(%r15), %edi
callq 0x1030
jmp 0x1de2
movq %rbx, %rdi
xorl %esi, %esi
movq (%rsp), %rdx
movq %r12, %rcx
movl %ebp, %r8d
callq 0x23ec
movq 0x8(%rbx), %rdi
callq 0x20de
pushq $0x1
popq %rdi
callq 0x1699
movq 0x543e(%rip), %rbx      # 0x7238
callq 0x10f0
movq %rbx, %rdi
movl %eax, %esi
callq 0x279f
movq %rax, %rdi
callq 0x1040
xorl %edi, %edi
callq 0x1699
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x53d0(%rip), %rax      # 0x7200
cmpq %rax, %r15
je 0x1e65
movq 0x51bc(%rip), %rax      # 0x6ff8
movq (%rax), %rdi
movq 0x10(%r15), %rdx
leaq 0x22b5(%rip), %rsi      # 0x40ff
movq %r12, %rcx
movl %ebp, %r8d
xorl %eax, %eax
callq 0x10a0
jmp 0x1de2
pushq $0x1
popq %rsi
movq (%rsp), %rdi
callq 0x1070
movq 0x8(%rbx), %rdi
callq 0x20de
pushq $0x1
popq %rbx
movl %ebx, %edi
callq 0x1699
movq 0x53b9(%rip), %r15      # 0x7238
callq 0x10f0
movq %r15, %rdi
movl %eax, %esi
callq 0x279f
movq %rax, %rdi
callq 0x1040
xorl %edi, %edi
callq 0x1699
movq (%rsp), %rdi
movl %ebx, %esi
callq 0x1070