// File: /workspace/github_c_makefile_star2_O2/vtereshkov[P]umka-lang/src/umka_stmt.c
// Function: doResolveExtern
void doResolveExtern(Compiler *comp)
{
    for (const Ident *ident = comp->idents.first; ident; ident = ident->next)
        if (ident->module == comp->blocks.module)
        {
            if (ident->prototypeOffset >= 0)
            {
                External *external = externalFind(&comp->externals, ident->name);

                // Try to find the function in the external function list or in an external implementation library
                void *fn = NULL;
                if (external)
                {
                    if (external->resolved)
                        comp->error.handler(comp->error.context, "External %s is already resolved", ident->name);

                    if (!comp->lex.hasSourceString || (external->resolveInTrusted && !comp->lex.trusted))
                        comp->error.handler(comp->error.context, "Cannot resolve %s in this module", ident->name);

                    fn = external->entry;
                    external->resolved = true;
                }
                else
                    fn = moduleGetImplLibFunc(comp->modules.module[comp->blocks.module], ident->name);

                if (!fn)
                    comp->error.handler(comp->error.context, "Unresolved prototype of %s", ident->name);

                blocksEnterFn(&comp->blocks, ident, false);
                genEntryPoint(&comp->gen, ident->prototypeOffset);
                genEnterFrameStub(&comp->gen);

                // All parameters must be declared since they may require garbage collection
                for (int i = 0; i < ident->type->sig.numParams; i++)
                    identAllocParam(&comp->idents, &comp->types, &comp->modules, &comp->blocks, &ident->type->sig, i);

                genCallExtern(&comp->gen, fn);

                doGarbageCollection(comp);
                identWarnIfUnusedAll(&comp->idents, blocksCurrent(&comp->blocks));
                identFree(&comp->idents, blocksCurrent(&comp->blocks));

                const ParamLayout *paramLayout = typeMakeParamLayout(&comp->types, &ident->type->sig);

                genLeaveFrameFixup(&comp->gen, typeMakeParamAndLocalVarLayout(&comp->types, paramLayout, 0));
                genReturn(&comp->gen, paramLayout->numParamSlots);

                blocksLeave(&comp->blocks);
            }

            identWarnIfUnused(&comp->idents, ident);
        }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
leaq 0x4e38(%rdi), %rbp
leaq 0x4220(%rdi), %r15
leaq 0x4b98(%rdi), %rax
movq %rax, 0x20(%rsp)
leaq 0x100(%rdi), %r13
leaq 0x4e70(%rdi), %rax
movq %rax, 0x18(%rsp)
movq %rdi, 0x8(%rsp)
leaq 0x4e18(%rdi), %r12
movq %rbp, %r14
movq (%r14), %r14
testq %r14, %r14
je 0x12796
movl 0x110(%r14), %eax
movq 0x8(%rsp), %rcx
cmpl 0x4b88(%rcx), %eax
jne 0x1278a
cmpl $0x0, 0x11c(%r14)
js 0x1277f
leaq 0x4(%r14), %rbx
movq 0x20(%rsp), %rdi
movq %rbx, %rsi
callq 0x4be4
testq %rax, %rax
je 0x12660
movq %rax, %rcx
movq %rbx, 0x10(%rsp)
cmpb $0x1, 0x110(%rax)
jne 0x12600
movq %rcx, %rbx
movq 0x8(%rsp), %rcx
movq 0x5118(%rcx), %rdi
leaq 0x59040(%rip), %rsi     # 0x6b630
movq 0x10(%rsp), %rdx
xorl %eax, %eax
callq *0x50f8(%rcx)
movq %rbx, %rcx
movq 0x8(%rsp), %rax
cmpb $0x1, 0x4bb0(%rax)
jne 0x12625
cmpb $0x1, 0x111(%rcx)
jne 0x1264b
movq 0x8(%rsp), %rax
cmpb $0x0, 0x4bb1(%rax)
jne 0x1264b
movq %rcx, %rbx
movq 0x8(%rsp), %rcx
movq 0x5118(%rcx), %rdi
leaq 0x59015(%rip), %rsi     # 0x6b650
movq 0x10(%rsp), %rdx
xorl %eax, %eax
callq *0x50f8(%rcx)
movq %rbx, %rcx
movq 0x108(%rcx), %rax
movb $0x1, 0x110(%rcx)
movq 0x10(%rsp), %rbx
jmp 0x1267c
movq 0x8(%rsp), %rcx
movslq 0x4b88(%rcx), %rax
movq 0x100(%rcx,%rax,8), %rdi
movq %rbx, %rsi
callq 0x4996
movq %rax, 0x10(%rsp)
testq %rax, %rax
jne 0x126a4
movq 0x8(%rsp), %rcx
movq 0x5118(%rcx), %rdi
leaq 0x58fd8(%rip), %rsi     # 0x6b671
movq %rbx, %rdx
xorl %eax, %eax
callq *0x50f8(%rcx)
xorl %ebx, %ebx
movq %r15, %rdi
movq %r14, %rsi
xorl %edx, %edx
callq 0x4b1c
movl 0x11c(%r14), %esi
movq 0x18(%rsp), %rdi
callq 0xfd33
movq 0x18(%rsp), %rdi
callq 0xfceb
movq 0x108(%r14), %r8
cmpl 0x28(%r8), %ebx
jge 0x126f7
addq $0x28, %r8
movq %rbp, %rdi
movq %r12, %rsi
movq %r13, %rdx
movq %r15, %rcx
movl %ebx, %r9d
callq 0x10b4f
incl %ebx
jmp 0x126ce
movq 0x18(%rsp), %rbx
movq %rbx, %rdi
movq 0x10(%rsp), %rsi
callq 0xf704
movq 0x8(%rsp), %rdi
callq 0x12350
movq %r15, %rdi
callq 0x4bcc
movq %rbp, %rdi
movl %eax, %esi
callq 0x10c75
movq %r15, %rdi
callq 0x4bcc
movq %rbp, %rdi
movl %eax, %esi
callq 0x1018b
movq 0x108(%r14), %rsi
addq $0x28, %rsi
movq %r12, %rdi
callq 0x15f55
movq %rax, 0x10(%rsp)
movq %r12, %rdi
movq %rax, %rsi
xorl %edx, %edx
callq 0x15ff7
movq %rbx, %rdi
movq %rax, %rsi
callq 0xfcfd
movq 0x10(%rsp), %rax
movl 0x10(%rax), %esi
movq %rbx, %rdi
callq 0xf937
movq %r15, %rdi
callq 0x4b91
movq %rbp, %rdi
movq %r14, %rsi
callq 0x10c21
addq $0x140, %r14            # imm = 0x140
jmp 0x1257d
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq