ffi issue-0047: #run print output now routes to stdout
`#run` / post-link callback `print` output was reaching stderr via `std.debug.print` flushes from three sites. The runtime JIT path already writes to fd 1 (stdout) directly. Anyone redirecting one stream saw the two halves disappear in different places. Switches all three flush sites + the `--- build done ---` delimiter in main.zig to `std.c.write(1, ...)` so build-time and runtime prints share the stream the user wrote them against (they typed the same `print(...)` at both call sites — there's no reason for them to land on different streams). Test runner uses `2>&1` so snapshots are unaffected; suite stays at 218/218. Closes issue-0047.
This commit is contained in:
13
src/core.zig
13
src/core.zig
@@ -184,13 +184,22 @@ pub const Compilation = struct {
|
|||||||
ir.Interpreter.last_bail_builtin = null;
|
ir.Interpreter.last_bail_builtin = null;
|
||||||
ir.Interpreter.last_bail_detail = null;
|
ir.Interpreter.last_bail_detail = null;
|
||||||
const result = interp.call(id, args) catch |err| {
|
const result = interp.call(id, args) catch |err| {
|
||||||
if (interp.output.items.len > 0) std.debug.print("{s}", .{interp.output.items});
|
flushInterpOutput(interp.output.items);
|
||||||
return err;
|
return err;
|
||||||
};
|
};
|
||||||
if (interp.output.items.len > 0) std.debug.print("{s}", .{interp.output.items});
|
flushInterpOutput(interp.output.items);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// #run / post-link callback `print` output lands here. Routes to
|
||||||
|
/// fd 1 (stdout) so it joins the JIT-executed runtime's output
|
||||||
|
/// stream — the user wrote `print(...)` in both call sites, so
|
||||||
|
/// the stream split is invisible to them. issue-0047.
|
||||||
|
fn flushInterpOutput(bytes: []const u8) void {
|
||||||
|
if (bytes.len == 0) return;
|
||||||
|
_ = std.c.write(1, bytes.ptr, bytes.len);
|
||||||
|
}
|
||||||
|
|
||||||
/// Get link flags accumulated from #run build blocks.
|
/// Get link flags accumulated from #run build blocks.
|
||||||
pub fn getBuildLinkFlags(self: *Compilation) []const []const u8 {
|
pub fn getBuildLinkFlags(self: *Compilation) []const []const u8 {
|
||||||
if (self.ir_emitter) |*e| return e.build_config.link_flags.items;
|
if (self.ir_emitter) |*e| return e.build_config.link_flags.items;
|
||||||
|
|||||||
@@ -1128,9 +1128,11 @@ pub const LLVMEmitter = struct {
|
|||||||
var interp_inst = Interpreter.init(self.ir_mod, self.alloc);
|
var interp_inst = Interpreter.init(self.ir_mod, self.alloc);
|
||||||
interp_inst.build_config = &self.build_config;
|
interp_inst.build_config = &self.build_config;
|
||||||
_ = interp_inst.call(func_id, &.{}) catch {};
|
_ = interp_inst.call(func_id, &.{}) catch {};
|
||||||
// Write comptime output to stderr (same as old comptime VM)
|
// Route #run `print` output to fd 1 so it joins the
|
||||||
|
// JIT-executed runtime's stream. Same call site shape as
|
||||||
|
// `core.flushInterpOutput` — see issue-0047.
|
||||||
if (interp_inst.output.items.len > 0) {
|
if (interp_inst.output.items.len > 0) {
|
||||||
std.debug.print("{s}", .{interp_inst.output.items});
|
_ = std.c.write(1, interp_inst.output.items.ptr, interp_inst.output.items.len);
|
||||||
}
|
}
|
||||||
interp_inst.deinit();
|
interp_inst.deinit();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -290,7 +290,14 @@ pub fn main(init: std.process.Init) !void {
|
|||||||
// run-time output ambiguously. Only when top-level #run exists —
|
// run-time output ambiguously. Only when top-level #run exists —
|
||||||
// pure-runtime tests keep their current snapshots.
|
// pure-runtime tests keep their current snapshots.
|
||||||
if (hasTopLevelRun(root)) {
|
if (hasTopLevelRun(root)) {
|
||||||
std.debug.print("--- build done ---\n", .{});
|
// Stay on the same stream as the #run output (stdout, via
|
||||||
|
// core.flushInterpOutput). Same reason as issue-0047: the
|
||||||
|
// user doesn't distinguish build-time `print` from
|
||||||
|
// runtime `print` at the call site, and the delimiter is
|
||||||
|
// meaningless if it lands on a different stream than the
|
||||||
|
// output it's separating.
|
||||||
|
const marker = "--- build done ---\n";
|
||||||
|
_ = std.c.write(1, marker.ptr, marker.len);
|
||||||
}
|
}
|
||||||
const exit_code = sx.target.runJITFromObject(obj_buf) catch {
|
const exit_code = sx.target.runJITFromObject(obj_buf) catch {
|
||||||
// JIT failed — fall back to AOT
|
// JIT failed — fall back to AOT
|
||||||
|
|||||||
Reference in New Issue
Block a user