XCX 4.2 — The HIR & Fast Path Update
XCX 4.2 introduces a new intermediate compilation layer, HIR, along with a substantial JIT optimization pass. Function ASTs are now lowered to HIR before being compiled to bytecode, unlocking HIR-level inlining. The JIT gains fast paths for arrays and BoolArray, JSON gets a parse cache, string concatenation gets new StrAppend* opcodes, and table.join moves to Hash-Join O(N+M).
~12x faster string append
~21x faster table.join (500x500)
97.8ms sieve under JIT
Available on Linux (Ubuntu, Arch/Manjaro, and other major distros), Windows, and macOS.
What's new
New Compilation Layer: HIR
Function ASTs are now lowered to HIR before being compiled to bytecode. HIR-level function inlining was introduced, excluding fibers, recursion, return inside a loop, and overly costly functions. Full compilation of TableLiteral, DatabaseLiteral, DateLiteral, and Tuple literals was added, eliminating the default Int initialization that used to cause method dispatch errors.
JIT: New Optimizations
Added a fast path bounds check for arrays (int[], bool[]) — the index < len comparison now happens directly in JIT code, with a runtime fallback for out-of-range access. A dedicated BoolArray fast path now bypasses FFI and RwLock. Fixed a type inference bug that failed to recognize array:b constants as BoolArray. Added constant tracking in registers (register_const), division/modulo by a power of 2 without guards, and typed JumpIfFalse reducing the comparison to a simple icmp.
JSON: Caching and Fast Access Paths
New thread-local cache for json.parse() (up to 128 entries). Fast path for simple keys in getters, has(), and keys()/len(). Fixed a thread-unsafe dirty: AtomicBool flag, replacing it with a version/cached_version counter pair, eliminating the risk of reading a corrupted JSON string under concurrent JIT/VM access.
String Concatenation: New StrAppend* Opcodes
StrAppendVar/StrAppendLocal/StrAppendMember/StrAppendElement mutate the string buffer in place when Arc ownership is unique, instead of three allocations per iteration. Results (100k iterations): global variable 1300ms → 2.2-3.5ms; array element 86ms → ~3-4ms; general append under JIT 10790ms → 5.5ms.
Table Queries
table.join with Hash-Join O(N+M) (500x500 rows: 215ms → 10ms). New row_cache on RowObj for table.where, auto-invalidated on modification. count()/len()/size() with an active sql_where now computed directly in the database.
Networking: HTTP
TCP/TLS connection pooling via a global agent (HTTP_AGENT) — 100 sequential HTTPS requests: 195ms/req → 63ms/req.
CLI
Reorganized --help, short flags -h/-v now working anywhere, combining options with |.
Bug Fixes
Fixed hangs on @step loops with bare backward jumps, a panic on JsonPush against a JSON object, missing argument propagation in table.where(...), an incorrect bitcast in Float + Int arithmetic, a missing SSA block switch in GetIndex for BoolArray, and a register allocation bug in closures/captures for table.where(...).
Performance results
New benchmark suite (more stable lcg/sieve measurements, more accurate json sampling):
Variant fib(30) lcg(100m) sieve json
| XCX 4.1, JIT | 13.119ms | 107.706ms | 201.003ms | 0.272ms |
| XCX 4.2, JIT | 12.303ms | 106.480ms | 97.814ms | 0.238ms |
Test system: AMD Ryzen 7 5800X, 32 GB RAM, Windows 11