comptime VM arc: abi(.compiler) ABI, out as sx fn, VM-native diagnostics, BuildConfig threaded

Lands the full VM/compiler-API arc on branch reify (701/0 both gates):
- abi(.compiler) ABI replaces abi(.zig) extern compiler + the fake
  #library "compiler"; bodiless decl = compiler-API surface, bodied =
  user compiler-domain fn (lowered for VM eval, emit-skipped).
- out is a plain sx fn (libc write) — the out builtin deleted; the VM
  handles it via host-FFI. trace_resolve + interp_print_frames ported.
- 4B VM-native diagnostics: 1179/1180 render proper comptime type
  construction failed: under strict.
- S5a: build_options/set_post_link_callback on abi(.compiler) with
  BuildConfig threaded into the VM (green intermediate).
- 0522 fixed (describe(args: []Type)); regression 0638.

Strict deletion-gate down to 4 compiler_call bails (1609/1614/1615/1616)
+ 1654 (legitimate unresolvable-symbol diagnostic).
This commit is contained in:
agra
2026-06-19 07:04:10 +03:00
parent fdc4ee2331
commit 2060373c16
80 changed files with 12684 additions and 11922 deletions

View File

@@ -403,6 +403,12 @@ pub const LLVMEmitter = struct {
// Pass 2: Emit function bodies
for (self.ir_mod.functions.items, 0..) |func, i| {
if (func.is_extern or func.blocks.items.len == 0) continue;
// A compiler-domain function (`abi(.compiler)` with a body — a post-link
// callback / compiler-side helper) runs ONLY in the comptime evaluator,
// never in the shipped binary. Skip its body emission (like `is_extern`);
// its only references are in comptime code, so DCE drops the leftover
// declaration. See current/PLAN-COMPILER-VM.md (S3).
if (func.is_compiler_domain) continue;
self.emitFunction(&func, @intCast(i));
}
@@ -875,7 +881,7 @@ pub const LLVMEmitter = struct {
// runs entirely on the VM (no buffered output); anything it can't handle
// (`print`, an unported op) bails → `null` → the legacy interpreter below.
const vm_result: ?Value = if (self.comptime_flat)
comptime_vm.tryEval(self.alloc, self.ir_mod, func_id)
comptime_vm.tryEval(self.alloc, self.ir_mod, func_id, &self.build_config, self.import_sources)
else
null;
if (self.comptime_flat and self.comptime_flat_trace) {
@@ -982,7 +988,7 @@ pub const LLVMEmitter = struct {
// bail / implicit-ctx) falls through to the legacy interpreter
// below, which produces the identical result. Default OFF.
const vm_result: ?Value = if (self.comptime_flat)
comptime_vm.tryEval(self.alloc, self.ir_mod, func_id)
comptime_vm.tryEval(self.alloc, self.ir_mod, func_id, &self.build_config, self.import_sources)
else
null;
// Coverage trace (gated): report whether the VM handled this
@@ -1384,8 +1390,14 @@ pub const LLVMEmitter = struct {
c.LLVMAddAttributeAtIndex(llvm_func, param1_idx, sret_attr);
}
// Set linkage
switch (func.linkage) {
// Set linkage. A compiler-domain function (`abi(.compiler)` with a body) is
// declared here but its body is Pass-2-skipped (it runs only in the comptime
// evaluator). An INTERNAL declaration with no body fails LLVM verification, so
// give it EXTERNAL linkage — a valid "defined elsewhere" declaration that the
// linker drops once DCE removes its (comptime-only) references.
if (func.is_compiler_domain) {
c.LLVMSetLinkage(llvm_func, c.LLVMExternalLinkage);
} else switch (func.linkage) {
.external => c.LLVMSetLinkage(llvm_func, c.LLVMExternalLinkage),
.internal => c.LLVMSetLinkage(llvm_func, c.LLVMInternalLinkage),
.private => c.LLVMSetLinkage(llvm_func, c.LLVMPrivateLinkage),