// File: /workspace/github_c_makefile_star2_O0/mahrr[P]raven/src/vm.c
// Function: call_cfunction
static bool call_cfunction(VM *vm, RavCFunction *cfunction, int count) {
    int arity_min = cfunction->arity_min;
    int arity_max = cfunction->arity_max;

    if (count < arity_min || count > arity_max) {
        if (arity_min == arity_max) { // non-variadic
            runtime_error(vm, "expect %d arguments, but got %d", arity_min, count);
        } else if (arity_max != PARAMS_LIMIT) { // non-variadic
            runtime_error(vm, "expect %d to %d arguments, but got %d", arity_min, arity_max, count);
        } else { // variadic
            runtime_error(vm, "expect at least %d arguments, but got %d", arity_min, count);
        }
        return false;
    }

    Value result = Nil_Value;

    Value *stack_before = vm->stack_top;
    bool succeed = cfunction->func(vm, vm->stack_top - count, count, &result);
    Value *stack_after = vm->stack_top;

    // an error has occured in the function call
    if (!succeed) {
        return false;
    }

    // native functions must not manipulate the stack at a level before their
    // passed arguments
    if (stack_after < (stack_before - count)) {
        runtime_error(vm, "corrupted stack");
        return false;
    }

    // rewind the stack to the point before the cfunction and its argument
    vm->stack_top = stack_before - (count + 1);

    // push the returned value from the function
    push(vm, result);
    return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq -0x18(%rbp), %rax
movl 0x18(%rax), %eax
movl %eax, -0x20(%rbp)
movq -0x18(%rbp), %rax
movl 0x1c(%rax), %eax
movl %eax, -0x24(%rbp)
movl -0x1c(%rbp), %eax
cmpl -0x20(%rbp), %eax
jl 0x6e07
movl -0x1c(%rbp), %eax
cmpl -0x24(%rbp), %eax
jle 0x6e73
movl -0x20(%rbp), %eax
cmpl -0x24(%rbp), %eax
jne 0x6e29
movq -0x10(%rbp), %rdi
movl -0x20(%rbp), %edx
movl -0x1c(%rbp), %ecx
leaq 0x774c(%rip), %rsi      # 0xe56c
movb $0x0, %al
callq 0x6630
jmp 0x6e6a
cmpl $0x100, -0x24(%rbp)     # imm = 0x100
je 0x6e50
movq -0x10(%rbp), %rdi
movl -0x20(%rbp), %edx
movl -0x24(%rbp), %ecx
movl -0x1c(%rbp), %r8d
leaq 0x7745(%rip), %rsi      # 0xe58c
movb $0x0, %al
callq 0x6630
jmp 0x6e68
movq -0x10(%rbp), %rdi
movl -0x20(%rbp), %edx
movl -0x1c(%rbp), %ecx
leaq 0x7751(%rip), %rsi      # 0xe5b2
movb $0x0, %al
callq 0x6630
jmp 0x6e6a
movb $0x0, -0x1(%rbp)
jmp 0x6f4b
movabsq $0x7ffc000000000001, %rax # imm = 0x7FFC000000000001
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq 0x40058(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rcx
movq 0x40058(%rcx), %rsi
movslq -0x1c(%rbp), %rdx
xorl %ecx, %ecx
subq %rdx, %rcx
shlq $0x3, %rcx
addq %rcx, %rsi
movslq -0x1c(%rbp), %rdx
leaq -0x30(%rbp), %rcx
callq *%rax
andb $0x1, %al
movb %al, -0x39(%rbp)
movq -0x10(%rbp), %rax
movq 0x40058(%rax), %rax
movq %rax, -0x48(%rbp)
testb $0x1, -0x39(%rbp)
jne 0x6ee1
movb $0x0, -0x1(%rbp)
jmp 0x6f4b
movq -0x48(%rbp), %rax
movq -0x38(%rbp), %rcx
movslq -0x1c(%rbp), %rsi
xorl %edx, %edx
subq %rsi, %rdx
shlq $0x3, %rdx
addq %rdx, %rcx
cmpq %rcx, %rax
jae 0x6f16
movq -0x10(%rbp), %rdi
leaq 0x76d2(%rip), %rsi      # 0xe5db
movb $0x0, %al
callq 0x6630
movb $0x0, -0x1(%rbp)
jmp 0x6f4b
movq -0x38(%rbp), %rcx
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdx
xorl %eax, %eax
subq %rdx, %rax
shlq $0x3, %rax
addq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x40058(%rax)
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x2bb0
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)