// File: /workspace/github_c_makefile_star2_O0/deplinenoise[P]tundra/src/JsonParse.cpp
// Function: t2::JsonParseObject(t2::JsonState*)
static const JsonValue* JsonParseObject(JsonState* json_state)
{
  JsonLexerState* lexer = &json_state->m_Lexer;

  if (!JsonLexerExpect(lexer, kJsonLexBeginObject))
    return JsonError(json_state, "expected '{'");

  MemAllocLinearScope scratch_scope(json_state->m_Scratch);

  bool seen_value = false;
  bool seen_comma = false;

  struct KvPair
  {
    const char      *m_Key;
    const JsonValue *m_Value;
    KvPair          *m_Next;
  };

  struct KvPairList
  {
    MemAllocLinear *m_Scratch;
    KvPair         *m_Head;
    KvPair         *m_Tail;
    size_t          m_Count;

    void Init(MemAllocLinear* scratch)
    {
      m_Scratch = scratch;
      m_Head    = nullptr;
      m_Tail    = nullptr;
      m_Count   = 0;
    }

    void Add(const char* key, const JsonValue* value)
    {
      if (1 == ++m_Count)
      {
        m_Head = m_Tail = LinearAllocate<KvPair>(m_Scratch);
        m_Head->m_Key   = key;
        m_Head->m_Value = value;
        m_Head->m_Next  = nullptr;
      }
      else
      {
        KvPair* tail = m_Tail;
        m_Tail          = LinearAllocate<KvPair>(m_Scratch);
        m_Tail->m_Key   = key;
        m_Tail->m_Value = value;
        m_Tail->m_Next  = nullptr;
        tail->m_Next    = m_Tail;
      }
    }
  };

  KvPairList kv_pairs;

  kv_pairs.Init(json_state->m_Scratch);

  bool done = false;
  while (!done)
  {
    JsonLexeme l = JsonLexerNext(lexer);

    switch (l.m_Type)
    {
      case kJsonLexString:
      {
        if (seen_value && !seen_comma)
          return JsonError(json_state, "expected ','");

        if (!JsonLexerExpect(lexer, kJsonLexNameSeparator))
          return JsonError(json_state, "expected ':'");

        const JsonValue* value = JsonParseValue(json_state);

        if (value == nullptr)
          return nullptr;

        kv_pairs.Add(l.m_String, value);

        seen_value = true;
        seen_comma = false;
      }
      break;

      case kJsonLexEndObject:
        done = true;
        break;

      case kJsonLexValueSeparator:
      {
        if (!seen_value)
          return JsonError(json_state, "expected key name");

        if (seen_comma)
          return JsonError(json_state, "duplicate comma");

        seen_value = false;
        seen_comma = true;
        break;
      }
      
      default:
        return JsonError(json_state, "expected object to continue");
    }
  }

  MemAllocLinear* alloc = json_state->m_Allocator;

  size_t       count  = kv_pairs.m_Count;
  const char **names  = LinearAllocateArray<const char*>(alloc, kv_pairs.m_Count);
  const JsonValue  **values = LinearAllocateArray<const JsonValue*>(alloc, kv_pairs.m_Count);

  size_t index = 0;
  for (KvPair* p = kv_pairs.m_Head; p; p = p->m_Next, ++index)
  {
    names[index]  = p->m_Key;
    values[index] = p->m_Value;
  }

  JsonObjectValue* result = LinearAllocate<JsonObjectValue>(alloc);
  result->m_Type = JsonValue::kObject;
  result->m_Count  = count;
  result->m_Names  = names;
  result->m_Values = values;

  return result;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rdi
movl $0x4, %esi
xorl %eax, %eax
movl %eax, %edx
callq 0x175b0
testb $0x1, %al
jne 0x17746
movq -0x10(%rbp), %rdi
leaq 0xd965(%rip), %rsi      # 0x2509d
callq 0x17610
movq %rax, -0x8(%rbp)
jmp 0x17b0d
movq -0x10(%rbp), %rax
movq 0x828(%rax), %rsi
leaq -0x28(%rbp), %rdi
callq 0x6e40
movb $0x0, -0x29(%rbp)
movb $0x0, -0x2a(%rbp)
movq -0x10(%rbp), %rax
movq 0x828(%rax), %rsi
leaq -0x50(%rbp), %rdi
callq 0x18570
jmp 0x17778
movb $0x0, -0x5d(%rbp)
movb -0x5d(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x1778a
jmp 0x179a2
movq -0x18(%rbp), %rdi
callq 0x185b0
movq %rdx, -0xc8(%rbp)
movl %eax, -0xbc(%rbp)
jmp 0x177a2
movq -0xc8(%rbp), %rax
movl -0xbc(%rbp), %ecx
movl %ecx, -0x70(%rbp)
movq %rax, -0x68(%rbp)
movl -0x70(%rbp), %eax
movl %eax, -0xcc(%rbp)
testl %eax, %eax
je 0x17804
jmp 0x177c5
movl -0xcc(%rbp), %eax
subl $0x2, %eax
je 0x178f7
jmp 0x177d6
movl -0xcc(%rbp), %eax
subl $0x6, %eax
je 0x178ee
jmp 0x1796d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x58(%rbp)
movl %eax, -0x5c(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x6f50
jmp 0x17b1a
testb $0x1, -0x29(%rbp)
je 0x17840
testb $0x1, -0x2a(%rbp)
jne 0x17840
movq -0x10(%rbp), %rdi
leaq 0xd88f(%rip), %rsi      # 0x250aa
callq 0x17610
movq %rax, -0xd8(%rbp)
jmp 0x17829
movq -0xd8(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0x74(%rbp)
jmp 0x17b04
movq -0x18(%rbp), %rdi
xorl %eax, %eax
movl %eax, %edx
movl $0x3, %esi
callq 0x175b0
movb %al, -0xd9(%rbp)
jmp 0x1785a
movb -0xd9(%rbp), %al
testb $0x1, %al
jne 0x17896
jmp 0x17866
movq -0x10(%rbp), %rdi
leaq 0xd846(%rip), %rsi      # 0x250b7
callq 0x17610
movq %rax, -0xe8(%rbp)
jmp 0x1787f
movq -0xe8(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0x74(%rbp)
jmp 0x17b04
movq -0x10(%rbp), %rdi
callq 0x17460
movq %rax, -0xf0(%rbp)
jmp 0x178a8
movq -0xf0(%rbp), %rax
movq %rax, -0x80(%rbp)
cmpq $0x0, -0x80(%rbp)
jne 0x178ce
movq $0x0, -0x8(%rbp)
movl $0x1, -0x74(%rbp)
jmp 0x17b04
movq -0x68(%rbp), %rsi
movq -0x80(%rbp), %rdx
leaq -0x50(%rbp), %rdi
callq 0x18610
jmp 0x178e1
movb $0x1, -0x29(%rbp)
movb $0x0, -0x2a(%rbp)
jmp 0x1799d
movb $0x1, -0x5d(%rbp)
jmp 0x1799d
testb $0x1, -0x29(%rbp)
jne 0x1792d
movq -0x10(%rbp), %rdi
leaq 0xd7bc(%rip), %rsi      # 0x250c4
callq 0x17610
movq %rax, -0xf8(%rbp)
jmp 0x17916
movq -0xf8(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0x74(%rbp)
jmp 0x17b04
testb $0x1, -0x2a(%rbp)
je 0x17963
movq -0x10(%rbp), %rdi
leaq 0xd798(%rip), %rsi      # 0x250d6
callq 0x17610
movq %rax, -0x100(%rbp)
jmp 0x1794c
movq -0x100(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0x74(%rbp)
jmp 0x17b04
movb $0x0, -0x29(%rbp)
movb $0x1, -0x2a(%rbp)
jmp 0x1799d
movq -0x10(%rbp), %rdi
leaq 0xd76e(%rip), %rsi      # 0x250e6
callq 0x17610
movq %rax, -0x108(%rbp)
jmp 0x17986
movq -0x108(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0x74(%rbp)
jmp 0x17b04
jmp 0x1777c
movq -0x10(%rbp), %rax
movq 0x820(%rax), %rax
movq %rax, -0x88(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x88(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x149f0
movq %rax, -0x110(%rbp)
jmp 0x179d8
movq -0x110(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x88(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x18890
movq %rax, -0x118(%rbp)
jmp 0x179ff
movq -0x118(%rbp), %rax
movq %rax, -0xa0(%rbp)
movq $0x0, -0xa8(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0xb0(%rbp)
cmpq $0x0, -0xb0(%rbp)
je 0x17a8c
movq -0xb0(%rbp), %rax
movq (%rax), %rdx
movq -0x98(%rbp), %rax
movq -0xa8(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0xb0(%rbp), %rax
movq 0x8(%rax), %rdx
movq -0xa0(%rbp), %rax
movq -0xa8(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0xb0(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0xb0(%rbp)
movq -0xa8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa8(%rbp)
jmp 0x17a23
movq -0x88(%rbp), %rdi
callq 0x188c0
movq %rax, -0x120(%rbp)
jmp 0x17aa1
movq -0x120(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rax
movl $0x2, (%rax)
movq -0x90(%rbp), %rcx
movq -0xb8(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x98(%rbp), %rcx
movq -0xb8(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0xa0(%rbp), %rcx
movq -0xb8(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0xb8(%rbp), %rax
movq %rax, -0x8(%rbp)
movl $0x1, -0x74(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x6f50
movq -0x8(%rbp), %rax
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq
movq -0x58(%rbp), %rdi
callq 0x35c0
nopw %cs:(%rax,%rax)