// File: tomfunkhouser[P]gaps/pkgs/GSV/GSVMesh.cpp
// Function: gaps::GSVMesh::ReadPlyFile(gaps::GSVScan*, char const*)
int GSVMesh::
ReadPlyFile(GSVScan *scan, const char *filename)
{
  FILE *fp;
  int i,j;
  PlyFile *ply;
  int nelems;
  PlyProperty **plist;
  char **elist;
  int file_type;
  int nprops;
  int num_elems;
  char *elem_name;
  float version;

  typedef struct PlyVertex {
    float x, y, z;
    int scanline_index;
    int point_index;
    int boundary_type;
  } PlyVertex;

  typedef struct PlyFace {
    unsigned char nverts;
    int *verts;
    int segment;
  } PlyFace;

  // List of property information for a vertex 
  // List of property information for a vertex 
  static PlyProperty vert_props[] = { 
    {(char *) "x", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,x), 0, 0, 0, 0},
    {(char *) "y", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,y), 0, 0, 0, 0},
    {(char *) "z", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,z), 0, 0, 0, 0},
    {(char *) "scanline_index", PLY_INT, PLY_INT, offsetof(PlyVertex,scanline_index), 0, 0, 0, 0},
    {(char *) "point_index", PLY_INT, PLY_INT, offsetof(PlyVertex,point_index), 0, 0, 0, 0},
    {(char *) "boundary_type", PLY_INT, PLY_INT, offsetof(PlyVertex,boundary_type), 0, 0, 0, 0}
  };

  // List of property information for a vertex 
  static PlyProperty face_props[] = { 
    {(char *) "vertex_indices", PLY_INT, PLY_INT, offsetof(PlyFace,verts), 1, PLY_UCHAR, PLY_UCHAR, offsetof(PlyFace,nverts)},
    {(char *) "segment", PLY_INT, PLY_INT, offsetof(PlyFace,segment), 0, 0, 0, 0}
  };

  // Open file 
  fp = fopen(filename, "rb");
  if (!fp) {
    RNFail("Unable to open file: %s", filename);
    return 0;
  }

  // Read PLY header
  ply = ply_read (fp, &nelems, &elist);
  if (!ply) {
    RNFail("Unable to read ply file: %s", filename);
    fclose(fp);
    return 0;
  }
  
  // Get header info
  ply_get_info (ply, &version, &file_type);

  // Read obj infos
  int scan_index = 0;
  int segment_index = 0;
  char run_name[1024];
  int num_obj_infos = 0;
  char **obj_infos = ply_get_obj_info(ply, &num_obj_infos);
  for (int i = 0; i < num_obj_infos; i++) {
    char obj_info[1024];
    strncpy(obj_info, obj_infos[i], 1023);
    char *info_type = strtok(obj_info, " ");
    if (!info_type) continue;
    char *valuep = strtok(NULL, " ");
    if (!strcmp(info_type, "scan_index")) scan_index = atoi(valuep);
    else if (!strcmp(info_type, "segment_index")) segment_index = atoi(valuep);
    else if (!strcmp(info_type, "run_name")) strcpy(run_name, valuep);
  }

  // To silence compiler about unused variables
  if (scan_index == -146) printf("Wow\n");
  if (segment_index == -146) printf("Wow\n");

  // Read all elements
  for (i = 0; i < nelems; i++) {
    // Get the description of the element 
    elem_name = elist[i];
    plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops);

    // Check element type
    if (equal_strings ("vertex", elem_name)) {
      // Allocate block of vertices
      gsv_vertex_block = new GSVMeshVertex [num_elems];
      if (!gsv_vertex_block) {
        RNFail("Unable to allocate vertex matrix\n");
        return 0;
      }

      // Resize array of vertices
      vertices.Resize(num_elems);

      // set up for getting vertex elements 
      for (j = 0; j < nprops; j++) {
	if (equal_strings("x", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[0]);
	else if (equal_strings("y", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[1]);
	else if (equal_strings("z", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[2]);
	else if (equal_strings("scanline_index", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[3]);
	else if (equal_strings("point_index", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[4]);
	else if (equal_strings("boundary_type", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[5]);
      }

      // Grab all the vertex elements 
      for (j = 0; j < num_elems; j++) {
        // Read vertex into local struct
        PlyVertex plyvertex;
        plyvertex.scanline_index = -1;
        plyvertex.point_index = -1;
        plyvertex.boundary_type = 0;
        ply_get_element(ply, (void *) &plyvertex);

        // Create mesh vertex
        R3Point position(plyvertex.x, plyvertex.y, plyvertex.z);
        GSVMeshVertex *v = (GSVMeshVertex *) CreateVertex(position, &gsv_vertex_block[j]);
        v->scanline = (scan && (plyvertex.scanline_index >= 0)) ? scan->Scanline(plyvertex.scanline_index) : NULL;
        v->point_index = plyvertex.point_index;
        v->boundary_type = plyvertex.boundary_type;
      }
    }
    else if (equal_strings ("face", elem_name)) {
      // Resize array of faces
      faces.Resize(num_elems);

      // set up for getting face elements 
      for (j = 0; j < nprops; j++) {
	if (equal_strings("vertex_indices", plist[j]->name)) ply_get_property (ply, elem_name, &face_props[0]);
	else if (equal_strings("segment", plist[j]->name)) ply_get_property (ply, elem_name, &face_props[1]);
      }

      // grab all the face elements 
      for (j = 0; j < num_elems; j++) {
        // Read face into local struct
        PlyFace plyface;
        plyface.nverts = 0;
        plyface.verts = NULL;
        plyface.segment = 0;
        ply_get_element(ply, (void *) &plyface);

        // Create mesh face(s)
        R3MeshVertex *v1 = vertices[plyface.verts[0]];
        for (int k = 2; k < plyface.nverts; k++) {
          // Get vertices
          R3MeshVertex *v2 = vertices[plyface.verts[k-1]];
          R3MeshVertex *v3 = vertices[plyface.verts[k]];

          // Check plyface
          assert(plyface.verts[0] >= 0);
          assert(plyface.verts[k-1] >= 0);
          assert(plyface.verts[k] >= 0);
          assert(plyface.verts[0] < vertices.NEntries());
          assert(plyface.verts[k-1] < vertices.NEntries());
          assert(plyface.verts[k] < vertices.NEntries());

          // Check vertices
          if ((v1 == v2) || (v2 == v3) || (v1 == v3)) continue;

          // Create face
          R3MeshFace *f = CreateFace(v1, v2, v3);
          if (!f) {
            // Must have been degeneracy (e.g., three faces sharing an edge), create new vertices
            // Note: these vertices are allocated separately, and so they will not be deleted (memory leak)
            // R3MeshVertex *v1a = CreateVertex(VertexPosition(v1));
            // R3MeshVertex *v2a = CreateVertex(VertexPosition(v2));
            // R3MeshVertex *v3a = CreateVertex(VertexPosition(v3));
            // f = CreateFace(v1a, v2a, v3a);
          } 

          // Set boundary_type
          if (f) SetFaceSegment(f, plyface.segment);
        }

        // Free face data allocated by ply 
        if (plyface.verts) free(plyface.verts);
      }
    }
    else {
      ply_get_other_element (ply, elem_name, num_elems);
    }
  }

  // Close the file 
  ply_close (ply);

  // Return number of faces created
  return faces.NEntries();
}

// Assembly:
subq $0x988, %rsp            # imm = 0x988
movq %rdi, 0x978(%rsp)
movq %rsi, 0x970(%rsp)
movq %rdx, 0x968(%rsp)
movq 0x978(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x968(%rsp), %rdi
leaq 0x20a636(%rip), %rsi    # 0x266cc1
callq 0x2a520
movq %rax, 0x960(%rsp)
cmpq $0x0, 0x960(%rsp)
jne 0x5c6c9
movq 0x968(%rsp), %rsi
leaq 0x20aeca(%rip), %rdi    # 0x26757c
movb $0x0, %al
callq 0x1cbff0
movl $0x0, 0x984(%rsp)
jmp 0x5d10a
movq 0x960(%rsp), %rdi
leaq 0x94c(%rsp), %rsi
leaq 0x938(%rsp), %rdx
callq 0x18b460
movq %rax, 0x950(%rsp)
cmpq $0x0, 0x950(%rsp)
jne 0x5c72c
movq 0x968(%rsp), %rsi
leaq 0x20ae8c(%rip), %rdi    # 0x267594
movb $0x0, %al
callq 0x1cbff0
movq 0x960(%rsp), %rdi
callq 0x297e0
movl $0x0, 0x984(%rsp)
jmp 0x5d10a
movq 0x950(%rsp), %rdi
leaq 0x91c(%rsp), %rsi
leaq 0x934(%rsp), %rdx
callq 0x18d660
movl $0x0, 0x918(%rsp)
movl $0x0, 0x914(%rsp)
movl $0x0, 0x50c(%rsp)
movq 0x950(%rsp), %rdi
leaq 0x50c(%rsp), %rsi
callq 0x18cd80
movq %rax, 0x500(%rsp)
movl $0x0, 0x4fc(%rsp)
movl 0x4fc(%rsp), %eax
cmpl 0x50c(%rsp), %eax
jge 0x5c8b8
leaq 0xf0(%rsp), %rdi
movq 0x500(%rsp), %rax
movslq 0x4fc(%rsp), %rcx
movq (%rax,%rcx,8), %rsi
movl $0x3ff, %edx            # imm = 0x3FF
callq 0x292d0
leaq 0xf0(%rsp), %rdi
leaq 0x20e60e(%rip), %rsi    # 0x26ade9
callq 0x29520
movq %rax, 0xe8(%rsp)
cmpq $0x0, 0xe8(%rsp)
jne 0x5c7f8
jmp 0x5c8a2
xorl %eax, %eax
movl %eax, %edi
leaq 0x20e5e6(%rip), %rsi    # 0x26ade9
callq 0x29520
movq %rax, 0xe0(%rsp)
movq 0xe8(%rsp), %rdi
leaq 0x20ad91(%rip), %rsi    # 0x2675b0
callq 0x29f00
cmpl $0x0, %eax
jne 0x5c83f
movq 0xe0(%rsp), %rdi
callq 0x29610
movl %eax, 0x918(%rsp)
jmp 0x5c8a0
movq 0xe8(%rsp), %rdi
leaq 0x20ad6d(%rip), %rsi    # 0x2675bb
callq 0x29f00
cmpl $0x0, %eax
jne 0x5c86e
movq 0xe0(%rsp), %rdi
callq 0x29610
movl %eax, 0x914(%rsp)
jmp 0x5c89e
movq 0xe8(%rsp), %rdi
leaq 0x20ad4c(%rip), %rsi    # 0x2675c9
callq 0x29f00
cmpl $0x0, %eax
jne 0x5c89c
leaq 0x510(%rsp), %rdi
movq 0xe0(%rsp), %rsi
callq 0x29780
jmp 0x5c89e
jmp 0x5c8a0
jmp 0x5c8a2
movl 0x4fc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4fc(%rsp)
jmp 0x5c792
cmpl $0xffffff6e, 0x918(%rsp) # imm = 0xFFFFFF6E
jne 0x5c8d3
leaq 0x20ad06(%rip), %rdi    # 0x2675d2
movb $0x0, %al
callq 0x290f0
cmpl $0xffffff6e, 0x914(%rsp) # imm = 0xFFFFFF6E
jne 0x5c8ee
leaq 0x20aceb(%rip), %rdi    # 0x2675d2
movb $0x0, %al
callq 0x290f0
movl $0x0, 0x95c(%rsp)
movl 0x95c(%rsp), %eax
cmpl 0x94c(%rsp), %eax
jge 0x5d0e8
movq 0x938(%rsp), %rax
movslq 0x95c(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x920(%rsp)
movq 0x950(%rsp), %rdi
movq 0x920(%rsp), %rsi
leaq 0x92c(%rsp), %rdx
leaq 0x930(%rsp), %rcx
callq 0x18c180
movq %rax, 0x940(%rsp)
movq 0x920(%rsp), %rsi
leaq 0x20e365(%rip), %rdi    # 0x26acca
callq 0x18bc50
cmpl $0x0, %eax
je 0x5ce25
movslq 0x92c(%rsp), %rax
movq %rax, 0x38(%rsp)
movl $0xa8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
addq $0x8, %rdi
setb %al
orb %al, %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
movq %rdi, 0x30(%rsp)
callq 0x29820
movq %rax, %rcx
movq 0x38(%rsp), %rax
movq %rcx, 0x40(%rsp)
movq %rax, (%rcx)
addq $0x8, %rcx
movq %rcx, 0x48(%rsp)
cmpq $0x0, %rax
je 0x5ca1a
movq 0x48(%rsp), %rax
movq 0x38(%rsp), %rcx
imulq $0xa8, %rcx, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq %rcx, 0x20(%rsp)
movq %rax, 0x28(%rsp)
movq 0x28(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x5e0a0
jmp 0x5ca00
movq 0x20(%rsp), %rcx
movq 0x18(%rsp), %rax
addq $0xa8, %rax
cmpq %rcx, %rax
movq %rax, 0x28(%rsp)
jne 0x5c9ef
movq 0x50(%rsp), %rax
movq 0x48(%rsp), %rcx
movq %rcx, 0x138(%rax)
cmpq $0x0, 0x138(%rax)
jne 0x5cabb
leaq 0x20ab97(%rip), %rdi    # 0x2675d7
movb $0x0, %al
callq 0x1cbff0
movl $0x0, 0x984(%rsp)
jmp 0x5d10a
movq 0x48(%rsp), %rcx
movq %rax, %rsi
movq 0x18(%rsp), %rax
movq %rsi, 0xd8(%rsp)
movl %edx, 0xd4(%rsp)
cmpq %rax, %rcx
movq %rax, 0x10(%rsp)
je 0x5caa7
movq 0x10(%rsp), %rdi
addq $-0xa8, %rdi
movq %rdi, 0x8(%rsp)
callq 0x5e0f0
movq 0x48(%rsp), %rcx
movq 0x8(%rsp), %rax
cmpq %rcx, %rax
movq %rax, 0x10(%rsp)
jne 0x5ca7d
movq 0x30(%rsp), %rsi
movq 0x40(%rsp), %rdi
callq 0x29030
jmp 0x5d119
movq 0x50(%rsp), %rdi
addq $0x8, %rdi
movl 0x92c(%rsp), %esi
callq 0x1c7de0
movl $0x0, 0x958(%rsp)
movl 0x958(%rsp), %eax
cmpl 0x930(%rsp), %eax
jge 0x5ccd9
movq 0x940(%rsp), %rax
movslq 0x958(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rsi
leaq 0x225d45(%rip), %rdi    # 0x282852
callq 0x18bc50
cmpl $0x0, %eax
je 0x5cb38
movq 0x950(%rsp), %rdi
movq 0x920(%rsp), %rsi
leaq 0x293092(%rip), %rdx    # 0x2efbc0
callq 0x18c480
jmp 0x5ccc1
movq 0x940(%rsp), %rax
movslq 0x958(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rsi
leaq 0x20a2db(%rip), %rdi    # 0x266e31
callq 0x18bc50
cmpl $0x0, %eax
je 0x5cb85
movq 0x950(%rsp), %rdi
movq 0x920(%rsp), %rsi
leaq 0x293049(%rip), %rdx    # 0x2efbc0
addq $0x28, %rdx
callq 0x18c480
jmp 0x5ccbf
movq 0x940(%rsp), %rax
movslq 0x958(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rsi
leaq 0x209e4f(%rip), %rdi    # 0x2669f2
callq 0x18bc50
cmpl $0x0, %eax
je 0x5cbd2
movq 0x950(%rsp), %rdi
movq 0x920(%rsp), %rsi
leaq 0x292ffc(%rip), %rdx    # 0x2efbc0
addq $0x50, %rdx
callq 0x18c480
jmp 0x5ccbd
movq 0x940(%rsp), %rax
movslq 0x958(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rsi
leaq 0x20a954(%rip), %rdi    # 0x267544
callq 0x18bc50
cmpl $0x0, %eax
je 0x5cc1f
movq 0x950(%rsp), %rdi
movq 0x920(%rsp), %rsi
leaq 0x292faf(%rip), %rdx    # 0x2efbc0
addq $0x78, %rdx
callq 0x18c480
jmp 0x5ccbb
movq 0x940(%rsp), %rax
movslq 0x958(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rsi
leaq 0x20a916(%rip), %rdi    # 0x267553
callq 0x18bc50
cmpl $0x0, %eax
je 0x5cc6c
movq 0x950(%rsp), %rdi
movq 0x920(%rsp), %rsi
leaq 0x292f62(%rip), %rdx    # 0x2efbc0
addq $0xa0, %rdx
callq 0x18c480
jmp 0x5ccb9
movq 0x940(%rsp), %rax
movslq 0x958(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rsi
leaq 0x20a8d5(%rip), %rdi    # 0x26755f
callq 0x18bc50
cmpl $0x0, %eax
je 0x5ccb7
movq 0x950(%rsp), %rdi
movq 0x920(%rsp), %rsi
leaq 0x292f15(%rip), %rdx    # 0x2efbc0
addq $0xc8, %rdx
callq 0x18c480
jmp 0x5ccb9
jmp 0x5ccbb
jmp 0x5ccbd
jmp 0x5ccbf
jmp 0x5ccc1
jmp 0x5ccc3
movl 0x958(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x958(%rsp)
jmp 0x5cadb
movl $0x0, 0x958(%rsp)
movl 0x958(%rsp), %eax
cmpl 0x92c(%rsp), %eax
jge 0x5ce20
movl $0xffffffff, 0xc8(%rsp) # imm = 0xFFFFFFFF
movl $0xffffffff, 0xcc(%rsp) # imm = 0xFFFFFFFF
movl $0x0, 0xd0(%rsp)
movq 0x950(%rsp), %rdi
leaq 0xbc(%rsp), %rsi
callq 0x18c560
movss 0xbc(%rsp), %xmm0
cvtss2sd %xmm0, %xmm0
movss 0xc0(%rsp), %xmm1
cvtss2sd %xmm1, %xmm1
movss 0xc4(%rsp), %xmm2
cvtss2sd %xmm2, %xmm2
leaq 0xa0(%rsp), %rdi
callq 0x17fd90
movq 0x50(%rsp), %rdi
movq 0x138(%rdi), %rdx
movslq 0x958(%rsp), %rax
imulq $0xa8, %rax, %rax
addq %rax, %rdx
movq (%rdi), %rax
leaq 0xa0(%rsp), %rsi
callq *0x20(%rax)
movq %rax, 0x98(%rsp)
cmpq $0x0, 0x970(%rsp)
je 0x5cdc5
cmpl $0x0, 0xc8(%rsp)
jl 0x5cdc5
movq 0x970(%rsp), %rdi
movl 0xc8(%rsp), %esi
callq 0x3a0f0
movq %rax, (%rsp)
jmp 0x5cdcd
xorl %eax, %eax
movq %rax, (%rsp)
jmp 0x5cdcd
movq (%rsp), %rcx
movq 0x98(%rsp), %rax
movq %rcx, 0x98(%rax)
movl 0xcc(%rsp), %ecx
movq 0x98(%rsp), %rax
movl %ecx, 0xa0(%rax)
movl 0xd0(%rsp), %ecx
movq 0x98(%rsp), %rax
movl %ecx, 0xa4(%rax)
movl 0x958(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x958(%rsp)
jmp 0x5cce4
jmp 0x5d0d0
movq 0x920(%rsp), %rsi
leaq 0x20a7c5(%rip), %rdi    # 0x2675f9
callq 0x18bc50
cmpl $0x0, %eax
je 0x5d0b2
movq 0x50(%rsp), %rdi
addq $0x28, %rdi
movl 0x92c(%rsp), %esi
callq 0x1c7de0
movl $0x0, 0x958(%rsp)
movl 0x958(%rsp), %eax
cmpl 0x930(%rsp), %eax
jge 0x5cf1e
movq 0x940(%rsp), %rax
movslq 0x958(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rsi
leaq 0x20a6d9(%rip), %rdi    # 0x26756d
callq 0x18bc50
cmpl $0x0, %eax
je 0x5cebc
movq 0x950(%rsp), %rdi
movq 0x920(%rsp), %rsi
leaq 0x292dfb(%rip), %rdx    # 0x2efcb0
callq 0x18c480
jmp 0x5cf06
movq 0x940(%rsp), %rax
movslq 0x958(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rsi
leaq 0x226613(%rip), %rdi    # 0x2834ed
callq 0x18bc50
cmpl $0x0, %eax
je 0x5cf04
movq 0x950(%rsp), %rdi
movq 0x920(%rsp), %rsi
leaq 0x292db5(%rip), %rdx    # 0x2efcb0
addq $0x28, %rdx
callq 0x18c480
jmp 0x5cf06
jmp 0x5cf08
movl 0x958(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x958(%rsp)
jmp 0x5ce62
movl $0x0, 0x958(%rsp)
movl 0x958(%rsp), %eax
cmpl 0x92c(%rsp), %eax
jge 0x5d0b0
movb $0x0, 0x80(%rsp)
movq $0x0, 0x88(%rsp)
movl $0x0, 0x90(%rsp)
movq 0x950(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0x18c560
movq 0x50(%rsp), %rdi
addq $0x8, %rdi
movq 0x88(%rsp), %rax
movl (%rax), %esi
callq 0x5e370
movq (%rax), %rax
movq %rax, 0x78(%rsp)
movl $0x2, 0x74(%rsp)
movl 0x74(%rsp), %eax
movzbl 0x80(%rsp), %ecx
cmpl %ecx, %eax
jge 0x5d080
movq 0x50(%rsp), %rdi
addq $0x8, %rdi
movq 0x88(%rsp), %rax
movl 0x74(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %esi
callq 0x5e370
movq 0x50(%rsp), %rdi
movq (%rax), %rax
movq %rax, 0x68(%rsp)
addq $0x8, %rdi
movq 0x88(%rsp), %rax
movslq 0x74(%rsp), %rcx
movl (%rax,%rcx,4), %esi
callq 0x5e370
movq (%rax), %rax
movq %rax, 0x60(%rsp)
movq 0x78(%rsp), %rax
cmpq 0x68(%rsp), %rax
je 0x5d022
movq 0x68(%rsp), %rax
cmpq 0x60(%rsp), %rax
je 0x5d022
movq 0x78(%rsp), %rax
cmpq 0x60(%rsp), %rax
jne 0x5d024
jmp 0x5d070
movq 0x50(%rsp), %rdi
movq 0x78(%rsp), %rsi
movq 0x68(%rsp), %rdx
movq 0x60(%rsp), %rcx
movq (%rdi), %rax
xorl %r8d, %r8d
callq *0x48(%rax)
movq %rax, 0x58(%rsp)
cmpq $0x0, 0x58(%rsp)
jne 0x5d050
jmp 0x5d050
cmpq $0x0, 0x58(%rsp)
je 0x5d06e
movq 0x50(%rsp), %rdi
movq 0x58(%rsp), %rsi
movl 0x90(%rsp), %edx
callq 0x5e130
jmp 0x5d070
movl 0x74(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x74(%rsp)
jmp 0x5cf99
cmpq $0x0, 0x88(%rsp)
je 0x5d098
movq 0x88(%rsp), %rdi
callq 0x29350
jmp 0x5d09a
movl 0x958(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x958(%rsp)
jmp 0x5cf29
jmp 0x5d0ce
movq 0x950(%rsp), %rdi
movq 0x920(%rsp), %rsi
movl 0x92c(%rsp), %edx
callq 0x18d0f0
jmp 0x5d0d0
jmp 0x5d0d2
movl 0x95c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x95c(%rsp)
jmp 0x5c8f9
movq 0x950(%rsp), %rdi
callq 0x18d640
movq 0x50(%rsp), %rdi
addq $0x28, %rdi
callq 0x38730
movl %eax, 0x984(%rsp)
movl 0x984(%rsp), %eax
addq $0x988, %rsp            # imm = 0x988
retq
movq 0xd8(%rsp), %rdi
callq 0x29c10
nopw %cs:(%rax,%rax)