test: retarget Pattern-B gates to sep .sepwork layout; 915 off private global (M4 E3, #93)

The driver flip moves build artifacts from next-to-source <stem>.s to a
.sepwork/ scratch dir. 29 Pattern-B gates now build `ww build --sep -o <stem>`
and read <stem>.sepwork/__root.s (multi-package gates concat all
<stem>.sepwork/*.s, since cross-package labels live in per-package .s).
All intermediates redirect to /tmp (WW_PKGCACHE + -o), so the corpus runs
parallel-safe with no source-tree pollution. Tests pass now (--sep is live)
and survive the flip.

915 additionally retargeted off strconv's PRIVATE left_shift_table (a let,
not export) — which separate compilation correctly hides — onto a test-local
package that exports its own probe table (#96). The combined path only linked
it via a single-unit private leak; encapsulation is now honored under sep.

Test-only; all 5 *_ww binaries HOLD. 989_m1mangle_run deferred (blocked by
#99, imported-package fn main mangling under sep).
This commit is contained in:
2026-06-18 11:12:04 +09:00
parent 24ca570a7e
commit eb6083e54a
30 changed files with 583 additions and 324 deletions

View File

@@ -199,8 +199,10 @@ cleanup_sources(const struct row *r, const char *tmpdir, const char *base)
snprintf(p, sizeof p, "%s/%s.ww", tmpdir, base); unlink(p);
snprintf(p, sizeof p, "%s/%s.s", tmpdir, base); unlink(p);
snprintf(p, sizeof p, "%s/%s.o", tmpdir, base); unlink(p);
snprintf(p, sizeof p, "%s/%s.combined.ww", tmpdir, base); unlink(p);
snprintf(p, sizeof p, "%s/%s", tmpdir, base); unlink(p);
/* #93: the sep scratch dir + the tmpdir-pinned pkgcache. */
snprintf(p, sizeof p, "rm -rf %s/%s.sepwork %s/pkgc", tmpdir, base, tmpdir);
if (system(p) != 0) { /* best-effort */ }
if (r->modname != NULL) {
char moddir[256];
snprintf(moddir, sizeof moddir, "%s/%s", tmpdir, r->modname);
@@ -215,9 +217,17 @@ cleanup_sources(const struct row *r, const char *tmpdir, const char *base)
static int
build_via_driver(const char *driver, const char *tmpdir, const char *src)
{
char cmd[1024];
snprintf(cmd, sizeof cmd, "cd %s && timeout 180 %s build %s 2>/dev/null",
tmpdir, driver, src);
/* #93 sep layout: `--sep -o <src-stem>` emits the asm to
* <stem>.sepwork/__root.s (the post-flip layout); WW_PKGCACHE is
* pinned under tmpdir so the shared out/.pkgcache is untouched and
* the cache dies with the tmpdir. */
char stem[512], cmd[1280];
snprintf(stem, sizeof stem, "%s", src);
char *dot = strrchr(stem, '.');
if (dot && strcmp(dot, ".ww") == 0) *dot = '\0';
snprintf(cmd, sizeof cmd,
"cd %s && WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep -o %s %s "
"2>/dev/null", tmpdir, tmpdir, driver, stem, src);
return runwait(cmd);
}
@@ -266,7 +276,7 @@ check_leaq(const char *driver, const struct row *r, int seq)
return -1;
int rc = -1;
if (build_via_driver(driver, tmpdir, src) == 0) {
snprintf(asmf, sizeof asmf, "%s/%s.s", tmpdir, base);
snprintf(asmf, sizeof asmf, "%s/%s.sepwork/__root.s", tmpdir, base);
if (file_contains(asmf, r->expected_leaq)) rc = 0;
}
cleanup_sources(r, tmpdir, base);
@@ -284,7 +294,7 @@ asm_byte_identical(const char *cdrv, const char *wdrv,
return -1;
int rc = -1;
if (build_via_driver(cdrv, tdc, src) != 0) goto out;
snprintf(cs, sizeof cs, "%s/%s.s", tdc, base);
snprintf(cs, sizeof cs, "%s/%s.sepwork/__root.s", tdc, base);
/* Build a parallel tree for wwstage so we don't clobber the
* cstage .s. ww_ww writes intermediates next to the .ww source
@@ -296,7 +306,7 @@ asm_byte_identical(const char *cdrv, const char *wdrv,
cleanup_sources(r, tdw, base);
goto out;
}
snprintf(ws, sizeof ws, "%s/%s.s", tdw, base);
snprintf(ws, sizeof ws, "%s/%s.sepwork/__root.s", tdw, base);
FILE *fc = fopen(cs, "rb");
FILE *fw = fopen(ws, "rb");