// File: /workspace/github_c_makefile_star2_O2/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 0x53c60
movq 0x38(%rbx), %r12
movq 0x8(%r12), %rax
movq 0x8(%rax), %r15
leaq 0x40201(%rip), %rsi     # 0x93e25
movq %r15, %rdi
callq 0x1f2e0
testl %eax, %eax
jne 0x53c73
callq 0x53343
leaq 0x73bc4(%rip), %rax     # 0xc7800
movq 0x8(%rax), %rsi
movq %rbx, %rdi
callq 0x2c10d
callq 0x32011
leaq 0x73354(%rip), %rax     # 0xc6fa8
incq 0x560(%rax)
jmp 0x53d3b
jl 0x53dbc
movq 0x38(%rbx), %r12
movq 0x8(%r12), %rax
movq 0x8(%rax), %r15
leaq 0x3c1a5(%rip), %rsi     # 0x8fe1f
movq %r15, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x53d47
cmpl $0x3, %r14d
jne 0x53da3
leaq 0x3d4bd(%rip), %rsi     # 0x91158
movq %r15, %rdi
callq 0x1f2e0
testl %eax, %eax
jne 0x53dbc
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 0x529ed
pushq $0x28
popq %rsi
movq %r14, %rdi
callq 0x27158
movq %rax, %r15
leaq 0x732c7(%rip), %r12     # 0xc6fa8
movq 0x7f8(%r12), %rdi
movq %rax, %rsi
callq 0x21b64
testq %rax, %rax
jne 0x53d1a
movq 0x7e0(%r12), %rsi
movq 0x38(%rbx), %rax
movq 0x10(%rax), %rcx
movq %rsp, %rdx
movq %rbx, %rdi
callq 0x53644
cmpl $-0x1, %eax
je 0x53e1b
pushq $0x28
popq %rdx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x2c87d
movq %r15, %rdi
callq 0x271f7
pushq $0x3
popq %rsi
movq %rbx, %rdi
callq 0x24c79
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
addl $-0x2, %r14d
movq %rbx, %rdi
movq %r14, %rsi
callq 0x2c7c7
pushq $0x2
popq %r14
leaq 0x73247(%rip), %r15     # 0xc6fa8
leaq 0x73a98(%rip), %r12     # 0xc7800
movslq 0x30(%rbx), %rax
cmpq %rax, %r14
jge 0x53d3b
movq 0x7f8(%r15), %rdi
movq 0x38(%rbx), %rax
movq (%rax,%r14,8), %rax
movq 0x8(%rax), %rsi
callq 0x21b64
xorl %ecx, %ecx
testq %rax, %rax
setne %cl
movq 0x20(%r12,%rcx,8), %rsi
movq %rbx, %rdi
callq 0x2c10d
incq %r14
jmp 0x53d68
cmpl $0x2, %r14d
jne 0x53dbc
leaq 0x39343(%rip), %rsi     # 0x8d0f3
movq %r15, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x53dd6
leaq 0x40159(%rip), %rsi     # 0x93f1c
movq %rbx, %rdi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x2c2da
leaq 0x731cb(%rip), %rax     # 0xc6fa8
cmpq $0x0, 0x7f0(%rax)
je 0x53df9
cmpl $0x0, 0x810(%rax)
je 0x53e28
leaq 0x40062(%rip), %rdi     # 0x93e59
jmp 0x53e00
leaq 0x4002b(%rip), %rdi     # 0x93e2b
callq 0x271cd
movq %rbx, %rdi
movq %rax, %rsi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x2c20f
movq %r15, %rdi
callq 0x271f7
jmp 0x53d3b
movl $0x1, 0x81c(%rax)
leaq 0x739c7(%rip), %rax     # 0xc7800
movq 0x8(%rax), %rsi
movq %rbx, %rdi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x2c10d