Ash runs HashLink (.hl) bytecode compiled from Haxe. Execution is tiered: an interpreter runs everything, hot functions are promoted to Cranelift, and the hottest are recompiled by LLVM.
Two compiler backends over a typed SSA IR, an Immix collector, cooperative fibers for sys.thread, and the HashLink standard library rewritten in Rust.
Promotion is brokered by beadie, which counts invocations, compiles on background threads, and publishes code pointers atomically. ash --jit-tier pins a single rung for testing.
One script, no toolchain. Prebuilt binaries for macOS and Linux on aarch64 and x86_64.
Drops the ash binary into ~/.ash/bin and adds them to your PATH. Ash requires a 64-bit target.
Ash runs HashLink bytecode, so build a .hl file with Haxe — or use one you already have.
One binary, one flag set: --mode interp|hybrid|jit, --jit-tier auto|cranelift|llvm|off, promotion thresholds, and --jit-log.
std/ rebuild steps spelled out in the README.Across fib(40), Mandelbrot, n-body, inlined calls, method calls, and free-function calls, Ash's tiered JIT is measured against HashLink's released JIT, its in-development hl2-ir JIT, and its ahead-of-time HL/C output — same bytecode, every engine in a row timed on the same runner, every run checksum-verified. Numbers land fresh from CI with each push to main.
Being fast is worth nothing if the answers are wrong. Ash runs the official Haxe test suite unmodified, from CI on every push.
Ash compiles natively for aarch64 and x86_64. One binary per platform, with the full interpreter → Cranelift → LLVM ladder on each.