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

@@ -232,8 +232,12 @@ run_row(const char *driver, const struct row *r, int idx, const char *tag)
}
char cmd[2048];
/* #93 sep layout: emit asm to <entry-stem>.sepwork/<pkg>.s; pin
* WW_PKGCACHE under tmpdir so out/.pkgcache is untouched. */
snprintf(cmd, sizeof cmd,
"cd %s && %s build %s >/dev/null 2>&1", tmpdir, driver, r->entry);
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc %s build --sep "
"-o \"${b%%.ww}\" \"$b\" >/dev/null 2>&1",
tmpdir, r->entry, tmpdir, driver);
if (runwait(cmd) != 0) {
fprintf(stderr,
"mklabel_modscoped[%s][%s]: build failed\n",
@@ -255,17 +259,26 @@ run_row(const char *driver, const struct row *r, int idx, const char *tag)
fail++;
}
/* Required-substring check on the emitted .s. */
char entry_s[512];
snprintf(entry_s, sizeof entry_s, "%s/%s", tmpdir, r->entry);
char *d2 = strrchr(entry_s, '.');
if (d2 && strcmp(d2, ".ww") == 0) { strcpy(d2, ".s"); }
/* Required-substring check on the emitted .s. #93: root + every
* imported pkg now compile to separate <stem>.sepwork/<pkg>.s; the
* cross-module label substrings (mod1.x / strings.x) live in the
* per-package files, so concat ALL of them (sorted glob) — a single
* __root.s read would FALSE-FAIL the multi-package rows. */
char stem[512];
snprintf(stem, sizeof stem, "%s/%s", tmpdir, r->entry);
char *d2 = strrchr(stem, '.');
if (d2 && strcmp(d2, ".ww") == 0) *d2 = '\0';
char alls[600], catcmd[1200];
snprintf(alls, sizeof alls, "%s/all.s", tmpdir);
snprintf(catcmd, sizeof catcmd, "cat %s.sepwork/*.s > %s 2>/dev/null",
stem, alls);
(void)runwait(catcmd);
size_t sz = 0;
char *asm_buf = slurp(entry_s, &sz);
char *asm_buf = slurp(alls, &sz);
if (!asm_buf) {
fprintf(stderr,
"mklabel_modscoped[%s][%s]: cannot read %s\n",
tag, r->label, entry_s);
tag, r->label, alls);
fail++;
} else {
for (int k = 0; k < r->n_required; k++) {
@@ -273,7 +286,7 @@ run_row(const char *driver, const struct row *r, int idx, const char *tag)
fprintf(stderr,
"mklabel_modscoped[%s][%s]: missing label "
"substring \"%s\" in %s\n",
tag, r->label, r->required[k], entry_s);
tag, r->label, r->required[k], alls);
fail++;
}
}