// File: /workspace/github_c_makefile_star2_O0/naleksiev[P]fin/src/fin_mod.c
// Function: fin_mod_create
fin_mod_t* fin_mod_create(fin_ctx_t* ctx, const char* name, fin_mod_func_desc_t* descs, int32_t descs_count) {
    fin_mod_func_t* funcs = (fin_mod_func_t*)ctx->alloc(NULL, sizeof(fin_mod_func_t) * descs_count);

    fin_mod_t* mod = (fin_mod_t*)ctx->alloc(NULL, sizeof(fin_mod_t));
    mod->name = fin_str_create(ctx, name, -1);
    mod->types = NULL;
    mod->funcs = funcs;
    mod->binds = NULL;
    mod->consts = NULL;
    mod->types_count = 0;
    mod->funcs_count = descs_count;
    mod->binds_count = 0;
    mod->consts_count = 0;
    mod->next = NULL;

    for (int32_t i=0; i<descs_count; i++) {
        funcs[i].mod = mod;
        funcs[i].func = descs[i].func;
        funcs[i].is_native = true;
        funcs[i].code = NULL;
        funcs[i].code_length = 0;
        funcs[i].args = 0;

        // ret_type name "(" arg? ("," arg)* ")"
        fin_lex_t* lex = fin_lex_create(ctx->alloc, descs[i].sign);

        char signature[256];
        signature[0] = '\0';

        if (name != NULL && name[0] != '\0') {
            strcat(signature, name);
            strcat(signature, ".");
        }

        if (fin_lex_match(lex, fin_lex_type_void))
            funcs[i].ret_type = NULL;
        else {
            fin_lex_str_t lex_str = fin_lex_consume_name(lex);
            funcs[i].ret_type = fin_str_create(ctx, lex_str.cstr, lex_str.len);
        }

        fin_lex_consume_name_to(lex, signature + strlen(signature));

        fin_lex_match(lex, fin_lex_type_l_paren);
        strcat(signature, "(");
        while (!fin_lex_match(lex, fin_lex_type_r_paren)) {
            if (funcs[i].args) {
                fin_lex_match(lex, fin_lex_type_comma);
                strcat(signature, ",");
            }
            fin_lex_consume_name_to(lex, signature + strlen(signature));
            funcs[i].args++;
        }
        strcat(signature, ")");
        funcs[i].sign = fin_str_create(ctx, signature, -1);

        fin_lex_destroy(ctx->alloc, lex);
    }

    fin_mod_register(ctx, mod);
    return mod;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x170, %rsp            # imm = 0x170
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
movslq -0x1c(%rbp), %rcx
imulq $0x38, %rcx, %rcx
movl %ecx, %esi
xorl %ecx, %ecx
movl %ecx, %edi
callq *%rax
movq %rax, -0x28(%rbp)
movq -0x8(%rbp), %rax
xorl %ecx, %ecx
movl %ecx, %edi
movl $0x48, %esi
callq *(%rax)
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0xae20
movq %rax, %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
movq -0x30(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x28(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x30(%rbp), %rax
movq $0x0, 0x20(%rax)
movq -0x30(%rbp), %rax
movq $0x0, 0x18(%rax)
movq -0x30(%rbp), %rax
movl $0x0, 0x28(%rax)
movl -0x1c(%rbp), %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x2c(%rax)
movq -0x30(%rbp), %rax
movl $0x0, 0x34(%rax)
movq -0x30(%rbp), %rax
movl $0x0, 0x30(%rax)
movq -0x30(%rbp), %rax
movq $0x0, 0x40(%rax)
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jge 0x791a
movq -0x30(%rbp), %rcx
movq -0x28(%rbp), %rax
movslq -0x34(%rbp), %rdx
imulq $0x38, %rdx, %rdx
addq %rdx, %rax
movq %rcx, (%rax)
movq -0x18(%rbp), %rax
movslq -0x34(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rcx
movq -0x28(%rbp), %rax
movslq -0x34(%rbp), %rdx
imulq $0x38, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x18(%rax)
movq -0x28(%rbp), %rax
movslq -0x34(%rbp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movb $0x1, 0x20(%rax)
movq -0x28(%rbp), %rax
movslq -0x34(%rbp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movq $0x0, 0x28(%rax)
movq -0x28(%rbp), %rax
movslq -0x34(%rbp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movl $0x0, 0x30(%rax)
movq -0x28(%rbp), %rax
movslq -0x34(%rbp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movb $0x0, 0x34(%rax)
movq -0x8(%rbp), %rax
movq (%rax), %rdi
movq -0x18(%rbp), %rax
movslq -0x34(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rsi
callq 0x6420
movq %rax, -0x40(%rbp)
movb $0x0, -0x140(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x774c
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x0, %eax
je 0x774c
leaq -0x140(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x3270
leaq -0x140(%rbp), %rdi
leaq 0x5dd8(%rip), %rsi      # 0xd51f
callq 0x3270
movq -0x40(%rbp), %rdi
movl $0x34, %esi
callq 0x6cd0
testb $0x1, %al
jne 0x7760
jmp 0x7779
movq -0x28(%rbp), %rax
movslq -0x34(%rbp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movq $0x0, 0x8(%rax)
jmp 0x77bb
movq -0x40(%rbp), %rdi
callq 0x6e30
movq %rax, -0x150(%rbp)
movl %edx, -0x148(%rbp)
movq -0x8(%rbp), %rdi
movq -0x150(%rbp), %rsi
movl -0x148(%rbp), %edx
callq 0xae20
movq %rax, %rcx
movq -0x28(%rbp), %rax
movslq -0x34(%rbp), %rdx
imulq $0x38, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x8(%rax)
movq -0x40(%rbp), %rax
movq %rax, -0x158(%rbp)
leaq -0x140(%rbp), %rax
movq %rax, -0x160(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x30f0
movq -0x160(%rbp), %rsi
movq -0x158(%rbp), %rdi
addq %rax, %rsi
callq 0x6e70
movq -0x40(%rbp), %rdi
movl $0x2e, %esi
callq 0x6cd0
leaq -0x140(%rbp), %rdi
leaq 0x5fae(%rip), %rsi      # 0xd7c0
callq 0x3270
movq -0x40(%rbp), %rdi
movl $0x2f, %esi
callq 0x6cd0
xorb $-0x1, %al
testb $0x1, %al
jne 0x7830
jmp 0x78be
movq -0x28(%rbp), %rax
movslq -0x34(%rbp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
cmpb $0x0, 0x34(%rax)
je 0x7866
movq -0x40(%rbp), %rdi
movl $0x9, %esi
callq 0x6cd0
leaq -0x140(%rbp), %rdi
leaq 0x5e0f(%rip), %rsi      # 0xd670
callq 0x3270
movq -0x40(%rbp), %rax
movq %rax, -0x168(%rbp)
leaq -0x140(%rbp), %rax
movq %rax, -0x170(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x30f0
movq -0x170(%rbp), %rsi
movq -0x168(%rbp), %rdi
addq %rax, %rsi
callq 0x6e70
movq -0x28(%rbp), %rax
movslq -0x34(%rbp), %rcx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movb 0x34(%rax), %cl
addb $0x1, %cl
movb %cl, 0x34(%rax)
jmp 0x7817
leaq -0x140(%rbp), %rdi
leaq 0x6848(%rip), %rsi      # 0xe114
callq 0x3270
movq -0x8(%rbp), %rdi
leaq -0x140(%rbp), %rsi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0xae20
movq %rax, %rcx
movq -0x28(%rbp), %rax
movslq -0x34(%rbp), %rdx
imulq $0x38, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x10(%rax)
movq -0x8(%rbp), %rax
movq (%rax), %rdi
movq -0x40(%rbp), %rsi
callq 0x64e0
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x7652
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x7940
movq -0x30(%rbp), %rax
addq $0x170, %rsp            # imm = 0x170
popq %rbp
retq
nopw %cs:(%rax,%rax)