// File: /workspace/github_c_makefile_star2_O0/janet-lang[P]janet/src/core/ev.c
// Function: ev_callback_read
void ev_callback_read(JanetFiber *fiber, JanetAsyncEvent event) {
    JanetStream *stream = fiber->ev_stream;
    StateRead *state = (StateRead *) fiber->ev_state;
    switch (event) {
        default:
            break;
        case JANET_ASYNC_EVENT_MARK:
            janet_mark(janet_wrap_buffer(state->buf));
            break;
        case JANET_ASYNC_EVENT_CLOSE:
            janet_schedule(fiber, janet_wrap_nil());
            janet_async_end(fiber);
            break;
#ifdef JANET_WINDOWS
        case JANET_ASYNC_EVENT_FAILED:
        case JANET_ASYNC_EVENT_COMPLETE: {
            /* Called when read finished */
            uint32_t ev_bytes = (uint32_t) state->overlapped.InternalHigh;
            state->bytes_read += ev_bytes;
            if (state->bytes_read == 0 && (state->mode != JANET_ASYNC_READMODE_RECVFROM)) {
                janet_schedule(fiber, janet_wrap_nil());
                janet_async_end(fiber);
                return;
            }

            janet_buffer_push_bytes(state->buf, state->chunk_buf, ev_bytes);
            state->bytes_left -= ev_bytes;

            if (state->bytes_left == 0 || !state->is_chunk || ev_bytes == 0) {
                Janet resume_val;
#ifdef JANET_NET
                if (state->mode == JANET_ASYNC_READMODE_RECVFROM) {
                    void *abst = janet_abstract(&janet_address_type, state->fromlen);
                    memcpy(abst, &state->from, state->fromlen);
                    resume_val = janet_wrap_abstract(abst);
                } else
#endif
                {
                    resume_val = janet_wrap_buffer(state->buf);
                }
                janet_schedule(fiber, resume_val);
                janet_async_end(fiber);
                return;
            }
        }

        /* fallthrough */
        case JANET_ASYNC_EVENT_INIT: {
            int32_t chunk_size = state->bytes_left > JANET_EV_CHUNKSIZE ? JANET_EV_CHUNKSIZE : state->bytes_left;
            memset(&(state->overlapped), 0, sizeof(OVERLAPPED));
            int status;
#ifdef JANET_NET
            if (state->mode == JANET_ASYNC_READMODE_RECVFROM) {
                state->wbuf.len = (ULONG) chunk_size;
                state->wbuf.buf = (char *) state->chunk_buf;
                state->fromlen = sizeof(state->from);
                status = WSARecvFrom((SOCKET) stream->handle, &state->wbuf, 1,
                                     NULL, &state->flags, &state->from, &state->fromlen, &state->overlapped, NULL);
                if (status && (WSA_IO_PENDING != WSAGetLastError())) {
                    janet_cancel(fiber, janet_ev_lasterr());
                    janet_async_end(fiber);
                    return;
                }
            } else
#endif
            {
                /* Some handles (not all) read from the offset in lpOverlapped
                 * if its not set before calling `ReadFile` these streams will always read from offset 0 */
                state->overlapped.Offset = (DWORD) state->bytes_read;

                status = ReadFile(stream->handle, state->chunk_buf, chunk_size, NULL, &state->overlapped);
                if (!status && (ERROR_IO_PENDING != GetLastError())) {
                    if (GetLastError() == ERROR_BROKEN_PIPE) {
                        if (state->bytes_read) {
                            janet_schedule(fiber, janet_wrap_buffer(state->buf));
                        } else {
                            janet_schedule(fiber, janet_wrap_nil());
                        }
                    } else {
                        janet_cancel(fiber, janet_ev_lasterr());
                    }
                    janet_async_end(fiber);
                    return;
                }
            }
            janet_async_in_flight(fiber);
        }
        break;
#else
        case JANET_ASYNC_EVENT_ERR: {
            if (state->bytes_read) {
                janet_schedule(fiber, janet_wrap_buffer(state->buf));
            } else {
                janet_schedule(fiber, janet_wrap_nil());
            }
            stream->read_fiber = NULL;
            janet_async_end(fiber);
            break;
        }

    read_more:
        case JANET_ASYNC_EVENT_HUP:
        case JANET_ASYNC_EVENT_INIT:
        case JANET_ASYNC_EVENT_READ: {
            JanetBuffer *buffer = state->buf;
            int32_t bytes_left = state->bytes_left;
            int32_t read_limit = state->is_chunk ? (bytes_left > 4096 ? 4096 : bytes_left) : bytes_left;
            janet_buffer_extra(buffer, read_limit);
            ssize_t nread;
#ifdef JANET_NET
            char saddr[256];
            socklen_t socklen = sizeof(saddr);
#endif
            do {
#ifdef JANET_NET
                if (state->mode == JANET_ASYNC_READMODE_RECVFROM) {
                    nread = recvfrom(stream->handle, buffer->data + buffer->count, read_limit, state->flags,
                                     (struct sockaddr *)&saddr, &socklen);
                } else if (state->mode == JANET_ASYNC_READMODE_RECV) {
                    nread = recv(stream->handle, buffer->data + buffer->count, read_limit, state->flags);
                } else
#endif
                {
                    nread = read(stream->handle, buffer->data + buffer->count, read_limit);
                }
            } while (nread == -1 && errno == EINTR);

            /* Check for errors - special case errors that can just be waited on to fix */
            if (nread == -1) {
                if (errno == EAGAIN || errno == EWOULDBLOCK) {
                    break;
                }
                /* In stream protocols, a pipe error is end of stream */
                if (errno == EPIPE && (state->mode != JANET_ASYNC_READMODE_RECVFROM)) {
                    nread = 0;
                } else {
                    janet_cancel(fiber, janet_ev_lasterr());
                    janet_async_end(fiber);
                    break;
                }
            }

            /* Only allow 0-length packets in recv-from. In stream protocols, a zero length packet is EOS. */
            state->bytes_read += nread;
            if (state->bytes_read == 0 && (state->mode != JANET_ASYNC_READMODE_RECVFROM)) {
                janet_schedule(fiber, janet_wrap_nil());
                janet_async_end(fiber);
                break;
            }

            /* Increment buffer counts */
            buffer->count += nread;
            bytes_left -= nread;
            state->bytes_left = bytes_left;

            /* Resume if done */
            if (!state->is_chunk || bytes_left == 0 || nread == 0) {
                Janet resume_val;
#ifdef JANET_NET
                if (state->mode == JANET_ASYNC_READMODE_RECVFROM) {
                    void *abst = janet_abstract(&janet_address_type, socklen);
                    memcpy(abst, &saddr, socklen);
                    resume_val = janet_wrap_abstract(abst);
                } else
#endif
                {
                    resume_val = janet_wrap_buffer(buffer);
                }
                janet_schedule(fiber, resume_val);
                janet_async_end(fiber);
                break;
            }

            /* Read some more if possible */
            goto read_more;
        }
        break;
#endif
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1e0, %rsp            # imm = 0x1E0
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq -0x8(%rbp), %rax
movq 0x58(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq 0x60(%rax), %rax
movq %rax, -0x20(%rbp)
movl -0xc(%rbp), %eax
movq %rax, -0x1a8(%rbp)
subq $0x6, %rax
ja 0x2f851
movq -0x1a8(%rbp), %rax
leaq 0x567ac(%rip), %rcx     # 0x85ff4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
jmp 0x2fc7a
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rdi
movabsq $-0x2800000000000, %rsi # imm = 0xFFFD800000000000
callq 0x7b610
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x38b90
jmp 0x2fc7a
movq -0x8(%rbp), %rax
movq %rax, -0x1b0(%rbp)
movabsq $-0x77fffffffffff, %rdi # imm = 0xFFF8800000000001
callq 0x7b460
movq -0x1b0(%rbp), %rdi
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rsi
callq 0x2b160
movq -0x8(%rbp), %rdi
callq 0x2a730
jmp 0x2fc7a
movq -0x20(%rbp), %rax
cmpl $0x0, 0x8(%rax)
je 0x2f8fd
movq -0x8(%rbp), %rax
movq %rax, -0x1b8(%rbp)
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rdi
movabsq $-0x2800000000000, %rsi # imm = 0xFFFD800000000000
callq 0x7b610
movq -0x1b8(%rbp), %rdi
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rsi
callq 0x2b160
jmp 0x2f92b
movq -0x8(%rbp), %rax
movq %rax, -0x1c0(%rbp)
movabsq $-0x77fffffffffff, %rdi # imm = 0xFFF8800000000001
callq 0x7b460
movq -0x1c0(%rbp), %rdi
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rsi
callq 0x2b160
movq -0x18(%rbp), %rax
movq $0x0, 0x10(%rax)
movq -0x8(%rbp), %rdi
callq 0x2a730
jmp 0x2fc7a
jmp 0x2f947
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x20(%rbp), %rax
movl 0x4(%rax), %eax
movl %eax, -0x4c(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x0, 0x18(%rax)
je 0x2f994
cmpl $0x1000, -0x4c(%rbp)    # imm = 0x1000
jle 0x2f97d
movl $0x1000, %eax           # imm = 0x1000
movl %eax, -0x1c4(%rbp)
jmp 0x2f986
movl -0x4c(%rbp), %eax
movl %eax, -0x1c4(%rbp)
movl -0x1c4(%rbp), %eax
movl %eax, -0x1c8(%rbp)
jmp 0x2f99d
movl -0x4c(%rbp), %eax
movl %eax, -0x1c8(%rbp)
movl -0x1c8(%rbp), %eax
movl %eax, -0x50(%rbp)
movq -0x48(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x18650
movl $0x100, -0x164(%rbp)    # imm = 0x100
movq -0x20(%rbp), %rax
cmpl $0x2, 0x1c(%rax)
jne 0x2fa10
movq -0x18(%rbp), %rax
movl (%rax), %edi
movq -0x48(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x48(%rbp), %rax
movslq 0x10(%rax), %rax
addq %rax, %rsi
movslq -0x50(%rbp), %rdx
movq -0x20(%rbp), %rax
movl (%rax), %ecx
leaq -0x160(%rbp), %rax
movq %rax, -0x170(%rbp)
movq -0x170(%rbp), %r8
leaq -0x164(%rbp), %r9
callq 0x127c0
movq %rax, -0x58(%rbp)
jmp 0x2fa70
movq -0x20(%rbp), %rax
cmpl $0x1, 0x1c(%rax)
jne 0x2fa48
movq -0x18(%rbp), %rax
movl (%rax), %edi
movq -0x48(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x48(%rbp), %rax
movslq 0x10(%rax), %rax
addq %rax, %rsi
movslq -0x50(%rbp), %rdx
movq -0x20(%rbp), %rax
movl (%rax), %ecx
callq 0x120d0
movq %rax, -0x58(%rbp)
jmp 0x2fa6e
movq -0x18(%rbp), %rax
movl (%rax), %edi
movq -0x48(%rbp), %rax
movq 0x18(%rax), %rsi
movq -0x48(%rbp), %rax
movslq 0x10(%rax), %rax
addq %rax, %rsi
movslq -0x50(%rbp), %rdx
callq 0x12520
movq %rax, -0x58(%rbp)
jmp 0x2fa70
jmp 0x2fa72
xorl %eax, %eax
cmpq $-0x1, -0x58(%rbp)
movb %al, -0x1c9(%rbp)
jne 0x2fa92
callq 0x12120
cmpl $0x4, (%rax)
sete %al
movb %al, -0x1c9(%rbp)
movb -0x1c9(%rbp), %al
testb $0x1, %al
jne 0x2f9bc
cmpq $-0x1, -0x58(%rbp)
jne 0x2fb18
callq 0x12120
cmpl $0xb, (%rax)
je 0x2fabb
callq 0x12120
cmpl $0xb, (%rax)
jne 0x2fac0
jmp 0x2fc7a
callq 0x12120
cmpl $0x20, (%rax)
jne 0x2fade
movq -0x20(%rbp), %rax
cmpl $0x2, 0x1c(%rax)
je 0x2fade
movq $0x0, -0x58(%rbp)
jmp 0x2fb16
movq -0x8(%rbp), %rax
movq %rax, -0x1d8(%rbp)
callq 0x2f7c0
movq -0x1d8(%rbp), %rdi
movq %rax, -0x178(%rbp)
movq -0x178(%rbp), %rsi
callq 0x2b130
movq -0x8(%rbp), %rdi
callq 0x2a730
jmp 0x2fc7a
jmp 0x2fb18
movq -0x58(%rbp), %rdx
movq -0x20(%rbp), %rax
movslq 0x8(%rax), %rcx
addq %rdx, %rcx
movl %ecx, 0x8(%rax)
movq -0x20(%rbp), %rax
cmpl $0x0, 0x8(%rax)
jne 0x2fb80
movq -0x20(%rbp), %rax
cmpl $0x2, 0x1c(%rax)
je 0x2fb80
movq -0x8(%rbp), %rax
movq %rax, -0x1e0(%rbp)
movabsq $-0x77fffffffffff, %rdi # imm = 0xFFF8800000000001
callq 0x7b460
movq -0x1e0(%rbp), %rdi
movq %rax, -0x180(%rbp)
movq -0x180(%rbp), %rsi
callq 0x2b160
movq -0x8(%rbp), %rdi
callq 0x2a730
jmp 0x2fc7a
movq -0x58(%rbp), %rdx
movq -0x48(%rbp), %rax
movslq 0x10(%rax), %rcx
addq %rdx, %rcx
movl %ecx, 0x10(%rax)
movq -0x58(%rbp), %rcx
movslq -0x4c(%rbp), %rax
subq %rcx, %rax
movl %eax, -0x4c(%rbp)
movl -0x4c(%rbp), %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0x4(%rax)
movq -0x20(%rbp), %rax
cmpl $0x0, 0x18(%rax)
je 0x2fbc5
cmpl $0x0, -0x4c(%rbp)
je 0x2fbc5
cmpq $0x0, -0x58(%rbp)
jne 0x2fc75
movq -0x20(%rbp), %rax
cmpl $0x2, 0x1c(%rax)
jne 0x2fc32
movl -0x164(%rbp), %eax
movl %eax, %esi
leaq 0x7dec2(%rip), %rdi     # 0xadaa0
callq 0x12de0
movq %rax, -0x190(%rbp)
movq -0x190(%rbp), %rdi
movl -0x164(%rbp), %eax
movl %eax, %edx
leaq -0x160(%rbp), %rsi
callq 0x12680
movq -0x190(%rbp), %rdi
movabsq $-0x1000000000000, %rsi # imm = 0xFFFF000000000000
callq 0x7b610
movq %rax, -0x198(%rbp)
movq -0x198(%rbp), %rax
movq %rax, -0x188(%rbp)
jmp 0x2fc5a
movq -0x48(%rbp), %rdi
movabsq $-0x2800000000000, %rsi # imm = 0xFFFD800000000000
callq 0x7b610
movq %rax, -0x1a0(%rbp)
movq -0x1a0(%rbp), %rax
movq %rax, -0x188(%rbp)
movq -0x8(%rbp), %rdi
movq -0x188(%rbp), %rsi
callq 0x2b160
movq -0x8(%rbp), %rdi
callq 0x2a730
jmp 0x2fc7a
jmp 0x2f945
addq $0x1e0, %rsp            # imm = 0x1E0
popq %rbp
retq
nopw %cs:(%rax,%rax)