// File: /workspace/github_c_makefile_star2_O0/jiribenes[P]scheme/src/vm.c
// Function: mark
static void mark(vm_t *vm, value_t val) {
    if (IS_VAL(val)) {
        return;
    }
    ptrvalue_t *ptr = AS_PTR(val);
    if (ptr == NULL) {
        error_runtime(vm, "|GC: Cannot mark a NULL!");
        return;
    }
    if (ptr->gcmark) {
        return;
    }

    ptr->gcmark = true;

    if (ptr->type == T_CONS) {
        cons_t *cons = (cons_t *) ptr;
        mark(vm, cons->car);
        mark(vm, cons->cdr);
    } else if (ptr->type == T_ENV) {
        env_t *env = (env_t *) ptr;
        mark(vm, env->variables);
        if (!IS_NIL(env->variables)) {
            cons_t *vars = AS_CONS(env->variables);
            while (true) {
                value_t pair = vars->car;
                mark(vm, pair);
                if (IS_NIL(vars->cdr)) {
                    break;
                }
                vars = AS_CONS(vars->cdr);
            }
        }

        if (env->up != NULL) {
            mark(vm, PTR_VAL(env->up));
        }
    } else if (ptr->type == T_PRIMITIVE) {
        primitive_t *prim = (primitive_t *) ptr;
        if (prim->name != NULL) {
            mark(vm, PTR_VAL(prim->name));
        }
    } else if (ptr->type == T_FUNCTION || ptr->type == T_MACRO) {
        function_t *func = (function_t *) ptr;

        if (func->name != NULL) {
            mark(vm, PTR_VAL(func->name));
        }

        mark(vm, func->params);
        mark(vm, func->body);
        mark(vm, PTR_VAL(func->env));
    } else if (ptr->type == T_VECTOR) {
        vector_t *vec = (vector_t *) ptr;

        for (uint32_t i = 0; i < vec->count; i++) {
            mark(vm, vec->data[i]);
        }
    }
}

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x70(%rsp)
movq %rsi, 0x68(%rsp)
movabsq $-0x4000000000000, %rax # imm = 0xFFFC000000000000
andq 0x68(%rsp), %rax
movabsq $-0x4000000000000, %rcx # imm = 0xFFFC000000000000
cmpq %rcx, %rax
je 0x8a71
jmp 0x8d1f
movabsq $0x3ffffffffffff, %rax  # imm = 0x3FFFFFFFFFFFF
andq 0x68(%rsp), %rax
movq %rax, 0x60(%rsp)
cmpq $0x0, 0x60(%rsp)
jne 0x8aa5
movq 0x70(%rsp), %rdi
leaq 0x217d(%rip), %rsi      # 0xac16
movb $0x0, %al
callq 0x73a0
jmp 0x8d1f
movq 0x60(%rsp), %rax
testb $0x1, 0x4(%rax)
je 0x8ab5
jmp 0x8d1f
movq 0x60(%rsp), %rax
movb $0x1, 0x4(%rax)
movq 0x60(%rsp), %rax
cmpl $0x0, (%rax)
jne 0x8afd
movq 0x60(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0x70(%rsp), %rdi
movq 0x58(%rsp), %rax
movq 0x10(%rax), %rsi
callq 0x8a40
movq 0x70(%rsp), %rdi
movq 0x58(%rsp), %rax
movq 0x18(%rax), %rsi
callq 0x8a40
jmp 0x8d1f
movq 0x60(%rsp), %rax
cmpl $0x7, (%rax)
jne 0x8bdb
movq 0x60(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x70(%rsp), %rdi
movq 0x50(%rsp), %rax
movq 0x10(%rax), %rsi
callq 0x8a40
movq 0x50(%rsp), %rax
movabsq $0x7ffc000000000001, %rcx # imm = 0x7FFC000000000001
cmpq %rcx, 0x10(%rax)
je 0x8ba5
movq 0x50(%rsp), %rcx
movabsq $0x3ffffffffffff, %rax  # imm = 0x3FFFFFFFFFFFF
andq 0x10(%rcx), %rax
movq %rax, 0x48(%rsp)
movq 0x48(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x40(%rsp)
movq 0x70(%rsp), %rdi
movq 0x40(%rsp), %rsi
callq 0x8a40
movq 0x48(%rsp), %rax
movabsq $0x7ffc000000000001, %rcx # imm = 0x7FFC000000000001
cmpq %rcx, 0x18(%rax)
jne 0x8b89
jmp 0x8ba3
movq 0x48(%rsp), %rcx
movabsq $0x3ffffffffffff, %rax  # imm = 0x3FFFFFFFFFFFF
andq 0x18(%rcx), %rax
movq %rax, 0x48(%rsp)
jmp 0x8b55
jmp 0x8ba5
movq 0x50(%rsp), %rax
cmpq $0x0, 0x18(%rax)
je 0x8bd6
movq 0x70(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x50(%rsp), %rax
movq 0x18(%rax), %rdi
callq 0x7c50
movq 0x18(%rsp), %rdi
movq %rax, %rsi
callq 0x8a40
jmp 0x8d1d
movq 0x60(%rsp), %rax
cmpl $0x3, (%rax)
jne 0x8c25
movq 0x60(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x38(%rsp), %rax
cmpq $0x0, 0x10(%rax)
je 0x8c20
movq 0x70(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x38(%rsp), %rax
movq 0x10(%rax), %rdi
callq 0x7c50
movq 0x10(%rsp), %rdi
movq %rax, %rsi
callq 0x8a40
jmp 0x8d1b
movq 0x60(%rsp), %rax
cmpl $0x4, (%rax)
je 0x8c3d
movq 0x60(%rsp), %rax
cmpl $0x5, (%rax)
jne 0x8cc3
movq 0x60(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x30(%rsp), %rax
cmpq $0x0, 0x10(%rax)
je 0x8c78
movq 0x70(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x30(%rsp), %rax
movq 0x10(%rax), %rdi
callq 0x7c50
movq 0x8(%rsp), %rdi
movq %rax, %rsi
callq 0x8a40
movq 0x70(%rsp), %rdi
movq 0x30(%rsp), %rax
movq 0x20(%rax), %rsi
callq 0x8a40
movq 0x70(%rsp), %rdi
movq 0x30(%rsp), %rax
movq 0x28(%rax), %rsi
callq 0x8a40
movq 0x70(%rsp), %rax
movq %rax, (%rsp)
movq 0x30(%rsp), %rax
movq 0x18(%rax), %rdi
callq 0x7c50
movq (%rsp), %rdi
movq %rax, %rsi
callq 0x8a40
jmp 0x8d19
movq 0x60(%rsp), %rax
cmpl $0x6, (%rax)
jne 0x8d17
movq 0x60(%rsp), %rax
movq %rax, 0x28(%rsp)
movl $0x0, 0x24(%rsp)
movl 0x24(%rsp), %eax
movq 0x28(%rsp), %rcx
cmpl 0x14(%rcx), %eax
jae 0x8d15
movq 0x70(%rsp), %rdi
movq 0x28(%rsp), %rax
movq 0x18(%rax), %rax
movl 0x24(%rsp), %ecx
movq (%rax,%rcx,8), %rsi
callq 0x8a40
movl 0x24(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x24(%rsp)
jmp 0x8cdf
jmp 0x8d17
jmp 0x8d19
jmp 0x8d1b
jmp 0x8d1d
jmp 0x8d1f
addq $0x78, %rsp
retq
nopw %cs:(%rax,%rax)
nop