// File: /workspace/github_c_makefile_star2_O2/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 0x3b2a1
movq (%r14), %rax
movq 0x10(%r14), %rcx
xorl %r15d, %r15d
cmpq %rcx, %rax
jae 0x3b268
xorl %edx, %edx
cmpb $0xa, (%rax)
sete %dl
addl %edx, %r15d
incq %rax
jmp 0x3b253
movl %r15d, %edi
shlq $0x2, %rdi
callq 0x29673
movq (%r14), %rcx
movq 0x10(%r14), %rdx
xorl %esi, %esi
xorl %edi, %edi
leaq (%rcx,%rsi), %r8
cmpq %rdx, %r8
jae 0x3b299
cmpb $0xa, (%r8)
jne 0x3b294
movl %esi, (%rax,%rdi,4)
incq %rdi
incq %rsi
jmp 0x3b27f
movl %r15d, 0x60(%r14)
movq %rax, 0x50(%r14)
xorl %ecx, %ecx
pushq $0x2
popq %rsi
movl %r15d, %edi
leal 0x1(%rcx), %eax
cmpl %edi, %eax
jge 0x3b2ca
movl %edi, %eax
subl %ecx, %eax
cltd
idivl %esi
addl %ecx, %eax
movq 0x50(%r14), %rdx
cltq
cmpl %ebx, (%rdx,%rax,4)
cmovgel %eax, %edi
cmovll %eax, %ecx
jmp 0x3b2a9
testl %r15d, %r15d
je 0x3b2e6
movq 0x50(%r14), %rax
testl %ecx, %ecx
jne 0x3b2db
cmpl %ebx, (%rax)
jge 0x3b2e6
movslq %ecx, %rdx
addl $0x2, %ecx
subl (%rax,%rdx,4), %ebx
jmp 0x3b2eb
incl %ebx
pushq $0x1
popq %rcx
shlq $0x20, %rbx
orq %rcx, %rbx
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq