// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/scripting.c
// Function: scriptCommand
void scriptCommand(redisClient *c) {

    // SCRIPT FLUSH 命令
    if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"flush")) {
        scriptingReset();
        addReply(c,shared.ok);
        replicationScriptCacheFlush();
        server.dirty++; /* Propagating this command is a good idea. */

    // SCRIPT EXISTS 命令
    } else if (c->argc >= 2 && !strcasecmp(c->argv[1]->ptr,"exists")) {
        int j;

        addReplyMultiBulkLen(c, c->argc-2);
        for (j = 2; j < c->argc; j++) {
            if (dictFind(server.lua_scripts,c->argv[j]->ptr))
                addReply(c,shared.cone);
            else
                addReply(c,shared.czero);
        }

    // SCRIPT LOAD 命令
    } else if (c->argc == 3 && !strcasecmp(c->argv[1]->ptr,"load")) {
        char funcname[43];
        sds sha;

        // 函数名前缀
        funcname[0] = 'f';
        funcname[1] = '_';

        // 计算脚本的 SHA1 值
        sha1hex(funcname+2,c->argv[2]->ptr,sdslen(c->argv[2]->ptr));
        sha = sdsnewlen(funcname+2,40);

        // 根据 SHA1 值，在字典中查找脚本
        // 如果脚本未定义，在 Lua 中创建新函数
        if (dictFind(server.lua_scripts,sha) == NULL) {
            if (luaCreateFunction(c,server.lua,funcname,c->argv[2])
                    == REDIS_ERR) {
                sdsfree(sha);
                return;
            }
        }

        // 返回脚本的 SHA1 值
        addReplyBulkCBuffer(c,funcname+2,40);

        sdsfree(sha);

        forceCommandPropagation(c,REDIS_PROPAGATE_REPL|REDIS_PROPAGATE_AOF);

    // SCRIPT KILL 命令
    } else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"kill")) {
        if (server.lua_caller == NULL) {
            addReplySds(c,sdsnew("-NOTBUSY No scripts in execution right now.\r\n"));
        } else if (server.lua_write_dirty) {
            addReplySds(c,sdsnew("-UNKILLABLE Sorry the script already executed write commands against the dataset. You can either wait the script termination or kill the server in a hard way using the SHUTDOWN NOSAVE command.\r\n"));
        } else {
            server.lua_kill = 1;
            addReply(c,shared.ok);
        }

    } else {
        addReplyError(c, "Unknown SCRIPT subcommand or wrong # of args.");
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdi, %rbx
movl 0x30(%rdi), %r14d
cmpl $0x2, %r14d
jne 0x58826
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rdi
leaq 0x4560c(%rip), %rsi     # 0x9de25
callq 0x1f2e0
testl %eax, %eax
je 0x588b2
cmpl $0x2, %r14d
jl 0x5884c
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rdi
leaq 0x415d4(%rip), %rsi     # 0x99e13
callq 0x1f2e0
testl %eax, %eax
je 0x588e2
cmpl $0x3, %r14d
jne 0x58872
movq 0x38(%rbx), %r15
movq 0x8(%r15), %rax
movq 0x8(%rax), %rdi
leaq 0x428f3(%rip), %rsi     # 0x9b158
callq 0x1f2e0
testl %eax, %eax
je 0x5894d
cmpl $0x2, %r14d
jne 0x58898
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rdi
leaq 0x3e838(%rip), %rsi     # 0x970c3
callq 0x1f2e0
testl %eax, %eax
je 0x589ee
leaq 0x4567d(%rip), %rsi     # 0x9df1c
movq %rbx, %rdi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x2d9d7
callq 0x57e6a
leaq 0x71f42(%rip), %rax     # 0xca800
movq 0x8(%rax), %rsi
movq %rbx, %rdi
callq 0x2d6f0
callq 0x33d87
leaq 0x716d2(%rip), %rax     # 0xc9fa8
incq 0x560(%rax)
jmp 0x589e2
addl $-0x2, %r14d
movq %rbx, %rdi
movq %r14, %rsi
callq 0x2ded8
cmpl $0x3, 0x30(%rbx)
jl 0x589e2
movl $0x2, %r14d
leaq 0x716a0(%rip), %r15     # 0xc9fa8
leaq 0x71ef1(%rip), %r12     # 0xca800
movq 0x7f8(%r15), %rdi
movq 0x38(%rbx), %rax
movq (%rax,%r14,8), %rax
movq 0x8(%rax), %rsi
callq 0x224dc
xorl %ecx, %ecx
testq %rax, %rax
setne %cl
movq 0x20(%r12,%rcx,8), %rsi
movq %rbx, %rdi
callq 0x2d6f0
incq %r14
movslq 0x30(%rbx), %rax
cmpq %rax, %r14
jl 0x5890f
jmp 0x589e2
leaq 0x2(%rsp), %r14
movw $0x5f66, -0x2(%r14)     # imm = 0x5F66
movq 0x10(%r15), %rax
movq 0x8(%rax), %rsi
movslq -0x8(%rsi), %rdx
movq %r14, %rdi
callq 0x574a4
movl $0x28, %esi
movq %r14, %rdi
callq 0x28148
movq %rax, %r15
leaq 0x71624(%rip), %r12     # 0xc9fa8
movq 0x7f8(%r12), %rdi
movq %rax, %rsi
callq 0x224dc
testq %rax, %rax
jne 0x589bd
movq 0x7e0(%r12), %rsi
movq 0x38(%rbx), %rax
movq 0x10(%rax), %rcx
movq %rsp, %rdx
movq %rbx, %rdi
callq 0x581e4
cmpl $-0x1, %eax
je 0x58a5b
movl $0x28, %edx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x2dfa7
movq %r15, %rdi
callq 0x28204
movq %rbx, %rdi
movl $0x3, %esi
callq 0x25b1c
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
leaq 0x715b3(%rip), %rax     # 0xc9fa8
cmpq $0x0, 0x7f0(%rax)
je 0x58a11
cmpl $0x0, 0x810(%rax)
je 0x58a33
leaq 0x4544a(%rip), %rdi     # 0x9de59
jmp 0x58a18
leaq 0x45413(%rip), %rdi     # 0x9de2b
callq 0x281da
movq %rbx, %rdi
movq %rax, %rsi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x2d894
movl $0x1, 0x81c(%rax)
leaq 0x71dbc(%rip), %rax     # 0xca800
movq 0x8(%rax), %rsi
movq %rbx, %rdi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x2d6f0
movq %r15, %rdi
callq 0x28204
jmp 0x589e2