// File: /workspace/github_c_makefile_star2_O3/janet-lang[P]janet/src/core/bytecode.c
// Function: janet_verify
int janet_verify(JanetFuncDef *def) {
    int vargs = !!(def->flags & JANET_FUNCDEF_FLAG_VARARG);
    int32_t i;
    int32_t maxslot = def->arity + vargs;
    int32_t sc = def->slotcount;

    if (def->bytecode_length == 0) return 1;

    if (maxslot > sc) return 2;

    /* Verify each instruction */
    for (i = 0; i < def->bytecode_length; i++) {
        uint32_t instr = def->bytecode[i];
        /* Check for invalid instructions */
        if ((instr & 0x7F) >= JOP_INSTRUCTION_COUNT) {
            return 3;
        }
        enum JanetInstructionType type = janet_instructions[instr & 0x7F];
        switch (type) {
            case JINT_0:
                continue;
            case JINT_S: {
                if ((int32_t)(instr >> 8) >= sc) return 4;
                continue;
            }
            case JINT_SI:
            case JINT_SU:
            case JINT_ST: {
                if ((int32_t)((instr >> 8) & 0xFF) >= sc) return 4;
                continue;
            }
            case JINT_L: {
                int32_t jumpdest = i + (((int32_t)instr) >> 8);
                if (jumpdest < 0 || jumpdest >= def->bytecode_length) return 5;
                continue;
            }
            case JINT_SS: {
                if ((int32_t)((instr >> 8) & 0xFF) >= sc ||
                        (int32_t)(instr >> 16) >= sc) return 4;
                continue;
            }
            case JINT_SSI:
            case JINT_SSU: {
                if ((int32_t)((instr >> 8) & 0xFF) >= sc ||
                        (int32_t)((instr >> 16) & 0xFF) >= sc) return 4;
                continue;
            }
            case JINT_SL: {
                int32_t jumpdest = i + (((int32_t)instr) >> 16);
                if ((int32_t)((instr >> 8) & 0xFF) >= sc) return 4;
                if (jumpdest < 0 || jumpdest >= def->bytecode_length) return 5;
                continue;
            }
            case JINT_SSS: {
                if (((int32_t)(instr >> 8) & 0xFF) >= sc ||
                        ((int32_t)(instr >> 16) & 0xFF) >= sc ||
                        ((int32_t)(instr >> 24) & 0xFF) >= sc) return 4;
                continue;
            }
            case JINT_SD: {
                if ((int32_t)((instr >> 8) & 0xFF) >= sc) return 4;
                if ((int32_t)(instr >> 16) >= def->defs_length) return 6;
                continue;
            }
            case JINT_SC: {
                if ((int32_t)((instr >> 8) & 0xFF) >= sc) return 4;
                if ((int32_t)(instr >> 16) >= def->constants_length) return 7;
                continue;
            }
            case JINT_SES: {
                /* How can we check the last slot index? We need info parent funcdefs. Resort
                 * to runtime checks for now. Maybe invalid upvalue references could be defaulted
                 * to nil? (don't commit to this in the long term, though) */
                if ((int32_t)((instr >> 8) & 0xFF) >= sc) return 4;
                if ((int32_t)((instr >> 16) & 0xFF) >= def->environments_length) return 8;
                continue;
            }
        }
    }

    /* Verify last instruction is either a jump, return, return-nil, or tailcall. Eventually,
     * some real flow analysis would be ideal, but this should be very effective. Will completely
     * prevent running over the end of bytecode. However, valid functions with dead code will
     * be rejected. */
    {
        uint32_t lastop = def->bytecode[def->bytecode_length - 1] & 0xFF;
        switch (lastop) {
            default:
                return 9;
            case JOP_RETURN:
            case JOP_RETURN_NIL:
            case JOP_JUMP:
            case JOP_ERROR:
            case JOP_TAILCALL:
                break;
        }
    }

    return 0;
}

// Assembly:
movl 0x70(%rdi), %ecx
testq %rcx, %rcx
je 0x18f1a
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
movl 0x5c(%rdi), %r14d
movl 0x60(%rdi), %esi
btl $0x10, 0x58(%rdi)
adcl $0x0, %esi
movl $0x2, %eax
cmpl %r14d, %esi
jg 0x18f2c
movq 0x28(%rdi), %r11
testl %ecx, %ecx
jle 0x18ef2
xorl %r8d, %r8d
leaq 0x6c87c(%rip), %r9      # 0x85640
leaq 0x3b211(%rip), %r10     # 0x53fdc
movl (%r11,%r8,4), %ebx
movl %ebx, %eax
andl $0x7f, %eax
cmpl $0x4c, %eax
ja 0x18f20
movl (%r9,%rax,4), %eax
decl %eax
cmpl $0xc, %eax
ja 0x18ee6
movslq (%r10,%rax,4), %rax
addq %r10, %rax
jmpq *%rax
movzbl %bh, %eax
cmpl %r14d, %eax
jl 0x18ee6
jmp 0x18f27
movzbl %bh, %esi
movl $0x4, %eax
cmpl %r14d, %esi
jge 0x18f2c
shrl $0x10, %ebx
movzbl %bl, %esi
cmpl %r14d, %esi
jb 0x18ee6
jmp 0x18f2c
movzbl %bh, %eax
cmpl %r14d, %eax
jge 0x18f27
shrl $0x10, %ebx
movzbl %bl, %eax
cmpl 0x74(%rdi), %eax
jl 0x18ee6
jmp 0x18f46
movzbl %bh, %eax
cmpl %r14d, %eax
jge 0x18f27
shrl $0x10, %ebx
cmpl 0x6c(%rdi), %ebx
jl 0x18ee6
jmp 0x18f3f
movl %ebx, %edx
shrl $0x10, %edx
movl $0x4, %eax
cmpl %r14d, %edx
jge 0x18f2c
movzbl %bh, %ebx
cmpl %r14d, %ebx
jl 0x18ee6
jmp 0x18f2c
movzbl %bh, %eax
cmpl %r14d, %eax
jge 0x18f27
shrl $0x10, %ebx
cmpl 0x78(%rdi), %ebx
jl 0x18ee6
jmp 0x18f38
movzbl %bh, %eax
cmpl %r14d, %eax
jge 0x18f27
sarl $0x10, %ebx
jmp 0x18ebb
shrl $0x8, %ebx
cmpl %r14d, %ebx
jl 0x18ee6
jmp 0x18f27
sarl $0x8, %ebx
addl %r8d, %ebx
cmpl %ecx, %ebx
jb 0x18ee6
jmp 0x18f31
movzbl %bh, %esi
movl $0x4, %eax
cmpl %r14d, %esi
jge 0x18f2c
movl %ebx, %edx
shrl $0x18, %edx
cmpl %r14d, %edx
jae 0x18f2c
shrl $0x10, %ebx
movzbl %bl, %edx
cmpl %r14d, %edx
jae 0x18f2c
incq %r8
cmpq %r8, %rcx
jne 0x18dcb
movslq %ecx, %rax
movzbl -0x4(%r11,%rax,4), %ecx
movl $0x9, %eax
cmpq $0x36, %rcx
ja 0x18f2c
movabsq $0x4000001000001a, %rdx # imm = 0x4000001000001A
btq %rcx, %rdx
jae 0x18f2c
xorl %eax, %eax
jmp 0x18f2c
movl $0x1, %eax
retq
movl $0x3, %eax
jmp 0x18f2c
movl $0x4, %eax
popq %rbx
popq %r14
popq %rbp
retq
movl $0x5, %eax
jmp 0x18f2c
movl $0x6, %eax
jmp 0x18f2c
movl $0x7, %eax
jmp 0x18f2c
movl $0x8, %eax
jmp 0x18f2c