// File: /workspace/github_c_makefile_star2_O3/janet-lang[P]janet/src/core/os.c
// Function: os_execute_impl
static Janet os_execute_impl(int32_t argc, Janet *argv, JanetExecuteMode mode) {
    janet_sandbox_assert(JANET_SANDBOX_SUBPROCESS);
    janet_arity(argc, 1, 3);

    /* Get flags */
    int is_spawn = mode == JANET_EXECUTE_SPAWN;
    uint64_t flags = 0;
    if (argc > 1) {
        flags = janet_getflags(argv, 1, "epxd");
    }

    /* Get environment */
    int use_environ = !janet_flag_at(flags, 0);
    EnvBlock envp = os_execute_env(argc, argv);

    /* Get arguments */
    JanetView exargs = janet_getindexed(argv, 0);
    if (exargs.len < 1) {
        janet_panic("expected at least 1 command line argument");
    }

    /* Optional stdio redirections */
    JanetAbstract orig_in = NULL, orig_out = NULL, orig_err = NULL;
    JanetHandle new_in = JANET_HANDLE_NONE, new_out = JANET_HANDLE_NONE, new_err = JANET_HANDLE_NONE;
    JanetHandle pipe_in = JANET_HANDLE_NONE, pipe_out = JANET_HANDLE_NONE, pipe_err = JANET_HANDLE_NONE;
    int stderr_is_stdout = 0;
    int pipe_errflag = 0; /* Track errors setting up pipes */
    int pipe_owner_flags = (is_spawn && (flags & 0x8)) ? JANET_PROC_ALLOW_ZOMBIE : 0;

    /* Get optional redirections */
    if (argc > 2 && (mode != JANET_EXECUTE_EXEC)) {
        JanetDictView tab = janet_getdictionary(argv, 2);
        Janet maybe_stdin = janet_dictionary_get(tab.kvs, tab.cap, janet_ckeywordv("in"));
        Janet maybe_stdout = janet_dictionary_get(tab.kvs, tab.cap, janet_ckeywordv("out"));
        Janet maybe_stderr = janet_dictionary_get(tab.kvs, tab.cap, janet_ckeywordv("err"));
        if (is_spawn && janet_keyeq(maybe_stdin, "pipe")) {
            new_in = make_pipes(&pipe_in, 1, &pipe_errflag);
            pipe_owner_flags |= JANET_PROC_OWNS_STDIN;
        } else if (!janet_checktype(maybe_stdin, JANET_NIL)) {
            new_in = janet_getjstream(&maybe_stdin, 0, &orig_in);
        }
        if (is_spawn && janet_keyeq(maybe_stdout, "pipe")) {
            new_out = make_pipes(&pipe_out, 0, &pipe_errflag);
            pipe_owner_flags |= JANET_PROC_OWNS_STDOUT;
        } else if (!janet_checktype(maybe_stdout, JANET_NIL)) {
            new_out = janet_getjstream(&maybe_stdout, 0, &orig_out);
        }
        if (is_spawn && janet_keyeq(maybe_stderr, "pipe")) {
            new_err = make_pipes(&pipe_err, 0, &pipe_errflag);
            pipe_owner_flags |= JANET_PROC_OWNS_STDERR;
        } else if (is_spawn && janet_keyeq(maybe_stderr, "out")) {
            stderr_is_stdout = 1;
        } else if (!janet_checktype(maybe_stderr, JANET_NIL)) {
            new_err = janet_getjstream(&maybe_stderr, 0, &orig_err);
        }
    }

    /* Optional working directory. Available for both os/execute and os/spawn. */
    const char *chdir_path = NULL;
    if (argc > 2) {
        JanetDictView tab = janet_getdictionary(argv, 2);
        Janet workdir = janet_dictionary_get(tab.kvs, tab.cap, janet_ckeywordv("cd"));
        if (janet_checktype(workdir, JANET_STRING)) {
            chdir_path = (const char *) janet_unwrap_string(workdir);
#ifndef JANET_SPAWN_CHDIR
            janet_panicf(":cd argument not supported on this system - %s", chdir_path);
#endif
        } else if (!janet_checktype(workdir, JANET_NIL)) {
            janet_panicf("expected string for :cd argumnet, got %v", workdir);
        }
    }

    /* Clean up if any of the pipes have any issues */
    if (pipe_errflag) {
        if (pipe_in != JANET_HANDLE_NONE) close_handle(pipe_in);
        if (pipe_out != JANET_HANDLE_NONE) close_handle(pipe_out);
        if (pipe_err != JANET_HANDLE_NONE) close_handle(pipe_err);
        janet_panic("failed to create pipes");
    }

#ifdef JANET_WINDOWS

    HANDLE pHandle, tHandle;
    SECURITY_ATTRIBUTES saAttr;
    PROCESS_INFORMATION processInfo;
    STARTUPINFO startupInfo;
    LPCSTR lpCurrentDirectory = NULL;
    memset(&saAttr, 0, sizeof(saAttr));
    memset(&processInfo, 0, sizeof(processInfo));
    memset(&startupInfo, 0, sizeof(startupInfo));
    startupInfo.cb = sizeof(startupInfo);
    startupInfo.dwFlags |= STARTF_USESTDHANDLES;
    saAttr.nLength = sizeof(saAttr);

    JanetBuffer *buf = os_exec_escape(exargs);
    if (buf->count > 8191) {
        if (pipe_in != JANET_HANDLE_NONE) CloseHandle(pipe_in);
        if (pipe_out != JANET_HANDLE_NONE) CloseHandle(pipe_out);
        if (pipe_err != JANET_HANDLE_NONE) CloseHandle(pipe_err);
        janet_panic("command line string too long (max 8191 characters)");
    }
    const char *path = (const char *) janet_unwrap_string(exargs.items[0]);

    if (chdir_path != NULL) {
        lpCurrentDirectory = chdir_path;
    }

    /* Do IO redirection */

    if (pipe_in != JANET_HANDLE_NONE) {
        startupInfo.hStdInput = pipe_in;
    } else if (new_in != JANET_HANDLE_NONE) {
        startupInfo.hStdInput = new_in;
    } else {
        startupInfo.hStdInput = (HANDLE) _get_osfhandle(_fileno(stdin));
    }

    if (pipe_out != JANET_HANDLE_NONE) {
        startupInfo.hStdOutput = pipe_out;
    } else if (new_out != JANET_HANDLE_NONE) {
        startupInfo.hStdOutput = new_out;
    } else {
        startupInfo.hStdOutput = (HANDLE) _get_osfhandle(_fileno(stdout));
    }

    if (pipe_err != JANET_HANDLE_NONE) {
        startupInfo.hStdError = pipe_err;
    } else if (new_err != NULL) {
        startupInfo.hStdError = new_err;
    } else if (stderr_is_stdout) {
        startupInfo.hStdError = startupInfo.hStdOutput;
    } else {
        startupInfo.hStdError = (HANDLE) _get_osfhandle(_fileno(stderr));
    }

    int cp_failed = 0;
    if (!CreateProcess(janet_flag_at(flags, 1) ? NULL : path,
                       (char *) buf->data, /* Single CLI argument */
                       &saAttr, /* no proc inheritance */
                       &saAttr, /* no thread inheritance */
                       TRUE, /* handle inheritance */
                       0, /* flags */
                       use_environ ? NULL : envp, /* pass in environment */
                       lpCurrentDirectory,
                       &startupInfo,
                       &processInfo)) {
        cp_failed = 1;
    }

    if (pipe_in != JANET_HANDLE_NONE) CloseHandle(pipe_in);
    if (pipe_out != JANET_HANDLE_NONE) CloseHandle(pipe_out);
    if (pipe_err != JANET_HANDLE_NONE) CloseHandle(pipe_err);

    os_execute_cleanup(envp, NULL);

    if (cp_failed)  {
        janet_panic("failed to create process");
    }

    pHandle = processInfo.hProcess;
    tHandle = processInfo.hThread;

#else

    /* Result */
    int status = 0;

    const char **child_argv = janet_smalloc(sizeof(char *) * ((size_t) exargs.len + 1));
    for (int32_t i = 0; i < exargs.len; i++)
        child_argv[i] = janet_getcstring(exargs.items, i);
    child_argv[exargs.len] = NULL;
    /* Coerce to form that works for spawn. I'm fairly confident no implementation
     * of posix_spawn would modify the argv array passed in. */
    char *const *cargv = (char *const *)child_argv;

    if (use_environ) {
        janet_lock_environ();
    }

    /* exec mode */
    if (mode == JANET_EXECUTE_EXEC) {
        int status;
        if (!use_environ) {
            environ = envp;
        }
        do {
            if (janet_flag_at(flags, 1)) {
                status = execvp(cargv[0], cargv);
            } else {
                status = execv(cargv[0], cargv);
            }
        } while (status == -1 && errno == EINTR);
        janet_panicf("%p: %s", cargv[0], janet_strerror(errno ? errno : ENOENT));
    }

    /* Use posix_spawn to spawn new process */

    /* Posix spawn setup */
    posix_spawn_file_actions_t actions;
    posix_spawn_file_actions_init(&actions);
#ifdef JANET_SPAWN_CHDIR
    if (chdir_path != NULL) {
#ifdef JANET_SPAWN_CHDIR_NO_NP
        posix_spawn_file_actions_addchdir(&actions, chdir_path);
#else
        posix_spawn_file_actions_addchdir_np(&actions, chdir_path);
#endif
    }
#endif
    if (pipe_in != JANET_HANDLE_NONE) {
        posix_spawn_file_actions_adddup2(&actions, pipe_in, 0);
        posix_spawn_file_actions_addclose(&actions, pipe_in);
    } else if (new_in != JANET_HANDLE_NONE && new_in != 0) {
        posix_spawn_file_actions_adddup2(&actions, new_in, 0);
        if (new_in != new_out && new_in != new_err)
            posix_spawn_file_actions_addclose(&actions, new_in);
    }
    if (pipe_out != JANET_HANDLE_NONE) {
        posix_spawn_file_actions_adddup2(&actions, pipe_out, 1);
        posix_spawn_file_actions_addclose(&actions, pipe_out);
    } else if (new_out != JANET_HANDLE_NONE && new_out != 1) {
        posix_spawn_file_actions_adddup2(&actions, new_out, 1);
        if (new_out != new_err)
            posix_spawn_file_actions_addclose(&actions, new_out);
    }
    if (pipe_err != JANET_HANDLE_NONE) {
        posix_spawn_file_actions_adddup2(&actions, pipe_err, 2);
        posix_spawn_file_actions_addclose(&actions, pipe_err);
    } else if (new_err != JANET_HANDLE_NONE && new_err != 2) {
        posix_spawn_file_actions_adddup2(&actions, new_err, 2);
        posix_spawn_file_actions_addclose(&actions, new_err);
    } else if (stderr_is_stdout) {
        posix_spawn_file_actions_adddup2(&actions, 1, 2);
    }

    pid_t pid;
    if (janet_flag_at(flags, 1)) {
        status = posix_spawnp(&pid,
                              child_argv[0], &actions, NULL, cargv,
                              use_environ ? environ : envp);
    } else {
        status = posix_spawn(&pid,
                             child_argv[0], &actions, NULL, cargv,
                             use_environ ? environ : envp);
    }

    posix_spawn_file_actions_destroy(&actions);

    if (pipe_in != JANET_HANDLE_NONE) close(pipe_in);
    if (pipe_out != JANET_HANDLE_NONE) close(pipe_out);
    if (pipe_err != JANET_HANDLE_NONE) close(pipe_err);

    if (use_environ) {
        janet_unlock_environ();
    }

    os_execute_cleanup(envp, child_argv);
    if (status) {
        /* correct for macos bug where errno is not set */
        janet_panicf("%p: %s", argv[0], janet_strerror(errno ? errno : ENOENT));
    }

#endif
    JanetProc *proc = janet_abstract(&ProcAT, sizeof(JanetProc));
    proc->return_code = -1;
#ifdef JANET_WINDOWS
    proc->pHandle = pHandle;
    proc->tHandle = tHandle;
#else
    proc->pid = pid;
#endif
    proc->in = NULL;
    proc->out = NULL;
    proc->err = NULL;
    proc->flags = pipe_owner_flags;
    if (janet_flag_at(flags, 2)) {
        proc->flags |= JANET_PROC_ERROR_NONZERO;
    }
    if (is_spawn) {
        /* Only set up pointers to stdin, stdout, and stderr if os/spawn. */
        if (new_in != JANET_HANDLE_NONE) {
            proc->in = get_stdio_for_handle(new_in, orig_in, 1);
            if (NULL == proc->in) janet_panic("failed to construct proc");
        }
        if (new_out != JANET_HANDLE_NONE) {
            proc->out = get_stdio_for_handle(new_out, orig_out, 0);
            if (NULL == proc->out) janet_panic("failed to construct proc");
        }
        if (new_err != JANET_HANDLE_NONE) {
            proc->err = get_stdio_for_handle(new_err, orig_err, 0);
            if (NULL == proc->err) janet_panic("failed to construct proc");
        }
        return janet_wrap_abstract(proc);
    } else {
#ifdef JANET_EV
        os_proc_wait_impl(proc);
#else
        return os_proc_wait_impl(proc);
#endif
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
movl %edx, -0x60(%rbp)
movq %rsi, %rbx
movl %edi, %r12d
movabsq $-0x800000000000, %r15  # imm = 0xFFFF800000000000
movl $0x2, %edi
callq 0x4e921
movl %r12d, %edi
movl $0x1, %esi
movl $0x3, %edx
callq 0x1920c
cmpl $0x2, %r12d
movq %rbx, -0x68(%rbp)
jl 0x35b77
leaq 0x309ac(%rip), %rdx     # 0x664ef
movq %rbx, %rdi
movl $0x1, %esi
callq 0x19fef
movq %rbx, %rdi
movq %rax, %rbx
testb $0x1, %bl
sete -0x29(%rbp)
cmpl $0x2, %r12d
movq %rax, -0x78(%rbp)
jne 0x35b90
movq $0x0, -0x70(%rbp)
movq %rdi, %rbx
jmp 0x35ce5
movb $0x1, -0x29(%rbp)
movq $0x0, -0x78(%rbp)
movq $0x0, -0x70(%rbp)
jmp 0x35ce5
movl $0x2, %esi
callq 0x19d02
movq %rax, %r14
movq %rdx, %r13
movslq %r13d, %rax
leaq 0x8(,%rax,8), %rdi
callq 0x2bb46
movq %r13, %rcx
shrq $0x20, %rcx
xorl %edx, %edx
testl %ecx, %ecx
movq %rax, -0x70(%rbp)
jle 0x35cd9
movq $0x0, -0x38(%rbp)
movabsq $-0x6000000000000, %rdx # imm = 0xFFFA000000000000
xorl %r13d, %r13d
movl %r12d, -0x30(%rbp)
movq %rcx, -0x48(%rbp)
movq %r14, -0x58(%rbp)
movq %r13, %rbx
shlq $0x4, %rbx
movq (%r14,%rbx), %rdi
movq %rdi, %rax
andq %r15, %rax
cmpq %rdx, %rax
jne 0x35cc2
addq %r14, %rbx
movq 0x8(%rbx), %rax
andq %r15, %rax
cmpq %rdx, %rax
jne 0x35cc2
callq 0x4ebc4
movq %rax, %r15
movq 0x8(%rbx), %rdi
callq 0x4ebc4
movslq -0x8(%r15), %r12
movslq -0x8(%rax), %r14
testq %r12, %r12
jle 0x35c49
xorl %edx, %edx
movzbl (%r15,%rdx), %ecx
testl %ecx, %ecx
je 0x35ca2
cmpl $0x3d, %ecx
je 0x35ca2
incq %rdx
cmpq %rdx, %r12
jne 0x35c33
leaq (%r12,%r14), %rdi
addq $0x2, %rdi
movq %rax, -0x50(%rbp)
callq 0x2bb46
movq %rax, %rbx
movq %rax, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x12670
leaq (%rbx,%r12), %rdi
incq %rdi
movb $0x3d, -0x1(%rdi)
movq -0x50(%rbp), %rsi
movq %r14, %rdx
callq 0x12670
leal (%r12,%r14), %eax
cltq
movb $0x0, 0x1(%rbx,%rax)
movq -0x38(%rbp), %rcx
movslq %ecx, %rax
incl %ecx
movq %rcx, -0x38(%rbp)
movq -0x70(%rbp), %rcx
movq %rbx, (%rcx,%rax,8)
movabsq $-0x800000000000, %r15  # imm = 0xFFFF800000000000
movl -0x30(%rbp), %r12d
movq -0x48(%rbp), %rcx
movabsq $-0x6000000000000, %rdx # imm = 0xFFFA000000000000
movq -0x58(%rbp), %r14
incq %r13
cmpq %rcx, %r13
jne 0x35be6
movq -0x38(%rbp), %rdx
movslq %edx, %rdx
movq -0x70(%rbp), %rax
movq $0x0, (%rax,%rdx,8)
movq -0x68(%rbp), %rbx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x19cbb
testl %edx, %edx
jle 0x3649f
movq %rax, %r13
movl -0x60(%rbp), %r14d
cmpl $0x1, %r14d
sete %al
movabsq $-0x5000000000000, %r15 # imm = 0xFFFB000000000000
xorl %ecx, %ecx
movq %rcx, -0xa0(%rbp)
movq %rcx, -0x98(%rbp)
movq %rcx, -0x90(%rbp)
movq -0x78(%rbp), %rcx
andl $0x8, %ecx
shrl $0x3, %ecx
andb %al, %cl
movzbl %cl, %eax
shll $0x7, %eax
movl %eax, -0x5c(%rbp)
cmpl $0x3, %r12d
setl %al
cmpl $0x2, %r14d
sete %cl
orb %al, %cl
jne 0x35e72
movl %edx, -0x80(%rbp)
movq %rbx, %rdi
movl $0x2, %esi
callq 0x19d02
movq %rax, %rbx
movq %rdx, %r12
shrq $0x20, %r12
leaq 0x22640(%rip), %rdi     # 0x583b2
callq 0x47261
movq %rax, %rdi
movq %r15, %rsi
callq 0x4ed39
movq %rbx, %rdi
movl %r12d, %esi
movq %rax, %rdx
callq 0x486a9
movq %rax, %r15
movq %rax, -0x88(%rbp)
leaq 0x287c0(%rip), %rdi     # 0x5e561
callq 0x47261
movq %rax, %rdi
movabsq $-0x5000000000000, %rsi # imm = 0xFFFB000000000000
callq 0x4ed39
movq %rbx, %rdi
movl %r12d, %esi
movq %rax, %rdx
callq 0x486a9
movq %rax, -0x38(%rbp)
movq %rax, -0xb0(%rbp)
leaq 0x24c46(%rip), %rdi     # 0x5aa1e
callq 0x47261
movq %rax, %rdi
movabsq $-0x5000000000000, %rsi # imm = 0xFFFB000000000000
callq 0x4ed39
movq %rbx, %rdi
movl %r12d, %esi
movq %rax, %rdx
callq 0x486a9
movq %rax, %rbx
movq %rax, -0xa8(%rbp)
cmpl $0x1, %r14d
jne 0x35eb6
leaq 0x24b8e(%rip), %rsi     # 0x5a9a6
movq %r15, %rdi
callq 0x19331
testl %eax, %eax
je 0x35eb6
leaq -0x100(%rbp), %r15
movq %r15, %rdi
movl $0x2, %esi
callq 0x25b52
xorl %r12d, %r12d
testl %eax, %eax
setne %r12b
xorl %ecx, %ecx
negl %eax
sbbl %ecx, %ecx
movl (%r15), %eax
orl %ecx, %eax
movl %eax, -0x30(%rbp)
orl 0x4(%r15), %ecx
movq %rcx, -0x58(%rbp)
orl $0x10, -0x5c(%rbp)
movabsq $-0x800000000000, %r15  # imm = 0xFFFF800000000000
movq -0x38(%rbp), %r14
jmp 0x35f0c
movb $0x1, %r14b
cmpl $0x3, %r12d
jl 0x35ffa
movl %edx, -0x80(%rbp)
movl $0xffffffff, -0x30(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movq %rax, -0x58(%rbp)
movl $0xffffffff, -0x50(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x3c(%rbp) # imm = 0xFFFFFFFF
movb $0x1, %r12b
movl $0xffffffff, -0x48(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x38(%rbp) # imm = 0xFFFFFFFF
jmp 0x3609e
movabsq $-0x800000000000, %rax  # imm = 0xFFFF800000000000
andq %rax, %r15
movl $0xffffffff, -0x30(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movabsq $-0x7800000000000, %rcx # imm = 0xFFF8800000000000
cmpq %rcx, %r15
je 0x35ef1
leaq -0x88(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x387b0
movq %rax, -0x58(%rbp)
xorl %r12d, %r12d
cmpl $0x1, -0x60(%rbp)
movabsq $-0x800000000000, %r15  # imm = 0xFFFF800000000000
movq -0x38(%rbp), %r14
jne 0x35f63
leaq 0x24a93(%rip), %rsi     # 0x5a9a6
movq %r14, %rdi
callq 0x19331
testl %eax, %eax
je 0x35f63
leaq -0x100(%rbp), %r14
movl $0x1, %r15d
movq %r14, %rdi
movl $0x1, %esi
callq 0x25b52
xorl %edx, %edx
movl %eax, %ecx
negl %ecx
sbbl %edx, %edx
movl 0x4(%r14), %ecx
orl %edx, %ecx
testl %eax, %eax
cmovnel %r15d, %r12d
movabsq $-0x800000000000, %r15  # imm = 0xFFFF800000000000
orl (%r14), %edx
movl %edx, -0x50(%rbp)
orl $0x20, -0x5c(%rbp)
jmp 0x35fa6
andq %r15, %r14
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
movl $0xffffffff, -0x50(%rbp) # imm = 0xFFFFFFFF
movabsq $-0x7800000000000, %rax # imm = 0xFFF8800000000000
cmpq %rax, %r14
je 0x35f9c
leaq -0xb0(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x387b0
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
movl %eax, -0x50(%rbp)
cmpl $0x1, -0x60(%rbp)
jne 0x36055
movl %ecx, -0x38(%rbp)
leaq 0x249f6(%rip), %rsi     # 0x5a9a6
movq %rbx, %rdi
callq 0x19331
testl %eax, %eax
je 0x36033
leaq -0x100(%rbp), %rbx
movl $0x1, %r14d
movq %rbx, %rdi
movl $0x1, %esi
callq 0x25b52
xorl %edx, %edx
movl %eax, %ecx
negl %ecx
sbbl %edx, %edx
movl 0x4(%rbx), %ecx
orl %edx, %ecx
movl %ecx, -0x48(%rbp)
testl %eax, %eax
cmovnel %r14d, %r12d
orl (%rbx), %edx
orl $0x40, -0x5c(%rbp)
movb $0x1, %r14b
jmp 0x36090
movb $0x1, %al
movl %eax, -0x7c(%rbp)
movl $0xffffffff, -0x30(%rbp) # imm = 0xFFFFFFFF
xorl %r15d, %r15d
movl $0xffffffff, -0x38(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x48(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x3c(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x50(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movq %rax, -0x58(%rbp)
jmp 0x36130
leaq 0x28527(%rip), %rsi     # 0x5e561
movq %rbx, %rdi
callq 0x19331
testl %eax, %eax
je 0x36052
movl $0xffffffff, -0x48(%rbp) # imm = 0xFFFFFFFF
xorl %r14d, %r14d
jmp 0x36074
movl -0x38(%rbp), %ecx
andq %r15, %rbx
movb $0x1, %r14b
movl $0xffffffff, -0x48(%rbp) # imm = 0xFFFFFFFF
movabsq $-0x7800000000000, %rax # imm = 0xFFF8800000000000
cmpq %rax, %rbx
movl %ecx, -0x38(%rbp)
jne 0x3607b
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
jmp 0x36090
leaq -0xa8(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x387b0
movl %eax, %edx
movq -0x68(%rbp), %rbx
movl %edx, -0x3c(%rbp)
testl %r12d, %r12d
sete %r12b
movq %rbx, %rdi
movl $0x2, %esi
callq 0x19d02
movq %rax, %rbx
movq %rdx, %r15
shrq $0x20, %r15
leaq 0x3023b(%rip), %rdi     # 0x662f7
callq 0x47261
movq %rax, %rdi
movabsq $-0x5000000000000, %rsi # imm = 0xFFFB000000000000
callq 0x4ed39
movq %rbx, %rdi
movl %r15d, %esi
movq %rax, %rdx
callq 0x486a9
movabsq $-0x800000000000, %rdx  # imm = 0xFFFF800000000000
andq %rax, %rdx
movabsq $-0x7800000000000, %rcx # imm = 0xFFF8800000000000
cmpq %rcx, %rdx
je 0x3611d
movabsq $-0x6000000000000, %rcx # imm = 0xFFFA000000000000
cmpq %rcx, %rdx
jne 0x3657a
movq %rax, %rdi
callq 0x4ebc4
movq %rax, %r15
jmp 0x36120
xorl %r15d, %r15d
testb %r12b, %r12b
je 0x36544
movl %r14d, -0x7c(%rbp)
movl -0x80(%rbp), %edx
movl %edx, %r14d
leaq 0x8(,%r14,8), %rdi
callq 0x2bb46
movq %rax, %rbx
xorl %r12d, %r12d
movq %r13, %rdi
movl %r12d, %esi
callq 0x19817
movq %rax, (%rbx,%r12,8)
incq %r12
cmpq %r12, %r14
jne 0x36146
movq $0x0, (%rbx,%r14,8)
movl -0x60(%rbp), %r12d
cmpl $0x2, %r12d
je 0x364ab
leaq -0x100(%rbp), %rdi
callq 0x120f0
testq %r15, %r15
movq -0x70(%rbp), %r14
je 0x36197
leaq -0x100(%rbp), %rdi
movq %r15, %rsi
callq 0x12b70
movl -0x30(%rbp), %r15d
cmpl $-0x1, %r15d
je 0x361c3
leaq -0x100(%rbp), %rdi
movl %r15d, %esi
xorl %edx, %edx
callq 0x12af0
movl %r15d, %esi
leaq -0x100(%rbp), %rdi
callq 0x12aa0
jmp 0x361f4
movq -0x58(%rbp), %rax
decl %eax
cmpl $-0x3, %eax
ja 0x361f4
leaq -0x100(%rbp), %rdi
movq -0x58(%rbp), %r15
movl %r15d, %esi
xorl %edx, %edx
callq 0x12af0
cmpl -0x50(%rbp), %r15d
je 0x361f4
movq -0x58(%rbp), %rax
movl %eax, %esi
cmpl -0x3c(%rbp), %eax
jne 0x361b5
movl -0x38(%rbp), %r15d
cmpl $-0x1, %r15d
je 0x363fe
leaq -0x100(%rbp), %rdi
movl %r15d, %esi
movl $0x1, %edx
callq 0x12af0
movl %r15d, %esi
leaq -0x100(%rbp), %rdi
callq 0x12aa0
movl -0x48(%rbp), %esi
movl %r12d, %r13d
cmpl $-0x1, %esi
je 0x3643c
leaq -0x100(%rbp), %r15
movq %r15, %rdi
movl $0x2, %edx
movl %esi, %r12d
callq 0x12af0
movq %r15, %rdi
movl %r12d, %esi
callq 0x12aa0
movq %r14, %r9
cmpb $0x0, -0x29(%rbp)
je 0x36269
movq 0x4ed5a(%rip), %rax     # 0x84fc0
movq (%rax), %r9
movq (%rbx), %rsi
testb $0x2, -0x78(%rbp)
jne 0x3628c
leaq -0x88(%rbp), %rdi
leaq -0x100(%rbp), %rdx
xorl %ecx, %ecx
movq %rbx, %r8
callq 0x12980
jmp 0x362a4
leaq -0x88(%rbp), %rdi
leaq -0x100(%rbp), %rdx
xorl %ecx, %ecx
movq %rbx, %r8
callq 0x12800
movl %eax, %r15d
leaq -0x100(%rbp), %rdi
callq 0x122c0
movl -0x30(%rbp), %edi
cmpl $-0x1, %edi
je 0x362c0
callq 0x12460
movl -0x38(%rbp), %edi
cmpl $-0x1, %edi
je 0x362cd
callq 0x12460
movl -0x48(%rbp), %edi
cmpl $-0x1, %edi
je 0x362da
callq 0x12460
movq %rbx, %rdi
callq 0x2bcd9
testq %r14, %r14
je 0x36304
movq (%r14), %rdi
testq %rdi, %rdi
je 0x36304
leaq 0x8(%r14), %rbx
callq 0x2bcd9
movq (%rbx), %rdi
addq $0x8, %rbx
testq %rdi, %rdi
jne 0x362f3
movq %r14, %rdi
callq 0x2bcd9
testl %r15d, %r15d
jne 0x3650e
leaq 0x4c454(%rip), %rdi     # 0x82770
movl $0x28, %esi
callq 0x144c2
movq %rax, %rbx
movq -0x78(%rbp), %rax
addl %eax, %eax
andl $0x8, %eax
movl -0x5c(%rbp), %ecx
orl %eax, %ecx
movl $0xffffffff, 0x8(%rbx)  # imm = 0xFFFFFFFF
movl -0x88(%rbp), %eax
movl %eax, 0x4(%rbx)
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%rbx)
movq $0x0, 0x20(%rbx)
movl %ecx, (%rbx)
cmpl $0x1, %r13d
jne 0x3653c
movq -0x58(%rbp), %rdi
cmpl $-0x1, %edi
movl -0x50(%rbp), %r15d
je 0x36393
movq %rbx, %r14
addq $0x10, %r14
movq -0xa0(%rbp), %rsi
movl $0x1, %edx
callq 0x38833
movq %rax, (%r14)
testq %rax, %rax
je 0x36493
cmpl $-0x1, %r15d
je 0x363b7
movq -0x98(%rbp), %rsi
movl %r15d, %edi
xorl %edx, %edx
callq 0x38833
movq %rax, 0x18(%rbx)
testq %rax, %rax
je 0x36493
movl -0x3c(%rbp), %edi
cmpl $-0x1, %edi
je 0x363da
movq -0x90(%rbp), %rsi
xorl %edx, %edx
callq 0x38833
movq %rax, 0x20(%rbx)
testq %rax, %rax
je 0x36493
movabsq $-0x1000000000000, %rsi # imm = 0xFFFF000000000000
movq %rbx, %rdi
callq 0x4ed7e
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $-0x1, -0x50(%rbp)
je 0x36225
cmpl $0x1, -0x50(%rbp)
je 0x36225
leaq -0x100(%rbp), %rdi
movl -0x50(%rbp), %r15d
movl %r15d, %esi
movl $0x1, %edx
callq 0x12af0
movl %r15d, %esi
cmpl -0x3c(%rbp), %r15d
jne 0x36219
jmp 0x36225
movl -0x3c(%rbp), %r15d
cmpl $-0x1, %r15d
je 0x3644c
cmpl $0x2, %r15d
jne 0x36471
cmpb $0x0, -0x7c(%rbp)
jne 0x36256
leaq -0x100(%rbp), %rdi
movl $0x1, %esi
movl $0x2, %edx
callq 0x12af0
jmp 0x36256
leaq -0x100(%rbp), %r12
movq %r12, %rdi
movl %r15d, %esi
movl $0x2, %edx
callq 0x12af0
movq %r12, %rdi
movl %r15d, %esi
jmp 0x36251
leaq 0x300cb(%rip), %rdi     # 0x66565
callq 0x191a3
leaq 0x3004e(%rip), %rdi     # 0x664f4
callq 0x191a3
cmpb $0x0, -0x29(%rbp)
jne 0x364bf
movq 0x4eb08(%rip), %rax     # 0x84fc0
movq -0x70(%rbp), %rcx
movq %rcx, (%rax)
movq -0x78(%rbp), %r15
movq (%rbx), %rdi
movq %rbx, %rsi
testb $0x2, %r15b
jne 0x364d6
callq 0x12bd0
jmp 0x364db
callq 0x12a10
movl %eax, %r14d
callq 0x12120
cmpl $-0x1, %r14d
jne 0x364ee
cmpl $0x4, (%rax)
je 0x364c3
movq (%rbx), %rbx
movl (%rax), %eax
testl %eax, %eax
movl $0x2, %edi
cmovnel %eax, %edi
callq 0x49d9a
leaq 0x30055(%rip), %rdi     # 0x6655e
movq %rbx, %rsi
jmp 0x36532
callq 0x12120
movl (%rax), %eax
testl %eax, %eax
movl $0x2, %edi
cmovnel %eax, %edi
callq 0x49d9a
movq -0x68(%rbp), %rcx
movq (%rcx), %rsi
leaq 0x3002c(%rip), %rdi     # 0x6655e
movq %rax, %rdx
xorl %eax, %eax
callq 0x190bb
movq %rbx, %rdi
callq 0x355ca
cmpl $-0x1, -0x30(%rbp)
je 0x36552
movl -0x30(%rbp), %edi
callq 0x12460
cmpl $-0x1, -0x38(%rbp)
je 0x36560
movl -0x38(%rbp), %edi
callq 0x12460
cmpl $-0x1, -0x48(%rbp)
je 0x3656e
movl -0x48(%rbp), %edi
callq 0x12460
leaq 0x2ffd2(%rip), %rdi     # 0x66547
callq 0x191a3
leaq 0x2ff9d(%rip), %rdi     # 0x6651e
movq %rax, %rsi
xorl %eax, %eax
callq 0x190bb