// File: /workspace/github_c_makefile_star2_O2/gplessis[P]dotdeb-redis/src/multi.c
// Function: execCommand
void execCommand(client *c) {
    int j;
    robj **orig_argv;
    int orig_argc;
    struct redisCommand *orig_cmd;
    int must_propagate = 0; /* Need to propagate MULTI/EXEC to AOF / slaves? */

    if (!(c->flags & CLIENT_MULTI)) {
        addReplyError(c,"EXEC without MULTI");
        return;
    }

    /* Check if we need to abort the EXEC because:
     * 1) Some WATCHed key was touched.
     * 2) There was a previous error while queueing commands.
     * A failed EXEC in the first case returns a multi bulk nil object
     * (technically it is not an error but a special behavior), while
     * in the second an EXECABORT error is returned. */
    if (c->flags & (CLIENT_DIRTY_CAS|CLIENT_DIRTY_EXEC)) {
        addReply(c, c->flags & CLIENT_DIRTY_EXEC ? shared.execaborterr :
                                                  shared.nullmultibulk);
        discardTransaction(c);
        goto handle_monitor;
    }

    /* Exec all the queued commands */
    unwatchAllKeys(c); /* Unwatch ASAP otherwise we'll waste CPU cycles */
    orig_argv = c->argv;
    orig_argc = c->argc;
    orig_cmd = c->cmd;
    addReplyMultiBulkLen(c,c->mstate.count);
    for (j = 0; j < c->mstate.count; j++) {
        c->argc = c->mstate.commands[j].argc;
        c->argv = c->mstate.commands[j].argv;
        c->cmd = c->mstate.commands[j].cmd;

        /* Propagate a MULTI request once we encounter the first write op.
         * This way we'll deliver the MULTI/..../EXEC block as a whole and
         * both the AOF and the replication link will have the same consistency
         * and atomicity guarantees. */
        if (!must_propagate && !(c->cmd->flags & CMD_READONLY)) {
            execCommandPropagateMulti(c);
            must_propagate = 1;
        }

        call(c,CMD_CALL_FULL);

        /* Commands may alter argc/argv, restore mstate. */
        c->mstate.commands[j].argc = c->argc;
        c->mstate.commands[j].argv = c->argv;
        c->mstate.commands[j].cmd = c->cmd;
    }
    c->argv = orig_argv;
    c->argc = orig_argc;
    c->cmd = orig_cmd;
    discardTransaction(c);
    /* Make sure the EXEC command will be propagated as well if MULTI
     * was already propagated. */
    if (must_propagate) server.dirty++;

handle_monitor:
    /* Send EXEC to clients waiting data from MONITOR. We do it here
     * since the natural order of commands execution is actually:
     * MUTLI, EXEC, ... commands inside transaction ...
     * Instead EXEC is flagged as CMD_SKIP_MONITOR in the command
     * table, and we do it here with correct ordering. */
    if (listLength(server.monitors) && !server.loading)
        replicationFeedMonitors(c,server.monitors,c->db->id,c->argv,c->argc);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %rbx
movl 0x98(%rdi), %eax
testb $0x8, %al
jne 0x570af
leaq 0x60083(%rip), %rsi     # 0xb711c
movq %rbx, %rdi
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x36b6f
testw $0x1020, %ax            # imm = 0x1020
je 0x570e5
btl $0xc, %eax
leaq 0xa3250(%rip), %rax     # 0xfa310
pushq $0x58
popq %rcx
movl $0xc8, %edx
cmovaeq %rcx, %rdx
movq (%rax,%rdx), %rsi
movq %rbx, %rdi
callq 0x36987
movq %rbx, %rdi
callq 0x56ea3
jmp 0x571c3
movq %rbx, %rdi
callq 0x56ece
movl 0x38(%rbx), %eax
movl %eax, 0xc(%rsp)
movups 0x40(%rbx), %xmm0
movaps %xmm0, 0x10(%rsp)
movslq 0x158(%rbx), %rsi
movq %rbx, %rdi
callq 0x370d9
xorl %r15d, %r15d
pushq $0x10
popq %r12
pushq $0x1
popq %r14
pushq $0xf
popq %rbp
xorl %r13d, %r13d
movslq 0x158(%rbx), %rax
cmpq %rax, %r15
jge 0x57198
movq 0x150(%rbx), %rax
movl -0x8(%rax,%r12), %ecx
movl %ecx, 0x38(%rbx)
movq -0x10(%rax,%r12), %rcx
movq %rcx, 0x40(%rbx)
movq (%rax,%r12), %rax
movq %rax, 0x48(%rbx)
testl %r13d, %r13d
movl %r14d, %r13d
jne 0x57165
xorl %r13d, %r13d
testb $0x2, 0x20(%rax)
jne 0x57165
movq %rbx, %rdi
callq 0x57027
movl %r14d, %r13d
movq %rbx, %rdi
movl %ebp, %esi
callq 0x2e246
movl 0x38(%rbx), %eax
movq 0x150(%rbx), %rcx
movl %eax, -0x8(%rcx,%r12)
movq 0x40(%rbx), %rax
movq %rax, -0x10(%rcx,%r12)
movq 0x48(%rbx), %rax
movq %rax, (%rcx,%r12)
incq %r15
addq $0x18, %r12
jmp 0x5711d
movl 0xc(%rsp), %eax
movl %eax, 0x38(%rbx)
movaps 0x10(%rsp), %xmm0
movups %xmm0, 0x40(%rbx)
movq %rbx, %rdi
callq 0x56ea3
testl %r13d, %r13d
je 0x571c3
leaq 0xa26ec(%rip), %rax     # 0xf98a8
incq 0x720(%rax)
leaq 0xa26de(%rip), %rax     # 0xf98a8
movq 0x1e8(%rax), %rsi
cmpq $0x0, 0x28(%rsi)
je 0x57206
cmpl $0x0, 0x31c(%rax)
jne 0x57206
movq 0x10(%rbx), %rax
movl 0x30(%rax), %edx
movq 0x40(%rbx), %rcx
movl 0x38(%rbx), %r8d
movq %rbx, %rdi
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3d1ad
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq