// File: /workspace/github_c_makefile_star2_O3/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
movl 0x60(%rdi), %r15d
testl %r15d, %r15d
jns 0x3e7b5
movq (%r14), %rax
movq 0x10(%r14), %rcx
xorl %r15d, %r15d
cmpq %rcx, %rax
jae 0x3e776
xorl %r15d, %r15d
xorl %edx, %edx
cmpb $0xa, (%rax)
sete %dl
addl %edx, %r15d
incq %rax
cmpq %rcx, %rax
jne 0x3e763
movslq %r15d, %rdi
shlq $0x2, %rdi
callq 0x2bb46
movq (%r14), %rcx
movq 0x10(%r14), %rdx
cmpq %rdx, %rcx
jae 0x3e7ad
xorl %esi, %esi
xorl %edi, %edi
cmpb $0xa, (%rcx,%rsi)
jne 0x3e79e
movl %esi, (%rax,%rdi,4)
incq %rdi
leaq (%rcx,%rsi), %r8
incq %r8
incq %rsi
cmpq %rdx, %r8
jne 0x3e792
movl %r15d, 0x60(%r14)
movq %rax, 0x50(%r14)
cmpl $0x2, %r15d
jl 0x3e7f2
movq 0x50(%r14), %rcx
xorl %eax, %eax
movl %r15d, %esi
subl %eax, %esi
movl %esi, %edx
shrl $0x1f, %edx
addl %esi, %edx
sarl %edx
addl %eax, %edx
movslq %edx, %rsi
cmpl %ebx, (%rcx,%rsi,4)
jl 0x3e7de
movl %edx, %r15d
jmp 0x3e7e0
movl %edx, %eax
leal 0x1(%rax), %edx
cmpl %r15d, %edx
jl 0x3e7c1
testl %eax, %eax
je 0x3e7f7
movq 0x50(%r14), %rcx
jmp 0x3e801
testl %r15d, %r15d
je 0x3e80c
movq 0x50(%r14), %rcx
xorl %eax, %eax
cmpl %ebx, (%rcx)
jge 0x3e80c
movslq %eax, %rdx
addl $0x2, %eax
subl (%rcx,%rdx,4), %ebx
jmp 0x3e813
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