Speak in meaning. Think beyond syntax. Built beyond language.

Object Build & Debugging

The object runner exists to answer one question precisely:

Which parts of the compiler can already be lowered to native COFF objects, and where does lowering fail?

For SWC, this question is deliberately narrower than “did the compiler command exit successfully?”. A source unit may be parsed, indexed, lowered partially, emitted as an object, linked into a PE image, or executed successfully. These are different milestones. Reports must name the highest milestone that was actually observed.

Stable strategy

The reliable build strategy is one Semantic unit per child process.

  • several units run in parallel;
  • each process has a hard timeout;
  • a failed unit does not abort the queue;
  • successful units persist their .obj files;
  • status and logs remain available after the run.

SWC evidence levels

EvidenceWhat it provesWhat it does not prove
source unitSemantic source exists in the compiler graphthe unit is linked or executable
contract or routethe intended semantic seam is named and validatedmachine-code emission is complete
COFF objectone unit emitted a persisted native objectall symbols, relocations, or runtime behavior are correct
linked PEobjects were combined into a Windows imagethe entry point and generated program are runnable
runtime executablethe produced image starts and behaves for the tested caseselfhosting or universal UAST coverage
Stage 2 → Stage 3 proofthe compiler recompiles its source under the declared deterministic contractunsupported features may be silently ignored

A small PE file or a zero exit code is therefore not enough to claim a completed SWC backend. In particular, a fallback return stub must be reported as a stub.

Status phases

Phase Meaning
queued waiting for a worker slot
compiling worker process active
objects_ready unit compiled and objects were persisted
failed compiler returned a real diagnostic
timeout worker exceeded the hard timeout and was killed

Common error families

NATIVE_EXTERNAL_VALUE_UNRESOLVED

Example:

NATIVE_EXTERNAL_VALUE_UNRESOLVED: "m.Rows"

Usually means the source-level selector exists but the native selector cannot map its base value/type/layout safely.

NATIVE_UNRESOLVED_BINDING

Example:

NATIVE_UNRESOLVED_BINDING: "ID"

Often indicates that a transported node retained the field or local name but lost enough context to identify the source binding.

native member ... has no structured layout

The compiler found a member operation but cannot prove a safe field offset for the base type.

UNIMPLEMENTED_NATIVE_GAP

A structural native lowering case is recognized but not yet implemented. This is intentionally explicit.

Debugging by family, not file

A single resolver bug can affect dozens of compiler units. The preferred loop is:

run all units
→ group errors by root cause
→ implement one general fix
→ run all units again
→ compare ready/object counts

This is more valuable than patching individual functions with special cases.

AI-assisted object debugging

This workflow is also the development model for building Semantic with AI for AI. Human developers define the semantic contract and the required proof. AI workers inspect one unit or one error family, follow bindings and relation evidence, propose a general fix, run the focused object probe, and record whether the result reached source, lowering, object, link, runtime, or selfhosting status.

The worker model is intentionally evidence-oriented. Several independent units may be processed in parallel, but their results are not merged into a claim until diagnostics, object files, logs, and exit states have been checked. An AI must not infer that a whole compiler is native merely because many units succeeded.

AI debugging loop

flowchart TD I[Unit and semantic contract] --> W[AI worker runs focused build] W --> D[Diagnostic family] D --> F[General resolver/lowering fix] F --> R[Repeat unit and regression set] R --> E[Persist object and evidence] E --> V[Human and AI review] V -->|proven| L[Link next layer] V -->|not proven| D

This makes the compiler legible to future AI systems: each failure has a named semantic cause, each fix has a bounded scope, and each claimed capability points to an artifact or test rather than to optimistic prose.

What a useful report contains

  • total/ready/failed/timeout counts;
  • object count;
  • one current error per failed unit;
  • worker durations;
  • object paths;
  • worker logs where needed.

Historical example

An earlier stable report showed 95 total units with 16 ready units and 54 objects. Later resolver work substantially increased object production. Treat these numbers as development snapshots, not compatibility guarantees.

Current SWC boundary

SWC currently exposes native version/help and compile CLI paths, the Semantic reader pipeline, the current canonical UAST subset, transpiler-matrix data, module/lowering contracts, and the PE-target contract. Complete rich-UAST lowering, full machine-code emission, executable link closure, and Windows selfhosting remain in progress. The old Go transpiler is still a behavioral reference for missing capabilities, not proof that those capabilities already exist in SWC.