Blaise v0.12.0 — Changelog
Headline: the native x86-64 backend is now the default, with a complete
internal assembler and internal linker — Blaise compiles and links a binary
with zero external tools. Compilation is incremental (per-unit) by default,
and per-unit OPDF makes incrementally-built multi-unit programs fully
debuggable in pdr. Ships the first real standard library (JSON, crypto,
networking, exact decimals). QBE is now opt-in and deprecated.
Native backend & toolchain (default)
- Native x86-64 is the default backend; QBE is opt-in via
--backend qbe
(deprecated, slated for removal in a later release). - Internal assembler + internal linker are the default:
blaise --source X --output Yproduces and links an executable with no externalas/ld/gcc
(only the distro CRT objects are read). - Internal linker: symbol resolution, static relocations, ET_EXEC,
then dynamic linking — GOT/PLT, CRT object discovery, PIE (ET_DYN) emission,
TLS relocations,.init_array/.fini_array, GOTPCRELX relaxation. - Internal linker wired into the compiler driver;
--assemblerand--linker
acceptinternal|external(both default to internal on the native backend). - Escape hatches:
--no-incremental(whole-program build),--assembler external,--linker external,--backend qbe.
Compilation model
- Incremental, per-unit compilation is the default (like FPC): each unit is
compiled to its own.o, then linked. Faster rebuilds; sidesteps the
whole-program assembly memory blow-up.--no-incrementalforces the old
whole-program mode. - Fixed a class of cached-interface (
.bif) rebuild bugs so a warm-cache
rebuild is lossless and coherent (dropped unit-init calls, impl-onlyuses
dependencies dropped from the link, duplicate globals, and cached-.bif
method vtable-slot reconstruction). .bifinterface format advanced to v2 (carries impl-section uses, unit
initialisation flag, generic template locals, parameter defaults, exit
values, and vtable facts); old.bifare rejected and recompiled.- New
WARMCACHE_FIXPOINT_OKguard plus an extendedbif-coveragedrift guard
covering the.bifinterface container types.
Debugging (OPDF)
- Per-unit OPDF: every object (each unit and the program) carries its own
.opdfsection; the linker concatenates them, mirroring FPC's multi-unit
layout. pdr can now set breakpoints, show cross-unit callstacks, and inspect
params/locals/fields inside dependency units of an incrementally-built
program — under both the internal and external toolchains. - The internal assembler now carries the
.opdfsection; the internal linker
merges it (SHF_ALLOC).
Language
- Qualified type names:
UnitName.TypeName, including dotted qualifiers
(System.SysUtils.TFormatSettings). - Chained l-value assignment:
Self.FStack[0].Count := valueand similar
subscript-then-field chains. - Writable string subscript with copy-on-write:
S[i] := ch. - Conditional compilation: symbol-presence
{$IFDEF}/{$IFNDEF}/{$DEFINE}
with a predefinedBLAISEsymbol plus CPU/OS symbols (-d/--define). - Sets over an integer-subrange base (
set of 0..255) and Boolean set
operands; integer literals and ranges in const-decl set literals. - Named integer-subrange types;
forwardroutines in a program declaration
section; nested-proc-first unit implementation bodies.
Examples
// native, one step — no external tools
// blaise --source hello.pas --output hello
program hello;
begin
WriteLn('Hello, Blaise 0.12!')
end.uses Json.Types, Json.Writer;
var o: TJSONObject;
begin
o := TJSONObject.Create();
o.Add('name', 'Blaise');
o.Add('version', 12);
WriteLn(o.AsJSON()); // {"name":"Blaise","version":12}
o.Free()
end.var s: String;
begin
s := 'hello';
s[0] := 'H'; // writable subscript, copy-on-write
WriteLn(s) // Hello
end.Standard library (opt-in)
- JSON — DOM (
Json.Types), parser (Json.Parser), reader (Json.Reader),
writer (Json.Writer). - Encoding.Base64 —
Base64Encode/Base64Decode. - Security.Crypto — SHA-1 (
Sha1,Sha1Hex). - Security.Guid — RFC 4122 v4 GUIDs.
- Net.Sockets — IPv4 TCP.
- Net.WebSockets — RFC 6455 framing + handshake.
- Net.Http.Server — minimal HTTP/1.1 server with WebSocket upgrade.
- Numerics.Decimal (
TDecimal, exact decimal) and Numerics.Money
(TMoney, currency-aware, configurable rounding). - StrUtils additions —
SplitChar,SplitLines,JoinList,
CodePointToString. blaise.testingunit-test framework moved into the stdlib; stdlib ships its
own test suite (pasbuild test -m blaise-stdlib).
Codegen / ARC / runtime fixes
- Float arguments to methods, constructors, and inherited calls are passed in
SSE (xmm) registers per the System V ABI, including the >6-slot overflow path
and on the callee side; float-returning method calls and implicit-Self
float-field reads are correct on both backends. - Implicit-
Selfvirtual method calls dispatch through the vtable (previously
bound statically — silently wrong for overrides, a link error for abstract
bases). HasClassAttributeemits the runtime call and the class attribute RTTI table
on the native backend.- Record-copy uses field-width loads/stores; interface arguments to
record-returning routines; transient record-returning call receivers. - 64-bit integer constants keep their full bit pattern (no truncation);
internal assembler encodes SSEmovq/movdbetween XMM and GP registers.
Tooling / CI
- Rolling-bootstrap re-anchored at v0.12.0: the replay range is entirely
native-default with the internal toolchain — no QBE, no gcc. - CI runs the bootstrap on
masterplus branch-scoped validate-only pre-flight
runs (ci/**,feature/**,bootstrap/**) that never write the master
carry-forward cache.
Verification
- Self-hosting fixpoint at 410,477 lines of QBE IR —
FIXPOINT_OK,
NATIVE_FIXPOINT_OK,NATIVE_INTERNAL_OK, andWARMCACHE_FIXPOINT_OKall
green. - 3,745 compiler tests + 57 stdlib tests passing.