Skip to content

Blaise v0.11.0 — Changelog

Latest

Choose a tag to compare

@graemeg graemeg released this 17 Jun 23:17
· 30 commits to master since this release

237 commits since v0.10.0. Grouped by area; each line is a notable change.

Native x86-64 backend

The native backend reached parity with QBE and enabled via --backend native.

  • Multi-unit program support (whole-program model).
  • By-value record parameters with full ARC; ABI-correct record-by-value returns (sret).
  • Method calls returning records use the sret convention; interface/procedural/dynarray param and return types.
  • Property reads via getter methods; property writes via setter methods.
  • Nested (local) procedures with captured variables.
  • TIndirectFuncCallExpr (callbacks as expressions); TIsExpr/TAsExpr/TSupportsExpr.
  • ClassName/ClassType, ClassCreate metaclass construction; method calls with >6 argument slots in all call variants.
  • Inc/Dec on field access, deref and var params; type-cast fixes.
  • Trig/math builtins with Single-precision dispatch; float Format() (%f/%e/%g with width/precision).
  • Const array data emission with ConstArraySymbol references; open-array literal args in method/inherited calls.
  • File/process/path/math builtins for self-hosting; 32-bit comparison, sar, unsigned and mixed-float comparison fixes.
  • Caller-side const-string ARC with a unified call-arg hoist region.
  • Implicit-Self method calls with >6 register slots spilled correctly.

Toolchain independence

  • Self-assembler for the native backend (--assembler internal) — emits ELF objects directly.
  • Internal linker Phase A: ELF object + ar-archive reader and section merger (blaise.elfreader.pas, section merger in blaise.linker.elf.pas).
  • Host-aware tool resolution with spec + prefix environment variables.
  • Native fixpoint verification script (fixpoint-native.sh); internal-assembler conformance guard.

Language

Representative examples of the new syntax:

// Constant folding (integer + float) and array constants
const
  Tau = 3.14159 * 2;
  Grid: array[0..1, 0..1] of Integer = ((1, 2), (3, 4));

// Static-array bounds: expressions and enum indices
const N = 8;
type TColour = (Red, Green, Blue);
var
  Buffer: array[0..N - 1] of Byte;
  Hits: array[TColour] of Integer;

// Sets: ordinal element types, ranges, subset/superset
var Digits: set of Byte;
Digits := [0..9];
if [1, 2] <= Digits then ...;          // subset operator

// Default array property
WriteLn(List[0]);                       // TList<Integer> via List[i]

// inherited in expression position; for-in over codepoints
Total := inherited Sum() + 1;

// codepoint iteration strings (utf-8)
var CP: integer;
for CP in 'héllo' do WriteLn(CP);

// byte iteration over string
var B: byte;
for B in 'héllo' do WriteLn(B);
  • Compile-time integer constant expressions (#96); floating-point constant folding (const X = 3.14 * 2, #108).
  • Promote integer initialisers to float for Double/Single vars and typed consts.
  • Multi-dimensional static arrays and multi-dimensional array constants.
  • Named constants and expressions as static-array bounds (array[0..N], #109).
  • Enum-indexed static arrays in var/type declarations (array[TEnum], #114).
  • set of Byte/Boolean ordinal sets (#105); range syntax in set literals ([lo..hi]); subset/superset operators; enum sets up to 64 members (#81); jumbo sets up to 256 members.
  • Generic methods (method-level type parameters) and an out-of-line impl form with argument checking.
  • Default array properties — Obj[I] sugar; List[i] on TList<T>; Items default property on TDictionary/TOrderedDictionary.
  • inherited Method() in expression position; interface properties; implicit-virtual constructor dispatch via metaclass.
  • Implicit integer→float widening for math builtins and float typecasts.
  • Initialised global variables (var G: T = value); inline set types in any type position.
  • Guaranteed zero-initialisation of all variables — a language semantic: ints 0, floats 0.0, pointers/classes/interfaces nil, strings empty, records/arrays recursively zeroed. Also makes output deterministic across backends (native previously left scalar locals as stack garbage while QBE zeroed them).
  • array of const (heterogeneous variadic parameters); case-label ranges and Succ/Pred ordinal builtins.
  • for..in over a string iterates Unicode codepoints (Integer var).
  • Reserve module names as identifiers; reject variables shadowing a type name (#102); clear diagnostics for packed/bitpacked arrays.

ARC / runtime

  • Integer div/mod by zero raises a catchable EDivByZero.
  • One-time RTL setup runs via a _BlaiseInit startup hook.
  • ARC parity fixes across record-field, ExprOwnsRef, and interface-in-field stores; chained-field-store and program-exit global release fixes.
  • _Utf8DecodeAt helper for UTF-8 codepoint decoding.

stdlib

  • StrUtils: clean literal replace API — Replace (first) + ReplaceAll; UTF-8 codepoint functions.
  • Hash indexes for TDictionary, TOrderedDictionary, TSet, and unsorted TStringList.Find/IndexOf.

Codegen (QBE)

  • ABI-correct record-by-value returns for C-FFI.
  • Function-returning-interface and interface-field assignment via the sret convention; weak interface vars + interface type-cast fix.
  • String relational operators (< > <= >=); Boolean xor emitted correctly (was ceqw).
  • Fixed-size static array returned by value via sret (#112); chained element write on dynamic-array-of-dynamic-array.
  • Class const accessed via the type name (both backends); virtual-dispatch property accessors through the vtable.
  • 0-based string iteration corrected in FNV-1a hash loops.

Semantic

  • Resolve inherited property accessors to the declaring class (#111); honour interface inheritance in type compatibility.
  • Merge method overload sets across inheritance; generic class implementing a non-generic interface; inherit non-generic class from a generic instance.
  • Repair generic instance methods when a type alias precedes the impl (#124); typed array const with a named type alias (#113).

Debugging (OPDF / pdr)

  • Native-first debugging: exact frame offsets, statement-level line info.
  • Field drilldown — unit-class symbols, Self typing, record-param shadows; indirect variable locations.
  • --debug-opdf binaries link as PIE
  • open-array debug info (ArrayKind=2 + companion slot).
  • Leak tracker extended to strings and dynamic arrays, with allocation-site (unit:line) info.

Performance

  • Overload groups replace per-call index scans in the semantic pass.
  • Stack buffers for WriteDecimal and Format; inlined header checks in _StringRelease.
  • SIMD-accelerated UTF-8 codepoint counting (SSE2 + AVX2)
  • Amortised byte buffers in the internal assembler's ELF writer.
  • Borrowed-local and shape-aware const-string argument ARC.

Tooling / CI

  • bif-coverage verifier for AST/encoder/decoder drift.
  • Per-backend CLI option contract (Chain of Responsibility); reject --emit-ir/--emit-asm with an incompatible explicit backend.
  • GitHub Actions rolling-bootstrap pipeline; CLI-contract and internal-assembler tests in CI.

Summary

  • Self-hosting fixpoint verified on 371,292 lines of QBE IR.
  • QBE, native, and internal-assembler fixpoints all green.
  • 3,474 tests passing.