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