lib/fmt+lib/log: drop rt_syscall stubs; use os

After #9 (f1440bf) fn labels mangle by module, so lib/fmt and lib/log
can use os; without colliding with lib/io on the read/write/close
leaves at link.

Drop the @symbol("rt_syscall") rtsyscall3/rtsyscall1 + rawwrite/
rawexit wrappers in both files; route the 7 fmt + 3 log call sites
through os.write / os.exit. Trim the workaround-rationale comments.

Mechanical rename; underlying syscall numbers and args unchanged.
This commit is contained in:
2026-05-15 23:53:02 +09:00
parent f1440bf9e8
commit 12436ddaca
2 changed files with 18 additions and 61 deletions

View File

@@ -20,27 +20,7 @@
// via `args...`. // via `args...`.
use io; use io;
use os;
// Direct rt_syscall / rt_exit bindings rather than `use os;` because
// os exports read/write/close, which collide with io.read/write/close
// under the driver's flat-scope concat — same workaround used by
// lib/memio. Both fmt's fd sink and io.stream sink need to coexist
// in this module, so the os surface has to come in à la carte.
@symbol("rt_syscall") fn rtsyscall3(num: i64, a: i64, b: i64, c: i64) i64;
@symbol("rt_syscall") fn rtsyscall1(num: i64, a: i64) i64;
// rawwrite — Linux write(2) syscall (nr=1). The fd sinks below call
// this directly instead of [[os.write]] to keep the collision off
// fmt's exported surface. Same signature, same negative-errno
// convention.
fn rawwrite(fd: i32, buf: *u8, n: u64) i64 = {
return rtsyscall3(1i64, fd: i64, buf: i64, n: i64);
};
// rawexit — Linux exit(2) syscall (nr=60). Used only by `fatal`.
fn rawexit(code: i32) void = {
rtsyscall1(60i64, code: i64);
};
// i64dec_buf — scratch buffer for [[i64dec]] below. Module-level // i64dec_buf — scratch buffer for [[i64dec]] below. Module-level
// because Hare's `strconv::i64tos` is a static-buffer view and we // because Hare's `strconv::i64tos` is a static-buffer view and we
@@ -102,33 +82,33 @@ export fn fdprint(fd: i32, args: formattable...) i64 = {
let i: i32 = 0; let i: i32 = 0;
for (i < args.len) { for (i < args.len) {
if (i > 0) { if (i > 0) {
let r: i64 = rawwrite(fd, " ".ptr, 1u64); let r: i64 = os.write(fd, " ".ptr, 1u64);
if (r < 0) { return r; }; if (r < 0) { return r; };
total += r; total += r;
}; };
match (args[i]) { match (args[i]) {
case let n: i64 => { case let n: i64 => {
let s: str = i64dec(n); let s: str = i64dec(n);
let r: i64 = rawwrite(fd, s.ptr, s.len: u64); let r: i64 = os.write(fd, s.ptr, s.len: u64);
if (r < 0) { return r; }; if (r < 0) { return r; };
total += r; total += r;
}; };
case let s: str => { case let s: str => {
let r: i64 = rawwrite(fd, s.ptr, s.len: u64); let r: i64 = os.write(fd, s.ptr, s.len: u64);
if (r < 0) { return r; }; if (r < 0) { return r; };
total += r; total += r;
}; };
case let b: bool => { case let b: bool => {
let s: str = "false"; let s: str = "false";
if (b) { s = "true"; }; if (b) { s = "true"; };
let r: i64 = rawwrite(fd, s.ptr, s.len: u64); let r: i64 = os.write(fd, s.ptr, s.len: u64);
if (r < 0) { return r; }; if (r < 0) { return r; };
total += r; total += r;
}; };
case let r: rune => { case let r: rune => {
let buf: [4]u8; let buf: [4]u8;
buf[0] = r: u8; buf[0] = r: u8;
let n: i64 = rawwrite(fd, &buf[0], 1u64); let n: i64 = os.write(fd, &buf[0], 1u64);
if (n < 0) { return n; }; if (n < 0) { return n; };
total += n; total += n;
}; };
@@ -142,7 +122,7 @@ export fn fdprint(fd: i32, args: formattable...) i64 = {
export fn fdprintln(fd: i32, args: formattable...) i64 = { export fn fdprintln(fd: i32, args: formattable...) i64 = {
let n: i64 = fdprint(fd, args...); let n: i64 = fdprint(fd, args...);
if (n < 0) { return n; }; if (n < 0) { return n; };
let m: i64 = rawwrite(fd, "\n".ptr, 1u64); let m: i64 = os.write(fd, "\n".ptr, 1u64);
if (m < 0) { return m; }; if (m < 0) { return m; };
return n + m; return n + m;
}; };
@@ -267,5 +247,5 @@ export fn errorln(args: formattable...) i64 = {
// follows immediately). // follows immediately).
export fn fatal(args: formattable...) never = { export fn fatal(args: formattable...) never = {
fdprintln(2, args...); fdprintln(2, args...);
rawexit(255); os.exit(255);
}; };

View File

@@ -39,13 +39,8 @@
// //
// Sink today is [[io.stream]] only — lib/io has no fd-backed stream // Sink today is [[io.stream]] only — lib/io has no fd-backed stream
// yet (Hare's `io::handle = file | int` collapses to one variant). // yet (Hare's `io::handle = file | int` collapses to one variant).
// The default logger writes to stderr via a private io.stream that // The default logger writes to stderr via a private io.stream whose
// dispatches through an rt_syscall write callback; mirrors lib/fmt's // write callback forwards to [[os.write]] on fd 2.
// defensive `rawwrite` / `rawexit` shape for the same C-symbol
// collision reason (lib/os and lib/io both export `write`/`read`/
// `close`, and `use os;` from log would re-trip #17). Both fmt and
// log drop their rt_syscall stubs in one cleanup commit once #17
// (cgen module-mangling of fn labels) lands.
// //
// Compiler note: wwstage cgen's variadic dispatch is name-based // Compiler note: wwstage cgen's variadic dispatch is name-based
// (`fnparamslookup(callee.str)`), which would conflate the // (`fnparamslookup(callee.str)`), which would conflate the
@@ -74,25 +69,7 @@
use fmt; use fmt;
use io; use io;
use os;
// Direct rt_syscall bindings rather than `use os;` — os exports
// read/write/close, which collide with io.read/write/close under the
// driver's flat-scope concat. Mirrors lib/fmt and lib/memio. Removed
// once #17 (cgen mod-mangle for fn labels) lands.
@symbol("rt_syscall") fn rtsyscall3(num: i64, a: i64, b: i64, c: i64) i64;
@symbol("rt_syscall") fn rtsyscall1(num: i64, a: i64) i64;
// rawwrite — Linux write(2) syscall (nr=1). Private stderr sink uses
// this so log's exported surface stays clear of the os.write symbol.
fn rawwrite(fd: i32, p: *u8, n: u64) i64 = {
return rtsyscall3(1i64, fd: i64, p: i64, n: i64);
};
// rawexit — Linux exit(2) syscall (nr=60). Used by [[fatal]] and
// [[lfatal]] for the process-terminating arm.
fn rawexit(code: i32) void = {
rtsyscall1(60i64, code: i64);
};
// logger — interface for log dispatch. v1 carries a single vtable // logger — interface for log dispatch. v1 carries a single vtable
// slot. Hare layers a `printfln` slot for format-string callbacks; // slot. Hare layers a `printfln` slot for format-string callbacks;
@@ -115,10 +92,10 @@ export type stdlogger = struct {
sink: *io.stream, sink: *io.stream,
}; };
// stderrsink — private io.stream wired through the raw stderr fd (2) // stderrsink — private io.stream wired through fd 2 via [[os.write]].
// via [[rawwrite]]. Used as [[default]]'s sink. Independent of lib/io's // Used as [[default]]'s sink. Independent of lib/io's future fd-backed
// future fd-backed stream — when that lands, this collapses to a // stream — when that lands, this collapses to a thin wrapper and
// thin wrapper and graduates in one go. // graduates in one go.
let stderrsink: io.stream; let stderrsink: io.stream;
// _silent — backing storage for the [[silent]] global. // _silent — backing storage for the [[silent]] global.
@@ -167,7 +144,7 @@ fn stderrread(s: *io.stream, buf: []u8) (i32 | io.eof | io.closed) = {
}; };
fn stderrwrite(s: *io.stream, buf: []u8) (i32 | io.closed) = { fn stderrwrite(s: *io.stream, buf: []u8) (i32 | io.closed) = {
let r: i64 = rawwrite(2, buf.ptr, buf.len: u64); let r: i64 = os.write(2, buf.ptr, buf.len: u64);
if (r < 0) { if (r < 0) {
let e: io.closed; let e: io.closed;
return e; return e;
@@ -218,14 +195,14 @@ export fn println(args: fmt.formattable...) void = {
// Hare's lib/log/funcs.ha counterpart at line 28. // Hare's lib/log/funcs.ha counterpart at line 28.
export fn lfatal(log: *logger, args: fmt.formattable...) never = { export fn lfatal(log: *logger, args: fmt.formattable...) never = {
lprintln(log, args...); lprintln(log, args...);
rawexit(255); os.exit(255);
}; };
// fatal — lprintln to [[global]] then exit(255). Hare's lib/log/ // fatal — lprintln to [[global]] then exit(255). Hare's lib/log/
// funcs.ha counterpart at line 45. // funcs.ha counterpart at line 45.
export fn fatal(args: fmt.formattable...) never = { export fn fatal(args: fmt.formattable...) never = {
println(args...); println(args...);
rawexit(255); os.exit(255);
}; };
// setlogger — install `log` as the [[global]] logger. Hare's // setlogger — install `log` as the [[global]] logger. Hare's