c: retire TODO-named-let-bytecode.md
Resolved by 45a90b8 (vm restores cur_code across CALL/RETURN).
The reproducer at lines 5-11 of the TODO file runs cleanly now
under both `lumbda --fast` and `lumbda -j --fast`, and the
proof/eml_proof_in_lumbda.lsp `normalize` function no longer
needs the `(define (iter ...))` workaround that the TODO
documented. Future regressions are caught by
tests/regression-named-let-leak.{lsp,sh}.
This commit is contained in:
parent
45a90b84e9
commit
03a3534f0e
1 changed files with 0 additions and 60 deletions
|
|
@ -1,60 +0,0 @@
|
|||
# C --fast bytecode compiler: named-let + inner `let`+`if` bug
|
||||
|
||||
## Reproduction (minimal)
|
||||
|
||||
```scheme
|
||||
(define (maybe x) (if (> x 3) #f (+ x 1)))
|
||||
(define (g start)
|
||||
(let loop ((t start))
|
||||
(let ((next (maybe t)))
|
||||
(if next (loop next) t))))
|
||||
(display (g 0)) (newline)
|
||||
```
|
||||
|
||||
Expected output: `4`
|
||||
|
||||
Actual with `c/lumbda --fast`: hangs or segfaults.
|
||||
Tree-walker (`c/lumbda` default) works correctly.
|
||||
Python `--fast` and asm tree-walker both work correctly.
|
||||
|
||||
## What's special
|
||||
|
||||
The bug fires when:
|
||||
- Outer named-let: `(let loop ((t ...)) BODY)`
|
||||
- Inside BODY: `(let ((next (fn t))) ...)` — another let
|
||||
- Inside inner let: `(if next (loop next) t)` — recursive call
|
||||
through an if branch that was reached via an inner let-body
|
||||
|
||||
The recursive tail call to `loop` through the nested let + if doesn't
|
||||
reach the loop closure. Bytecode emission likely walks the wrong env
|
||||
chain or targets the wrong stack slot.
|
||||
|
||||
## Workaround
|
||||
|
||||
Replace named-let with an internal recursive `define`:
|
||||
|
||||
```scheme
|
||||
(define (g start)
|
||||
(define (iter t)
|
||||
(let ((next (maybe t)))
|
||||
(if next (iter next) t)))
|
||||
(iter start))
|
||||
```
|
||||
|
||||
Compiles correctly under `--fast`. Applied to `proof/eml_proof_in_lumbda.lsp`
|
||||
for the `normalize` function.
|
||||
|
||||
## Where to look
|
||||
|
||||
`c/vm.c:344` `SYM_LET` named-let branch emits:
|
||||
`PUSH_ENV, MAKE_CLOSURE, DUP, BIND name, <args...>, CALL/TAIL_CALL`.
|
||||
|
||||
Suspected: the lambda body's closure-env capture plus the inner `let`
|
||||
PUSH_ENV interact badly when the tail call is behind an `if` whose
|
||||
compilation path doesn't POP_ENV back to the closure's expected level.
|
||||
|
||||
## Priority
|
||||
|
||||
Low for now — workaround lands in every affected .lsp and the other
|
||||
three tiers are unaffected. File for cleanup when the C --fast
|
||||
refactor happens.
|
||||
Loading…
Add table
Add a link
Reference in a new issue