// File: /workspace/github_c_makefile_star2_O1/adamjedlicka[P]blu/src/vm/memory.c
// Function: bluGrayObject
void bluGrayObject(bluVM* vm, bluObj* object) {
	if (object == NULL) return;

	if (object->isDark) return;

#ifdef DEBUG_GC_TRACE
	printf("%p gray ", object);
	bluPrintValue(OBJ_VAL(object));
	printf("\n");
#endif

	object->isDark = true;

	bluGrayObject(vm, (bluObj*)object->class);

	switch (object->type) {

	case OBJ_ARRAY: {
		bluObjArray* array = (bluObjArray*)object;
		for (int32_t i = 0; i < array->len; i++) {
			bluGrayValue(vm, array->data[i]);
		}
		break;
	}

	case OBJ_BOUND_METHOD: {
		bluObjBoundMethod* boundMethod = (bluObjBoundMethod*)object;
		bluGrayValue(vm, boundMethod->receiver);
		bluGrayObject(vm, (bluObj*)boundMethod->closure);
		break;
	}

	case OBJ_CLASS: {
		bluObjClass* class = (bluObjClass*)object;
		bluGrayObject(vm, (bluObj*)class->name);
		bluGrayTable(vm, &class->methods);
		bluGrayTable(vm, &class->fields);
		break;
	}

	case OBJ_CLOSURE: {
		bluObjClosure* closure = (bluObjClosure*)object;
		bluGrayObject(vm, (bluObj*)closure->function);
		for (int32_t i = 0; i < closure->upvalues.count; i++) {
			bluGrayObject(vm, &closure->upvalues.data[i]->obj);
		}
		break;
	}

	case OBJ_FUNCTION: {
		bluObjFunction* function = (bluObjFunction*)object;
		bluGrayObject(vm, (bluObj*)function->name);
		bluGrayValueBuffer(vm, &function->chunk.constants);
		break;
	}

	case OBJ_INSTANCE: {
		bluObjInstance* instance = (bluObjInstance*)object;
		bluGrayTable(vm, &instance->fields);
		break;
	}

	case OBJ_NATIVE: {
		break;
	}

	case OBJ_UPVALUE: {
		bluObjUpvalue* upvalue = (bluObjUpvalue*)object;
		bluGrayValue(vm, upvalue->closed);
		break;
	}

	case OBJ_STRING: {
		break;
	}
	}
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %r14
movq %rdi, %rbx
testq %r14, %r14
je 0x7ec7
cmpb $0x0, 0x10(%r14)
jne 0x7ec7
movb $0x1, 0x10(%r14)
movq 0x8(%r14), %rsi
movq %rbx, %rdi
callq 0x7d31
movl (%r14), %eax
cmpl $0x1, %eax
jne 0x7d92
movl 0x20(%r14), %eax
movsd 0x28(%r14), %xmm0
movsd %xmm0, (%rsp)
cmpl $0x3, %eax
jne 0x7d8c
movq (%rsp), %rsi
movq %rbx, %rdi
callq 0x7d31
movq 0x30(%r14), %r14
jmp 0x7d3f
cmpl $0x8, %eax
ja 0x7ec7
movl %eax, %eax
leaq 0x3d40(%rip), %rcx      # 0xbae4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
cmpl $0x0, 0x20(%r14)
jle 0x7ec7
movl $0x8, %r15d
xorl %r12d, %r12d
movq 0x28(%r14), %rax
movl -0x8(%rax,%r15), %ecx
movsd (%rax,%r15), %xmm0
movsd %xmm0, (%rsp)
cmpl $0x3, %ecx
jne 0x7de6
movq (%rsp), %rsi
movq %rbx, %rdi
callq 0x7d31
incq %r12
movslq 0x20(%r14), %rax
addq $0x10, %r15
cmpq %rax, %r12
jl 0x7dc1
jmp 0x7ec7
movq 0x20(%r14), %rsi
movq %rbx, %rdi
callq 0x7d31
leaq 0x30(%r14), %rsi
movq %rbx, %rdi
callq 0x7eed
addq $0x40, %r14
jmp 0x7ed7
movq 0x78(%r14), %rsi
movq %rbx, %rdi
callq 0x7d31
cmpl $0x0, 0x70(%r14)
jle 0x7ec7
movl $0x8, %r15d
xorl %r12d, %r12d
movq 0x68(%r14), %rax
movl -0x8(%rax,%r15), %ecx
movsd (%rax,%r15), %xmm0
movsd %xmm0, (%rsp)
cmpl $0x3, %ecx
jne 0x7e61
movq (%rsp), %rsi
movq %rbx, %rdi
callq 0x7d31
incq %r12
movslq 0x70(%r14), %rax
addq $0x10, %r15
cmpq %rax, %r12
jl 0x7e3c
jmp 0x7ec7
movq 0x20(%r14), %rsi
movq %rbx, %rdi
callq 0x7d31
cmpl $0x0, 0x30(%r14)
jle 0x7ec7
xorl %r15d, %r15d
movq 0x28(%r14), %rax
movq (%rax,%r15,8), %rsi
movq %rbx, %rdi
callq 0x7d31
incq %r15
movslq 0x30(%r14), %rax
cmpq %rax, %r15
jl 0x7e89
jmp 0x7ec7
movl 0x28(%r14), %eax
movsd 0x30(%r14), %xmm0
movsd %xmm0, (%rsp)
cmpl $0x3, %eax
jne 0x7ec7
movq (%rsp), %rsi
movq %rbx, %rdi
callq 0x7d31
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
addq $0x20, %r14
movq %rbx, %rdi
movq %r14, %rsi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x7eed