test: 995_self_rebuild — wwstage rebuilds itself byte-identical

Drives ww_ww (which already shells to 6c_ww/6a_ww/6l_ww) over each
wwstage tool's source and diffs the resulting binary against the
cstage-built canonical in $BIN. A green run means the toolchain
can recompile itself end-to-end without invoking cc, modulo the
cold-start binary that brings the wwstage into existence.

Stricter than `make bootstrap`: that loop pins wwdump's cgen
self-stabilising; this pins all five wwstage tools (6c, 6a, 6l,
ww, wwdump) round-tripping through the wwstage pipeline.

The .combined.ww refreshes are the expander picking up the
parser/cgen changes from the prior commit. selfhost/cmd/6c/
gains its main.combined.ww for the first time — 995 builds it,
994 reads it.
This commit is contained in:
2026-05-11 11:41:12 +09:00
parent af8836cc8e
commit 37bffa5284
6 changed files with 7108 additions and 18 deletions

View File

@@ -24,6 +24,7 @@ def SYS_OPEN: i64 = 2;
def SYS_CLOSE: i64 = 3;
def SYS_LSEEK: i64 = 8;
def SYS_ACCESS: i64 = 21;
def SYS_DUP2: i64 = 33;
def SYS_GETPID: i64 = 39;
def SYS_FORK: i64 = 57;
def SYS_EXECVE: i64 = 59;
@@ -62,6 +63,14 @@ export fn close(fd: i32) i32 = {
return syscall1(SYS_CLOSE, fd: i64): i32;
};
// dup2(2): make `newfd` refer to the same description as `oldfd`,
// closing `newfd` first if open. Returns `newfd` on success or a
// negative errno. Used by 6c_ww to redirect stdout into an output
// file without changing the cgen emit path.
export fn dup2(oldfd: i32, newfd: i32) i32 = {
return syscall2(SYS_DUP2, oldfd: i64, newfd: i64): i32;
};
// Fallible wrappers. The error variant is a plain str (Plan 9 errstr
// model, see lib/errors); the sum type makes success/failure explicit
// without overloading length-zero.