← board

Meta: pxx produces linkable code, not just programs

What already works — do not rebuild it

Measured 2026-08-31, not assumed:

So the prerequisites the owner expected to exist do exist. The gap is one direction only.

What is missing

Being linked into something else — now partly closed. Updated 2026-08-31, after 41045d7b4; the original text is one paragraph down, because the diagnosis in it is what the fix was built on.

The original diagnosis, which is what the fix was built on: there were two object writers, dispatched by architecture, when the discriminator should be what the object has to carry. That is now what compiler.pas asks.

Why it is priced above bug fixing

  1. It is a capability gap, not a defect — it does not compete with bugs on the same axis. Nothing is wrong; a whole class of use is absent.
  2. It converts an unanswerable design question into a measurement. Today the C-ABI convention on i386/arm32/aarch64 is unobservable from outside: the corpus is self-consistent before and after any change, which is exactly how that bug survived on three targets. An ET_REL writer lets a gcc-built caller be the oracle.
  3. The live boundary and the divergent targets do not overlap. GTK callbacks work on x86-64, which is the one target that never diverged — it has always used EmitParamSpillsForTarget. So today's working callbacks prove the machinery and say nothing about the three targets in question. Correct about something else.

Children

The last four were the "not yet filed, deliberately" set. They are filed now because the writer's shape is known, so each is written against a real interface rather than a guessed one — and two of them changed shape in the process: the .so turned out to be blocked on the backend rather than on a writer, and library lost most of its value to the export surface the writer already has.

Unblocks

[[decide-does-a-c-function-always-use-the-c-abi-or-only-when-a-pascal-program-uses-it]] — deferred on this, with the trigger named there.

TRIGGER FIRED 2026-08-31 — the measurement is in and says OPTION A. The x86-64 writer settled nothing, exactly as the third bullet above predicts: that target never diverged. The i386 writer, landed hours later, settled it in one run. With CProcUsesCAbi FALSE — a standalone C unit, the landed option B — two integer arguments arrive reversed (i_ii(1,2) returns 21) and every double argument and return is -nan, under a gcc -m32 -no-pie caller. With it TRUE (Pascal cdecl, same signatures, same object writer, same caller): all correct. Table, controls and the three limits of the claim are in the decision file. Awaiting the owner's ruling — it is evidence, not a re-ruling, and the change is one clause.

This is what the umbrella was priced for, and it is worth stating plainly: the object writer did not answer the question, it built the instrument that could.

The gate this must not break

--emit-obj on xtensa/riscv32 works today and is what the ESP path uses. A rewrite that unifies the two writers must keep those green; they are the only evidence any of this works at all.