P5.1: post-link build driver runs on the comptime VM (no fallback)

core.invokeByFuncId routes the post-link callback through comptime_vm.tryEval
instead of the legacy Interpreter. REQUIRED because the sx build driver
allocates/grows Lists, which the legacy interp can't do at comptime (issue
0141: struct_get: base has no fields); the VM can. No fallback (a
side-effecting post-link callback can't double-execute): a VM bail is a hard
build error (comptime_vm.last_bail_reason, surfaced by printInterpBailDiag).
BuildConfig + import_sources threaded in; non-empty args rejected loudly.
flushInterpOutput deleted (VM out writes direct via host-FFI).

Smoke test examples/1661-platform-post-link-vm-list (AOT): a post-link
callback grows a List to 3 + returns len==3, so the build succeeds (exit 0)
only via the VM. First corpus coverage of the post-link path.

702/0 both gates.
This commit is contained in:
agra
2026-06-19 07:20:42 +03:00
parent 2060373c16
commit 7cba33ea6d
9 changed files with 99 additions and 30 deletions

View File

@@ -462,6 +462,13 @@ fn deriveOutputName(input_path: []const u8) []const u8 {
/// and the source location (line:col) when the interpreter captured them.
fn printInterpBailDiag(comp: *const sx.core.Compilation, label: []const u8, err: anyerror) void {
const op = sx.ir.Interpreter.last_bail_op orelse {
// The post-link build driver runs on the comptime VM (core.invokeByFuncId),
// so a bail there sets `comptime_vm.last_bail_reason`, not the legacy
// interp's statics. Surface that reason when present.
if (sx.ir.comptime_vm.last_bail_reason) |reason| {
std.debug.print("error: {s} failed: {s}: {s}\n", .{ label, @errorName(err), reason });
return;
}
std.debug.print("error: {s} failed: {s}\n", .{ label, @errorName(err) });
return;
};