// File: /workspace/github_c_makefile_star2_O1/janet-lang[P]janet/src/core/peg.c
// Function: get_linecol_from_position
static LineCol get_linecol_from_position(PegState *s, int32_t position) {
    /* Generate if not made yet */
    if (s->linemaplen < 0) {
        int32_t newline_count = 0;
        for (const uint8_t *c = s->text_start; c < s->outer_text_end; c++) {
            if (*c == '\n') newline_count++;
        }
        int32_t *mem = janet_smalloc(sizeof(int32_t) * newline_count);
        size_t index = 0;
        for (const uint8_t *c = s->text_start; c < s->outer_text_end; c++) {
            if (*c == '\n') mem[index++] = (int32_t)(c - s->text_start);
        }
        s->linemaplen = newline_count;
        s->linemap = mem;
    }
    /* Do binary search for line. Slightly modified from classic binary search:
     * - if we find that our current character is a line break, just return immediately.
     *   a newline character is consider to be on the same line as the character before
     *   (\n is line terminator, not line separator).
     * - in the not-found case, we still want to find the greatest-indexed newline that
     *   is before position. we use that to calculate the line and column.
     * - in the case that lo = 0 and s->linemap[0] is still greater than position, we
     *   are on the first line and our column is position + 1. */
    int32_t hi = s->linemaplen; /* hi is greater than the actual line */
    int32_t lo = 0; /* lo is less than or equal to the actual line */
    LineCol ret;
    while (lo + 1 < hi) {
        int32_t mid = lo + (hi - lo) / 2;
        if (s->linemap[mid] >= position) {
            hi = mid;
        } else {
            lo = mid;
        }
    }
    /* first line case */
    if (s->linemaplen == 0 || (lo == 0 && s->linemap[0] >= position)) {
        ret.line = 1;
        ret.col = position + 1;
    } else {
        ret.line = lo + 2;
        ret.col = position - s->linemap[lo];
    }
    return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movl %esi, %ebx
movq %rdi, %r14
cmpl $0x0, 0x60(%rdi)
jns 0x3ee98
movq (%r14), %rax
movq 0x10(%r14), %rcx
xorl %r15d, %r15d
cmpq %rcx, %rax
jae 0x3ee59
xorl %r15d, %r15d
xorl %edx, %edx
cmpb $0xa, (%rax)
sete %dl
addl %edx, %r15d
incq %rax
cmpq %rcx, %rax
jne 0x3ee46
movslq %r15d, %rdi
shlq $0x2, %rdi
callq 0x2bfe0
movq (%r14), %rcx
movq 0x10(%r14), %rdx
cmpq %rdx, %rcx
jae 0x3ee90
xorl %esi, %esi
xorl %edi, %edi
cmpb $0xa, (%rcx,%rsi)
jne 0x3ee81
movl %esi, (%rax,%rdi,4)
incq %rdi
leaq (%rcx,%rsi), %r8
incq %r8
incq %rsi
cmpq %rdx, %r8
jne 0x3ee75
movl %r15d, 0x60(%r14)
movq %rax, 0x50(%r14)
movl 0x60(%r14), %ecx
xorl %eax, %eax
cmpl $0x2, %ecx
jl 0x3eed4
movq 0x50(%r14), %rdx
xorl %eax, %eax
movl %ecx, %esi
movl %esi, %r8d
subl %eax, %r8d
movl %r8d, %edi
shrl $0x1f, %edi
addl %r8d, %edi
sarl %edi
addl %eax, %edi
movslq %edi, %r8
cmpl %ebx, (%rdx,%r8,4)
jl 0x3eecb
movl %edi, %esi
jmp 0x3eecd
movl %edi, %eax
leal 0x1(%rax), %edi
cmpl %esi, %edi
jl 0x3eeab
testl %ecx, %ecx
je 0x3eef3
testl %eax, %eax
jne 0x3eee4
movq 0x50(%r14), %rcx
cmpl %ebx, (%rcx)
jge 0x3eef3
movq 0x50(%r14), %rcx
movslq %eax, %rdx
addl $0x2, %eax
subl (%rcx,%rdx,4), %ebx
jmp 0x3eefa
incl %ebx
movl $0x1, %eax
shlq $0x20, %rbx
orq %rax, %rbx
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
nop