asm tier: read-line for subprocess pipes
Closes the last asm-tier gap for hosting bend workers:
(read-line port) → string or #f
Reads bytes one at a time from the port's fd until '\n' or EOF.
Strips the trailing newline. Returns #f when no bytes were
available (peer closed / pipe drained).
Verified end-to-end on 3090-ai:
λ> (define p (spawn-process-stdio "./shake256-fanout" (quote (--daemon))))
λ> (display (read-line (cdr p))) (newline)
ready
λ> (display "quit\n" (car p))
λ> (flush-port (car p))
λ> (display (read-line (cdr p))) (newline)
bye
asm tier can now spawn, write, flush, read line — the full
subprocess capability gpu-worker.lsp's daemon pool needs.
Implementation:
- Stack scratch buffer: 4096 bytes via %rbp (heap-safe; %r15 is
lumbda's heap pointer, do not touch)
- One-byte-at-a-time SYS_READ via fd from decode_port
- Max line: 4094 bytes (fits the daemon protocol — "ready",
"done /path", "bye" all under 100)
- heap_alloc(8 + len) + length header + byte copy + TAG_STRING
matches the Python/C tier string format byte-for-byte
- GC_NAIVE path stamps HT_STRING header for the GC pass
BI_READLINE = 123; GC_* renumbered to 124..128; BI_COUNT = 129
(GC_NAIVE) / 124. bn_readline added to symbol table + name array.
Remaining asm-tier gaps for full gpu-worker.lsp hosting:
- *argv* binding (used to parse --port)
- define-syntax + syntax-rules (used by bend.lsp macros — handled
by splitting bend-macros.lsp out in a prior commit)
- error builtin (also handled by portable bend-error wrapper)
Per-tier matrix:
Python tier ✓ macro + function client; full worker host
C tier ✓ macro + function client; full worker host
asm tier ✓ function client; subprocess primitives complete;
gpu-worker.lsp needs *argv* + a few other helpers
before pure-asm hosting is fully working
This commit is contained in:
parent
ceb497ac96
commit
6262a24d47
1 changed files with 98 additions and 8 deletions
106
asm/lumbda.s
106
asm/lumbda.s
|
|
@ -212,15 +212,16 @@
|
|||
.equ BI_CWV, 120
|
||||
.equ BI_SPAWNPROC, 121
|
||||
.equ BI_FLUSHPORT, 122
|
||||
.equ BI_READLINE, 123
|
||||
.ifdef GC_NAIVE
|
||||
.equ BI_GC_COLLECT, 123
|
||||
.equ BI_GC_STATS, 124
|
||||
.equ BI_WITH_ARENA, 125
|
||||
.equ BI_ARENA_STATS, 126
|
||||
.equ BI_ARENA_SET_MODE, 127
|
||||
.equ BI_COUNT, 128
|
||||
.equ BI_GC_COLLECT, 124
|
||||
.equ BI_GC_STATS, 125
|
||||
.equ BI_WITH_ARENA, 126
|
||||
.equ BI_ARENA_STATS, 127
|
||||
.equ BI_ARENA_SET_MODE, 128
|
||||
.equ BI_COUNT, 129
|
||||
.else
|
||||
.equ BI_COUNT, 123
|
||||
.equ BI_COUNT, 124
|
||||
.endif
|
||||
|
||||
# ============================================================
|
||||
|
|
@ -351,6 +352,7 @@ bn_tcpclose: .byte 9; .ascii "tcp-close"
|
|||
bn_tcpsendfile: .byte 12; .ascii "tcp-sendfile"
|
||||
bn_spawnproc: .byte 19; .ascii "spawn-process-stdio"
|
||||
bn_flushport: .byte 10; .ascii "flush-port"
|
||||
bn_readline: .byte 9; .ascii "read-line"
|
||||
bn_heapsnap: .byte 13; .ascii "heap-snapshot"
|
||||
bn_heaprest: .byte 12; .ascii "heap-restore"
|
||||
bn_curtime: .byte 15; .ascii "current-time-ms"
|
||||
|
|
@ -495,7 +497,7 @@ bi_names:
|
|||
.quad bn_randomseed, bn_randomint, bn_randomstate, bn_randomstateset
|
||||
.quad bn_randomseedfromos
|
||||
.quad bn_cadr, bn_sort, bn_gensym, bn_exit, bn_values, bn_cwv
|
||||
.quad bn_spawnproc, bn_flushport
|
||||
.quad bn_spawnproc, bn_flushport, bn_readline
|
||||
.ifdef GC_NAIVE
|
||||
.quad bn_gccollect, bn_gcstats, bn_witharena, bn_arenastats, bn_arenamode
|
||||
.endif
|
||||
|
|
@ -4286,6 +4288,8 @@ eval_list:
|
|||
je bi_spawn_process_stdio
|
||||
cmpq $BI_FLUSHPORT, %rax
|
||||
je bi_flush_port
|
||||
cmpq $BI_READLINE, %rax
|
||||
je bi_read_line
|
||||
.ifdef GC_NAIVE
|
||||
cmpq $BI_GC_COLLECT, %rax
|
||||
je bi_gc_collect_user
|
||||
|
|
@ -8838,6 +8842,92 @@ bi_flush_port:
|
|||
movq $VAL_VOID, %rax
|
||||
RET_VAL
|
||||
|
||||
# ============================================================
|
||||
# bi_read_line: (read-line port) → string or #f on EOF
|
||||
#
|
||||
# Reads bytes one at a time from the port's fd until '\n' or EOF.
|
||||
# Strips the trailing '\n'. Returns a Scheme string, or #f if no
|
||||
# bytes were available (peer closed / pipe drained).
|
||||
#
|
||||
# Used by gpu-worker.lsp to consume daemon responses ("ready",
|
||||
# "done /path", "bye") line by line.
|
||||
#
|
||||
# Max line length: 4095 bytes (fits in a 4 KB scratch). Longer lines
|
||||
# truncated — fine for our daemon protocol.
|
||||
# ============================================================
|
||||
bi_read_line:
|
||||
pushq %r13
|
||||
pushq %r14
|
||||
subq $4104, %rsp
|
||||
movq %rsp, %rbp # %rbp = byte buffer
|
||||
|
||||
# Get port → fd in %r13
|
||||
GETARG %rdi
|
||||
call decode_port
|
||||
testq %rax, %rax
|
||||
js .rl_fail
|
||||
movq %rax, %r13 # %r13 = fd
|
||||
|
||||
xorq %r14, %r14 # %r14 = byte count
|
||||
.rl_loop:
|
||||
cmpq $4094, %r14 # leave room for final byte
|
||||
jge .rl_done
|
||||
movq $SYS_READ, %rax
|
||||
movq %r13, %rdi
|
||||
leaq (%rbp,%r14), %rsi
|
||||
movq $1, %rdx
|
||||
syscall
|
||||
cmpq $1, %rax
|
||||
jne .rl_done # EOF or error
|
||||
movb (%rbp,%r14), %al
|
||||
incq %r14
|
||||
cmpb $10, %al # '\n'
|
||||
je .rl_strip_nl
|
||||
jmp .rl_loop
|
||||
|
||||
.rl_strip_nl:
|
||||
decq %r14 # exclude the newline
|
||||
|
||||
.rl_done:
|
||||
testq %r14, %r14
|
||||
jz .rl_eof # 0 bytes & EOF → #f
|
||||
|
||||
# heap_alloc(8 + len)
|
||||
movq %r14, %rdi
|
||||
addq $8, %rdi
|
||||
call heap_alloc
|
||||
.ifdef GC_NAIVE
|
||||
movb $HT_STRING, -7(%rax)
|
||||
.endif
|
||||
movq %r14, (%rax) # length header
|
||||
xorq %rcx, %rcx
|
||||
.rl_copy:
|
||||
cmpq %r14, %rcx
|
||||
jge .rl_copy_done
|
||||
movb (%rbp,%rcx), %dl
|
||||
movb %dl, 8(%rax,%rcx)
|
||||
incq %rcx
|
||||
jmp .rl_copy
|
||||
.rl_copy_done:
|
||||
orq $TAG_STRING, %rax
|
||||
addq $4104, %rsp
|
||||
popq %r14
|
||||
popq %r13
|
||||
RET_VAL
|
||||
|
||||
.rl_eof:
|
||||
movq $VAL_FALSE, %rax
|
||||
addq $4104, %rsp
|
||||
popq %r14
|
||||
popq %r13
|
||||
RET_VAL
|
||||
.rl_fail:
|
||||
movq $VAL_FALSE, %rax
|
||||
addq $4104, %rsp
|
||||
popq %r14
|
||||
popq %r13
|
||||
RET_VAL
|
||||
|
||||
# ============================================================
|
||||
# list_reverse: %rdi = list -> %rax = reversed list
|
||||
# ============================================================
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue