Skip to content

Aether 0.115.0

Choose a tag to compare

@github-actions github-actions released this 02 May 21:46
· 4140 commits to main since this release
Immutable release. Only release title and notes can be modified.
1e5a1a0

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-coverage reported 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 from runtime/examples/*.c bench 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 real schedulers[] Scheduler state — already covered by the separate test_scheduler.c suite). 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 in send_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-reading spsc_enqueue_batch showed it's all-or-nothing (returns count on full success, 0 if space < 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 via gcovr, with auto-bootstrap into a project-local venv if gcovr isn't on PATH (Makefile, tests/scripts/coverage_html.sh (new)). After make ci-coverage populates .gcda data, this target runs gcovr over the merged stdlib + runtime + compiler + .ae-tests data set and writes build/coverage/index.html (browsable per-file detail) plus build/coverage/coverage.json (5.7 MB structured dump for CI / dashboard pickup). Three install paths in priority order: (1) gcovr already on PATH (auto-detected), (2) project-local venv at build/cov-venv/ auto-created on first run via python3 -m venv, (3) clear diagnostic with apt/dnf/brew instructions if neither is available. The venv path keeps the install self-contained — no pip install --break-system-packages, no sudo, no system pollution. Honours --merge-mode-functions=merge-use-line-min since every per-test program defines its own main (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 in coverage_report.sh (it includes header inlines, function entry/exit branches, etc.); both are valid views of the same data.

  • ae build --coverage — inject gcc --coverage into the user-program build, write .gcda files at runtime, produce .ae.gcov reports (tools/ae.c). Pairs with make ci-coverage to extend coverage data from the C-level test runner (which only hits stdlib / runtime / compiler-as-library paths) to the 397 .ae regression tests (which exercise the parser+typechecker+codegen via every test compilation, plus module.ae files in the stdlib). Forces -O0 -g to keep gcov line attribution accurate — at -O2 gcc inlines and merges blocks, scrambling the .gcov line numbers. Added g_coverage global, parsed from --coverage in cmd_build, plumbed through build_gcc_cmd via a new opt_flags(optimize) helper. make ci-coverage now also runs the .ae regression suite under AE_BUILD_FLAGS=--coverage, so .ae.gcov reports 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 #line directives (Makefile, tests/scripts/coverage_report.sh (new), tests/integration/ci_coverage_smoke/). Builds a coverage-instrumented variant of aetherc + libaether.a under build/cov-obj/ (mirrors the existing build/asan-obj/ pattern), runs the C-level test_runner, then walks the .gcda files with gcov -p -b -c to produce per-source .c.gcov and (where the source originated as an .ae lowered through aetherc) .ae.gcov reports under build/coverage/. Summary printed by source-tree bucket: stdlib / runtime / compiler. Optional richer reports if gcovr (HTML) or lcov + 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. Companion make ci-coverage-clean clears .gcda between runs while keeping the .gcno instrumentation graphs for reuse. Not part of make ci — coverage rebuild is too heavy for every PR; run on demand. Phase 2 of the coverage work — Phase 1 was the #line directives that make this whole pipeline possible (no custom .ae↔.c sourcemap layer; gcov reads the directives natively).

  • #line source-map directives in generated C — gcc errors / gdb breakpoints / gcov reports point at .ae source (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, aetherc lowered .ae → .c with no source-position metadata, so gcc warnings 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 new source_file field on ASTNode is populated by ast_stamp_source_file() after each parse — once for the top-level program, once per imported module — so cloned-by-module_merge_into_program nodes preserve their original file. Codegen's new codegen_maybe_emit_line() writes #line N "src.ae" directives (dedup'd: back-to-back nodes on the same line emit one directive) at every generate_statement and generate_function_definition entry. 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 add make ci-coverage (gcov + lcov/gcovr) on top, since gcov reads #line directives natively and produces .ae.gcov reports 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 version

Windows

Extract the .zip archive, then run bin\ae.exe version from the extracted folder.


Documentation: https://github.com/nicolasmd87/aether#readme