test: retarget 809_idx_structlit_store asm byte-id to sep .sepwork layout (M4 E3, #103)

The last flip casualty in the test-migration class (the filed #66
"WW_W6C under sep" framing was a phantom — cstage honors the override;
see re-scoped #66 for the real wwstage align-up). 809_idx_structlit_store's
asm_byte_identical drove `bin/ww build` then read <src>.s next-to-source;
the flip relocates asm to .sepwork/, so it now drives `ww build --sep -o
<stem>` (cstage + WW_W6C=w6c_ww wwstage legs) and byte-diffs the
concatenated per-package .sepwork/*.s. callee_capture imports strings, so
concat-all is the faithful equivalent of the old whole-program compare.
Adding --sep is flip-invariant (green pre- and post-flip). 809_delete_range
is flip-invariant (direct w6c -o), left untouched. Test-only; all 5 pins HOLD.
This commit is contained in:
2026-06-18 17:59:25 +09:00
parent 107d31cc01
commit f98033293e

View File

@@ -402,80 +402,82 @@ run_driver(const char *driver, const struct row *r, int i)
return got;
}
/* asm_byte_identical — generate .s via the driver, once with cstage's
* w6c and once with the wwstage compiler (WW_W6C override; w6a/w6l stay
* cstage — only the .s is compared), and diff. The driver route — not a
* bare `w6c src.ww` — so importing rows (callee_capture pulls strings)
* resolve; the driver leaves src.s NEXT TO the source. Pre-fix the asm
* was byte-identically WRONG (both stages dropped the fill), so these
* rows pin only that the converged fix stays symmetric; the runtime
* rows above carry correctness. */
/* asm_byte_identical — #103 sep layout: the driver flip moves build
* artifacts from next-to-source <stem>.s to a <stem>.sepwork/ scratch
* dir, so drive `ww build --sep -o <stem>` twice — once with cstage's w6c
* and once with the wwstage compiler (WW_W6C override; w6a/w6l stay
* cstage — only the .s is compared) — then concat each build's
* per-package .sepwork asm (sorted glob, identical package set:
* callee_capture pulls strings, so this is multi-package) and diff. The
* driver route — not a bare `w6c src.ww` — so importing rows resolve;
* --sep is flip-invariant (green pre- and post-flip). WW_PKGCACHE pins
* the package cache to the scratch dir so out/.pkgcache stays untouched.
* Pre-fix the asm was byte-identically WRONG (both stages dropped the
* fill), so these rows pin only that the converged fix stays symmetric;
* the runtime rows above carry correctness. */
static int
asm_byte_identical(const char *bin, const struct row *r, int i)
{
char src[64], srcs[64], comb[80], srco[64], tmpdir[64];
char cs[64], ws[64], cmd[1024];
snprintf(src, sizeof src, "/tmp/isls_asm_%d_%d.ww", getpid(), i);
snprintf(srcs, sizeof srcs, "/tmp/isls_asm_%d_%d.s", getpid(), i);
snprintf(srco, sizeof srco, "/tmp/isls_asm_%d_%d.o", getpid(), i);
snprintf(comb, sizeof comb, "/tmp/isls_asm_%d_%d.combined.ww",
getpid(), i);
char src[96], tmpdir[64], outc[128], outw[128];
char cs[96], ws[96], cmd[1024];
snprintf(tmpdir, sizeof tmpdir, "/tmp/isls_asm_%d_d_%d", getpid(), i);
snprintf(cs, sizeof cs, "/tmp/isls_asm_%d_%d_c.s", getpid(), i);
snprintf(ws, sizeof ws, "/tmp/isls_asm_%d_%d_w.s", getpid(), i);
snprintf(src, sizeof src, "%s/main809.ww", tmpdir);
snprintf(outc, sizeof outc, "%s/main809c", tmpdir);
snprintf(outw, sizeof outw, "%s/main809w", tmpdir);
snprintf(cs, sizeof cs, "%s/all_cs.s", tmpdir);
snprintf(ws, sizeof ws, "%s/all_ww.s", tmpdir);
mkdir(tmpdir, 0755);
FILE *f = fopen(src, "wb");
if (!f) return -1;
fputs(r->src, f);
fclose(f);
mkdir(tmpdir, 0755);
snprintf(cmd, sizeof cmd, "cd %s && %s/ww build %s 2>/dev/null",
tmpdir, bin, src);
if (runwait(cmd) != 0 || rename(srcs, cs) != 0) {
fprintf(stderr, "row[%s]: cstage driver .s failed\n",
r->label);
unlink(src); unlink(srco); unlink(comb); rmdir(tmpdir);
return -1;
}
snprintf(cmd, sizeof cmd,
"cd %s && WW_W6C=%s/w6c_ww %s/ww build %s 2>/dev/null",
tmpdir, bin, bin, src);
if (runwait(cmd) != 0 || rename(srcs, ws) != 0) {
fprintf(stderr, "row[%s]: wwstage driver .s failed\n",
r->label);
unlink(src); unlink(srco); unlink(comb); unlink(cs);
rmdir(tmpdir);
return -1;
}
FILE *fc = fopen(cs, "rb");
FILE *fw = fopen(ws, "rb");
int rc = 0;
if (!fc || !fw) {
snprintf(cmd, sizeof cmd,
"cd %s && WW_PKGCACHE=%s/pkgc_c %s/ww build --sep -o %s %s 2>/dev/null",
tmpdir, tmpdir, bin, outc, src);
if (runwait(cmd) != 0) {
fprintf(stderr, "row[%s]: cstage sep build failed\n", r->label);
rc = -1;
} else {
for (;;) {
int a = fgetc(fc);
int b = fgetc(fw);
if (a != b) { rc = -1; break; }
if (a == EOF) break;
}
if (rc == 0) {
snprintf(cmd, sizeof cmd,
"cd %s && WW_PKGCACHE=%s/pkgc_w WW_W6C=%s/w6c_ww "
"%s/ww build --sep -o %s %s 2>/dev/null",
tmpdir, tmpdir, bin, bin, outw, src);
if (runwait(cmd) != 0) {
fprintf(stderr, "row[%s]: wwstage sep build failed\n",
r->label);
rc = -1;
}
}
if (fc) fclose(fc);
if (fw) fclose(fw);
if (rc != 0)
fprintf(stderr, "row[%s]: cstage vs wwstage asm differs\n",
r->label);
{
char outbin[128];
snprintf(outbin, sizeof outbin, "%s/isls_asm_%d_%d",
tmpdir, getpid(), i);
unlink(outbin);
if (rc == 0) {
snprintf(cmd, sizeof cmd, "cat %s.sepwork/*.s > %s 2>/dev/null",
outc, cs); if (system(cmd)) {}
snprintf(cmd, sizeof cmd, "cat %s.sepwork/*.s > %s 2>/dev/null",
outw, ws); if (system(cmd)) {}
FILE *fc = fopen(cs, "rb");
FILE *fw = fopen(ws, "rb");
if (!fc || !fw) {
rc = -1;
} else {
for (;;) {
int a = fgetc(fc);
int b = fgetc(fw);
if (a != b) { rc = -1; break; }
if (a == EOF) break;
}
}
if (fc) fclose(fc);
if (fw) fclose(fw);
if (rc != 0)
fprintf(stderr,
"row[%s]: cstage vs wwstage asm differs\n",
r->label);
}
unlink(src); unlink(srco); unlink(comb);
unlink(cs); unlink(ws);
rmdir(tmpdir);
snprintf(cmd, sizeof cmd, "rm -rf %s", tmpdir);
if (system(cmd)) {}
return rc;
}