Skip to content

fix(kernel): apply three upstream rxi/fe patches#20

Merged
jschairb merged 1 commit into
mainfrom
worktree-fe-kernel-patches
Jun 15, 2026
Merged

fix(kernel): apply three upstream rxi/fe patches#20
jschairb merged 1 commit into
mainfrom
worktree-fe-kernel-patches

Conversation

@jschairb

Copy link
Copy Markdown
Contributor

Summary

Applies three correctness fixes from open (but unmerged) upstream rxi/fe PRs to kernel/fe.c. The upstream repo is effectively unmaintained — we vendor the kernel directly — so this is the right place for these.

  • Circular-list crash in fe_write() (rxi/fe#22): fe_write() would infinite-loop / stack-overflow on any circular pair structure. Relevant now that the REPL is first-class — (setcar ...) / (setcdr ...) can trivially produce one. Fix borrows GCMARKBIT during traversal to detect cycles, prints ... in place of the back-edge, then immediately clears marks.
  • \r comment termination (rxi/fe#25 partial): ; comment parser stopped only on \n, so a \r\n-encoded cart source file would swallow the \r into the next token. One-character fix.
  • GC save ordering in fe_open() (rxi/fe#25 partial): fe_savegc() was called after fe_symbol(ctx, "t"), leaving a window where GC during that allocation could collect the fresh t object before it was stored in ctx->t. Moved the save to before the allocation.

The delimiter change also in PR #25 was intentionally skipped — KEC's kernel already carries a different (extended) delimiter set.

Test plan

  • cmake --build build — clean compile, zero warnings
  • ctest --test-dir build --output-on-failure — 19/19 passed

🤖 Generated with Claude Code

- fe_write() now detects and prints "..." for circular structures instead
  of looping forever / stack-overflowing (upstream PR #22). Relevant for
  the REPL where setcar/setcdr can produce circular lists.
- Comment parser now terminates on \r as well as \n, fixing parse
  corruption with Windows-style CRLF cart source files (upstream PR #25).
- fe_savegc() in fe_open() now precedes the t symbol allocation, closing
  a theoretical GC-during-init window (upstream PR #25).

All 19 tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jschairb
jschairb merged commit d8dbf70 into main Jun 15, 2026
2 checks passed
@jschairb
jschairb deleted the worktree-fe-kernel-patches branch June 15, 2026 06:36
jschairb added a commit that referenced this pull request Jun 15, 2026
PR #20 added the fe_write() cycle-detection fix (borrow GCMARKBIT, clear
it in unmarkpairs) but shipped no test for it. This closes that gap.

The mark bit lives in the low byte of a pair's car field, so a leaked
mark corrupts the car pointer — which makes walking the structure after
repr a direct, deterministic check of mark restoration (no GC needed).
repr also runs fe_write twice internally (measure + fill), so a stale
mark would skew the two passes.

Verified the test has teeth: neutering unmarkpairs to a no-op makes the
walkability checks segfault (exit 139), which ctest scores as a failure.

20/20 ctest, 23 checks in the kernel file.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant