// File: /workspace/github_c_makefile_star2_O2/atomlang[P]atomlang/src/pk_var.c
// Function: mapFindEntry
static bool _mapFindEntry(Map* self, Var key, MapEntry** result) {

  // An empty map won't contain the key.
  if (self->capacity == 0) return false;

  // The [start_index] is where the entry supposed to be if there wasn't any
  // collision occurred. It'll be the start index for the linear probing.
  uint32_t start_index = varHashValue(key) % self->capacity;
  uint32_t index = start_index;

  // Keep track of the first tombstone after the [start_index] if we don't find
  // the key anywhere. The tombstone would be the entry at where we will have
  // to insert the key/value pair.
  MapEntry* tombstone = NULL;

  do {
    MapEntry* entry = &self->entries[index];

    if (IS_UNDEF(entry->key)) {
      ASSERT(IS_BOOL(entry->value), OOPS);

      if (IS_TRUE(entry->value)) {

        // We've found a tombstone, if we haven't found one [tombstone] should
        // be updated. We still need to keep search for if the key exists.
        if (tombstone == NULL) tombstone = entry;

      } else {
        // We've found a new empty slot and the key isn't found. If we've
        // found a tombstone along the sequence we could use that entry
        // otherwise the entry at the current index.

        *result = (tombstone != NULL) ? tombstone : entry;
        return false;
      }

    } else if (isValuesEqual(entry->key, key)) {
      // We've found the key.
      *result = entry;
      return true;
    }

    index = (index + 1) % self->capacity;

  } while (index != start_index);

  // If we reach here means the map is filled with tombstone. Set the first
  // tombstone as result for the next insertion and return false.
  ASSERT(tombstone != NULL, OOPS);
  *result = tombstone;
  return false;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
cmpl $0x0, 0x10(%rdi)
je 0x4403
movq %rdi, %r15
movq %rdx, 0x8(%rsp)
movabsq $0x7ffd000000000000, %rbx # imm = 0x7FFD000000000000
movq %rsi, 0x20(%rsp)
movq %rsi, %rdi
callq 0x41fa
movl 0x10(%r15), %esi
xorl %edx, %edx
divl %esi
movq 0x18(%r15), %r9
leaq 0x2(%rbx), %rax
movq %rax, 0x18(%rsp)
leaq 0x3(%rbx), %rax
movq %rax, 0x10(%rsp)
movl %edx, %ebp
xorl %r14d, %r14d
movl %esi, 0x4(%rsp)
movl %ebp, %eax
shlq $0x4, %rax
leaq (%r9,%rax), %r13
movq (%r9,%rax), %rdi
movabsq $0x7ffd000000000000, %rax # imm = 0x7FFD000000000000
cmpq %rax, %rdi
setne %r12b
je 0x43bb
movq 0x20(%rsp), %rsi
movl %edx, %r15d
movq %r9, %rbx
callq 0x4f07
movq %rbx, %r9
movl %r15d, %edx
movl 0x4(%rsp), %esi
testb %al, %al
je 0x43de
jmp 0x43f9
movq 0x8(%r13), %rax
movq %rax, %rcx
andq $-0x2, %rcx
cmpq 0x18(%rsp), %rcx
jne 0x4418
testq %r14, %r14
cmovneq %r14, %r13
movq %r13, %r14
cmpq 0x10(%rsp), %rax
jne 0x43f9
incl %ebp
cmpl %esi, %ebp
movl $0x0, %eax
cmovel %eax, %ebp
cmpl %edx, %ebp
jne 0x437a
testq %r14, %r14
je 0x444d
xorl %r12d, %r12d
movq %r14, %r13
movq 0x8(%rsp), %rax
movq %r13, (%rax)
jmp 0x4406
xorl %r12d, %r12d
movl %r12d, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x1ebd9(%rip), %rax     # 0x22ff8
movq (%rax), %rdi
leaq 0x13cc7(%rip), %rsi     # 0x180f0
leaq 0x13dd4(%rip), %rdx     # 0x18204
leaq 0x13f39(%rip), %rcx     # 0x18370
leaq 0x13cfe(%rip), %r8      # 0x1813c
movl $0x359, %r9d            # imm = 0x359
xorl %eax, %eax
callq 0x2250
ud2
movq 0x1eba4(%rip), %rax     # 0x22ff8
movq (%rax), %rdi
leaq 0x13c92(%rip), %rsi     # 0x180f0
leaq 0x13d9f(%rip), %rdx     # 0x18204
leaq 0x13f04(%rip), %rcx     # 0x18370
leaq 0x13cc9(%rip), %r8      # 0x1813c
movl $0x376, %r9d            # imm = 0x376
jmp 0x4444