Native backend contract

inauguration owns these backend paths today:

  1. Bytecode VM subset (all hosts): supported Core IR fronts lower to textual SIL, then to .bca bytecode assembly, then execute in the in-tree stack VM.
  2. Native exit-stub subset (aarch64-apple-darwin only): scalar-return entry functions in the Core IR subset are const-evaluated through the bytecode pipeline and emitted as a tiny owned Mach-O executable that exits with the evaluated code. No swiftc, clang, or linker invocation occurs on this path.
  3. Target-triple object/module subsets: selected non-host triples emit inspectable object, archive, module, or minimal executable artifacts for const-evaluable scalar entry functions without invoking an external linker or language compiler.

All languages including Swift go through the unified Core IR pipeline. The old swiftc/SwiftPM fallback has been removed — Swift is now a Tree-sitter Core IR front like all other languages.

Stable status

Bytecode backend

FieldValue
namebytecode
implementedtrue (all hosts)
stageowned-runtime-subset
reason_codebytecode-vm-subset
reasoninauguration owns this bytecode assembly format, SIL-to-bytecode lowering path, and stack VM runtime for the supported Core IR subset
input_stagecore-ir-to-textual-sil
artifact_kindbytecode-assembly

Native backend

Hostimplementedstagereason_codeartifact_kind
aarch64-apple-darwin host executabletrueowned-native-subsetnative-aarch64-subsetmach-o-executable
aarch64-apple-darwin staticlibtrueowned-object-subsetnative-object-subsetmach-o-static-archive
aarch64-apple-darwin app bundletrueowned-native-subset-aarch64-appnative-aarch64-darwin-app-subset.app bundle
x86_64-unknown-linux-gnu staticlibtrueowned-object-subsetnative-object-subsetelf-relocatable-object
x86_64-unknown-linux-gnu executabletrueowned-native-subset-x86_64native-x86_64-linux-exit-subsetelf-executable
x86_64-unknown-linux-gnu AppDirtrueowned-native-subset-x86_64-appdirnative-x86_64-linux-appdir-subsetAppDir
x86_64-pc-windows-msvc executabletrueowned-native-subset-x86_64native-x86_64-windows-exe-subsetpe-executable
aarch64-unknown-linux-gnu staticlibtrueowned-object-subsetnative-object-subsetelf-relocatable-object
aarch64-unknown-linux-gnu executabletrueowned-native-subset-aarch64native-aarch64-linux-exit-subsetelf-executable
armv7-unknown-linux-gnueabihf staticlibtrueowned-object-subsetnative-object-subsetelf32-relocatable-object
armv7-unknown-linux-gnueabihf executabletrueowned-native-subset-arm32native-armv7-linux-exit-subsetelf32-executable
wasm32-unknown-unknown staticlibtrueowned-object-subsetnative-object-subsetwasm-module
otherfalsecontract-onlynative-backend-not-implementednone

On Apple Silicon macOS, in compile --path apps/polyglot-sample/sample.in --target native --entry answer --out target/in/answer-sample produces an owned executable that exits 42. On Linux and other hosts, the same command reports native-backend-not-implemented and bytecode remains the primary owned executable path.

in backend --path <file> --target bytecode --json reports the owned bytecode backend and artifact facts for supported inputs. in backend --target native --json mirrors the host-specific native status above.

The target registry also carries checked-in In target equivalents for the Rust target triple matrix. These names are compiler target identities for planning, reports, manifests, and future lowering work. They do not imply object emission, linking, ABI lowering, or a native runtime until a target-specific backend is implemented and tested in this repository.

The first non-host object backends are x86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu, armv7-unknown-linux-gnueabihf, and wasm32-unknown-unknown for const-evaluable scalar entry functions. in compile --target native --target-triple x86_64-unknown-linux-gnu --linkage static-lib --entry answer --out target/answer.o emits an ELF64 relocatable object with x86_64 machine code returning the evaluated scalar value. aarch64-unknown-linux-gnu emits an ELF64 AArch64 relocatable object for the same scalar subset. armv7-unknown-linux-gnueabihf emits an ELF32 ARM relocatable object for the same scalar subset. wasm32-unknown-unknown emits a WebAssembly module exporting the scalar function.

in compile --target native --target-triple aarch64-apple-darwin --linkage static-lib --entry answer --out target/libanswer.a emits an ar archive containing a Mach-O ARM64 object member with an exported _answer symbol. This is a static archive route, not a bare Mach-O object route.

in compile --target native --target-triple x86_64-unknown-linux-gnu --linkage executable --entry answer --out target/answer emits a minimal ELF64 Linux executable that exits with the const-evaluated scalar value through the Linux exit syscall. This is not general x86_64 native lowering: it has no linker, libc, dynamic loader, relocations, argv/envp contract, heap, imports, or general function ABI support.

aarch64-unknown-linux-gnu and armv7-unknown-linux-gnueabihf also emit minimal Linux executables for the same const-evaluated scalar subset. They use target-native Linux exit syscalls and are checked structurally on all hosts, with QEMU runtime checks when qemu-aarch64 or qemu-arm is installed.

in compile --target native --target-triple x86_64-pc-windows-msvc --linkage executable --entry answer --out target/answer.exe emits a PE32+ AMD64 console executable whose entry imports kernel32.dll!ExitProcess and exits with the const-evaluated scalar value. It does not link a CRT, emit unwind metadata, or claim Windows ABI/runtime coverage beyond this minimal process-exit artifact.

in compile --target native --target-triple aarch64-apple-darwin --linkage executable --entry answer --out target/Answer.app emits a macOS .app bundle containing the owned AArch64 Mach-O executable plus Info.plist and PkgInfo. A normal host executable path without .app remains the host native route.

in compile --target native --target-triple x86_64-unknown-linux-gnu --linkage executable --entry answer --out target/Answer.AppDir emits a Linux AppDir with an AppRun ELF executable and desktop entry. .AppImage remains fail-closed with native-package-not-implemented until the repository owns an AppImage runtime and SquashFS writer.

Explicit --target-triple requests fail closed when the owned backend has no target/linkage implementation. They do not fall through to the host Mach-O path.

The runnable cross-artifact example lives in apps/native-artifact-sample/. Run bash scripts/check-native-artifact-sample.sh to build and inspect the supported ELF, PE, Mach-O bundle, AppDir, object, archive, and WASM outputs from one .in source file.

bash scripts/check-native-linkable-objects.sh links the x86_64 ELF relocatable object into a C harness and runs it on Linux x86_64 hosts with cc; other hosts skip that runtime gate.

bash scripts/check-native-windows-executable.sh validates the PE32+ import table and runs the generated .exe through Wine when Wine or Docker is available. This is a runtime smoke test, not a replacement for native Windows CI.

Compile cache (Wave 6)

in compile hashes source path + content into target/in/cache/<frontend_hash>/metadata.json, storing the serialized owned compile report (including frontend_hash). Repeated compiles with the same frontend input reuse cached metadata when target, entry, and module id match.

Scope

The native backend is the stage after source fronts, Core IR, textual SIL, and SIL analysis. It is responsible for turning a checked program into a runnable artifact without silently delegating code generation to a language toolchain.

AreaFirst contract
InputA checked Core IR subset with explicit functions, locals, calls, returns, and scalar values.
Output.bca bytecode assembly on all hosts; Mach-O exit stubs on aarch64-apple-darwin for const-evaluable scalar entry functions.
RuntimeOnly the runtime pieces present in this repository may be claimed.
DiagnosticsUnsupported constructs fail closed with native-backend-not-implemented or a narrower backend reason code.
ObservabilityBackend reports include input language, frontend level, IR stage, backend stage, artifact kind, timing, jobs, cache hit, and reason codes.

Non-goals for the first backend slice

Integration points