// File: /workspace/github_c_makefile_star2_O3/adamjedlicka[P]blu/src/vm/memory.c
// Function: freeObject
static void freeObject(bluVM* vm, bluObj* object) {

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

	switch (object->type) {

	case OBJ_ARRAY: {
		bluObjArray* array = (bluObjArray*)object;
		bluDeallocate(vm, array->data, (sizeof(bluValue) * array->cap));
		bluDeallocate(vm, array, sizeof(bluObjArray));
		break;
	}

	case OBJ_BOUND_METHOD: {
		bluObjBoundMethod* boundMethod = (bluObjBoundMethod*)object;
		bluDeallocate(vm, boundMethod, sizeof(bluObjBoundMethod));
		break;
	}

	case OBJ_CLASS: {
		bluObjClass* class = (bluObjClass*)object;
		bluTableFree(vm, &class->methods);
		bluTableFree(vm, &class->fields);
		bluDeallocate(vm, class, sizeof(bluObjClass));
		break;
	}

	case OBJ_CLOSURE: {
		bluObjClosure* closure = (bluObjClosure*)object;
		bluObjUpvalueBufferFree(&closure->upvalues);
		bluDeallocate(vm, closure, sizeof(bluObjClosure));
		break;
	}

	case OBJ_FUNCTION: {
		bluObjFunction* function = (bluObjFunction*)object;
		bluChunkFree(&function->chunk);
		bluDeallocate(vm, function, sizeof(bluObjFunction));
		break;
	}

	case OBJ_INSTANCE: {
		bluObjInstance* instance = (bluObjInstance*)object;

		if (instance->obj.class->destruct != NULL) {
			instance->obj.class->destruct(vm, instance);
		}

		bluTableFree(vm, &instance->fields);
		bluDeallocate(vm, instance, sizeof(bluObjInstance));
		break;
	}

	case OBJ_NATIVE: {
		bluObjNative* native = (bluObjNative*)object;
		bluDeallocate(vm, native, sizeof(bluObjNative));
		break;
	}

	case OBJ_UPVALUE: {
		bluObjUpvalue* upvalue = (bluObjUpvalue*)object;
		bluDeallocate(vm, upvalue, sizeof(bluObjUpvalue));
		break;
	}

	case OBJ_STRING: {
		bluObjString* string = (bluObjString*)object;
		bluDeallocate(vm, string, sizeof(bluObjString) + (sizeof(char) * (string->length + 1)));
		break;
	}
	}
}

// Assembly:
movl (%rsi), %eax
cmpq $0x8, %rax
ja 0x6168
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x4771(%rip), %rcx      # 0xa7c0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x28(%rbx), %rdi
movslq 0x24(%rbx), %rax
shlq $0x4, %rax
movq 0x101890(%r14), %rcx
subq %rax, %rcx
movq %rcx, 0x101890(%r14)
cmpq 0x101898(%r14), %rcx
jbe 0x6086
movb $0x1, 0x1018a0(%r14)
callq 0x2030
movq 0x101890(%r14), %rax
addq $-0x30, %rax
jmp 0x6141
leaq 0x28(%rbx), %rdi
callq 0x619f
jmp 0x6129
leaq 0x30(%rbx), %rsi
movq %r14, %rdi
callq 0x73fb
leaq 0x40(%rbx), %rsi
movq %r14, %rdi
callq 0x73fb
movq 0x101890(%r14), %rax
addq $-0x60, %rax
jmp 0x6141
movslq 0x20(%rbx), %rax
movq 0x101890(%r14), %rcx
subq %rax, %rcx
addq $-0x29, %rcx
movq %rcx, 0x101890(%r14)
cmpq 0x101898(%r14), %rcx
ja 0x6151
jmp 0x6159
leaq 0x28(%rbx), %rdi
callq 0x2a26
movq 0x101890(%r14), %rax
addq $-0x80, %rax
jmp 0x6141
movq 0x8(%rbx), %rax
movq 0x58(%rax), %rax
testq %rax, %rax
je 0x611d
movq %r14, %rdi
movq %rbx, %rsi
callq *%rax
leaq 0x20(%rbx), %rsi
movq %r14, %rdi
callq 0x73fb
movq 0x101890(%r14), %rax
addq $-0x38, %rax
jmp 0x6141
movq 0x101890(%r14), %rax
addq $-0x40, %rax
movq %rax, 0x101890(%r14)
cmpq 0x101898(%r14), %rax
jbe 0x6159
movb $0x1, 0x1018a0(%r14)
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0x2030
retq