Sigil 0.17.5

release

A bug-fix release centered on exception handling. On native and release builds, an uncaught exception could silently evaluate to #<undefined> and let execution continue instead of stopping; that is fixed, and dynamic-wind cleanup now runs correctly when an exception unwinds through it. Alongside that, the sigil mcp developer-tools server works again after being broken since an earlier refactor, and (gc-stats) gains real pause and memory observability. Existing projects keep building without changes.

Download 0.17.5Get started

Uncaught exceptions on native builds now stop and report

The native backend had no propagation path for an exception with no handler: the raising expression evaluated to #<undefined>, surrounding side effects kept running, and the program exited successfully. Now a handler-less exception prints its error and a trace and exits with a failure code, matching bytecode. This also covers the release sigil eval case where an uncaught error was swallowed, and it removes a class of silent-wrong-answer bugs where a native build quietly ran past a failure.

dynamic-wind cleanup runs when an exception unwinds

An exception caught by an outer guard used to skip the after thunks of any dynamic-wind it unwound through, so cleanup (closing a file, releasing a lock, restoring a parameter) was silently missed. Every exception-dispatch path now runs those after thunks in the correct inside-out order. A related hazard where concurrent goroutines could run each other's cleanup thunks, which had been corrupting a large share of cold parallel builds, is fixed as well.

The sigil mcp developer-tools server works again

sigil mcp serve (the server exposing format, check, lint, eval, test, run-file, and the rest as MCP tools) had been exiting immediately on startup ever since a refactor moved it between modules and left two imports pointing at the wrong place. It starts and serves correctly now. It is also sturdier: a runaway eval, a hanging test, or a script that blocks on input can no longer wedge the server, each is bounded by a timeout and the server stays up.

(gc-stats) gains pause and memory observability

(gc-stats) now reports collection pause times (a maximum plus a bucketed histogram), resident memory, young and tenured object counts, and which collector backend produced the numbers. Two new procedures, gc-minor-collect! and gc-young-occupancy, let latency-sensitive code such as a game loop schedule a minor collection at a quiet moment like a frame boundary instead of taking an allocation-triggered pause mid-frame. These are additive, with no change to when collection happens on its own.