Skip to content

Releases: The-Mettle-Project/Mettle

Mettle v0.13.0

Choose a tag to compare

@marquisburg marquisburg released this 06 Jul 18:51
f066ade

Second backend target, first-class closures, and a wave of new optimizer and
tooling work.

BREAKING CHANGE

  • The function keyword is now fn. Existing sources using function will not
    compile; rename to fn. All docs and examples have been updated.

AArch64 backend (new target)

  • --emit-arm64 compiles scalar Mettle to AArch64 ELF that runs under QEMU:
    from-scratch instruction encoder, AAPCS64 ABI, and executable emit layer.
  • Direct ir_aarch64 backend plus a MIR->AArch64 lowering path with vreg
    stack allocation and parameter homing.
  • Supported: pointers, arrays, narrow ints, full scalar floats, string
    literals, and write-syscall I/O.

Closures and lambdas

  • Anonymous fn(...) lambda expressions.
  • Capturing closures with mutations that persist across calls.
  • Cross-boundary closures and revived expression-calls.
  • Closures and function pointers stored in and called from struct fields.
  • A plain function or non-capturing lambda flows anywhere an Fn(...) closure
    type is expected.

Optimizer and IR

  • Zero-run PGO (--pgo): interprets main() at compile time to drive
    hot-callee inlining and hotness-aware optimizer thresholds.
  • Tail-recursion elimination and layout factorization passes.
  • New prefetch and if-conversion IR passes.
  • ML-guided IR optimization pass (--ml-opt).
  • Per-pass translation validation with automatic quarantine of unsound passes.

Compile-time testing and diagnostics

  • @test functions with mettle test (interpreted, assert diagnostics, leak
    detection) and mettle trace.
  • mettle explain command, new warnings, richer diagnostics, and multi-error
    recovery.
  • Codegen annotation and profiling views in the VS Code extension.

Language

  • Local const now accepts float, string, and aggregate values.

Correctness fixes

  • Fixed a gather-sum miscompile.
  • Fixed float global variables reading back as 0 in the direct-object backend.
  • Fixed two aggregate-by-value truncation bugs.
  • Const-pool sinking now dominates all uses (#40).

Other

  • New benchmark suite and examples; contributor guide; installer and Linux
    build-flag fixes; dead-code cleanup.

What's Changed

  • Backend, optimizer, and tooling overhaul: AArch64 target, closures, PGO/TRE, compile-time testing, and ML-guided IR opt by @marquisburg in #44

Full Changelog: v0.12.0...v0.13.0

Mettle v0.12.0

Choose a tag to compare

@marquisburg marquisburg released this 24 Jun 16:51
705b13e

Implemented COFF IMAGE_SCN_LNK_NRELOC_OVFL support in binary_emitter.c (write) and linker/coff_reader.c (read) so sections with >65535 relocations encode the real count in a synthetic first relocation record instead of erroring.

What's Changed

Full Changelog: v0.11.0...v0.12.0

Mettle v0.11.0

Choose a tag to compare

@marquisburg marquisburg released this 12 Jun 22:14
59825ec

v0.10.0 shipped the optimizer as a little helper. v0.11.0 does the same for safety: the compiler now catches use-after-free, dangling returns, loop off-by-ones, and null dereferences before the binary exists, explains what went wrong and where, and when it can't catch something statically, the runtime names the faulting address instead of printing an anonymous pointer.

The vectorizer also grew up: runtime scalar broadcasts, integer lanes, and a confirmed miscompile class found and fixed across the entire recognizer suite.

Compiler: memory safety diagnostics

Hard build errors

  • Returning the address of a stack local, directly or through an alias
  • Constant-size memory ops that exceed the destination array's capacity
  • Constant array index out of bounds, including through pointer aliases (var p = &a[2]; p[6] is a build error naming a[8])
  • Loop off-by-one: j <= 8 over an int32[8] fails with the exact comparison to change
  • Divide-by-zero and over-width shift, with honest hardware explanations (x << 32 on int32 produces x; the hardware masks the count)

Warnings with fixes

  • Use-after-free and double-free
  • Stack address stored into a global
  • Allocation that never escapes and is never freed (suggests defer free(p) at the allocation site)
  • Null dereference through an unguarded pointer (any conditional on the pointer ends the claim)

Whole-program ownership inference

The compiler flattens imports into one program for codegen. It now uses the same call graph to compute per-function ownership summaries bottom-up: does this function free its parameter, store it, return a fresh allocation? The analysis re-runs with those summaries to catch UAF and leaks across call boundaries, through helper functions, and through wrapper allocators like make() -> malloc. Zero annotations required. Only definite summaries propagate; the zero-false-positive budget holds.

Runtime: access violation forensics

0x10 is no longer anonymous. With -s, a fault now explains the address:

Attempted to write inaccessible memory at 0x0000000000000010
This address is null plus offset 16: a field or array access through a null pointer
  --> tests/debug_crash.mettle:13:14 in main
  • Null-plus-offset: prints the field offset
  • Stack region: dangling-frame note
  • Freed heap: names the block, its size, and that it was already freed

--native-heap is now a UAF detector. Freed page-backed blocks keep their mapping with all access revoked and sit in a quarantine ring. Freed small blocks are poisoned 0xDD. A dangling read or write faults immediately with classification text, at the point of access, not three functions away where the corruption surfaces.

The static analyzer and the runtime fault handler compound: a UAF that escapes compile-time analysis faults instantly at runtime with the block named. Linux signal path covered.

Vectorizer: correctness and generalization

Confirmed miscompile fixed

Loops with a nonzero induction variable start (j = 3; while (j < n)) were silently replayed as 0..n by SIMD recognizers. Confirmed live repro returning 100 instead of 97. Fixed via a shared ir_iv_zero_at_header guard, one implementation, no duplicates. Eight recognizers had the same hole and all received the fix: sum_i32, dot_i32, dot_i8, exp_f32, memcmp byte-loop, clamp_i32, reverse-copy, both SLP MAC matchers, i2f, outer-lane vectorizer, and all pointer-walk matchers.

VLOOP generalized

  • Runtime scalar broadcasts: any loop-invariant scalar symbol (param or local) now vectorizes as a broadcast. out[i] = (a[i]*s1 + b[i])*s2 with runtime coefficients vectorizes at 9.8x over scalar.
  • Integer lanes: new IR_OP_SIMD_VLOOP_I32 opcode covers int32/uint32 unit-stride maps and +-reductions over + - * & | ^ <<literal DAGs, 8 lanes per iteration. Results are bit-exact against scalar. Int maps 3.9x, int reductions 5.8x.

uint32 wrap semantics

Unsigned sub-64-bit arithmetic now wraps mod 2^width consistently in all four modes (encoder, MIR, fallback backend, return canonicalization). Root cause was binary_emit_mov_reg_reg32 silently no-oping on dst==src, eating every uint32 zero-extension. Fixed with a dedicated binary_emit_movzx_reg_reg32 and three-layer canonicalization.

VS Code extension

  • Full Debug Adapter Protocol: F5, conditional breakpoints, live variable editing, crash reporting via named-pipe debug runtime
  • Optimization report panel: regression detection, verified fix application, click-to-source
  • @inline! and @noalloc contracts surface in the panel
  • Complete language service: go-to-definition, references, rename, outline, completion, signature help, inlay hints, CodeLens, hovers, compiler-backed diagnostics
  • All memory diagnostic warnings and errors surface in the VS Code Problems panel with fix suggestions attached

Other

  • DCE pass: dead code elimination in IR, improved compile speeds
  • IR optimizer speedups: hash value maps, dead copy-propagation pruning, getenv caching
  • type_checker.c and ir_lowering.c split into focused modules
  • Bounded self-recursion inlining
  • Site-aware inliner with repeated-refusal folding
  • Linux build fix: explicit -pthread -ldl for glibc < 2.34
  • 416/416 tests, 400/400 differential-fuzz seeds clean

What's Changed

  • Add source-level debugger and interactive --explain optimization report panel with verified fixes by @marquisburg in #41
  • Memory safety diagnostics, access violation forensics, and vectorizer correctness by @marquisburg in #42

Full Changelog: v0.10.0...v0.11.0

Mettle v.0.10.0

Choose a tag to compare

@marquisburg marquisburg released this 10 Jun 05:59
3ae2de9

Mettle now compiles for the GPU: a native CUDA/PTX backend with kernel and
dispatch syntax. On the CPU, the legacy text-asm backend is gone and nearly every
function now goes through the register-allocating MIR backend. The language gains
function decorators, range-for loops, and @simd vectorization contracts, and the
runtime gets its own native memory allocator.

What's new

  • GPU compilation: the compiler emits PTX natively for NVIDIA GPUs. Write
    kernel functions as peers of function, launch them with
    dispatch K[grid, block](args), and index with thread.x, block.x,
    block_dim.x, and grid_dim.x. A new std/gpu module wraps the CUDA Driver
    API. The PTX backend is validated by a ptxas round-trip gate in the test suite
    and differential execution tests on real hardware.
  • One backend: the legacy text-asm backend has been removed. The MIR register
    allocator now covers ~97% of functions (up from ~72%), including structs passed
    and returned by value, calls with more than 4 arguments, address-of, switch
    dispatch, and runtime safety checks. Almost no code falls back to
    spill-everything codegen anymore.
  • Function decorators: @inline, @noinline, @pure (lets the optimizer
    hoist pure calls out of loops), and @simd / @simd! contracts that verify a
    loop actually vectorized, with diagnostics explaining any bail.
  • Range-for syntax: for i in 0..n and inclusive for i in 0..=n.
  • Faster integer code: quantized int8 dot products and matmul tiles are
    auto-vectorized with AVX2 (vpmaddwd): 11x over scalar and 3.5x faster than
    gcc -march=native on the dot kernel. Constant division and modulo are
    strength-reduced to magic multiplies, paired div+mod fuse into one division,
    and SIMD kernels now inline into register-allocated functions instead of
    forcing a fallback.
  • Native memory subsystem: Mettle's allocator is now written in Mettle
    (std/osmem, std/alloc, std/mem). Build with --native-heap to route
    new/malloc/free through it on Windows and Linux. Double-free and
    invalid-free are detected and rejected.
  • Imports: stronger visibility enforcement and selective dependency
    resolution, so only what you import gets compiled in.
  • Correctness: the differential fuzzer got new program shapes and automatic
    pass attribution, and found 4 silent miscompiles, all fixed. Also fixed: three
    register-promoted-global bugs exposed by a real GUI program, a uint32
    signedness bug at -O, float32 narrowing bugs, a callee-saved register clobber
    on Win64, and a missing diagnostic for non-void functions without a return.
    Full test suite green throughout.

Full Changelog: v0.9.1...v0.10.0

What's Changed

  • Add MIR register allocator, auto-vectorizators, SROA, magic-divide, and modularize SIMD & IR by @marquisburg in #37
  • wcs_broadcast_i32_to_ymm emitted legacy movd immediately before a VEX… by @marquisburg in #38
  • Native CUDA/PTX backend, full MIR register allocation, and function decorators by @marquisburg in #39

Full Changelog: v0.9.1...v0.10.0

Mettle v0.9.1

Choose a tag to compare

@marquisburg marquisburg released this 27 May 14:32
be28175

What's Changed

Full Changelog: v0.9.0...v0.9.1

v0.9.0

Choose a tag to compare

@marquisburg marquisburg released this 27 May 14:22
094cf97

Mettle v0.9.0

Native Linux --build with a self-contained ELF backend, GitHub Actions CI and release packaging, reworked installers, a richer VS Code extension, and compiler fixes from a new differential fuzzer.

What's new

  • Linux native --build: emits ELF objects with SysV AMD64 ABI and a compiler-owned _start, then links with ld -static into standalone executables. No NASM, libc, or CRT required. See README and docs/compilation.md.
  • CI and releases: GitHub Actions for Windows build+test, nightly fuzz, and tagged release packaging (Windows .zip + GUI installer, Linux .tar.gz). A Linux elf-native job exercises the ELF backend.
  • Installers: reworked install.ps1, new install.sh for per-user Linux installs, and an updated Inno Setup wizard with bundled docs and runtime.
  • VS Code / Cursor extension: hover docs, snippets, syntax updates, import/declaration hovers, and compiler-backed linting.
  • Compiler fixes: struct method calls desugared correctly in the type checker (fixes #31). The differential miscompile fuzzer found and fixed three silent optimizer/backend bugs.
  • Tooling cleanup: removed obsolete build_engine_editor.bat. Benchmark reports and release workflow updated.

Full Changelog: v0.8.0...v0.9.0

What's Changed

  • Development by @marquisburg in #33
  • Add native Linux ELF backend with CI coverage, installer rework, and VS Code extension improvements by @marquisburg in #35

Full Changelog: v0.8.0...v0.9.0

v0.8.0

Choose a tag to compare

@marquisburg marquisburg released this 25 May 23:23
4b92fe8

Mettle v0.8.0

Tracy profiling, source-aware crash tracebacks on Windows, a large compiler correctness pass, and continued IR and codegen optimization work since v0.7.1.

What's new

  • mettle --build --tracy links the real Tracy client. std/tracy covers zones, frame marks, plots, and memory tracking. Without --tracy, the same source links a no-op stub so release and profiled builds stay in sync. See examples/tracy_demo/.
  • Windows --build programs built with -s or debug/trap flags get COFF stack traces with trap context and source snippets.
  • Fixed sign-extension bugs, codegen miscompiles, uint32 compares, int32 call-result corruption on cross-module calls, and scaled pointer arithmetic lowering, with regression tests for the latter.
  • Multiple IR optimization passes, loop fusion, SIMD lowering (including insertion-sort fusion), and compilation-speed work across the pipeline.
  • The compiler itself can be built with Clang on Windows via CC=clang or build.bat clang, including MSVC/UCRT header compatibility fixes.
  • Mettle strings now flow to cstring parameters implicitly where safe, so cstr() wrappers are no longer required for common C interop and I/O call sites.
  • IR dumps include an explicit CFG view for basic blocks.
  • Makefile source list fixes, unified -O2 and CFLAGS in build.bat, Hello World examples, and a README refresh.
  • Shared utilities, deduplicated cross-file logic, named phases for oversized functions, and consolidated linker utilities and test helpers. Critical fixes in posix_helpers, ast_destroy_node, and method-declaration parsing. Full test suite passing again.

Full Changelog: v0.7.1...v0.8.0

v0.7.1

Choose a tag to compare

@marquisburg marquisburg released this 21 May 21:08
759ef4e

Burnt away the GC and async runtimes.
Optimizations can be observed in compilation speed & runtime performance.

v0.7.0

Choose a tag to compare

@marquisburg marquisburg released this 18 May 14:41

Mettle v0.7.0 - Rebrand & Async Runtime

Note: The project has been rebranded from Meth to Mettle. The compiler binary is now mettle / mettle.exe, source files use the .mettle extension, and the installer is updated accordingly. Update any scripts that invoke the old meth binary or reference .meth files.

Highlights

  • Rebrand to Mettle: new name, binary, file extension, icon, and documentation throughout.
  • Async/await runtime: bounded worker-pool executor (default) plus an experimental stackless coroutine model on a portable reactor (IOCP - on Windows, poll(2) on POSIX), with executor lifecycle management, token-routed task wakeups, and cooperative cancellation.
  • Compilation speed: multiple passes of compile-time optimization across the front end and codegen.
  • Runtime performance: codegen improvements for faster generated programs.

Language & Compiler

  • Allowed newlines inside unclosed brackets (more forgiving parsing).
  • Improved error reporting and diagnostics.
  • Concurrency work and improved operand handling.
  • Trait bounds / generic constraints, tagged-enum match, and namespaced imports (new test coverage added).
  • Better string/cstring interop and std/conv formatting.

Stability

  • Massive stability improvements and bug fixes across the compiler.
  • Better POSIX support for Linux.
  • Web server demo and form parser improvements.

v0.6.0

Choose a tag to compare

@marquisburg marquisburg released this 06 Mar 23:28

What's Changed

Full Changelog: v0.5.0...v0.6.0