// File: hzeller[P]jcxxgen/schema-compiler.cc
// Function: GenerateCode(char const*, char const*, std::vector<ObjectType*, std::allocator<ObjectType*>> const&, _IO_FILE*)
void GenerateCode(const char *filename,
                  const char *nlohmann_json_include,
                  const ObjectTypeVector &objects,
                  FILE *out) {
  fprintf(out, "// Don't modify. Generated from %s\n", filename);
  fprintf(out, "#pragma once\n"
          "#include <string>\n"
          "#include <vector>\n");
  fprintf(out, "#include %s\n\n", nlohmann_json_include);
  for (const auto& o : objects) {
    fprintf(out, "struct %s", o->name.c_str());
    bool is_first = true;
    for (const auto &e : o->extends) {
      fprintf(out, "%s", is_first ? " :" : ",");
      fprintf(out, " public %s", e.c_str());
      is_first = false;
    }
    fprintf(out, " {\n");
    for (const auto&p : o->properties) {
      std::string type;
      if (p.object_type) type = p.object_type->name;
      else if (p.type == "string") type = "std::string";
      else if (p.type == "integer") type = "int";
      else if (p.type == "object") type = "nlohmann::json";
      else if (p.type == "boolean") type = "bool";
      // TODO: optional and array
      if (type.empty()) {
        std::cerr << p.location << "Not supported yet '" << p.type << "'\n";
        continue;
      }
      if (p.is_array) {
        fprintf(out, "  std::vector<%s> %s", type.c_str(), p.name.c_str());
      } else {
        fprintf(out, "  %s %s", type.c_str(), p.name.c_str());
      }
      if (!p.default_value.empty())
        fprintf(out, " = %s", p.default_value.c_str());
      fprintf(out, ";\n");
      if (p.is_optional) {
        fprintf(out, "  bool has_%s = false;  // optional property\n",
                p.name.c_str());
      }
    }

    // nlohmann::json serialization
    fprintf(out, "\n");
    fprintf(out, "  void Deserialize(const nlohmann::json &j) {\n");
    for (const auto &e : o->extends) {
      fprintf(out, "    %s::Deserialize(j);\n",
              e.c_str());
    }
    for (const auto&p : o->properties) {
      int indent = 4;
      std::string access_call = "j.at(\"" + p.name + "\")";
      std::string access_deref =  access_call + ".";
      if (p.is_optional) {
        fprintf(out, "%*sif (auto found = j.find(\"%s\"); found != j.end()) {\n",
                indent, "", p.name.c_str());
        indent += 4;
        fprintf(out, "%*shas_%s = true;\n", indent, "", p.name.c_str());
        access_call = "*found";
        access_deref = "found->";
      }
      if (p.object_type == nullptr || p.is_array) {
        fprintf(out, "%*s%sget_to(%s);\n",
                indent, "", access_deref.c_str(), p.name.c_str());
      } else {
        fprintf(out, "%*s%s.Deserialize(%s);\n",
                indent, "", p.name.c_str(), access_call.c_str());
      }
      if (p.is_optional) {
        fprintf(out, "%*s}\n", indent-4, "");
      }
    }
    fprintf(out, "  }\n");

    fprintf(out, "  void Serialize(nlohmann::json *j) const {\n");
    for (const auto &e : o->extends) {
      fprintf(out, "    %s::Serialize(j);\n", e.c_str());
    }
    for (const auto&p : o->properties) {
      int indent = 4;
      if (p.is_optional) {
        fprintf(out, "%*sif (has_%s)", indent, "", p.name.c_str());
        indent = 1;
      }
      if (p.object_type == nullptr || p.is_array) {
        fprintf(out, "%*s(*j)[\"%s\"] = %s;\n",
                indent, "", p.name.c_str(), p.name.c_str());
      } else {
        fprintf(out, "%*s%s.Serialize(&(*j)[\"%s\"]);\n",
                indent, "", p.name.c_str(), p.name.c_str());
      }
    }
    fprintf(out, "  }\n");

    fprintf(out, "};\n"); // End of struct

    // functions that are picked up by the nlohmann::json serializer
    // We could generate template code once for all to_json/from_json that take
    // a T obj, but to limit method lookup confusion for other objects that
    // might interact with the json library, let's be explicit for each struct
    fprintf(out, "inline void to_json(nlohmann::json &j, const %s &obj) "
            "{ obj.Serialize(&j); }\n", o->name.c_str());
    fprintf(out, "inline void from_json(const nlohmann::json &j, %s &obj) "
            "{ obj.Deserialize(j); }\n\n", o->name.c_str());
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2d0, %rsp            # imm = 0x2D0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x20(%rbp), %rdi
movq -0x8(%rbp), %rdx
leaq 0x3133e(%rip), %rsi     # 0x38178
movb $0x0, %al
callq 0x5570
movq -0x20(%rbp), %rdi
leaq 0x31350(%rip), %rsi     # 0x3819c
movb $0x0, %al
callq 0x5570
movq -0x20(%rbp), %rdi
movq -0x10(%rbp), %rdx
leaq 0x3136c(%rip), %rsi     # 0x381ce
movb $0x0, %al
callq 0x5570
movq -0x18(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x7ea0
movq %rax, -0x30(%rbp)
movq -0x28(%rbp), %rdi
callq 0x7ed0
movq %rax, -0x38(%rbp)
leaq -0x30(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x7f00
testb $0x1, %al
jne 0x6ea1
jmp 0x7af4
leaq -0x30(%rbp), %rdi
callq 0x7f40
movq %rax, -0x40(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x1b0(%rbp)
movq -0x40(%rbp), %rax
movq (%rax), %rdi
addq $0x10, %rdi
callq 0x5190
movq -0x1b0(%rbp), %rdi
movq %rax, %rdx
leaq 0x31302(%rip), %rsi     # 0x381dc
movb $0x0, %al
callq 0x5570
movb $0x1, -0x41(%rbp)
movq -0x40(%rbp), %rax
movq (%rax), %rax
addq $0x30, %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
callq 0x7f60
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rdi
callq 0x7f90
movq %rax, -0x60(%rbp)
leaq -0x58(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x7fc0
testb $0x1, %al
jne 0x6f21
jmp 0x6f96
leaq -0x58(%rbp), %rdi
callq 0x8000
movq %rax, -0x68(%rbp)
movq -0x20(%rbp), %rdi
movb -0x41(%rbp), %cl
leaq 0x312ad(%rip), %rdx     # 0x381e9
leaq 0x312a3(%rip), %rax     # 0x381e6
testb $0x1, %cl
cmovneq %rax, %rdx
leaq 0x31310(%rip), %rsi     # 0x38261
movb $0x0, %al
callq 0x5570
movq -0x20(%rbp), %rax
movq %rax, -0x1b8(%rbp)
movq -0x68(%rbp), %rdi
callq 0x5190
movq -0x1b8(%rbp), %rdi
movq %rax, %rdx
leaq 0x3126e(%rip), %rsi     # 0x381eb
movb $0x0, %al
callq 0x5570
movb $0x0, -0x41(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x8020
jmp 0x6f0e
movq -0x20(%rbp), %rdi
leaq 0x31376(%rip), %rsi     # 0x38317
movb $0x0, %al
callq 0x5570
movq -0x40(%rbp), %rax
movq (%rax), %rax
addq $0x48, %rax
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rdi
callq 0x8040
movq %rax, -0x78(%rbp)
movq -0x70(%rbp), %rdi
callq 0x8070
movq %rax, -0x80(%rbp)
leaq -0x78(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x80a0
testb $0x1, %al
jne 0x6fe7
jmp 0x7376
leaq -0x78(%rbp), %rdi
callq 0x80e0
movq %rax, -0x88(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x5530
movq -0x88(%rbp), %rax
cmpq $0x0, 0x80(%rax)
je 0x705c
movq -0x88(%rbp), %rax
movq 0x80(%rax), %rsi
addq $0x10, %rsi
leaq -0xa8(%rbp), %rdi
callq 0x5060
jmp 0x7034
jmp 0x7172
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x5280
jmp 0x7afd
movq -0x88(%rbp), %rdi
addq $0x60, %rdi
leaq 0x3118d(%rip), %rsi     # 0x381fb
callq 0x8100
movb %al, -0x1b9(%rbp)
jmp 0x707b
movb -0x1b9(%rbp), %al
testb $0x1, %al
jne 0x7087
jmp 0x70a1
leaq 0x31168(%rip), %rsi     # 0x381f6
leaq -0xa8(%rbp), %rdi
callq 0x5520
jmp 0x709c
jmp 0x7170
movq -0x88(%rbp), %rdi
addq $0x60, %rdi
leaq 0x3114f(%rip), %rsi     # 0x38202
callq 0x8100
movb %al, -0x1ba(%rbp)
jmp 0x70c0
movb -0x1ba(%rbp), %al
testb $0x1, %al
jne 0x70cc
jmp 0x70e6
leaq 0x319bc(%rip), %rsi     # 0x38a8f
leaq -0xa8(%rbp), %rdi
callq 0x5520
jmp 0x70e1
jmp 0x716e
movq -0x88(%rbp), %rdi
addq $0x60, %rdi
leaq 0x31112(%rip), %rsi     # 0x3820a
callq 0x8100
movb %al, -0x1bb(%rbp)
jmp 0x7105
movb -0x1bb(%rbp), %al
testb $0x1, %al
jne 0x7111
jmp 0x7128
leaq 0x310f9(%rip), %rsi     # 0x38211
leaq -0xa8(%rbp), %rdi
callq 0x5520
jmp 0x7126
jmp 0x716c
movq -0x88(%rbp), %rdi
addq $0x60, %rdi
leaq 0x310e6(%rip), %rsi     # 0x38220
callq 0x8100
movb %al, -0x1bc(%rbp)
jmp 0x7147
movb -0x1bc(%rbp), %al
testb $0x1, %al
jne 0x7153
jmp 0x716a
leaq 0x310ce(%rip), %rsi     # 0x38228
leaq -0xa8(%rbp), %rdi
callq 0x5520
jmp 0x7168
jmp 0x716a
jmp 0x716c
jmp 0x716e
jmp 0x7170
jmp 0x7172
leaq -0xa8(%rbp), %rdi
callq 0x55f0
testb $0x1, %al
jne 0x7184
jmp 0x7200
movq -0x88(%rbp), %rsi
movq 0x4ce5e(%rip), %rdi     # 0x53ff0
callq 0x8130
movq %rax, -0x1c8(%rbp)
jmp 0x71a0
movq -0x1c8(%rbp), %rdi
leaq 0x3107f(%rip), %rsi     # 0x3822d
callq 0x53c0
movq %rax, -0x1d0(%rbp)
jmp 0x71bc
movq -0x1d0(%rbp), %rdi
movq -0x88(%rbp), %rsi
addq $0x60, %rsi
callq 0x5390
movq %rax, -0x1d8(%rbp)
jmp 0x71dc
movq -0x1d8(%rbp), %rdi
leaq 0x3139d(%rip), %rsi     # 0x38587
callq 0x53c0
jmp 0x71f1
movl $0x7, -0xb8(%rbp)
jmp 0x734c
movq -0x88(%rbp), %rax
testb $0x1, 0x39(%rax)
je 0x725c
movq -0x20(%rbp), %rax
movq %rax, -0x1e8(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x5190
movq %rax, -0x1e0(%rbp)
movq -0x88(%rbp), %rdi
addq $0x18, %rdi
callq 0x5190
movq -0x1e8(%rbp), %rdi
movq -0x1e0(%rbp), %rdx
movq %rax, %rcx
leaq 0x30fee(%rip), %rsi     # 0x38241
movb $0x0, %al
callq 0x5570
jmp 0x72a9
movq -0x20(%rbp), %rax
movq %rax, -0x1f8(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x5190
movq %rax, -0x1f0(%rbp)
movq -0x88(%rbp), %rdi
addq $0x18, %rdi
callq 0x5190
movq -0x1f8(%rbp), %rdi
movq -0x1f0(%rbp), %rdx
movq %rax, %rcx
leaq 0x30fb4(%rip), %rsi     # 0x38256
movb $0x0, %al
callq 0x5570
movq -0x88(%rbp), %rdi
addq $0x40, %rdi
callq 0x55f0
testb $0x1, %al
jne 0x72f0
movq -0x20(%rbp), %rax
movq %rax, -0x200(%rbp)
movq -0x88(%rbp), %rdi
addq $0x40, %rdi
callq 0x5190
movq -0x200(%rbp), %rdi
movq %rax, %rdx
leaq 0x30f75(%rip), %rsi     # 0x3825e
movb $0x0, %al
callq 0x5570
movq -0x20(%rbp), %rdi
leaq 0x310fb(%rip), %rsi     # 0x383f6
movb $0x0, %al
callq 0x5570
movq -0x88(%rbp), %rax
testb $0x1, 0x38(%rax)
je 0x7342
movq -0x20(%rbp), %rax
movq %rax, -0x208(%rbp)
movq -0x88(%rbp), %rdi
addq $0x18, %rdi
callq 0x5190
movq -0x208(%rbp), %rdi
movq %rax, %rdx
leaq 0x30f29(%rip), %rsi     # 0x38264
movb $0x0, %al
callq 0x5570
movl $0x0, -0xb8(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x5280
movl -0xb8(%rbp), %eax
testl %eax, %eax
je 0x7366
jmp 0x7364
jmp 0x7368
jmp 0x7368
leaq -0x78(%rbp), %rdi
callq 0x8190
jmp 0x6fd1
movq -0x20(%rbp), %rdi
leaq 0x30e59(%rip), %rsi     # 0x381da
movb $0x0, %al
callq 0x5570
movq -0x20(%rbp), %rdi
leaq 0x30eff(%rip), %rsi     # 0x38292
movb $0x0, %al
callq 0x5570
movq -0x40(%rbp), %rax
movq (%rax), %rax
addq $0x30, %rax
movq %rax, -0xc0(%rbp)
movq -0xc0(%rbp), %rdi
callq 0x7f60
movq %rax, -0xc8(%rbp)
movq -0xc0(%rbp), %rdi
callq 0x7f90
movq %rax, -0xd0(%rbp)
leaq -0xc8(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x7fc0
testb $0x1, %al
jne 0x73eb
jmp 0x743b
leaq -0xc8(%rbp), %rdi
callq 0x8000
movq %rax, -0xd8(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x210(%rbp)
movq -0xd8(%rbp), %rdi
callq 0x5190
movq -0x210(%rbp), %rdi
movq %rax, %rdx
leaq 0x30e9b(%rip), %rsi     # 0x382c1
movb $0x0, %al
callq 0x5570
leaq -0xc8(%rbp), %rdi
callq 0x8020
jmp 0x73d2
movq -0x40(%rbp), %rax
movq (%rax), %rax
addq $0x48, %rax
movq %rax, -0xe0(%rbp)
movq -0xe0(%rbp), %rdi
callq 0x8040
movq %rax, -0xe8(%rbp)
movq -0xe0(%rbp), %rdi
callq 0x8070
movq %rax, -0xf0(%rbp)
leaq -0xe8(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
callq 0x80a0
testb $0x1, %al
jne 0x748f
jmp 0x77bc
leaq -0xe8(%rbp), %rdi
callq 0x80e0
movq %rax, -0xf8(%rbp)
movl $0x4, -0xfc(%rbp)
movq -0xf8(%rbp), %rdx
addq $0x18, %rdx
leaq 0x30e1c(%rip), %rsi     # 0x382da
leaq -0x140(%rbp), %rdi
movq %rdi, -0x218(%rbp)
callq 0x8200
movq -0x218(%rbp), %rsi
leaq 0x30e02(%rip), %rdx     # 0x382e1
leaq -0x120(%rbp), %rdi
callq 0x81b0
jmp 0x74ed
leaq -0x140(%rbp), %rdi
callq 0x5280
leaq 0x31499(%rip), %rdx     # 0x38999
leaq -0x160(%rbp), %rdi
leaq -0x120(%rbp), %rsi
callq 0x8310
jmp 0x7515
movq -0xf8(%rbp), %rax
testb $0x1, 0x38(%rax)
je 0x7667
movq -0x20(%rbp), %rax
movq %rax, -0x248(%rbp)
movl -0xfc(%rbp), %eax
movl %eax, -0x23c(%rbp)
movq -0xf8(%rbp), %rdi
addq $0x18, %rdi
callq 0x5190
movq -0x248(%rbp), %rdi
movl -0x23c(%rbp), %edx
movq %rax, %r8
leaq 0x30d80(%rip), %rsi     # 0x382e4
leaq 0x30c70(%rip), %rcx     # 0x381db
movq %rcx, -0x228(%rbp)
xorl %eax, %eax
movb %al, -0x219(%rbp)
callq 0x5570
movl -0xfc(%rbp), %eax
addl $0x4, %eax
movl %eax, -0xfc(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x238(%rbp)
movl -0xfc(%rbp), %eax
movl %eax, -0x22c(%rbp)
movq -0xf8(%rbp), %rdi
addq $0x18, %rdi
callq 0x5190
movq -0x238(%rbp), %rdi
movl -0x22c(%rbp), %edx
movq -0x228(%rbp), %rcx
movq %rax, %r8
movb -0x219(%rbp), %al
leaq 0x30d42(%rip), %rsi     # 0x3831b
callq 0x5570
leaq 0x30d49(%rip), %rsi     # 0x3832e
leaq -0x120(%rbp), %rdi
callq 0x5520
jmp 0x75f3
leaq 0x30d3b(%rip), %rsi     # 0x38335
leaq -0x160(%rbp), %rdi
callq 0x5520
jmp 0x7608
jmp 0x7667
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x5280
jmp 0x7afd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
jmp 0x77ab
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
leaq -0x160(%rbp), %rdi
callq 0x5280
jmp 0x77ab
movq -0xf8(%rbp), %rax
cmpq $0x0, 0x80(%rax)
je 0x7685
movq -0xf8(%rbp), %rax
testb $0x1, 0x39(%rax)
je 0x76ed
movq -0x20(%rbp), %rax
movq %rax, -0x260(%rbp)
movl -0xfc(%rbp), %eax
movl %eax, -0x254(%rbp)
leaq -0x160(%rbp), %rdi
callq 0x5190
movq %rax, -0x250(%rbp)
movq -0xf8(%rbp), %rdi
addq $0x18, %rdi
callq 0x5190
movq -0x260(%rbp), %rdi
movl -0x254(%rbp), %edx
movq -0x250(%rbp), %r8
movq %rax, %r9
leaq 0x30c60(%rip), %rsi     # 0x3833d
leaq 0x30af7(%rip), %rcx     # 0x381db
movb $0x0, %al
callq 0x5570
jmp 0x7753
movq -0x20(%rbp), %rax
movq %rax, -0x278(%rbp)
movl -0xfc(%rbp), %eax
movl %eax, -0x26c(%rbp)
movq -0xf8(%rbp), %rdi
addq $0x18, %rdi
callq 0x5190
movq %rax, -0x268(%rbp)
leaq -0x120(%rbp), %rdi
callq 0x5190
movq -0x278(%rbp), %rdi
movl -0x26c(%rbp), %edx
movq -0x268(%rbp), %r8
movq %rax, %r9
leaq 0x30c0a(%rip), %rsi     # 0x3834f
leaq 0x30a8f(%rip), %rcx     # 0x381db
movb $0x0, %al
callq 0x5570
movq -0xf8(%rbp), %rax
testb $0x1, 0x38(%rax)
je 0x7782
movq -0x20(%rbp), %rdi
movl -0xfc(%rbp), %edx
subl $0x4, %edx
leaq 0x30bf3(%rip), %rsi     # 0x38367
leaq 0x30a60(%rip), %rcx     # 0x381db
movb $0x0, %al
callq 0x5570
leaq -0x160(%rbp), %rdi
callq 0x5280
leaq -0x120(%rbp), %rdi
callq 0x5280
leaq -0xe8(%rbp), %rdi
callq 0x8190
jmp 0x7473
leaq -0x120(%rbp), %rdi
callq 0x5280
jmp 0x7afd
movq -0x20(%rbp), %rdi
leaq 0x30ba6(%rip), %rsi     # 0x3836d
movb $0x0, %al
callq 0x5570
movq -0x20(%rbp), %rdi
leaq 0x30b99(%rip), %rsi     # 0x38372
movb $0x0, %al
callq 0x5570
movq -0x40(%rbp), %rax
movq (%rax), %rax
addq $0x30, %rax
movq %rax, -0x168(%rbp)
movq -0x168(%rbp), %rdi
callq 0x7f60
movq %rax, -0x170(%rbp)
movq -0x168(%rbp), %rdi
callq 0x7f90
movq %rax, -0x178(%rbp)
leaq -0x170(%rbp), %rdi
leaq -0x178(%rbp), %rsi
callq 0x7fc0
testb $0x1, %al
jne 0x7831
jmp 0x7881
leaq -0x170(%rbp), %rdi
callq 0x8000
movq %rax, -0x180(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x280(%rbp)
movq -0x180(%rbp), %rdi
callq 0x5190
movq -0x280(%rbp), %rdi
movq %rax, %rdx
leaq 0x30b33(%rip), %rsi     # 0x3839f
movb $0x0, %al
callq 0x5570
leaq -0x170(%rbp), %rdi
callq 0x8020
jmp 0x7818
movq -0x40(%rbp), %rax
movq (%rax), %rax
addq $0x48, %rax
movq %rax, -0x188(%rbp)
movq -0x188(%rbp), %rdi
callq 0x8040
movq %rax, -0x190(%rbp)
movq -0x188(%rbp), %rdi
callq 0x8070
movq %rax, -0x198(%rbp)
leaq -0x190(%rbp), %rdi
leaq -0x198(%rbp), %rsi
callq 0x80a0
testb $0x1, %al
jne 0x78d5
jmp 0x7a5c
leaq -0x190(%rbp), %rdi
callq 0x80e0
movq %rax, -0x1a0(%rbp)
movl $0x4, -0x1a4(%rbp)
movq -0x1a0(%rbp), %rax
testb $0x1, 0x38(%rax)
je 0x7955
movq -0x20(%rbp), %rax
movq %rax, -0x290(%rbp)
movl -0x1a4(%rbp), %eax
movl %eax, -0x284(%rbp)
movq -0x1a0(%rbp), %rdi
addq $0x18, %rdi
callq 0x5190
movq -0x290(%rbp), %rdi
movl -0x284(%rbp), %edx
movq %rax, %r8
leaq 0x30a79(%rip), %rsi     # 0x383b6
leaq 0x30897(%rip), %rcx     # 0x381db
movb $0x0, %al
callq 0x5570
movl $0x1, -0x1a4(%rbp)
movq -0x1a0(%rbp), %rax
cmpq $0x0, 0x80(%rax)
je 0x7973
movq -0x1a0(%rbp), %rax
testb $0x1, 0x39(%rax)
je 0x79df
movq -0x20(%rbp), %rax
movq %rax, -0x2a8(%rbp)
movl -0x1a4(%rbp), %eax
movl %eax, -0x29c(%rbp)
movq -0x1a0(%rbp), %rdi
addq $0x18, %rdi
callq 0x5190
movq %rax, -0x298(%rbp)
movq -0x1a0(%rbp), %rdi
addq $0x18, %rdi
callq 0x5190
movq -0x2a8(%rbp), %rdi
movl -0x29c(%rbp), %edx
movq -0x298(%rbp), %r8
movq %rax, %r9
leaq 0x309f6(%rip), %rsi     # 0x383c5
leaq 0x30805(%rip), %rcx     # 0x381db
movb $0x0, %al
callq 0x5570
jmp 0x7a49
movq -0x20(%rbp), %rax
movq %rax, -0x2c0(%rbp)
movl -0x1a4(%rbp), %eax
movl %eax, -0x2b4(%rbp)
movq -0x1a0(%rbp), %rdi
addq $0x18, %rdi
callq 0x5190
movq %rax, -0x2b0(%rbp)
movq -0x1a0(%rbp), %rdi
addq $0x18, %rdi
callq 0x5190
movq -0x2c0(%rbp), %rdi
movl -0x2b4(%rbp), %edx
movq -0x2b0(%rbp), %r8
movq %rax, %r9
leaq 0x3099f(%rip), %rsi     # 0x383da
leaq 0x30799(%rip), %rcx     # 0x381db
movb $0x0, %al
callq 0x5570
jmp 0x7a4b
leaq -0x190(%rbp), %rdi
callq 0x8190
jmp 0x78b9
movq -0x20(%rbp), %rdi
leaq 0x30906(%rip), %rsi     # 0x3836d
movb $0x0, %al
callq 0x5570
movq -0x20(%rbp), %rdi
leaq 0x30980(%rip), %rsi     # 0x383f9
movb $0x0, %al
callq 0x5570
movq -0x20(%rbp), %rax
movq %rax, -0x2d0(%rbp)
movq -0x40(%rbp), %rax
movq (%rax), %rdi
addq $0x10, %rdi
callq 0x5190
movq -0x2d0(%rbp), %rdi
movq %rax, %rdx
leaq 0x30951(%rip), %rsi     # 0x383fd
movb $0x0, %al
callq 0x5570
movq -0x20(%rbp), %rax
movq %rax, -0x2c8(%rbp)
movq -0x40(%rbp), %rax
movq (%rax), %rdi
addq $0x10, %rdi
callq 0x5190
movq -0x2c8(%rbp), %rdi
movq %rax, %rdx
leaq 0x3096c(%rip), %rsi     # 0x3844b
movb $0x0, %al
callq 0x5570
leaq -0x30(%rbp), %rdi
callq 0x8390
jmp 0x6e8b
addq $0x2d0, %rsp            # imm = 0x2D0
popq %rbp
retq
movq -0xb0(%rbp), %rdi
callq 0x5680
nopl (%rax)