ww: rename toolchain to w-prefix + hare-style build/run/test driver
Plan 9-style w-prefix on the per-arch tools, disambiguating from the
real Plan 9 6c/6a/6l in ref/plan9front/:
cmd/wwc/ → cmd/wcc/ libwwc.a → libwcc.a
cmd/6{c,a,l} → cmd/w6{c,a,l} binary names too
test/wwc/ → test/wcc/ 6 test files w/ w6 prefix
selfhost/cmd mirror in lockstep
bootstrap/amd64/{w6c,w6a,w6l} snapshot binaries (gitignored)
WW_6{C,A,L} → WW_W6{C,A,L} env-var overrides
Plan 9 source-tree refs ("Plan 9 6c shape", ref/plan9front/, etc.)
preserved. Hare-style driver, both C and ww sides:
ww test [path] discover *_test.ww in a directory module, run
each; single-file mode for `ww test foo.ww`
Module-by-name `ww build foo` resolves to foo.ww or foo/foo.ww
via search path (cwd : -I dirs : $WW_LIB)
Default-to-cwd `ww build` / `ww test` build the cwd module
Run pass-through `ww run path arg1 arg2` reaches the program
lib/os: getcwd (79) and getdents64 (217) syscalls power `.` resolution
and directory enumeration on the ww side.
Makefile: wwstage tool deps now include lib/os/os.ww (+ lib/strconv
for wwdump_ww) so lib/* edits force their rebuild instead of leaving
stale binaries — surfaced when test 995 first failed against a stale
w6c_ww built before the lib/os additions.
Test 993 byte-identical parity gate (C-side ww vs ww-side ww_ww on a
build corpus) stays green; all 19 tests pass.
This commit is contained in:
4
test/run
4
test/run
@@ -2,7 +2,7 @@
|
||||
# test/run — driver for `make test`. Plan 9 rc-flavoured but plain sh.
|
||||
#
|
||||
# Walks the test/ tree:
|
||||
# test/wwc/<NNN>_<name>.c → out/bin/test_<name> binary, run it.
|
||||
# test/wcc/<NNN>_<name>.c → out/bin/test_<name> binary, run it.
|
||||
# test/lang/<phase>/*.ww → compile/run via $WW, compare stdout/exit
|
||||
# with header comments (// expected: ...).
|
||||
# Exit non-zero on first failure.
|
||||
@@ -16,7 +16,7 @@ fail=0
|
||||
ran=0
|
||||
|
||||
# ---- C-side unit tests --------------------------------------------------
|
||||
for t in test/wwc/*.c; do
|
||||
for t in test/wcc/*.c; do
|
||||
[ -f "$t" ] || continue
|
||||
name=${t##*/}
|
||||
name=${name%.c}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* 000_smoke — Phase 0 smoke test.
|
||||
*
|
||||
* Asserts:
|
||||
* - libwwc symbols (newarena/amalloc/freearena, fatal/errorf/warnf)
|
||||
* - libwcc symbols (newarena/amalloc/freearena, fatal/errorf/warnf)
|
||||
* are linkable.
|
||||
* - `ww -V` exits 0 and prints the configured version.
|
||||
*/
|
||||
@@ -22,7 +22,7 @@ run6c(const char *src, char **out)
|
||||
char cmd[256];
|
||||
const char *bin = getenv("BIN");
|
||||
if (!bin) bin = "out/bin";
|
||||
snprintf(cmd, sizeof cmd, "%s/6c %s 2>&1", bin, path);
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c %s 2>&1", bin, path);
|
||||
FILE *p = popen(cmd, "r");
|
||||
if (p == NULL) { unlink(path); return -1; }
|
||||
size_t cap = 4096, n = 0;
|
||||
@@ -72,7 +72,7 @@ main(void)
|
||||
char *out = NULL;
|
||||
int rc = run6c(rows[i].src, &out);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "row %d: 6c rc=%d\n", i, rc);
|
||||
fprintf(stderr, "row %d: w6c rc=%d\n", i, rc);
|
||||
fail++;
|
||||
free(out);
|
||||
continue;
|
||||
@@ -84,7 +84,7 @@ main(void)
|
||||
}
|
||||
free(out);
|
||||
}
|
||||
if (fail) { fprintf(stderr, "%d/%d 6c tests failed\n", fail, n); return 1; }
|
||||
printf("6c: %d/%d ok\n", n, n);
|
||||
if (fail) { fprintf(stderr, "%d/%d w6c tests failed\n", fail, n); return 1; }
|
||||
printf("w6c: %d/%d ok\n", n, n);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 500_asm — assembler smoke. Drive 6c on a tiny program, feed the
|
||||
* output to 6a, then read back the .o magic to confirm we produced
|
||||
* 500_asm — assembler smoke. Drive w6c on a tiny program, feed the
|
||||
* output to w6a, then read back the .o magic to confirm we produced
|
||||
* a valid ELF64 relocatable object.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
@@ -39,10 +39,10 @@ main(void)
|
||||
fclose(f);
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof cmd, "%s/6c -o %s %s", bin, asmf, src);
|
||||
if (run(cmd) != 0) { fprintf(stderr, "6c fail: %s\n", programs[i]); fail++; continue; }
|
||||
snprintf(cmd, sizeof cmd, "%s/6a -o %s %s", bin, obj, asmf);
|
||||
if (run(cmd) != 0) { fprintf(stderr, "6a fail: %s\n", programs[i]); fail++; continue; }
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s", bin, asmf, src);
|
||||
if (run(cmd) != 0) { fprintf(stderr, "w6c fail: %s\n", programs[i]); fail++; continue; }
|
||||
snprintf(cmd, sizeof cmd, "%s/w6a -o %s %s", bin, obj, asmf);
|
||||
if (run(cmd) != 0) { fprintf(stderr, "w6a fail: %s\n", programs[i]); fail++; continue; }
|
||||
|
||||
FILE *of = fopen(obj, "rb");
|
||||
if (of == NULL) { fail++; continue; }
|
||||
@@ -56,7 +56,7 @@ main(void)
|
||||
}
|
||||
}
|
||||
unlink(src); unlink(asmf); unlink(obj);
|
||||
if (fail) { fprintf(stderr, "%d/%d 6a tests failed\n", fail, n); return 1; }
|
||||
printf("6a: %d/%d ok\n", n, n);
|
||||
if (fail) { fprintf(stderr, "%d/%d w6a tests failed\n", fail, n); return 1; }
|
||||
printf("w6a: %d/%d ok\n", n, n);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 600_6l — linker smoke. Drive 6c → 6a → 6l on a tiny program,
|
||||
* 600_6l — linker smoke. Drive w6c → w6a → w6l on a tiny program,
|
||||
* confirm the result is a static ELF executable with no PT_INTERP.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
@@ -24,12 +24,12 @@ main(void)
|
||||
fclose(f);
|
||||
|
||||
char cmd[1024];
|
||||
snprintf(cmd, sizeof cmd, "%s/6c -o %s %s", bin, asmf, src);
|
||||
if (system(cmd) != 0) { fprintf(stderr, "6c failed\n"); return 1; }
|
||||
snprintf(cmd, sizeof cmd, "%s/6a -o %s %s", bin, obj, asmf);
|
||||
if (system(cmd) != 0) { fprintf(stderr, "6a failed\n"); return 1; }
|
||||
snprintf(cmd, sizeof cmd, "%s/6l -o %s %s", bin, exe, obj);
|
||||
if (system(cmd) != 0) { fprintf(stderr, "6l failed\n"); return 1; }
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c -o %s %s", bin, asmf, src);
|
||||
if (system(cmd) != 0) { fprintf(stderr, "w6c failed\n"); return 1; }
|
||||
snprintf(cmd, sizeof cmd, "%s/w6a -o %s %s", bin, obj, asmf);
|
||||
if (system(cmd) != 0) { fprintf(stderr, "w6a failed\n"); return 1; }
|
||||
snprintf(cmd, sizeof cmd, "%s/w6l -o %s %s", bin, exe, obj);
|
||||
if (system(cmd) != 0) { fprintf(stderr, "w6l failed\n"); return 1; }
|
||||
|
||||
/* validate ELF magic + e_type=EXEC */
|
||||
FILE *of = fopen(exe, "rb");
|
||||
@@ -62,6 +62,6 @@ main(void)
|
||||
}
|
||||
|
||||
unlink(src); unlink(asmf); unlink(obj); unlink(exe);
|
||||
printf("6l: ok\n");
|
||||
printf("w6l: ok\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
* undefined external. Linking should pull only the needed member;
|
||||
* the other one's bad reference must NOT cause a link error.
|
||||
*
|
||||
* If 6l were still pulling all members, this test would fail with
|
||||
* If w6l were still pulling all members, this test would fail with
|
||||
* "undefined reference to 'this_symbol_does_not_exist'".
|
||||
*/
|
||||
#include <stdio.h>
|
||||
@@ -56,11 +56,11 @@ main(void)
|
||||
|
||||
char cmd[2048];
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"set -e; cd %s && %s/6c -o lib_good.s lib_good.ww && "
|
||||
"%s/6c -o lib_bad.s lib_bad.ww && "
|
||||
"%s/6a -o lib_good.o lib_good.s && %s/6a -o lib_bad.o lib_bad.s && "
|
||||
"set -e; cd %s && %s/w6c -o lib_good.s lib_good.ww && "
|
||||
"%s/w6c -o lib_bad.s lib_bad.ww && "
|
||||
"%s/w6a -o lib_good.o lib_good.s && %s/w6a -o lib_bad.o lib_bad.s && "
|
||||
"ar rcs libfoo.a lib_good.o lib_bad.o && "
|
||||
"%s/6c -o m.s m.ww && %s/6a -o m.o m.s",
|
||||
"%s/w6c -o m.s m.ww && %s/w6a -o m.o m.s",
|
||||
dir, bin, bin, bin, bin, bin, bin);
|
||||
if (run(cmd) != 0) { fprintf(stderr, "build failed\n"); return 1; }
|
||||
|
||||
@@ -69,7 +69,7 @@ main(void)
|
||||
snprintf(startobj, sizeof startobj, "%s/../obj/rt/start.o", bin);
|
||||
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"%s/6l -o %s/m %s/m.o %s %s/libfoo.a 2>%s/link.err",
|
||||
"%s/w6l -o %s/m %s/m.o %s %s/libfoo.a 2>%s/link.err",
|
||||
bin, dir, dir, startobj, dir, dir);
|
||||
if (run(cmd) != 0) {
|
||||
FILE *ef = fopen("/dev/null", "r");
|
||||
@@ -22,7 +22,7 @@ run6c(const char *bin, const char *src)
|
||||
fclose(f);
|
||||
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof cmd, "%s/6c %s 2>&1", bin, path);
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c %s 2>&1", bin, path);
|
||||
FILE *p = popen(cmd, "r");
|
||||
size_t cap = 4096, n = 0;
|
||||
char *buf = malloc(cap);
|
||||
@@ -66,10 +66,10 @@ main(void)
|
||||
char path[256];
|
||||
snprintf(path, sizeof path, "%s/../../lib/c/libc/libc.ww", bin);
|
||||
char cmd[512];
|
||||
snprintf(cmd, sizeof cmd, "%s/6c %s > /dev/null 2>&1", bin, path);
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c %s > /dev/null 2>&1", bin, path);
|
||||
int rc = system(cmd);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "ffi: 6c failed on libc.ww (rc=%d)\n", rc);
|
||||
fprintf(stderr, "ffi: w6c failed on libc.ww (rc=%d)\n", rc);
|
||||
fail++;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 810_dyn — end-to-end test of 6l's dynamic linker.
|
||||
* 810_dyn — end-to-end test of w6l's dynamic linker.
|
||||
*
|
||||
* Drives `ww build -L /usr/lib -l c` over a small ww program that
|
||||
* binds libc symbols via @symbol, then runs the produced binary and
|
||||
@@ -51,7 +51,7 @@ main(void)
|
||||
for (int i = 0; modules[i]; i++, n++) {
|
||||
char path[1024], cmd[2048];
|
||||
snprintf(path, sizeof path, "%s/%s", cwd, modules[i]);
|
||||
snprintf(cmd, sizeof cmd, "%s/6c %s > /dev/null 2>&1",
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c %s > /dev/null 2>&1",
|
||||
bin, path);
|
||||
int rc = system(cmd);
|
||||
if (rc != 0) {
|
||||
@@ -2,7 +2,7 @@
|
||||
* 990_selfhost — phase-10 marker test. Three probes:
|
||||
*
|
||||
* 1. The selfhost stubs (mem.ww, err.ww) must parse, typecheck and
|
||||
* codegen via C-side `6c`.
|
||||
* codegen via C-side `w6c`.
|
||||
*
|
||||
* 2. selfhost/test/smoke.ww — an actual ww program exercising the
|
||||
* patterns the real port will use (bump arena, error union,
|
||||
@@ -65,13 +65,13 @@ slurp(const char *path, char **outbuf, size_t *outlen)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Probe 1: each file must compile through `6c`. */
|
||||
/* Probe 1: each file must compile through `w6c`. */
|
||||
static int
|
||||
probe_codegen(const char *bin)
|
||||
{
|
||||
static const char *files[] = {
|
||||
"selfhost/cmd/wwc/mem.ww",
|
||||
"selfhost/cmd/wwc/err.ww",
|
||||
"selfhost/cmd/wcc/mem.ww",
|
||||
"selfhost/cmd/wcc/err.ww",
|
||||
NULL,
|
||||
};
|
||||
char cwd[1024];
|
||||
@@ -80,7 +80,7 @@ probe_codegen(const char *bin)
|
||||
for (int i = 0; files[i]; i++) {
|
||||
char cmd[2048];
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"%s/6c %s/%s > /dev/null 2>&1", bin, cwd, files[i]);
|
||||
"%s/w6c %s/%s > /dev/null 2>&1", bin, cwd, files[i]);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "codegen FAIL: %s\n", files[i]);
|
||||
fail++;
|
||||
@@ -169,12 +169,12 @@ static int
|
||||
probe_dump_diff(const char *bin)
|
||||
{
|
||||
const char *tok_inputs[] = {
|
||||
"selfhost/cmd/wwc/mem.ww",
|
||||
"selfhost/cmd/wwc/err.ww",
|
||||
"selfhost/cmd/wwc/lex.ww",
|
||||
"selfhost/cmd/wwc/tok.ww",
|
||||
"selfhost/cmd/wwc/ast.ww",
|
||||
"selfhost/cmd/wwc/parse.ww",
|
||||
"selfhost/cmd/wcc/mem.ww",
|
||||
"selfhost/cmd/wcc/err.ww",
|
||||
"selfhost/cmd/wcc/lex.ww",
|
||||
"selfhost/cmd/wcc/tok.ww",
|
||||
"selfhost/cmd/wcc/ast.ww",
|
||||
"selfhost/cmd/wcc/parse.ww",
|
||||
"selfhost/cmd/wwdump/main.ww",
|
||||
"selfhost/test/smoke.ww",
|
||||
NULL,
|
||||
@@ -186,16 +186,16 @@ probe_dump_diff(const char *bin)
|
||||
* against the C parser on every selfhost file plus the stdlib. */
|
||||
const char *ast_inputs[] = {
|
||||
"selfhost/test/uses.ww",
|
||||
"selfhost/cmd/wwc/err.ww",
|
||||
"selfhost/cmd/wwc/mem.ww",
|
||||
"selfhost/cmd/wwc/lex.ww",
|
||||
"selfhost/cmd/wwc/tok.ww",
|
||||
"selfhost/cmd/wwc/ast.ww",
|
||||
"selfhost/cmd/wwc/parse.ww",
|
||||
"selfhost/cmd/wwc/typ.ww",
|
||||
"selfhost/cmd/wwc/sym.ww",
|
||||
"selfhost/cmd/wwc/check.ww",
|
||||
"selfhost/cmd/wwc/cgen.ww",
|
||||
"selfhost/cmd/wcc/err.ww",
|
||||
"selfhost/cmd/wcc/mem.ww",
|
||||
"selfhost/cmd/wcc/lex.ww",
|
||||
"selfhost/cmd/wcc/tok.ww",
|
||||
"selfhost/cmd/wcc/ast.ww",
|
||||
"selfhost/cmd/wcc/parse.ww",
|
||||
"selfhost/cmd/wcc/typ.ww",
|
||||
"selfhost/cmd/wcc/sym.ww",
|
||||
"selfhost/cmd/wcc/check.ww",
|
||||
"selfhost/cmd/wcc/cgen.ww",
|
||||
"selfhost/cmd/wwdump/main.ww",
|
||||
"selfhost/test/smoke.ww",
|
||||
"lib/strconv/strconv.ww",
|
||||
@@ -226,7 +226,7 @@ probe_dump_diff(const char *bin)
|
||||
}
|
||||
|
||||
/* Probe 5: ww-side cgen (wwdump_ww -c) emits Plan 9 amd64 asm. For
|
||||
* each fixture we (a) diff the ww asm against C-side 6c and (b)
|
||||
* each fixture we (a) diff the ww asm against C-side w6c and (b)
|
||||
* assemble + link + run the ww output and compare exit codes. Both
|
||||
* must succeed. The cgen port handles literals, +/-/star/slash,
|
||||
* compound assignment, idents, calls, if/else, for loops, and
|
||||
@@ -349,7 +349,7 @@ probe_ww_compile(const char *bin)
|
||||
/* Chained N_DOT: o.ptr_to_inner.val (read field through a
|
||||
* pointer-to-struct field). Pre-fix the cgen fell through
|
||||
* silently and returned the inner pointer instead of the
|
||||
* dereferenced field. Surfaced porting 6l/pass.ww. */
|
||||
* dereferenced field. Surfaced porting w6l/pass.ww. */
|
||||
{ "@symbol(\"rt_alloc\") fn rt_alloc(n: u64) *void;\n"
|
||||
"type inner = struct { val: u64 };\n"
|
||||
"type outer = struct { p: *inner };\n"
|
||||
@@ -384,7 +384,7 @@ probe_ww_compile(const char *bin)
|
||||
fprintf(stderr, "ww-compile prog %d: wwdump_ww -c errored\n", i);
|
||||
fail++; goto cleanup;
|
||||
}
|
||||
snprintf(cmd, sizeof cmd, "%s/6c %s > %s 2>/dev/null", bin, src, cs);
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c %s > %s 2>/dev/null", bin, src, cs);
|
||||
runwait(cmd);
|
||||
|
||||
char *bw = NULL, *bc = NULL;
|
||||
@@ -398,15 +398,15 @@ probe_ww_compile(const char *bin)
|
||||
}
|
||||
free(bw); free(bc);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/6a -o %s %s 2>/dev/null", bin, obj, wws);
|
||||
snprintf(cmd, sizeof cmd, "%s/w6a -o %s %s 2>/dev/null", bin, obj, wws);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "ww-compile prog %d: 6a failed\n", i);
|
||||
fprintf(stderr, "ww-compile prog %d: w6a failed\n", i);
|
||||
fail++; goto cleanup;
|
||||
}
|
||||
snprintf(cmd, sizeof cmd, "%s/6l -o %s %s %s 2>/dev/null",
|
||||
snprintf(cmd, sizeof cmd, "%s/w6l -o %s %s %s 2>/dev/null",
|
||||
bin, exe, obj, rt);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "ww-compile prog %d: 6l failed\n", i);
|
||||
fprintf(stderr, "ww-compile prog %d: w6l failed\n", i);
|
||||
fail++; goto cleanup;
|
||||
}
|
||||
int rc = runwait(exe);
|
||||
@@ -433,9 +433,9 @@ probe_resolve(const char *bin)
|
||||
char cwd[1024];
|
||||
if (getcwd(cwd, sizeof cwd) == NULL) return -1;
|
||||
const char *complete[] = {
|
||||
"selfhost/cmd/wwc/err.ww",
|
||||
"selfhost/cmd/wwc/mem.ww",
|
||||
"selfhost/cmd/wwc/tok.ww",
|
||||
"selfhost/cmd/wcc/err.ww",
|
||||
"selfhost/cmd/wcc/mem.ww",
|
||||
"selfhost/cmd/wcc/tok.ww",
|
||||
"selfhost/test/smoke.ww",
|
||||
NULL,
|
||||
};
|
||||
@@ -463,8 +463,8 @@ probe_dump_stable(const char *bin)
|
||||
char cwd[1024];
|
||||
if (getcwd(cwd, sizeof cwd) == NULL) return -1;
|
||||
const char *inputs[] = {
|
||||
"selfhost/cmd/wwc/mem.ww",
|
||||
"selfhost/cmd/wwc/err.ww",
|
||||
"selfhost/cmd/wcc/mem.ww",
|
||||
"selfhost/cmd/wcc/err.ww",
|
||||
"selfhost/test/smoke.ww",
|
||||
NULL,
|
||||
};
|
||||
@@ -540,19 +540,19 @@ probe_bootstrap_fixed_point(const char *bin)
|
||||
"%s/wwdump_ww -c %s/selfhost/cmd/wwdump/main.combined.ww > %s 2>/dev/null",
|
||||
bin, cwd, ww2s);
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "fp FAIL: ww1 self-compile\n"); fail++; goto cleanup; }
|
||||
snprintf(cmd, sizeof cmd, "%s/6a -o %s %s 2>/dev/null", bin, ww2o, ww2s);
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "fp FAIL: 6a ww2.s\n"); fail++; goto cleanup; }
|
||||
snprintf(cmd, sizeof cmd, "%s/6l -o %s %s %s 2>/dev/null", bin, ww2e, ww2o, rt);
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "fp FAIL: 6l ww2\n"); fail++; goto cleanup; }
|
||||
snprintf(cmd, sizeof cmd, "%s/w6a -o %s %s 2>/dev/null", bin, ww2o, ww2s);
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "fp FAIL: w6a ww2.s\n"); fail++; goto cleanup; }
|
||||
snprintf(cmd, sizeof cmd, "%s/w6l -o %s %s %s 2>/dev/null", bin, ww2e, ww2o, rt);
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "fp FAIL: w6l ww2\n"); fail++; goto cleanup; }
|
||||
/* ww2 -> ww3 */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"%s -c %s/selfhost/cmd/wwdump/main.combined.ww > %s 2>/dev/null",
|
||||
ww2e, cwd, ww3s);
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "fp FAIL: ww2 self-compile\n"); fail++; goto cleanup; }
|
||||
snprintf(cmd, sizeof cmd, "%s/6a -o %s %s 2>/dev/null", bin, ww3o, ww3s);
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "fp FAIL: 6a ww3.s\n"); fail++; goto cleanup; }
|
||||
snprintf(cmd, sizeof cmd, "%s/6l -o %s %s %s 2>/dev/null", bin, ww3e, ww3o, rt);
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "fp FAIL: 6l ww3\n"); fail++; goto cleanup; }
|
||||
snprintf(cmd, sizeof cmd, "%s/w6a -o %s %s 2>/dev/null", bin, ww3o, ww3s);
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "fp FAIL: w6a ww3.s\n"); fail++; goto cleanup; }
|
||||
snprintf(cmd, sizeof cmd, "%s/w6l -o %s %s %s 2>/dev/null", bin, ww3e, ww3o, rt);
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "fp FAIL: w6l ww3\n"); fail++; goto cleanup; }
|
||||
/* The fixed-point check: ww2.s == ww3.s, ww2 == ww3. */
|
||||
snprintf(cmd, sizeof cmd, "cmp -s %s %s", ww2s, ww3s);
|
||||
if (runwait(cmd) != 0) { fprintf(stderr, "fp FAIL: ww2.s != ww3.s (no fixed point)\n"); fail++; }
|
||||
@@ -566,7 +566,7 @@ cleanup:
|
||||
|
||||
/* Probe 8: ww1 → ww2 ladder. wwdump_ww (= ww1, built by C tools)
|
||||
* compiles its own concatenated source. The output assembles + links
|
||||
* via 6a/6l into ww2 (a fresh ww-built compiler binary). Confirms
|
||||
* via w6a/w6l into ww2 (a fresh ww-built compiler binary). Confirms
|
||||
* the full ww-cgen pipeline is functionally correct end-to-end on
|
||||
* the entire frontend (lex+parse+check+cgen+ast+typ+sym+mem+err+
|
||||
* driver). Pre-fix-set this segfaulted at 5919 lines of asm; post-
|
||||
@@ -592,18 +592,18 @@ probe_ww1_to_ww2(const char *bin)
|
||||
fail++;
|
||||
goto cleanup;
|
||||
}
|
||||
snprintf(cmd, sizeof cmd, "%s/6a -o %s %s 2>/dev/null", bin, obj_p, asm_p);
|
||||
snprintf(cmd, sizeof cmd, "%s/w6a -o %s %s 2>/dev/null", bin, obj_p, asm_p);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "ww1->ww2 FAIL: 6a errored on ww1 output\n");
|
||||
fprintf(stderr, "ww1->ww2 FAIL: w6a errored on ww1 output\n");
|
||||
fail++;
|
||||
goto cleanup;
|
||||
}
|
||||
char rt[1024];
|
||||
snprintf(rt, sizeof rt, "%s/../lib/libwwrt.a", bin);
|
||||
snprintf(cmd, sizeof cmd, "%s/6l -o %s %s %s 2>/dev/null",
|
||||
snprintf(cmd, sizeof cmd, "%s/w6l -o %s %s %s 2>/dev/null",
|
||||
bin, exe_p, obj_p, rt);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "ww1->ww2 FAIL: 6l errored\n");
|
||||
fprintf(stderr, "ww1->ww2 FAIL: w6l errored\n");
|
||||
fail++;
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -619,8 +619,8 @@ cleanup:
|
||||
}
|
||||
|
||||
/* Probe 7: end-to-end via wwdump_ww. Use `ww build` to produce the
|
||||
* concatenated source as a side effect, then drive ww-cgen → 6a →
|
||||
* 6l → run, comparing the binary's exit code to the fixture's
|
||||
* concatenated source as a side effect, then drive ww-cgen → w6a →
|
||||
* w6l → run, comparing the binary's exit code to the fixture's
|
||||
* declared expectation. This is the bootstrap-grade signal: it
|
||||
* doesn't require ww-cgen output to be byte-identical to C-cgen,
|
||||
* only to be functionally correct. The byte-match probe above is
|
||||
@@ -656,7 +656,7 @@ probe_ww_links(const char *bin)
|
||||
runwait(cmd);
|
||||
/* ww build to get the .combined.ww as a side effect. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && %s/ww build -I %s/selfhost/cmd/wwc %s >/dev/null 2>&1",
|
||||
"cd %s && %s/ww build -I %s/selfhost/cmd/wcc %s >/dev/null 2>&1",
|
||||
tmpdir, bin, cwd, tmpsrc);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "ww-links FAIL: ww build %s\n", fix);
|
||||
@@ -676,19 +676,19 @@ probe_ww_links(const char *bin)
|
||||
fail++;
|
||||
goto cleanup;
|
||||
}
|
||||
snprintf(cmd, sizeof cmd, "%s/6a -o %s %s 2>/dev/null",
|
||||
snprintf(cmd, sizeof cmd, "%s/w6a -o %s %s 2>/dev/null",
|
||||
bin, wop, wsp);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "ww-links FAIL: 6a %s\n", fix);
|
||||
fprintf(stderr, "ww-links FAIL: w6a %s\n", fix);
|
||||
fail++;
|
||||
goto cleanup;
|
||||
}
|
||||
char rt[1024];
|
||||
snprintf(rt, sizeof rt, "%s/../lib/libwwrt.a", bin);
|
||||
snprintf(cmd, sizeof cmd, "%s/6l -o %s %s %s 2>/dev/null",
|
||||
snprintf(cmd, sizeof cmd, "%s/w6l -o %s %s %s 2>/dev/null",
|
||||
bin, wexep, wop, rt);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "ww-links FAIL: 6l %s\n", fix);
|
||||
fprintf(stderr, "ww-links FAIL: w6l %s\n", fix);
|
||||
fail++;
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -708,16 +708,16 @@ cleanup:
|
||||
}
|
||||
|
||||
/* Probe 6: ww-cgen byte-matches C-cgen on every selfhost file that
|
||||
* raw 6c can compile in isolation (no driver concatenation). The list
|
||||
* raw w6c can compile in isolation (no driver concatenation). The list
|
||||
* is the convergence set: when this stays empty, the cmp ww2 ww3
|
||||
* ceiling becomes feasible. */
|
||||
static int
|
||||
probe_cgen_match(const char *bin)
|
||||
{
|
||||
const char *files[] = {
|
||||
"selfhost/cmd/wwc/mem.ww",
|
||||
"selfhost/cmd/wwc/err.ww",
|
||||
"selfhost/cmd/wwc/tok.ww",
|
||||
"selfhost/cmd/wcc/mem.ww",
|
||||
"selfhost/cmd/wcc/err.ww",
|
||||
"selfhost/cmd/wcc/tok.ww",
|
||||
"selfhost/test/smoke.ww",
|
||||
NULL,
|
||||
};
|
||||
@@ -728,7 +728,7 @@ probe_cgen_match(const char *bin)
|
||||
char a[256], b[256], cmd[2048];
|
||||
snprintf(a, sizeof a, "/tmp/wwd_cm_%d_c", getpid());
|
||||
snprintf(b, sizeof b, "/tmp/wwd_cm_%d_w", getpid());
|
||||
snprintf(cmd, sizeof cmd, "%s/6c %s/%s > %s 2>/dev/null",
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c %s/%s > %s 2>/dev/null",
|
||||
bin, cwd, files[i], a);
|
||||
runwait(cmd);
|
||||
snprintf(cmd, sizeof cmd, "%s/wwdump_ww -c %s/%s > %s 2>/dev/null",
|
||||
@@ -1,15 +1,15 @@
|
||||
/*
|
||||
* 991_6a_ww — phase-10 marker for the ww-side 6a port.
|
||||
* 991_w6a_ww — phase-10 marker for the ww-side w6a port.
|
||||
*
|
||||
* Diffs the C-built `6a` against the ww-built `6a_ww` on a corpus of
|
||||
* Diffs the C-built `w6a` against the ww-built `w6a_ww` on a corpus of
|
||||
* .s files. Both must produce byte-identical ELF .o output. The corpus
|
||||
* spans:
|
||||
* - rt/X.s hand-written runtime; small, varied operands
|
||||
* - generated .s from the existing selfhost cgen pipeline
|
||||
* (wwdump/6a/6l main.s) - large, exercises
|
||||
* every encoding path 6c emits
|
||||
* (wwdump/w6a/w6l main.s) - large, exercises
|
||||
* every encoding path w6c emits
|
||||
*
|
||||
* Any divergence is a port bug in selfhost/cmd/6a/.
|
||||
* Any divergence is a port bug in selfhost/cmd/w6a/.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -65,15 +65,15 @@ diff_one(const char *bin, const char *src)
|
||||
snprintf(co, sizeof co, "/tmp/wwa_%d_c.o", getpid());
|
||||
snprintf(wo, sizeof wo, "/tmp/wwa_%d_w.o", getpid());
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/6a -o %s %s 2>/dev/null", bin, co, src);
|
||||
snprintf(cmd, sizeof cmd, "%s/w6a -o %s %s 2>/dev/null", bin, co, src);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "6a_ww FAIL: C 6a errored on %s\n", src);
|
||||
fprintf(stderr, "w6a_ww FAIL: C w6a errored on %s\n", src);
|
||||
unlink(co);
|
||||
return -1;
|
||||
}
|
||||
snprintf(cmd, sizeof cmd, "%s/6a_ww -o %s %s 2>/dev/null", bin, wo, src);
|
||||
snprintf(cmd, sizeof cmd, "%s/w6a_ww -o %s %s 2>/dev/null", bin, wo, src);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "6a_ww FAIL: ww 6a errored on %s\n", src);
|
||||
fprintf(stderr, "w6a_ww FAIL: ww w6a errored on %s\n", src);
|
||||
unlink(co); unlink(wo);
|
||||
return -1;
|
||||
}
|
||||
@@ -81,10 +81,10 @@ diff_one(const char *bin, const char *src)
|
||||
size_t nc = 0, nw = 0;
|
||||
int rc = 0;
|
||||
if (slurp(co, &bc, &nc) < 0 || slurp(wo, &bw, &nw) < 0) {
|
||||
fprintf(stderr, "6a_ww FAIL: cannot read .o for %s\n", src);
|
||||
fprintf(stderr, "w6a_ww FAIL: cannot read .o for %s\n", src);
|
||||
rc = -1;
|
||||
} else if (nc != nw || memcmp(bc, bw, nc) != 0) {
|
||||
fprintf(stderr, "6a_ww FAIL: %s — C %zu vs ww %zu bytes\n",
|
||||
fprintf(stderr, "w6a_ww FAIL: %s — C %zu vs ww %zu bytes\n",
|
||||
src, nc, nw);
|
||||
rc = -1;
|
||||
}
|
||||
@@ -110,11 +110,11 @@ main(void)
|
||||
"rt/alloc.s",
|
||||
"rt/streq.s",
|
||||
/* generated .s from the existing selfhost stack — large,
|
||||
* exercises every encoding 6c emits (the only way to hit
|
||||
* exercises every encoding w6c emits (the only way to hit
|
||||
* the long tail of operand shapes). */
|
||||
"selfhost/cmd/wwdump/main.s",
|
||||
"selfhost/cmd/6l/main.s",
|
||||
"selfhost/cmd/6a/main.s",
|
||||
"selfhost/cmd/w6l/main.s",
|
||||
"selfhost/cmd/w6a/main.s",
|
||||
NULL,
|
||||
};
|
||||
int fail = 0;
|
||||
@@ -126,10 +126,10 @@ main(void)
|
||||
n++;
|
||||
}
|
||||
if (fail) {
|
||||
fprintf(stderr, "6a_ww: %d/%d diff(s) failed\n", fail, n);
|
||||
fprintf(stderr, "w6a_ww: %d/%d diff(s) failed\n", fail, n);
|
||||
return 1;
|
||||
}
|
||||
printf("6a_ww: byte-identical to C 6a on %d corpus files "
|
||||
printf("w6a_ww: byte-identical to C w6a on %d corpus files "
|
||||
"(rt/*.s + selfhost generated main.s)\n", n);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
* 992_6l_ww — phase-10 marker for the ww-side 6l port.
|
||||
* 992_w6l_ww — phase-10 marker for the ww-side w6l port.
|
||||
*
|
||||
* Diffs the C-built `6l` against the ww-built `6l_ww` on a corpus of
|
||||
* Diffs the C-built `w6l` against the ww-built `w6l_ww` on a corpus of
|
||||
* link inputs. Both must produce byte-identical static ELF binaries.
|
||||
* The corpus mixes:
|
||||
* - a single .o input (no archive resolution)
|
||||
* - a .o + libwwrt.a link, exercising the SysV `ar` two-pass loader
|
||||
*
|
||||
* Any divergence is a port bug in selfhost/cmd/6l/.
|
||||
* Any divergence is a port bug in selfhost/cmd/w6l/.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -65,15 +65,15 @@ diff_one(const char *bin, const char *label, const char *inputs)
|
||||
snprintf(co, sizeof co, "/tmp/wwl_%d_c", getpid());
|
||||
snprintf(wo, sizeof wo, "/tmp/wwl_%d_w", getpid());
|
||||
|
||||
snprintf(cmd, sizeof cmd, "%s/6l -o %s %s 2>/dev/null", bin, co, inputs);
|
||||
snprintf(cmd, sizeof cmd, "%s/w6l -o %s %s 2>/dev/null", bin, co, inputs);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "6l_ww FAIL: C 6l errored on %s\n", label);
|
||||
fprintf(stderr, "w6l_ww FAIL: C w6l errored on %s\n", label);
|
||||
unlink(co);
|
||||
return -1;
|
||||
}
|
||||
snprintf(cmd, sizeof cmd, "%s/6l_ww -o %s %s 2>/dev/null", bin, wo, inputs);
|
||||
snprintf(cmd, sizeof cmd, "%s/w6l_ww -o %s %s 2>/dev/null", bin, wo, inputs);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "6l_ww FAIL: ww 6l errored on %s\n", label);
|
||||
fprintf(stderr, "w6l_ww FAIL: ww w6l errored on %s\n", label);
|
||||
unlink(co); unlink(wo);
|
||||
return -1;
|
||||
}
|
||||
@@ -81,10 +81,10 @@ diff_one(const char *bin, const char *label, const char *inputs)
|
||||
size_t nc = 0, nw = 0;
|
||||
int rc = 0;
|
||||
if (slurp(co, &bc, &nc) < 0 || slurp(wo, &bw, &nw) < 0) {
|
||||
fprintf(stderr, "6l_ww FAIL: cannot read output for %s\n", label);
|
||||
fprintf(stderr, "w6l_ww FAIL: cannot read output for %s\n", label);
|
||||
rc = -1;
|
||||
} else if (nc != nw || memcmp(bc, bw, nc) != 0) {
|
||||
fprintf(stderr, "6l_ww FAIL: %s — C %zu vs ww %zu bytes\n",
|
||||
fprintf(stderr, "w6l_ww FAIL: %s — C %zu vs ww %zu bytes\n",
|
||||
label, nc, nw);
|
||||
rc = -1;
|
||||
}
|
||||
@@ -112,10 +112,10 @@ main(void)
|
||||
* are pulled from libwwrt.a as undefs are encountered). */
|
||||
{ "wwdump+libwwrt",
|
||||
"%s/selfhost/cmd/wwdump/main.o %s/out/lib/libwwrt.a" },
|
||||
{ "6a+libwwrt",
|
||||
"%s/selfhost/cmd/6a/main.o %s/out/lib/libwwrt.a" },
|
||||
{ "6l+libwwrt",
|
||||
"%s/selfhost/cmd/6l/main.o %s/out/lib/libwwrt.a" },
|
||||
{ "w6a+libwwrt",
|
||||
"%s/selfhost/cmd/w6a/main.o %s/out/lib/libwwrt.a" },
|
||||
{ "w6l+libwwrt",
|
||||
"%s/selfhost/cmd/w6l/main.o %s/out/lib/libwwrt.a" },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
@@ -128,10 +128,10 @@ main(void)
|
||||
n++;
|
||||
}
|
||||
if (fail) {
|
||||
fprintf(stderr, "6l_ww: %d/%d diff(s) failed\n", fail, n);
|
||||
fprintf(stderr, "w6l_ww: %d/%d diff(s) failed\n", fail, n);
|
||||
return 1;
|
||||
}
|
||||
printf("6l_ww: byte-identical to C 6l on %d corpus links "
|
||||
printf("w6l_ww: byte-identical to C w6l on %d corpus links "
|
||||
"(.o + libwwrt.a archive resolution)\n", n);
|
||||
return 0;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
* 993_ww_ww — phase-10 marker for the ww-side driver port.
|
||||
*
|
||||
* Diffs the C-built `ww` against the ww-built `ww_ww`. Both drivers
|
||||
* orchestrate the same 6c/6a/6l, so the resulting binaries must be
|
||||
* orchestrate the same w6c/w6a/w6l, so the resulting binaries must be
|
||||
* byte-identical for every program in the corpus. The corpus mixes:
|
||||
* - a tiny single-file program (no -I flags)
|
||||
* - a multi-import build (selfhost/cmd/wwdump/main.ww), exercising
|
||||
@@ -152,7 +152,7 @@ main(void)
|
||||
* regardless of the per-driver workdir. */
|
||||
static char wwdump_src[2048], wwdump_inc_a[2048], wwdump_inc_b[2048];
|
||||
snprintf(wwdump_src, sizeof wwdump_src, "%s/selfhost/cmd/wwdump/main.ww", cwd);
|
||||
snprintf(wwdump_inc_a, sizeof wwdump_inc_a, "%s/selfhost/cmd/wwc", cwd);
|
||||
snprintf(wwdump_inc_a, sizeof wwdump_inc_a, "%s/selfhost/cmd/wcc", cwd);
|
||||
wwdump_inc_b[0] = '\0';
|
||||
cases[1].src = wwdump_src;
|
||||
cases[1].inc_a = wwdump_inc_a;
|
||||
@@ -1,13 +1,13 @@
|
||||
/*
|
||||
* 994_6c_ww — phase-10 marker for the ww-side 6c port.
|
||||
* 994_w6c_ww — phase-10 marker for the ww-side w6c port.
|
||||
*
|
||||
* 6c_ww is a thin packaging of selfhost/cmd/wwc/cgen.ww: it slurps a
|
||||
* w6c_ww is a thin packaging of selfhost/cmd/wcc/cgen.ww: it slurps a
|
||||
* .ww file, runs lex+parse+cgen, and writes Plan 9 amd64 asm to the
|
||||
* file given by -o. The same cgen is reached through `wwdump_ww -c`,
|
||||
* so 6c_ww must produce byte-identical output to wwdump_ww -c on
|
||||
* so w6c_ww must produce byte-identical output to wwdump_ww -c on
|
||||
* every program — this test pins that.
|
||||
*
|
||||
* (We do not diff against C-side `6c` here because the C compiler has
|
||||
* (We do not diff against C-side `w6c` here because the C compiler has
|
||||
* features the ww cgen has not yet ported — float compare, fn-address
|
||||
* @symbol, indirect call. Test 990 probe 5 covers the C-vs-ww diff on
|
||||
* the subset that the ww cgen handles today.)
|
||||
@@ -69,13 +69,13 @@ diff_one(const char *bin, const char *label, const char *src)
|
||||
snprintf(cmd, sizeof cmd, "%s/wwdump_ww -c %s > %s 2>/dev/null",
|
||||
bin, src, ws);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "6c_ww FAIL: wwdump_ww -c errored on %s\n", label);
|
||||
fprintf(stderr, "w6c_ww FAIL: wwdump_ww -c errored on %s\n", label);
|
||||
unlink(ws);
|
||||
return -1;
|
||||
}
|
||||
snprintf(cmd, sizeof cmd, "%s/6c_ww -o %s %s 2>/dev/null", bin, cs, src);
|
||||
snprintf(cmd, sizeof cmd, "%s/w6c_ww -o %s %s 2>/dev/null", bin, cs, src);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "6c_ww FAIL: 6c_ww errored on %s\n", label);
|
||||
fprintf(stderr, "w6c_ww FAIL: w6c_ww errored on %s\n", label);
|
||||
unlink(ws); unlink(cs);
|
||||
return -1;
|
||||
}
|
||||
@@ -83,10 +83,10 @@ diff_one(const char *bin, const char *label, const char *src)
|
||||
size_t nw = 0, nc = 0;
|
||||
int rc = 0;
|
||||
if (slurp(ws, &bw, &nw) < 0 || slurp(cs, &bc, &nc) < 0) {
|
||||
fprintf(stderr, "6c_ww FAIL: cannot read .s for %s\n", label);
|
||||
fprintf(stderr, "w6c_ww FAIL: cannot read .s for %s\n", label);
|
||||
rc = -1;
|
||||
} else if (nw != nc || memcmp(bw, bc, nw) != 0) {
|
||||
fprintf(stderr, "6c_ww FAIL: %s — wwdump_ww %zu vs 6c_ww %zu bytes\n",
|
||||
fprintf(stderr, "w6c_ww FAIL: %s — wwdump_ww %zu vs w6c_ww %zu bytes\n",
|
||||
label, nw, nc);
|
||||
rc = -1;
|
||||
}
|
||||
@@ -115,7 +115,7 @@ main(void)
|
||||
|
||||
/* In-source corpus: programs the ww-side cgen handles today.
|
||||
* Mirrors probe 5 in 990_selfhost without the parts that drift
|
||||
* against C 6c. */
|
||||
* against C w6c. */
|
||||
struct { const char *label; const char *src; } progs[] = {
|
||||
{ "ret42",
|
||||
"fn main() i32 = { return 42; };" },
|
||||
@@ -147,12 +147,12 @@ main(void)
|
||||
};
|
||||
|
||||
/* Source-tree corpus: the same .combined.ww files the bootstrap
|
||||
* fixed point chews on. Confirms 6c_ww handles realistic inputs,
|
||||
* fixed point chews on. Confirms w6c_ww handles realistic inputs,
|
||||
* not just hand-tailored ones. */
|
||||
const char *combined_rel[] = {
|
||||
"selfhost/cmd/wwdump/main.combined.ww",
|
||||
"selfhost/cmd/6a/main.combined.ww",
|
||||
"selfhost/cmd/6l/main.combined.ww",
|
||||
"selfhost/cmd/w6a/main.combined.ww",
|
||||
"selfhost/cmd/w6l/main.combined.ww",
|
||||
"selfhost/cmd/ww/main.combined.ww",
|
||||
NULL,
|
||||
};
|
||||
@@ -175,10 +175,10 @@ main(void)
|
||||
}
|
||||
|
||||
if (fail) {
|
||||
fprintf(stderr, "6c_ww: %d/%d diff(s) failed\n", fail, n);
|
||||
fprintf(stderr, "w6c_ww: %d/%d diff(s) failed\n", fail, n);
|
||||
return 1;
|
||||
}
|
||||
printf("6c_ww: byte-identical to wwdump_ww -c on %d corpus inputs "
|
||||
printf("w6c_ww: byte-identical to wwdump_ww -c on %d corpus inputs "
|
||||
"(in-source + selfhost combined.ww)\n", n);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* 995_self_rebuild — the wwstage rebuilds itself.
|
||||
*
|
||||
* Drives ww_ww (the ww-side driver, which shells to 6c_ww/6a_ww/6l_ww)
|
||||
* Drives ww_ww (the ww-side driver, which shells to w6c_ww/w6a_ww/w6l_ww)
|
||||
* over each wwstage tool's source and diffs the result byte-for-byte
|
||||
* against the cstage-built binary in $BIN. A green run means the
|
||||
* toolchain can recompile itself without touching cc, modulo the
|
||||
@@ -59,9 +59,9 @@ slurp_eq(const char *a, const char *b)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Each tool builds via `ww_ww build -I <local> -I selfhost/cmd/wwc src`.
|
||||
* Some tools have a local module dir (6a, 6l with sibling .ww files);
|
||||
* wwc-only tools (6c, ww, wwdump) just need the wwc -I. inc_local is
|
||||
/* Each tool builds via `ww_ww build -I <local> -I selfhost/cmd/wcc src`.
|
||||
* Some tools have a local module dir (w6a, w6l with sibling .ww files);
|
||||
* wwc-only tools (w6c, ww, wwdump) just need the wwc -I. inc_local is
|
||||
* "" for those.
|
||||
*/
|
||||
static int
|
||||
@@ -76,12 +76,12 @@ rebuild_one(const char *bin, const char *cwd, const char *tool,
|
||||
|
||||
if (inc_local && inc_local[0]) {
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && %s/ww_ww build -I %s/%s -I %s/selfhost/cmd/wwc "
|
||||
"cd %s && %s/ww_ww build -I %s/%s -I %s/selfhost/cmd/wcc "
|
||||
"%s/%s >/dev/null 2>&1",
|
||||
workdir, bin, cwd, inc_local, cwd, cwd, src_rel);
|
||||
} else {
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && %s/ww_ww build -I %s/selfhost/cmd/wwc "
|
||||
"cd %s && %s/ww_ww build -I %s/selfhost/cmd/wcc "
|
||||
"%s/%s >/dev/null 2>&1",
|
||||
workdir, bin, cwd, cwd, src_rel);
|
||||
}
|
||||
@@ -121,9 +121,9 @@ main(void)
|
||||
const char *src;
|
||||
const char *inc_local;
|
||||
} tools[] = {
|
||||
{ "6c", "selfhost/cmd/6c/main.ww", "" },
|
||||
{ "6a", "selfhost/cmd/6a/main.ww", "selfhost/cmd/6a" },
|
||||
{ "6l", "selfhost/cmd/6l/main.ww", "selfhost/cmd/6l" },
|
||||
{ "w6c", "selfhost/cmd/w6c/main.ww", "" },
|
||||
{ "w6a", "selfhost/cmd/w6a/main.ww", "selfhost/cmd/w6a" },
|
||||
{ "w6l", "selfhost/cmd/w6l/main.ww", "selfhost/cmd/w6l" },
|
||||
{ "ww", "selfhost/cmd/ww/main.ww", "" },
|
||||
{ "wwdump", "selfhost/cmd/wwdump/main.ww", "" },
|
||||
{ NULL, NULL, NULL },
|
||||
@@ -141,6 +141,6 @@ main(void)
|
||||
return 1;
|
||||
}
|
||||
printf("self-rebuild: %d wwstage tool(s) round-trip byte-identical "
|
||||
"through ww_ww + 6c_ww + 6a_ww + 6l_ww\n", n);
|
||||
"through ww_ww + w6c_ww + w6a_ww + w6l_ww\n", n);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* 996_dyn_ww — phase-8 marker for ET_DYN linking on the ww side.
|
||||
*
|
||||
* Drives 6l_ww with -L/-l flags over examples/snake/snake.o and diffs
|
||||
* the result against the C-built 6l on the same inputs. A green run
|
||||
* Drives w6l_ww with -L/-l flags over examples/snake/snake.o and diffs
|
||||
* the result against the C-built w6l on the same inputs. A green run
|
||||
* means the ww-side linker emits PT_INTERP/PT_DYNAMIC binaries byte-
|
||||
* for-byte identical to the C linker — i.e. the dynamic linking story
|
||||
* is fully ported and snake no longer depends on Cstage.
|
||||
@@ -71,7 +71,7 @@ main(void)
|
||||
"-l ncurses -l c >/dev/null 2>&1",
|
||||
cwd, bin);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "6l_ww-dyn FAIL: cannot build snake.o via C driver\n");
|
||||
fprintf(stderr, "w6l_ww-dyn FAIL: cannot build snake.o via C driver\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -79,24 +79,24 @@ main(void)
|
||||
snprintf(co, sizeof co, "/tmp/wwld_%d_c", getpid());
|
||||
snprintf(wo, sizeof wo, "/tmp/wwld_%d_w", getpid());
|
||||
|
||||
/* C-side 6l with the dynamic flags. */
|
||||
/* C-side w6l with the dynamic flags. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"%s/6l -o %s %s/examples/snake/snake.o -L /usr/lib "
|
||||
"%s/w6l -o %s %s/examples/snake/snake.o -L /usr/lib "
|
||||
"-l ncurses -l c %s/out/lib/libwwrt.a 2>/dev/null",
|
||||
bin, co, cwd, cwd);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "6l_ww-dyn FAIL: C 6l errored\n");
|
||||
fprintf(stderr, "w6l_ww-dyn FAIL: C w6l errored\n");
|
||||
unlink(co);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ww-side 6l with the same flags. */
|
||||
/* ww-side w6l with the same flags. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"%s/6l_ww -o %s %s/examples/snake/snake.o -L /usr/lib "
|
||||
"%s/w6l_ww -o %s %s/examples/snake/snake.o -L /usr/lib "
|
||||
"-l ncurses -l c %s/out/lib/libwwrt.a 2>/dev/null",
|
||||
bin, wo, cwd, cwd);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "6l_ww-dyn FAIL: ww 6l errored\n");
|
||||
fprintf(stderr, "w6l_ww-dyn FAIL: ww w6l errored\n");
|
||||
unlink(co); unlink(wo);
|
||||
return 1;
|
||||
}
|
||||
@@ -105,14 +105,14 @@ main(void)
|
||||
size_t nc = 0, nw = 0;
|
||||
int rc = 0;
|
||||
if (slurp(co, &bc, &nc) < 0 || slurp(wo, &bw, &nw) < 0) {
|
||||
fprintf(stderr, "6l_ww-dyn FAIL: cannot read outputs\n");
|
||||
fprintf(stderr, "w6l_ww-dyn FAIL: cannot read outputs\n");
|
||||
rc = 1;
|
||||
} else if (nc != nw || memcmp(bc, bw, nc) != 0) {
|
||||
fprintf(stderr, "6l_ww-dyn FAIL: C %zu vs ww %zu bytes\n",
|
||||
fprintf(stderr, "w6l_ww-dyn FAIL: C %zu vs ww %zu bytes\n",
|
||||
nc, nw);
|
||||
rc = 1;
|
||||
} else {
|
||||
printf("6l_ww-dyn: byte-identical to C 6l on snake "
|
||||
printf("w6l_ww-dyn: byte-identical to C w6l on snake "
|
||||
"(PT_INTERP + PT_DYNAMIC + .rela.plt + .gnu.version_r, "
|
||||
"%zu bytes)\n", nc);
|
||||
}
|
||||
Reference in New Issue
Block a user