From 225ee97f5c0f0d4e47c2046ee94098c6aa8384b2 Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Mon, 18 May 2026 00:30:49 +0900 Subject: [PATCH] lib/os: drop kstat.mode typed-alias workaround (post-#33) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pre-#33 workaround widened kstat.mode to a typed alias to dodge an MOVL emit issue. With #33 (session 3) landed, plain u32 works and matches both the kernel SYS_newfstatat struct layout (st_mode is unsigned int) and Hare's sys/+linux/types.ha:120 st.mode width. The cast-to-mode at fillfilestat is retained (kstat.mode is a u32 holding mode-typed bits, and the cast carries that intent). Keeps the kstat surface internally consistent with its other raw- primitive fields (uid: u32, gid: u32, ino: u64, …). A future Hare-fidelity pass can graduate kstat to the t-suffixed aliases ({uid,gid,mode,…}_t) but that's a separate consolidation. --- lib/os/os.ww | 10 ++-------- selfhost/cmd/w6a/main.combined.ww | 10 ++-------- selfhost/cmd/w6c/main.combined.ww | 10 ++-------- selfhost/cmd/w6l/main.combined.ww | 10 ++-------- selfhost/cmd/ww/main.combined.ww | 10 ++-------- selfhost/cmd/wwdump/main.combined.ww | 10 ++-------- selfhost/test/smoke.combined.ww | 10 ++-------- 7 files changed, 14 insertions(+), 56 deletions(-) diff --git a/lib/os/os.ww b/lib/os/os.ww index c81d1e48..9e89e0c5 100644 --- a/lib/os/os.ww +++ b/lib/os/os.ww @@ -527,17 +527,11 @@ export type filestat = struct { // fields). 144 bytes. Module-internal; SYS_newfstatat writes into // this buffer and the public stat fns then copy the bits into the // Hare-shaped [[filestat]]. -// -// Mode is typed as the public [[mode]] enum (rather than raw u32) -// so [[fillfilestat]]'s `out.mode = k.mode` needs no cast. Cstage -// emits a redundant `MOVL AX, AX` on u32 → enum-u32 casts that -// wwstage skips (task #25); the in-tree shape sidesteps it. -// Identical byte layout (both 4B at offset 24). type kstat = struct { dev: u64, // 0 ino: u64, // 8 nlink: u64, // 16 - mode: mode, // 24 + mode: u32, // 24 uid: u32, // 28 gid: u32, // 32 pad0: u32, // 36 @@ -572,7 +566,7 @@ fn fillfilestat(out: *filestat, k: *kstat) void = { out.mask = stat_mask.UID | stat_mask.GID | stat_mask.SIZE | stat_mask.INODE | stat_mask.ATIME | stat_mask.MTIME | stat_mask.CTIME; - out.mode = k.mode; + out.mode = k.mode: mode; out.uid = k.uid; out.gid = k.gid; out.sz = k.sz: u64; diff --git a/selfhost/cmd/w6a/main.combined.ww b/selfhost/cmd/w6a/main.combined.ww index 92301c6d..a1f5b62a 100644 --- a/selfhost/cmd/w6a/main.combined.ww +++ b/selfhost/cmd/w6a/main.combined.ww @@ -625,17 +625,11 @@ export type filestat = struct { // fields). 144 bytes. Module-internal; SYS_newfstatat writes into // this buffer and the public stat fns then copy the bits into the // Hare-shaped [[filestat]]. -// -// Mode is typed as the public [[mode]] enum (rather than raw u32) -// so [[fillfilestat]]'s `out.mode = k.mode` needs no cast. Cstage -// emits a redundant `MOVL AX, AX` on u32 → enum-u32 casts that -// wwstage skips (task #25); the in-tree shape sidesteps it. -// Identical byte layout (both 4B at offset 24). type kstat = struct { dev: u64, // 0 ino: u64, // 8 nlink: u64, // 16 - mode: mode, // 24 + mode: u32, // 24 uid: u32, // 28 gid: u32, // 32 pad0: u32, // 36 @@ -670,7 +664,7 @@ fn fillfilestat(out: *filestat, k: *kstat) void = { out.mask = stat_mask.UID | stat_mask.GID | stat_mask.SIZE | stat_mask.INODE | stat_mask.ATIME | stat_mask.MTIME | stat_mask.CTIME; - out.mode = k.mode; + out.mode = k.mode: mode; out.uid = k.uid; out.gid = k.gid; out.sz = k.sz: u64; diff --git a/selfhost/cmd/w6c/main.combined.ww b/selfhost/cmd/w6c/main.combined.ww index 93f10387..bde288f2 100644 --- a/selfhost/cmd/w6c/main.combined.ww +++ b/selfhost/cmd/w6c/main.combined.ww @@ -625,17 +625,11 @@ export type filestat = struct { // fields). 144 bytes. Module-internal; SYS_newfstatat writes into // this buffer and the public stat fns then copy the bits into the // Hare-shaped [[filestat]]. -// -// Mode is typed as the public [[mode]] enum (rather than raw u32) -// so [[fillfilestat]]'s `out.mode = k.mode` needs no cast. Cstage -// emits a redundant `MOVL AX, AX` on u32 → enum-u32 casts that -// wwstage skips (task #25); the in-tree shape sidesteps it. -// Identical byte layout (both 4B at offset 24). type kstat = struct { dev: u64, // 0 ino: u64, // 8 nlink: u64, // 16 - mode: mode, // 24 + mode: u32, // 24 uid: u32, // 28 gid: u32, // 32 pad0: u32, // 36 @@ -670,7 +664,7 @@ fn fillfilestat(out: *filestat, k: *kstat) void = { out.mask = stat_mask.UID | stat_mask.GID | stat_mask.SIZE | stat_mask.INODE | stat_mask.ATIME | stat_mask.MTIME | stat_mask.CTIME; - out.mode = k.mode; + out.mode = k.mode: mode; out.uid = k.uid; out.gid = k.gid; out.sz = k.sz: u64; diff --git a/selfhost/cmd/w6l/main.combined.ww b/selfhost/cmd/w6l/main.combined.ww index 7c74baf4..3644ea0f 100644 --- a/selfhost/cmd/w6l/main.combined.ww +++ b/selfhost/cmd/w6l/main.combined.ww @@ -625,17 +625,11 @@ export type filestat = struct { // fields). 144 bytes. Module-internal; SYS_newfstatat writes into // this buffer and the public stat fns then copy the bits into the // Hare-shaped [[filestat]]. -// -// Mode is typed as the public [[mode]] enum (rather than raw u32) -// so [[fillfilestat]]'s `out.mode = k.mode` needs no cast. Cstage -// emits a redundant `MOVL AX, AX` on u32 → enum-u32 casts that -// wwstage skips (task #25); the in-tree shape sidesteps it. -// Identical byte layout (both 4B at offset 24). type kstat = struct { dev: u64, // 0 ino: u64, // 8 nlink: u64, // 16 - mode: mode, // 24 + mode: u32, // 24 uid: u32, // 28 gid: u32, // 32 pad0: u32, // 36 @@ -670,7 +664,7 @@ fn fillfilestat(out: *filestat, k: *kstat) void = { out.mask = stat_mask.UID | stat_mask.GID | stat_mask.SIZE | stat_mask.INODE | stat_mask.ATIME | stat_mask.MTIME | stat_mask.CTIME; - out.mode = k.mode; + out.mode = k.mode: mode; out.uid = k.uid; out.gid = k.gid; out.sz = k.sz: u64; diff --git a/selfhost/cmd/ww/main.combined.ww b/selfhost/cmd/ww/main.combined.ww index ea9bb197..8cbd698c 100644 --- a/selfhost/cmd/ww/main.combined.ww +++ b/selfhost/cmd/ww/main.combined.ww @@ -625,17 +625,11 @@ export type filestat = struct { // fields). 144 bytes. Module-internal; SYS_newfstatat writes into // this buffer and the public stat fns then copy the bits into the // Hare-shaped [[filestat]]. -// -// Mode is typed as the public [[mode]] enum (rather than raw u32) -// so [[fillfilestat]]'s `out.mode = k.mode` needs no cast. Cstage -// emits a redundant `MOVL AX, AX` on u32 → enum-u32 casts that -// wwstage skips (task #25); the in-tree shape sidesteps it. -// Identical byte layout (both 4B at offset 24). type kstat = struct { dev: u64, // 0 ino: u64, // 8 nlink: u64, // 16 - mode: mode, // 24 + mode: u32, // 24 uid: u32, // 28 gid: u32, // 32 pad0: u32, // 36 @@ -670,7 +664,7 @@ fn fillfilestat(out: *filestat, k: *kstat) void = { out.mask = stat_mask.UID | stat_mask.GID | stat_mask.SIZE | stat_mask.INODE | stat_mask.ATIME | stat_mask.MTIME | stat_mask.CTIME; - out.mode = k.mode; + out.mode = k.mode: mode; out.uid = k.uid; out.gid = k.gid; out.sz = k.sz: u64; diff --git a/selfhost/cmd/wwdump/main.combined.ww b/selfhost/cmd/wwdump/main.combined.ww index 203fd91a..9c7d45fb 100644 --- a/selfhost/cmd/wwdump/main.combined.ww +++ b/selfhost/cmd/wwdump/main.combined.ww @@ -625,17 +625,11 @@ export type filestat = struct { // fields). 144 bytes. Module-internal; SYS_newfstatat writes into // this buffer and the public stat fns then copy the bits into the // Hare-shaped [[filestat]]. -// -// Mode is typed as the public [[mode]] enum (rather than raw u32) -// so [[fillfilestat]]'s `out.mode = k.mode` needs no cast. Cstage -// emits a redundant `MOVL AX, AX` on u32 → enum-u32 casts that -// wwstage skips (task #25); the in-tree shape sidesteps it. -// Identical byte layout (both 4B at offset 24). type kstat = struct { dev: u64, // 0 ino: u64, // 8 nlink: u64, // 16 - mode: mode, // 24 + mode: u32, // 24 uid: u32, // 28 gid: u32, // 32 pad0: u32, // 36 @@ -670,7 +664,7 @@ fn fillfilestat(out: *filestat, k: *kstat) void = { out.mask = stat_mask.UID | stat_mask.GID | stat_mask.SIZE | stat_mask.INODE | stat_mask.ATIME | stat_mask.MTIME | stat_mask.CTIME; - out.mode = k.mode; + out.mode = k.mode: mode; out.uid = k.uid; out.gid = k.gid; out.sz = k.sz: u64; diff --git a/selfhost/test/smoke.combined.ww b/selfhost/test/smoke.combined.ww index b2042555..78241e65 100644 --- a/selfhost/test/smoke.combined.ww +++ b/selfhost/test/smoke.combined.ww @@ -625,17 +625,11 @@ export type filestat = struct { // fields). 144 bytes. Module-internal; SYS_newfstatat writes into // this buffer and the public stat fns then copy the bits into the // Hare-shaped [[filestat]]. -// -// Mode is typed as the public [[mode]] enum (rather than raw u32) -// so [[fillfilestat]]'s `out.mode = k.mode` needs no cast. Cstage -// emits a redundant `MOVL AX, AX` on u32 → enum-u32 casts that -// wwstage skips (task #25); the in-tree shape sidesteps it. -// Identical byte layout (both 4B at offset 24). type kstat = struct { dev: u64, // 0 ino: u64, // 8 nlink: u64, // 16 - mode: mode, // 24 + mode: u32, // 24 uid: u32, // 28 gid: u32, // 32 pad0: u32, // 36 @@ -670,7 +664,7 @@ fn fillfilestat(out: *filestat, k: *kstat) void = { out.mask = stat_mask.UID | stat_mask.GID | stat_mask.SIZE | stat_mask.INODE | stat_mask.ATIME | stat_mask.MTIME | stat_mask.CTIME; - out.mode = k.mode; + out.mode = k.mode: mode; out.uid = k.uid; out.gid = k.gid; out.sz = k.sz: u64;