// File: /workspace/github_c_makefile_star2_O2/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:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movslq 0x70(%rdi), %r15
testq %r15, %r15
je 0x173c1
movl 0x5c(%rdi), %edx
btl $0x10, 0x58(%rdi)
movl 0x60(%rdi), %eax
adcl $0x0, %eax
cmpl %edx, %eax
jle 0x173cb
movl $0x2, %eax
jmp 0x17513
movl $0x1, %eax
jmp 0x17513
xorl %r8d, %r8d
testl %r15d, %r15d
movl $0x0, %r9d
cmovgl %r15d, %r9d
movq 0x28(%rdi), %r10
movl $0x3, %eax
leaq 0x69255(%rip), %r11     # 0x80640
leaq 0x38bea(%rip), %r14     # 0x4ffdc
movl $0x4, %esi
movl $0x8, %r12d
movl $0x7, %r13d
cmpq %r8, %r9
je 0x174ec
movl (%r10,%r8,4), %ecx
movl %ecx, %ebx
andl $0x7f, %ebx
cmpl $0x4c, %ebx
ja 0x17513
movl (%r11,%rbx,4), %ebx
decl %ebx
cmpl $0xc, %ebx
ja 0x174e4
movslq (%r14,%rbx,4), %rbx
addq %r14, %rbx
jmpq *%rbx
movzbl %ch, %ebx
cmpl %edx, %ebx
jl 0x174da
jmp 0x17511
movzbl %ch, %ebx
cmpl %edx, %ebx
jge 0x17511
shrl $0x10, %ecx
movzbl %cl, %ecx
cmpl 0x74(%rdi), %ecx
jl 0x174e4
jmp 0x17525
movzbl %ch, %ebx
cmpl %edx, %ebx
jge 0x17511
shrl $0x10, %ecx
cmpl 0x6c(%rdi), %ecx
jl 0x174e4
jmp 0x17531
shrl $0x8, %ecx
cmpl %edx, %ecx
jl 0x174e4
jmp 0x17511
sarl $0x8, %ecx
jmp 0x174be
movzbl %ch, %ebx
cmpl %edx, %ebx
jge 0x17511
shrl $0x10, %ecx
cmpl 0x78(%rdi), %ecx
jl 0x174e4
jmp 0x1752a
movl %ecx, %ebx
shrl $0x10, %ebx
cmpl %edx, %ebx
jge 0x17511
movzbl %ch, %ecx
cmpl %edx, %ecx
jl 0x174e4
jmp 0x17511
movzbl %ch, %ebx
cmpl %edx, %ebx
jge 0x17511
sarl $0x10, %ecx
addl %r8d, %ecx
js 0x1751e
cmpl %r15d, %ecx
jl 0x174e4
jmp 0x1751e
movzbl %ch, %ebx
cmpl %edx, %ebx
jge 0x17511
movl %ecx, %ebx
shrl $0x18, %ebx
cmpl %edx, %ebx
jae 0x17511
shrl $0x10, %ecx
movzbl %cl, %ecx
cmpl %edx, %ecx
jae 0x17511
incq %r8
jmp 0x17403
movzbl -0x4(%r10,%r15,4), %ecx
movl $0x9, %eax
cmpq $0x36, %rcx
ja 0x17513
movabsq $0x4000001000001a, %rdx # imm = 0x4000001000001A
btq %rcx, %rdx
jae 0x17513
xorl %eax, %eax
jmp 0x17513
movl %esi, %eax
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x5, %eax
jmp 0x17513
movl %r12d, %eax
jmp 0x17513
movl $0x6, %eax
jmp 0x17513
movl %r13d, %eax
jmp 0x17513