// File: /workspace/github_c_makefile_star2_O3/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 0x582ce
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %r15
leaq 0x45bff(%rip), %rsi     # 0x9de65
movq %r15, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x5838b
leaq 0x41bde(%rip), %rsi     # 0x99e5b
movq %r15, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x58327
leaq 0x3ee8f(%rip), %rsi     # 0x97123
movq %r15, %rdi
callq 0x1f2e0
testl %eax, %eax
jne 0x5830d
leaq 0x71d01(%rip), %rax     # 0xc9fa8
cmpq $0x0, 0x7f0(%rax)
je 0x58459
cmpl $0x0, 0x810(%rax)
je 0x5847b
leaq 0x45bd0(%rip), %rdi     # 0x9de99
jmp 0x58460
jl 0x5830d
movq 0x38(%rbx), %r12
movq 0x8(%r12), %rax
movq 0x8(%rax), %r15
leaq 0x41b77(%rip), %rsi     # 0x99e5b
movq %r15, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x58327
cmpl $0x3, %r14d
jne 0x5830d
leaq 0x42e9b(%rip), %rsi     # 0x9b198
movq %r15, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x583c2
leaq 0x45c48(%rip), %rsi     # 0x9df5c
movq %rbx, %rdi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x2dc63
addl $-0x2, %r14d
movq %rbx, %rdi
movq %r14, %rsi
callq 0x2e168
cmpl $0x3, 0x30(%rbx)
jl 0x583b6
movl $0x2, %r14d
leaq 0x71c5f(%rip), %r15     # 0xc9fa8
leaq 0x724b0(%rip), %r12     # 0xca800
movq 0x7f8(%r15), %rdi
movq 0x38(%rbx), %rax
movq (%rax,%r14,8), %rax
movq 0x8(%rax), %rsi
callq 0x226ac
xorl %ecx, %ecx
testq %rax, %rax
setne %cl
movq 0x20(%r12,%rcx,8), %rsi
movq %rbx, %rdi
callq 0x2d97c
incq %r14
movslq 0x30(%rbx), %rax
cmpq %rax, %r14
jl 0x58350
jmp 0x583b6
callq 0x578b2
leaq 0x72469(%rip), %rax     # 0xca800
movq 0x8(%rax), %rsi
movq %rbx, %rdi
callq 0x2d97c
callq 0x341c0
leaq 0x71bf9(%rip), %rax     # 0xc9fa8
incq 0x560(%rax)
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
leaq 0x2(%rsp), %r14
movw $0x5f66, -0x2(%r14)     # imm = 0x5F66
movq 0x10(%r12), %rax
movq 0x8(%rax), %rsi
movslq -0x8(%rsi), %rdx
movq %r14, %rdi
callq 0x56ee6
movl $0x28, %esi
movq %r14, %rdi
callq 0x283f4
movq %rax, %r15
leaq 0x71bae(%rip), %r12     # 0xc9fa8
movq 0x7f8(%r12), %rdi
movq %rax, %rsi
callq 0x226ac
testq %rax, %rax
jne 0x5842f
movq 0x7e0(%r12), %rsi
movq 0x38(%rbx), %rax
movq 0x10(%rax), %rcx
movq %rsp, %rdx
movq %rbx, %rdi
callq 0x57c2c
cmpl $-0x1, %eax
je 0x584a3
movl $0x28, %edx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x2e237
movq %r15, %rdi
callq 0x2850d
movq %rbx, %rdi
movl $0x3, %esi
callq 0x25d1e
jmp 0x583b6
leaq 0x45a0b(%rip), %rdi     # 0x9de6b
callq 0x28486
movq %rbx, %rdi
movq %rax, %rsi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x2db20
movl $0x1, 0x81c(%rax)
leaq 0x72374(%rip), %rax     # 0xca800
movq 0x8(%rax), %rsi
movq %rbx, %rdi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x2d97c
movq %r15, %rdi
callq 0x2850d
jmp 0x583b6