Aether 0.115.0
What's new in 0.115.0
Added
-
Test suite for
runtime/actors/aether_send_buffer.c(tests/runtime/test_send_buffer.c(new)). Coverage-data-driven test addition.make ci-coveragereported the file at 0% (0/34 lines): the public surface (send_buffer_flush,send_buffered,send_buffer_force_flush,send_buffer_pending) is referenced only fromruntime/examples/*.cbench programs that the test suite never builds, and the codegen never emits the calls either — so regressions in batched-send would have shipped silently. Twelve tests covering: empty-buffer flush, NULL-target flush, single-message SPSC fast path, multi-message batch flush, accumulation up to capacity, target-change-triggers-flush, capacity-triggers-flush, force-flush partial drain, force-flush empty no-op, SPSC-overflow no-double-send invariant, mailbox-fully-accepts after SPSC reject, pending-count reporter. Coverage on this file moved 0% → 70.6% (24/34). The remaining 10 lines are the cross-core slow path (lines 56-73, requires realschedulers[]Scheduler state — already covered by the separatetest_scheduler.csuite). Suite-level: runtime (.c) bucket moved 75.7% → 78.2%. Coverage as a debugging tool: while writing the SPSC-overflow test I had hypothesised a double-send bug insend_buffer_flush— that when SPSC partial-takes N of the batch and falls through, the mailbox would be sent buffer[0..count-1] and re-send messages 0..N-1. Wrote a unique-payloads-per-message test to expose it. Test passed. Re-readingspsc_enqueue_batchshowed it's all-or-nothing (returnscounton full success,0ifspace < count), never partial — so the bug I hypothesised cannot exist. Test now serves as a regression-locker against any future refactor that switches SPSC to partial-batch semantics. Confirmed: writing the test before the fix is what caught the wrong diagnosis, not the other way around. -
make ci-coverage-html— one-command HTML coverage report viagcovr, with auto-bootstrap into a project-local venv ifgcovrisn't on PATH (Makefile,tests/scripts/coverage_html.sh(new)). Aftermake ci-coveragepopulates.gcdadata, this target runsgcovrover the merged stdlib + runtime + compiler + .ae-tests data set and writesbuild/coverage/index.html(browsable per-file detail) plusbuild/coverage/coverage.json(5.7 MB structured dump for CI / dashboard pickup). Three install paths in priority order: (1)gcovralready on PATH (auto-detected), (2) project-local venv atbuild/cov-venv/auto-created on first run viapython3 -m venv, (3) clear diagnostic with apt/dnf/brew instructions if neither is available. The venv path keeps the install self-contained — nopip install --break-system-packages, nosudo, no system pollution. Honours--merge-mode-functions=merge-use-line-minsince every per-test program defines its ownmain(gcovr's default strict mode rejects that as a merge conflict). Sample output: lines 14.3% (3374/23609), functions 27.4% (425/1550), branches 7.0% (1438/20487) — gcovr counts more aggressively than the bare-gcov bucket summary incoverage_report.sh(it includes header inlines, function entry/exit branches, etc.); both are valid views of the same data. -
ae build --coverage— injectgcc --coverageinto the user-program build, write.gcdafiles at runtime, produce.ae.gcovreports (tools/ae.c). Pairs withmake ci-coverageto extend coverage data from the C-level test runner (which only hits stdlib / runtime / compiler-as-library paths) to the 397.aeregression tests (which exercise the parser+typechecker+codegen via every test compilation, plusmodule.aefiles in the stdlib). Forces-O0 -gto keep gcov line attribution accurate — at-O2gcc inlines and merges blocks, scrambling the .gcov line numbers. Addedg_coverageglobal, parsed from--coverageincmd_build, plumbed throughbuild_gcc_cmdvia a newopt_flags(optimize)helper.make ci-coveragenow also runs the .ae regression suite underAE_BUILD_FLAGS=--coverage, so.ae.gcovreports populate alongside the C-level data. New numbers on this branch: stdlib (.c) 31.0%, stdlib (.ae) 61.7%, runtime (.c) 75.7%, compiler (.c) 10.5%, tests (.ae) 81.1% — the stdlib-C 31% and compiler 10.5% are the actionable data points for "what's not tested." -
make ci-coverage— line + branch coverage of stdlib / runtime / compiler, attributed to .ae source via gcov + Phase 1's#linedirectives (Makefile,tests/scripts/coverage_report.sh(new),tests/integration/ci_coverage_smoke/). Builds a coverage-instrumented variant ofaetherc+libaether.aunderbuild/cov-obj/(mirrors the existingbuild/asan-obj/pattern), runs the C-level test_runner, then walks the.gcdafiles withgcov -p -b -cto produce per-source.c.gcovand (where the source originated as an.aelowered through aetherc).ae.gcovreports underbuild/coverage/. Summary printed by source-tree bucket: stdlib / runtime / compiler. Optional richer reports ifgcovr(HTML) orlcov + genhtml(browsable HTML) are installed — probe-and-degrade. Sample output on this branch's first run: stdlib 31.0% (1193/3849 lines), runtime 37.0% (541/1461), compiler 4.0% (259/6446) — the compiler number is low because the C unit tests barely exercise the parser/typechecker/codegen; that's the data point you need to decide which compiler paths most need direct unit-test coverage. Companionmake ci-coverage-cleanclears.gcdabetween runs while keeping the.gcnoinstrumentation graphs for reuse. Not part ofmake ci— coverage rebuild is too heavy for every PR; run on demand. Phase 2 of the coverage work — Phase 1 was the#linedirectives that make this whole pipeline possible (no custom .ae↔.c sourcemap layer; gcov reads the directives natively). -
#linesource-map directives in generated C — gcc errors / gdb breakpoints / gcov reports point at.aesource (compiler/ast.{c,h},compiler/aetherc.c,compiler/aether_module.c,compiler/codegen/{codegen.c,codegen.h,codegen_internal.h,codegen_stmt.c,codegen_func.c},tests/integration/source_map_line_directives/). Until now,aetherclowered.ae→.cwith no source-position metadata, sogccwarnings and segfaults inside the generated code reported against post-merge C-line space (which jumbles user code with stdlib glue and module-imported helpers in arbitrary order). The fix threads source-file paths through the AST: a newsource_filefield onASTNodeis populated byast_stamp_source_file()after each parse — once for the top-level program, once per imported module — so cloned-by-module_merge_into_programnodes preserve their original file. Codegen's newcodegen_maybe_emit_line()writes#line N "src.ae"directives (dedup'd: back-to-back nodes on the same line emit one directive) at everygenerate_statementandgenerate_function_definitionentry. Path is escaped (\\for backslashes,\"for quotes) so paths with those chars round-trip through the C preprocessor. Phase 1 of the coverage-instrumentation work — Phase 2 will addmake ci-coverage(gcov + lcov/gcovr) on top, sincegcovreads#linedirectives natively and produces.ae.gcovreports automatically once this lands.
Downloads
| Platform | Architecture | File |
|---|---|---|
| Linux | x86_64 | aether-0.115.0-linux-x86_64.tar.gz |
| macOS | x86_64 | aether-0.115.0-macos-x86_64.tar.gz |
| macOS | arm64 | aether-0.115.0-macos-arm64.tar.gz |
| Windows | x86_64 | aether-0.115.0-windows-x86_64.zip |
Quick install
Linux / macOS
# Download the archive for your platform, then:
tar -xzf aether-0.115.0-<platform>.tar.gz
export PATH="$PWD/bin:$PATH"
ae versionWindows
Extract the .zip archive, then run bin\ae.exe version from the extracted folder.
Documentation: https://github.com/nicolasmd87/aether#readme