portal benchmark + 3 mismatch defects fixed
Benchmark exercises full save×load matrix across Python/C/asm plus the mismatch cases (wrong format, truncated input, missing file, corrupt header). Cases that used to segfault or report wrong paths now degrade cleanly. asm (uncommonlisp.s): - (define var) with no value now binds to VOID instead of segfault - portal-resume checks sys_read returned full 48-byte header; sanity- checks heap_size and heap_base before committing r14/r15 restore. Corrupt/truncated portals now return #f cleanly. py (uncommonlisp.py): - file-not-found error inside a nested (load) now reports the actual missing path (via FileNotFoundError.filename) rather than the outer script path. - _load wraps UnicodeDecodeError (binary file loaded as text) into a LispErr with the path; no more raw Python traceback. tests/portal-benchmark.sh: 50-iter benchmark, 4 parts (save / load / cross-process / mismatch-classification). Representative numbers (this laptop, 2026-04-16): setup+save: Python 126ms, C 3ms, asm 0.9ms cross-proc: Py→Py 260ms, C→C 6ms, asm→asm 1.5ms All three test suites still pass: 571 py unit, 131 asm, 189 shared.
This commit is contained in:
parent
57f3c9fab1
commit
2f8b7dc737
5 changed files with 204 additions and 7 deletions
BIN
asm/uncommonlisp
BIN
asm/uncommonlisp
Binary file not shown.
Binary file not shown.
|
|
@ -1626,7 +1626,9 @@ env_lookup_both:
|
|||
cmpq $TAG_PAIR, %rax
|
||||
je .ev_define_func
|
||||
|
||||
# Simple: (define var expr)
|
||||
# Simple: (define var expr) — or (define var) with no expr → VAL_VOID
|
||||
cmpq $VAL_NIL, %r12
|
||||
je .ev_define_no_expr
|
||||
movq %r12, %rax
|
||||
andq $-8, %rax
|
||||
movq (%rax), %rdi # expr
|
||||
|
|
@ -1634,6 +1636,10 @@ env_lookup_both:
|
|||
movq %rbp, %rsi
|
||||
call eval
|
||||
popq %rbx # var symbol
|
||||
jmp .ev_define_bind
|
||||
.ev_define_no_expr:
|
||||
movq $VAL_VOID, %rax
|
||||
.ev_define_bind:
|
||||
movq %rbx, %rdi
|
||||
movq %rax, %rsi
|
||||
movq %r14, %rdx
|
||||
|
|
@ -3927,13 +3933,15 @@ bi_portal_resume:
|
|||
js .pr_fail
|
||||
movq %rax, %rbx # fd
|
||||
|
||||
# Read header
|
||||
# Read header — must get full PORTAL_HDR_SIZE bytes
|
||||
subq $PORTAL_HDR_SIZE, %rsp
|
||||
movq $SYS_READ, %rax
|
||||
movq %rbx, %rdi
|
||||
movq %rsp, %rsi
|
||||
movq $PORTAL_HDR_SIZE, %rdx
|
||||
syscall
|
||||
cmpq $PORTAL_HDR_SIZE, %rax
|
||||
jne .pr_bad_magic # short read → file is not a portal
|
||||
|
||||
# Verify magic
|
||||
leaq portal_magic(%rip), %rdi
|
||||
|
|
@ -3941,9 +3949,15 @@ bi_portal_resume:
|
|||
cmpq (%rdi), %rax
|
||||
jne .pr_bad_magic
|
||||
|
||||
# Read heap size, base, r14, r15
|
||||
# Sanity check header fields before committing
|
||||
movq 8(%rsp), %rcx # heap_size
|
||||
testq %rcx, %rcx
|
||||
jle .pr_bad_magic # zero or negative heap size → corrupt
|
||||
movq 16(%rsp), %rdx # heap_base (must match our mmap)
|
||||
testq %rdx, %rdx
|
||||
jz .pr_bad_magic # null heap base → corrupt
|
||||
|
||||
# Header looks valid — commit to r14/r15 restore
|
||||
movq 24(%rsp), %r14 # restore global env
|
||||
movq 32(%rsp), %r15 # restore bump pointer
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue