// File: /workspace/github_c_makefile_star2_O1/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 0x19005
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movl 0x5c(%rdi), %r12d
movl 0x60(%rdi), %edx
btl $0x10, 0x58(%rdi)
adcl $0x0, %edx
movl $0x2, %eax
cmpl %r12d, %edx
jg 0x18ffa
testl %ecx, %ecx
jle 0x18fd1
movq 0x28(%rdi), %rsi
xorl %r8d, %r8d
leaq 0x6d825(%rip), %r9      # 0x86650
leaq 0x3c1aa(%rip), %r10     # 0x54fdc
movl $0x4, %r11d
movl $0x5, %r15d
movl (%rsi,%r8,4), %edx
movl %edx, %ebx
andl $0x7f, %ebx
movl $0x3, %eax
movl $0x1, %r14d
cmpl $0x4c, %ebx
ja 0x18fbc
movl (%r9,%rbx,4), %eax
cmpq $0xd, %rax
ja 0x18fb6
movslq (%r10,%rax,4), %rax
addq %r10, %rax
jmpq *%rax
movzbl %dh, %eax
jmp 0x18e8e
movzbl %dh, %ebx
movl $0x4, %eax
cmpl %r12d, %ebx
jge 0x18fbc
shrl $0x10, %edx
movzbl %dl, %eax
xorl %edx, %edx
cmpl %r12d, %eax
setl %dl
leal 0x1(%rdx,%rdx,2), %r14d
cmovgel %r11d, %r13d
jmp 0x18fb9
movzbl %dh, %ebx
movl $0x4, %eax
cmpl %r12d, %ebx
jge 0x18fbc
sarl $0x10, %edx
jmp 0x18f0f
movzbl %dh, %ebx
movl $0x4, %eax
cmpl %r12d, %ebx
jge 0x18fbc
movl %edx, %eax
shrl $0x10, %eax
movzbl %al, %eax
cmpl %r12d, %eax
setl %al
shrl $0x18, %edx
jmp 0x18f33
movzbl %dh, %ebx
movl $0x4, %eax
cmpl %r12d, %ebx
jge 0x18fbc
shrl $0x10, %edx
movzbl %dl, %eax
xorl %edx, %edx
cmpl 0x74(%rdi), %eax
setl %dl
leal 0x1(%rdx,%rdx,2), %r14d
movl $0x8, %eax
jmp 0x18fb0
sarl $0x8, %edx
addl %r8d, %edx
xorl %eax, %eax
cmpl %ecx, %edx
setb %al
leal 0x1(%rax,%rax,2), %r14d
cmovael %r15d, %r13d
jmp 0x18fb9
movzbl %dh, %eax
cmpl %r12d, %eax
setl %al
shrl $0x10, %edx
cmpl %r12d, %edx
setl %dl
andb %al, %dl
movzbl %dl, %eax
leal (%rax,%rax,2), %r14d
incl %r14d
testb %al, %al
cmovel %r11d, %r13d
jmp 0x18fb9
movl $0x4, %r14d
jmp 0x18fb9
shrl $0x8, %edx
xorl %eax, %eax
cmpl %r12d, %edx
setl %al
leal 0x1(%rax,%rax,2), %r14d
jmp 0x18e9b
movzbl %dh, %ebx
movl $0x4, %eax
cmpl %r12d, %ebx
jge 0x18fbc
shrl $0x10, %edx
xorl %eax, %eax
cmpl 0x78(%rdi), %edx
setl %al
leal 0x1(%rax,%rax,2), %r14d
movl $0x6, %eax
jmp 0x18fb0
movzbl %dh, %ebx
movl $0x4, %eax
cmpl %r12d, %ebx
jge 0x18fbc
shrl $0x10, %edx
xorl %eax, %eax
cmpl 0x6c(%rdi), %edx
setl %al
leal 0x1(%rax,%rax,2), %r14d
movl $0x7, %eax
cmovgel %eax, %r13d
jmp 0x18fb9
xorl %r14d, %r14d
movl %r13d, %eax
testb $0x3, %r14b
jne 0x18ffa
incq %r8
movl %eax, %r13d
cmpq %r8, %rcx
jne 0x18e3e
movslq %ecx, %rax
movq 0x28(%rdi), %rcx
movzbl -0x4(%rcx,%rax,4), %ecx
movl $0x9, %eax
cmpq $0x36, %rcx
ja 0x18ffa
movabsq $0x4000001000001a, %rdx # imm = 0x4000001000001A
btq %rcx, %rdx
jae 0x18ffa
xorl %eax, %eax
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x1, %eax
retq