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:
@@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -142,10 +142,12 @@ cleanup_tmp(const char *tmpdir, const char *base)
|
||||
{
|
||||
char p[512];
|
||||
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)) {} /* best-effort */
|
||||
rmdir(tmpdir);
|
||||
}
|
||||
|
||||
@@ -153,8 +155,12 @@ 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: emit asm to <src-stem>.sepwork/__root.s; pin
|
||||
* WW_PKGCACHE under tmpdir so out/.pkgcache is untouched. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -198,12 +204,12 @@ asm_byte_identical(const char *cdrv, const char *wdrv,
|
||||
if (write_source(src, r->src) != 0) { cleanup_tmp(tdc, base); cleanup_tmp(tdw, base); 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);
|
||||
|
||||
snprintf(src, sizeof src, "%s/main766.ww", tdw);
|
||||
if (write_source(src, r->src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, src) != 0) 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");
|
||||
|
||||
@@ -192,10 +192,12 @@ cleanup_tmp(const char *tmpdir, const char *base)
|
||||
{
|
||||
char p[512];
|
||||
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)) {} /* best-effort */
|
||||
rmdir(tmpdir);
|
||||
}
|
||||
|
||||
@@ -203,8 +205,12 @@ 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: emit asm to <src-stem>.sepwork/__root.s; pin
|
||||
* WW_PKGCACHE under tmpdir so out/.pkgcache is untouched. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -246,12 +252,12 @@ asm_byte_identical(const char *cdrv, const char *wdrv,
|
||||
if (write_source(src, r->src) != 0) { cleanup_tmp(tdc, base); cleanup_tmp(tdw, base); 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);
|
||||
|
||||
snprintf(src, sizeof src, "%s/main767.ww", tdw);
|
||||
if (write_source(src, r->src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, src) != 0) 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");
|
||||
|
||||
@@ -201,10 +201,12 @@ cleanup_tmp(const char *tmpdir, const char *base)
|
||||
{
|
||||
char p[512];
|
||||
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)) {} /* best-effort */
|
||||
rmdir(tmpdir);
|
||||
}
|
||||
|
||||
@@ -212,8 +214,12 @@ 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: emit asm to <src-stem>.sepwork/__root.s; pin
|
||||
* WW_PKGCACHE under tmpdir so out/.pkgcache is untouched. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -255,12 +261,12 @@ asm_byte_identical(const char *cdrv, const char *wdrv,
|
||||
if (write_source(src, r->src) != 0) { cleanup_tmp(tdc, base); cleanup_tmp(tdw, base); 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);
|
||||
|
||||
snprintf(src, sizeof src, "%s/main769.ww", tdw);
|
||||
if (write_source(src, r->src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, src) != 0) 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");
|
||||
|
||||
@@ -214,7 +214,9 @@ cleanup_tmp(const struct row *r, const char *tmpdir, const char *base)
|
||||
{
|
||||
char p[512];
|
||||
snprintf(p, sizeof p, "%s/%s.ww", tmpdir, base); unlink(p);
|
||||
snprintf(p, sizeof p, "%s/%s.s", tmpdir, base); unlink(p);
|
||||
/* #93: the sep scratch + tmpdir-pinned pkgcache + concat scratch. */
|
||||
snprintf(p, sizeof p, "rm -rf %s/%s.sepwork %s/pkgc %s/all_cs.s %s/all_ww.s",
|
||||
tmpdir, base, tmpdir, tmpdir, tmpdir); if (system(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);
|
||||
@@ -233,9 +235,13 @@ cleanup_tmp(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: emit asm to <src-stem>.sepwork/<pkg>.s; pin
|
||||
* WW_PKGCACHE under tmpdir so out/.pkgcache is untouched. */
|
||||
char cmd[1280];
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -277,12 +283,21 @@ asm_byte_identical(const char *cdrv, const char *wdrv,
|
||||
if (write_sources(r, tdc, src) != 0) { cleanup_tmp(r, tdc, base); cleanup_tmp(r, tdw, base); return -1; }
|
||||
int rc = -1;
|
||||
if (build_via_driver(cdrv, tdc, src) != 0) goto out;
|
||||
snprintf(cs, sizeof cs, "%s/%s.s", tdc, base);
|
||||
/* #93: root + each imported pkg now compile to separate
|
||||
* <base>.sepwork/<pkg>.s; concat (sorted glob, identical set both
|
||||
* stages) for the full-asm byte-id compare. */
|
||||
snprintf(cs, sizeof cs, "%s/all_cs.s", tdc);
|
||||
{ char cc[1280]; snprintf(cc, sizeof cc,
|
||||
"cat %s/%s.sepwork/*.s > %s 2>/dev/null", tdc, base, cs);
|
||||
if (system(cc)) {} }
|
||||
|
||||
snprintf(src, sizeof src, "%s/main770.ww", tdw);
|
||||
if (write_sources(r, tdw, src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, src) != 0) goto out;
|
||||
snprintf(ws, sizeof ws, "%s/%s.s", tdw, base);
|
||||
snprintf(ws, sizeof ws, "%s/all_ww.s", tdw);
|
||||
{ char cc[1280]; snprintf(cc, sizeof cc,
|
||||
"cat %s/%s.sepwork/*.s > %s 2>/dev/null", tdw, base, ws);
|
||||
if (system(cc)) {} }
|
||||
|
||||
FILE *fc = fopen(cs, "rb");
|
||||
FILE *fw = fopen(ws, "rb");
|
||||
|
||||
@@ -161,10 +161,12 @@ cleanup_tmp(const char *tmpdir, const char *base)
|
||||
{
|
||||
char p[512];
|
||||
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)) {} /* best-effort */
|
||||
rmdir(tmpdir);
|
||||
}
|
||||
|
||||
@@ -172,8 +174,12 @@ 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: emit asm to <src-stem>.sepwork/__root.s; pin
|
||||
* WW_PKGCACHE under tmpdir so out/.pkgcache is untouched. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -221,12 +227,12 @@ asm_byte_identical(const char *cdrv, const char *wdrv,
|
||||
if (write_source(src, r->src) != 0) { cleanup_tmp(tdc, base); cleanup_tmp(tdw, base); 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);
|
||||
|
||||
snprintf(src, sizeof src, "%s/main771.ww", tdw);
|
||||
if (write_source(src, r->src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, src) != 0) 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");
|
||||
|
||||
@@ -190,10 +190,12 @@ cleanup_tmp(const char *tmpdir, const char *base)
|
||||
{
|
||||
char p[512];
|
||||
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)) {} /* best-effort */
|
||||
rmdir(tmpdir);
|
||||
}
|
||||
|
||||
@@ -201,8 +203,12 @@ 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: emit asm to <src-stem>.sepwork/__root.s; pin
|
||||
* WW_PKGCACHE under tmpdir so out/.pkgcache is untouched. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -241,12 +247,12 @@ asm_byte_identical(const char *cdrv, const char *wdrv,
|
||||
if (write_source(src, r->src) != 0) { cleanup_tmp(tdc, base); cleanup_tmp(tdw, base); 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);
|
||||
|
||||
snprintf(src, sizeof src, "%s/%s.ww", tdw, base);
|
||||
if (write_source(src, r->src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, src) != 0) 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");
|
||||
|
||||
@@ -166,10 +166,12 @@ cleanup_tmp(const char *tmpdir, const char *base)
|
||||
{
|
||||
char p[512];
|
||||
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)) {} /* best-effort */
|
||||
rmdir(tmpdir);
|
||||
}
|
||||
|
||||
@@ -177,8 +179,12 @@ 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: emit asm to <src-stem>.sepwork/__root.s; pin
|
||||
* WW_PKGCACHE under tmpdir so out/.pkgcache is untouched. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -220,12 +226,12 @@ asm_byte_identical(const char *cdrv, const char *wdrv,
|
||||
if (write_source(src, r->src) != 0) { cleanup_tmp(tdc, base); cleanup_tmp(tdw, base); 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);
|
||||
|
||||
snprintf(src, sizeof src, "%s/main773.ww", tdw);
|
||||
if (write_source(src, r->src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, src) != 0) 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");
|
||||
|
||||
@@ -177,7 +177,8 @@ cleanup_tmp(const char *tmpdir, const char *base)
|
||||
{
|
||||
char p[512];
|
||||
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, "rm -rf %s/%s.sepwork %s/pkgc", tmpdir, base, tmpdir);
|
||||
if (system(p)) {} /* best-effort */
|
||||
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);
|
||||
@@ -187,9 +188,13 @@ cleanup_tmp(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);
|
||||
char cmd[1280];
|
||||
/* #93 sep layout: emit asm to <src-stem>.sepwork/__root.s; pin
|
||||
* WW_PKGCACHE under tmpdir so out/.pkgcache is untouched. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -236,12 +241,12 @@ asm_byte_identical(const char *cdrv, const char *wdrv,
|
||||
if (write_source(src, r->src) != 0) { cleanup_tmp(tdc, base); cleanup_tmp(tdw, base); 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);
|
||||
|
||||
snprintf(src, sizeof src, "%s/main774.ww", tdw);
|
||||
if (write_source(src, r->src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, src) != 0) 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");
|
||||
|
||||
@@ -253,10 +253,10 @@ cleanup_tmp(const char *tmpdir, const char *base)
|
||||
{
|
||||
char p[640];
|
||||
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 sep layout: 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)) {} /* best-effort */
|
||||
rmdir(tmpdir);
|
||||
}
|
||||
|
||||
@@ -265,9 +265,14 @@ build_via_driver(const char *driver, const char *tmpdir, const char *cwd,
|
||||
const char *src)
|
||||
{
|
||||
char cmd[2048];
|
||||
/* #93 sep layout: `--sep -o <src-stem>` emits the asm to
|
||||
* <stem>.sepwork/__root.s; WW_PKGCACHE is pinned under tmpdir so the
|
||||
* shared out/.pkgcache is untouched and the cache dies with the
|
||||
* tmpdir. PRESERVES the `-I %s/lib` import-dir flag. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && timeout 180 %s build -I %s/lib %s 2>/dev/null",
|
||||
tmpdir, driver, cwd, src);
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-I %s/lib -o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver, cwd);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -309,12 +314,12 @@ asm_byte_identical(const char *cdrv, const char *wdrv, const char *cwd,
|
||||
if (write_source(src, r->src) != 0) { cleanup_tmp(tdc, base); cleanup_tmp(tdw, base); return -1; }
|
||||
int rc = -1;
|
||||
if (build_via_driver(cdrv, tdc, cwd, src) != 0) goto out;
|
||||
snprintf(cs, sizeof cs, "%s/%s.s", tdc, base);
|
||||
snprintf(cs, sizeof cs, "%s/%s.sepwork/__root.s", tdc, base);
|
||||
|
||||
snprintf(src, sizeof src, "%s/%s.ww", tdw, base);
|
||||
if (write_source(src, r->src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, cwd, src) != 0) 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");
|
||||
|
||||
@@ -277,10 +277,10 @@ cleanup_tmp(const char *tmpdir, const char *base)
|
||||
{
|
||||
char p[640];
|
||||
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 sep layout: 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)) {} /* best-effort */
|
||||
rmdir(tmpdir);
|
||||
}
|
||||
|
||||
@@ -289,9 +289,14 @@ build_via_driver(const char *driver, const char *tmpdir, const char *cwd,
|
||||
const char *src)
|
||||
{
|
||||
char cmd[2048];
|
||||
/* #93 sep layout: `--sep -o <src-stem>` emits the asm to
|
||||
* <stem>.sepwork/__root.s; WW_PKGCACHE is pinned under tmpdir so the
|
||||
* shared out/.pkgcache is untouched and the cache dies with the
|
||||
* tmpdir. PRESERVES the `-I %s/lib` import-dir flag. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && timeout 180 %s build -I %s/lib %s 2>/dev/null",
|
||||
tmpdir, driver, cwd, src);
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-I %s/lib -o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver, cwd);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -333,12 +338,12 @@ asm_byte_identical(const char *cdrv, const char *wdrv, const char *cwd,
|
||||
if (write_source(src, r->src) != 0) { cleanup_tmp(tdc, base); cleanup_tmp(tdw, base); return -1; }
|
||||
int rc = -1;
|
||||
if (build_via_driver(cdrv, tdc, cwd, src) != 0) goto out;
|
||||
snprintf(cs, sizeof cs, "%s/%s.s", tdc, base);
|
||||
snprintf(cs, sizeof cs, "%s/%s.sepwork/__root.s", tdc, base);
|
||||
|
||||
snprintf(src, sizeof src, "%s/%s.ww", tdw, base);
|
||||
if (write_source(src, r->src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, cwd, src) != 0) 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");
|
||||
|
||||
@@ -252,10 +252,10 @@ cleanup_tmp(const char *tmpdir, const char *base)
|
||||
{
|
||||
char p[640];
|
||||
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 sep layout: 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)) {} /* best-effort */
|
||||
rmdir(tmpdir);
|
||||
}
|
||||
|
||||
@@ -264,9 +264,14 @@ build_via_driver(const char *driver, const char *tmpdir, const char *cwd,
|
||||
const char *src)
|
||||
{
|
||||
char cmd[2048];
|
||||
/* #93 sep layout: `--sep -o <src-stem>` emits the asm to
|
||||
* <stem>.sepwork/__root.s; WW_PKGCACHE is pinned under tmpdir so the
|
||||
* shared out/.pkgcache is untouched and the cache dies with the
|
||||
* tmpdir. PRESERVES the `-I %s/lib` import-dir flag. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && timeout 180 %s build -I %s/lib %s 2>/dev/null",
|
||||
tmpdir, driver, cwd, src);
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-I %s/lib -o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver, cwd);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -310,12 +315,12 @@ asm_byte_identical(const char *cdrv, const char *wdrv, const char *cwd,
|
||||
if (write_source(src, r->src) != 0) { cleanup_tmp(tdc, base); cleanup_tmp(tdw, base); return -1; }
|
||||
int rc = -1;
|
||||
if (build_via_driver(cdrv, tdc, cwd, src) != 0) goto out;
|
||||
snprintf(cs, sizeof cs, "%s/%s.s", tdc, base);
|
||||
snprintf(cs, sizeof cs, "%s/%s.sepwork/__root.s", tdc, base);
|
||||
|
||||
snprintf(src, sizeof src, "%s/%s.ww", tdw, base);
|
||||
if (write_source(src, r->src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, cwd, src) != 0) 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");
|
||||
|
||||
@@ -433,10 +433,10 @@ cleanup_tmp(const char *tmpdir, const char *base)
|
||||
{
|
||||
char p[640];
|
||||
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 sep layout: 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)) {} /* best-effort */
|
||||
rmdir(tmpdir);
|
||||
}
|
||||
|
||||
@@ -445,9 +445,14 @@ build_via_driver(const char *driver, const char *tmpdir, const char *cwd,
|
||||
const char *src)
|
||||
{
|
||||
char cmd[2048];
|
||||
/* #93 sep layout: `--sep -o <src-stem>` emits the asm to
|
||||
* <stem>.sepwork/__root.s; WW_PKGCACHE is pinned under tmpdir so the
|
||||
* shared out/.pkgcache is untouched and the cache dies with the
|
||||
* tmpdir. PRESERVES the `-I %s/lib` import-dir flag. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && timeout 180 %s build -I %s/lib %s 2>/dev/null",
|
||||
tmpdir, driver, cwd, src);
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-I %s/lib -o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver, cwd);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -489,12 +494,12 @@ asm_byte_identical(const char *cdrv, const char *wdrv, const char *cwd,
|
||||
if (write_source(src, r->src) != 0) { cleanup_tmp(tdc, base); cleanup_tmp(tdw, base); return -1; }
|
||||
int rc = -1;
|
||||
if (build_via_driver(cdrv, tdc, cwd, src) != 0) goto out;
|
||||
snprintf(cs, sizeof cs, "%s/%s.s", tdc, base);
|
||||
snprintf(cs, sizeof cs, "%s/%s.sepwork/__root.s", tdc, base);
|
||||
|
||||
snprintf(src, sizeof src, "%s/%s.ww", tdw, base);
|
||||
if (write_source(src, r->src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, cwd, src) != 0) 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");
|
||||
|
||||
@@ -108,7 +108,8 @@ cleanup_tmp(const char *tmpdir, const char *base)
|
||||
{
|
||||
char p[1024];
|
||||
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, "rm -rf %s/%s.sepwork %s/pkgc", tmpdir, base, tmpdir);
|
||||
if (system(p)) {} /* best-effort */
|
||||
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);
|
||||
@@ -119,8 +120,12 @@ static int
|
||||
build_via_driver(const char *driver, const char *tmpdir, const char *src)
|
||||
{
|
||||
char cmd[2048];
|
||||
snprintf(cmd, sizeof cmd, "cd %s && timeout 180 %s build %s 2>/dev/null",
|
||||
tmpdir, driver, src);
|
||||
/* #93 sep layout: emit asm to <src-stem>.sepwork/__root.s; pin
|
||||
* WW_PKGCACHE under tmpdir so out/.pkgcache is untouched. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -163,12 +168,12 @@ asm_byte_identical(const char *cdrv, const char *wdrv, const struct row *r,
|
||||
if (write_source(src, r->src) != 0) { cleanup_tmp(tdc, base); cleanup_tmp(tdw, base); 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);
|
||||
|
||||
snprintf(src, sizeof src, "%s/%s.ww", tdw, base);
|
||||
if (write_source(src, r->src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, src) != 0) 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");
|
||||
|
||||
@@ -206,9 +206,11 @@ cleanup_tmp(const char *tmpdir, const char *base)
|
||||
char p[1024];
|
||||
snprintf(p, sizeof p, "%s/%s", tmpdir, base); unlink(p);
|
||||
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);
|
||||
/* #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)) {} /* best-effort */
|
||||
rmdir(tmpdir);
|
||||
}
|
||||
|
||||
@@ -226,8 +228,14 @@ static int
|
||||
build_via_driver(const char *driver, const char *tmpdir, const char *src)
|
||||
{
|
||||
char cmd[2048];
|
||||
snprintf(cmd, sizeof cmd, "cd %s && timeout 180 %s build %s 2>/dev/null",
|
||||
tmpdir, driver, src);
|
||||
/* #93 sep layout: `--sep -o <src-stem>` relocates artifacts to
|
||||
* <stem>.sepwork/; WW_PKGCACHE is pinned under tmpdir so the shared
|
||||
* out/.pkgcache is untouched. expect_fail rows still fail: a checker
|
||||
* error makes w6c return nonzero regardless of artifact placement. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -285,12 +293,12 @@ asm_byte_identical(const char *cdrv, const char *wdrv, const struct row *r,
|
||||
if (write_source(src, r->src) != 0) { cleanup_tmp(tdc, base); cleanup_tmp(tdw, base); 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);
|
||||
|
||||
snprintf(src, sizeof src, "%s/%s.ww", tdw, base);
|
||||
if (write_source(src, r->src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, src) != 0) 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");
|
||||
|
||||
@@ -117,7 +117,8 @@ cleanup_tmp(const char *tmpdir, const char *base)
|
||||
char p[1024];
|
||||
snprintf(p, sizeof p, "%s/%s", tmpdir, base); unlink(p);
|
||||
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, "rm -rf %s/%s.sepwork %s/pkgc", tmpdir, base, tmpdir);
|
||||
if (system(p)) {} /* best-effort */
|
||||
snprintf(p, sizeof p, "%s/%s.o", tmpdir, base); unlink(p);
|
||||
snprintf(p, sizeof p, "%s/%s.combined.ww", tmpdir, base); unlink(p);
|
||||
rmdir(tmpdir);
|
||||
@@ -137,8 +138,12 @@ static int
|
||||
build_via_driver(const char *driver, const char *tmpdir, const char *src)
|
||||
{
|
||||
char cmd[2048];
|
||||
snprintf(cmd, sizeof cmd, "cd %s && timeout 180 %s build %s 2>/dev/null",
|
||||
tmpdir, driver, src);
|
||||
/* #93 sep layout: emit asm to <src-stem>.sepwork/__root.s; pin
|
||||
* WW_PKGCACHE under tmpdir so out/.pkgcache is untouched. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -181,12 +186,12 @@ asm_byte_identical(const char *cdrv, const char *wdrv, const struct row *r,
|
||||
if (write_source(src, r->src) != 0) { cleanup_tmp(tdc, base); cleanup_tmp(tdw, base); 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);
|
||||
|
||||
snprintf(src, sizeof src, "%s/%s.ww", tdw, base);
|
||||
if (write_source(src, r->src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, src) != 0) 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");
|
||||
|
||||
@@ -117,7 +117,8 @@ cleanup_tmp(const char *tmpdir, const char *base)
|
||||
char p[1024];
|
||||
snprintf(p, sizeof p, "%s/%s", tmpdir, base); unlink(p);
|
||||
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, "rm -rf %s/%s.sepwork %s/pkgc", tmpdir, base, tmpdir);
|
||||
if (system(p)) {} /* best-effort */
|
||||
snprintf(p, sizeof p, "%s/%s.o", tmpdir, base); unlink(p);
|
||||
snprintf(p, sizeof p, "%s/%s.combined.ww", tmpdir, base); unlink(p);
|
||||
rmdir(tmpdir);
|
||||
@@ -137,8 +138,12 @@ static int
|
||||
build_via_driver(const char *driver, const char *tmpdir, const char *src)
|
||||
{
|
||||
char cmd[2048];
|
||||
snprintf(cmd, sizeof cmd, "cd %s && timeout 180 %s build %s 2>/dev/null",
|
||||
tmpdir, driver, src);
|
||||
/* #93 sep layout: emit asm to <src-stem>.sepwork/__root.s; pin
|
||||
* WW_PKGCACHE under tmpdir so out/.pkgcache is untouched. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -181,12 +186,12 @@ asm_byte_identical(const char *cdrv, const char *wdrv, const struct row *r,
|
||||
if (write_source(src, r->src) != 0) { cleanup_tmp(tdc, base); cleanup_tmp(tdw, base); 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);
|
||||
|
||||
snprintf(src, sizeof src, "%s/%s.ww", tdw, base);
|
||||
if (write_source(src, r->src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, src) != 0) 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");
|
||||
|
||||
@@ -111,9 +111,11 @@ cleanup_tmp(const char *tmpdir, const char *base)
|
||||
char p[1024];
|
||||
snprintf(p, sizeof p, "%s/%s", tmpdir, base); unlink(p);
|
||||
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);
|
||||
/* #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)) {} /* best-effort */
|
||||
rmdir(tmpdir);
|
||||
}
|
||||
|
||||
@@ -131,8 +133,14 @@ static int
|
||||
build_via_driver(const char *driver, const char *tmpdir, const char *src)
|
||||
{
|
||||
char cmd[2048];
|
||||
snprintf(cmd, sizeof cmd, "cd %s && timeout 180 %s build %s 2>/dev/null",
|
||||
tmpdir, driver, src);
|
||||
/* #93 sep layout: `--sep -o <src-stem>` relocates artifacts to
|
||||
* <stem>.sepwork/; WW_PKGCACHE is pinned under tmpdir so the shared
|
||||
* out/.pkgcache is untouched. The value_not_type_neg row still fails:
|
||||
* a checker error makes w6c return nonzero regardless of placement. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -175,12 +183,12 @@ asm_byte_identical(const char *cdrv, const char *wdrv, const struct row *r,
|
||||
if (write_source(src, r->src) != 0) { cleanup_tmp(tdc, base); cleanup_tmp(tdw, base); 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);
|
||||
|
||||
snprintf(src, sizeof src, "%s/%s.ww", tdw, base);
|
||||
if (write_source(src, r->src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, src) != 0) 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");
|
||||
|
||||
@@ -112,7 +112,8 @@ cleanup_tmp(const char *tmpdir, const char *base)
|
||||
char p[1024];
|
||||
snprintf(p, sizeof p, "%s/%s", tmpdir, base); unlink(p);
|
||||
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, "rm -rf %s/%s.sepwork %s/pkgc", tmpdir, base, tmpdir);
|
||||
if (system(p)) {} /* best-effort */
|
||||
snprintf(p, sizeof p, "%s/%s.o", tmpdir, base); unlink(p);
|
||||
snprintf(p, sizeof p, "%s/%s.combined.ww", tmpdir, base); unlink(p);
|
||||
rmdir(tmpdir);
|
||||
@@ -132,8 +133,12 @@ static int
|
||||
build_via_driver(const char *driver, const char *tmpdir, const char *src)
|
||||
{
|
||||
char cmd[2048];
|
||||
snprintf(cmd, sizeof cmd, "cd %s && timeout 180 %s build %s 2>/dev/null",
|
||||
tmpdir, driver, src);
|
||||
/* #93 sep layout: emit asm to <src-stem>.sepwork/__root.s; pin
|
||||
* WW_PKGCACHE under tmpdir so out/.pkgcache is untouched. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -186,11 +191,11 @@ asm_byte_identical(const char *cdrv, const char *wdrv, const struct row *r,
|
||||
if (write_source(src, r->src) != 0) { cleanup_tmp(tdc, base); cleanup_tmp(tdw, base); 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);
|
||||
snprintf(src, sizeof src, "%s/%s.ww", tdw, base);
|
||||
if (write_source(src, r->src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, src) != 0) 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");
|
||||
if (fc && fw) {
|
||||
|
||||
@@ -97,7 +97,8 @@ cleanup_tmp(const char *tmpdir, const char *base)
|
||||
char p[1024];
|
||||
snprintf(p, sizeof p, "%s/%s", tmpdir, base); unlink(p);
|
||||
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, "rm -rf %s/%s.sepwork %s/pkgc", tmpdir, base, tmpdir);
|
||||
if (system(p)) {} /* best-effort */
|
||||
snprintf(p, sizeof p, "%s/%s.o", tmpdir, base); unlink(p);
|
||||
snprintf(p, sizeof p, "%s/%s.combined.ww", tmpdir, base); unlink(p);
|
||||
rmdir(tmpdir);
|
||||
@@ -117,8 +118,12 @@ static int
|
||||
build_via_driver(const char *driver, const char *tmpdir, const char *src)
|
||||
{
|
||||
char cmd[2048];
|
||||
snprintf(cmd, sizeof cmd, "cd %s && timeout 180 %s build %s 2>/dev/null",
|
||||
tmpdir, driver, src);
|
||||
/* #93 sep layout: emit asm to <src-stem>.sepwork/__root.s; pin
|
||||
* WW_PKGCACHE under tmpdir so out/.pkgcache is untouched. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -156,11 +161,11 @@ asm_byte_identical(const char *cdrv, const char *wdrv, const struct row *r,
|
||||
if (write_source(src, r->src) != 0) { cleanup_tmp(tdc, base); cleanup_tmp(tdw, base); 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);
|
||||
snprintf(src, sizeof src, "%s/%s.ww", tdw, base);
|
||||
if (write_source(src, r->src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, src) != 0) 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");
|
||||
if (fc && fw) {
|
||||
|
||||
@@ -231,10 +231,10 @@ cleanup_tmp(const char *tmpdir, const char *base)
|
||||
{
|
||||
char p[640];
|
||||
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 sep layout: 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)) {} /* best-effort */
|
||||
rmdir(tmpdir);
|
||||
}
|
||||
|
||||
@@ -243,9 +243,14 @@ build_via_driver(const char *driver, const char *tmpdir, const char *cwd,
|
||||
const char *src)
|
||||
{
|
||||
char cmd[2048];
|
||||
/* #93 sep layout: `--sep -o <src-stem>` emits the asm to
|
||||
* <stem>.sepwork/__root.s; WW_PKGCACHE is pinned under tmpdir so the
|
||||
* shared out/.pkgcache is untouched and the cache dies with the
|
||||
* tmpdir. PRESERVES the `-I %s/lib` import-dir flag. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && timeout 180 %s build -I %s/lib %s 2>/dev/null",
|
||||
tmpdir, driver, cwd, src);
|
||||
"cd %s && b='%s'; WW_PKGCACHE=%s/pkgc timeout 180 %s build --sep "
|
||||
"-I %s/lib -o \"${b%%.ww}\" \"$b\" 2>/dev/null",
|
||||
tmpdir, src, tmpdir, driver, cwd);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -287,12 +292,12 @@ asm_byte_identical(const char *cdrv, const char *wdrv, const char *cwd,
|
||||
if (write_source(src, r->src) != 0) { cleanup_tmp(tdc, base); cleanup_tmp(tdw, base); return -1; }
|
||||
int rc = -1;
|
||||
if (build_via_driver(cdrv, tdc, cwd, src) != 0) goto out;
|
||||
snprintf(cs, sizeof cs, "%s/%s.s", tdc, base);
|
||||
snprintf(cs, sizeof cs, "%s/%s.sepwork/__root.s", tdc, base);
|
||||
|
||||
snprintf(src, sizeof src, "%s/%s.ww", tdw, base);
|
||||
if (write_source(src, r->src) != 0) goto out;
|
||||
if (build_via_driver(wdrv, tdw, cwd, src) != 0) 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");
|
||||
|
||||
@@ -32,15 +32,17 @@
|
||||
* shapes (defensive case; not exercised in committed code per
|
||||
* design-pass audit) aren't disturbed.
|
||||
*
|
||||
* Each row carries (a) cstage `ww build` + run asserting the exit
|
||||
* code (the cstage-segfault repro now exits cleanly) and (b) a w6c vs
|
||||
* w6c_ww `.s` cmp (rule-10 byte-id). Imports `strconv` because its
|
||||
* `let left_shift_table: [65]u16` is the canonical reviewer-stofdata
|
||||
* probe surface for this bug.
|
||||
* Each row carries a `ww build` + run asserting the exit code (the
|
||||
* cstage-segfault repro now exits cleanly). Single-file rows also carry
|
||||
* a w6c vs w6c_ww `.s` cmp (rule-10 byte-id); the cross-package module
|
||||
* rows gate on runtime exit here and are byte-id-covered cross-package
|
||||
* by 994. The probe table is a test-local exported `[8]u16` (package
|
||||
* wcmodarr — see the #93 retarget note below; it replaced strconv's
|
||||
* private `let left_shift_table`, which separate compilation correctly
|
||||
* hides).
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
@@ -54,55 +56,67 @@ runwait(const char *cmd)
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct row { const char *label; const char *src; int want_exit; };
|
||||
struct row {
|
||||
const char *label;
|
||||
const char *src; /* main.ww content */
|
||||
const char *modname; /* exported-probe-table package, or NULL */
|
||||
const char *modsrc; /* that package's content, or NULL */
|
||||
int want_exit;
|
||||
};
|
||||
|
||||
/* #93 (915 encapsulation retarget, ken-t): the module rows used to read
|
||||
* strconv's PRIVATE `let left_shift_table` — which separate compilation
|
||||
* CORRECTLY hides (the combined path only "worked" because the private
|
||||
* symbol leaked into one unit). Retargeted to a test-LOCAL package that
|
||||
* EXPORTS its own probe table: the same cross-package `mod.arr[i]` cgen
|
||||
* shape (LEAQ base + element-size stride, #128b), encapsulation-faithful
|
||||
* and sep-linkable. (The deeper checker tighten — loud-reject a cross-pkg
|
||||
* private ref — is tracked as #45; NOT attempted here.) Table prefix is
|
||||
* the same u16 sequence strconv used, so the expected exits are unchanged
|
||||
* (idx0→0, idx2→0x0801&0xFF=1, idx4→0x1006&0xFF=6). */
|
||||
#define PROBE_MOD \
|
||||
"export let probe_table: [8]u16 = [0u16, 0x0800u16, 0x0801u16, " \
|
||||
"0x0803u16, 0x1006u16, 0x1009u16, 0x100Du16, 0x1812u16];\n"
|
||||
|
||||
static const struct row rows[] = {
|
||||
/* The reviewer-stofdata probe: indexed read on an imported [N]u16
|
||||
* at idx=0. Pre-fix cstage segfaulted on nontrivial indices and
|
||||
* MOVZBQ-loaded the wrong byte; here at idx=0 the wrong-stride
|
||||
* doesn't matter, so the test exit reflects the load-width fix:
|
||||
* MOVZWQ now reads the full u16 = 0x0000 → exit 0. */
|
||||
/* Indexed read on an imported (exported) [N]u16 at idx=0 — load-
|
||||
* width fix: MOVZWQ reads the full u16 = 0x0000 → exit 0. */
|
||||
{ "mod_u16_idx0",
|
||||
"package main;\n"
|
||||
"import strconv;\n"
|
||||
"import wcmodarr;\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let v: u32 = (strconv.left_shift_table[0]: u32);\n"
|
||||
" let v: u32 = (wcmodarr.probe_table[0]: u32);\n"
|
||||
" return v: i32;\n"
|
||||
"};\n", 0 },
|
||||
/* Nontrivial idx: pre-fix segfault repro. table[2] = 0x0801;
|
||||
"};\n", "wcmodarr", PROBE_MOD, 0 },
|
||||
/* Nontrivial idx — pre-fix segfault repro. table[2] = 0x0801;
|
||||
* 0x0801 mod 256 = 1. */
|
||||
{ "mod_u16_idx2",
|
||||
"package main;\n"
|
||||
"import strconv;\n"
|
||||
"import wcmodarr;\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let v: u32 = (strconv.left_shift_table[2]: u32);\n"
|
||||
" let v: u32 = (wcmodarr.probe_table[2]: u32);\n"
|
||||
" return v: i32;\n"
|
||||
"};\n", 1 },
|
||||
"};\n", "wcmodarr", PROBE_MOD, 1 },
|
||||
/* Further idx — pins per-element stride. table[4] = 0x1006;
|
||||
* 0x1006 mod 256 = 6. */
|
||||
{ "mod_u16_idx4",
|
||||
"package main;\n"
|
||||
"import strconv;\n"
|
||||
"import wcmodarr;\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let v: u32 = (strconv.left_shift_table[4]: u32);\n"
|
||||
" let v: u32 = (wcmodarr.probe_table[4]: u32);\n"
|
||||
" return v: i32;\n"
|
||||
"};\n", 6 },
|
||||
"};\n", "wcmodarr", PROBE_MOD, 6 },
|
||||
/* Local-array control: confirms the existing IDENT-base path is
|
||||
* unchanged by the #128b cgindex edit. Pre-fix already worked; the
|
||||
* fix is gated by `bt == NULL` so this row's byte-id is
|
||||
* preserved. */
|
||||
* unchanged by the #128b cgindex edit. */
|
||||
{ "local_arr_control",
|
||||
"package main;\n"
|
||||
"export fn main() i32 = {\n"
|
||||
" let a: [4]u16 = [10u16, 20u16, 30u16, 40u16];\n"
|
||||
" let v: u32 = (a[2]: u32);\n"
|
||||
" return v: i32;\n"
|
||||
"};\n", 30 },
|
||||
/* Same-package access (NOT module-qualified) — pins that the
|
||||
* existing in-package IDENT path stays unchanged. left_shift_table
|
||||
* exists in strconv; access from within `package strconv` would be
|
||||
* IDENT-base. Wrap in a tiny helper here to keep test self-
|
||||
* contained; uses local table. */
|
||||
"};\n", NULL, NULL, 30 },
|
||||
/* Same-package (NOT module-qualified) access — pins the in-package
|
||||
* IDENT path stays unchanged; uses a local table. */
|
||||
{ "local_u16_idx_nonzero",
|
||||
"package main;\n"
|
||||
"export fn main() i32 = {\n"
|
||||
@@ -110,8 +124,8 @@ static const struct row rows[] = {
|
||||
"0x1006u16, 0x1009u16, 0x100Du16, 0x1812u16];\n"
|
||||
" let v: u32 = (t[2]: u32);\n"
|
||||
" return v: i32;\n"
|
||||
"};\n", 1 },
|
||||
{ NULL, NULL, 0 }
|
||||
"};\n", NULL, NULL, 1 },
|
||||
{ NULL, NULL, NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
static int
|
||||
@@ -155,96 +169,97 @@ main(void)
|
||||
|
||||
int n = 0, fail = 0;
|
||||
for (int i = 0; rows[i].src; i++, n++) {
|
||||
char src[64];
|
||||
snprintf(src, sizeof src, "/tmp/wwmoda_%d_%d.ww", getpid(), i);
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (f == NULL) { fail++; continue; }
|
||||
fputs(rows[i].src, f);
|
||||
fclose(f);
|
||||
|
||||
char tmpdir[64];
|
||||
char tmpdir[96];
|
||||
snprintf(tmpdir, sizeof tmpdir, "/tmp/wwmoda_%d_d_%d",
|
||||
getpid(), i);
|
||||
mkdir(tmpdir, 0755);
|
||||
|
||||
char src[160];
|
||||
snprintf(src, sizeof src, "%s/main915.ww", tmpdir);
|
||||
FILE *f = fopen(src, "wb");
|
||||
if (f == NULL) { fail++; rmdir(tmpdir); continue; }
|
||||
fputs(rows[i].src, f);
|
||||
fclose(f);
|
||||
|
||||
char cmd[2048];
|
||||
snprintf(cmd, sizeof cmd, "cd %s && %s/ww build %s",
|
||||
tmpdir, bin, src);
|
||||
/* Exported-probe-table package lives at <tmpdir>/<mod>/<mod>.ww
|
||||
* so the sep dep-scan (rooted at the entry's dir) resolves the
|
||||
* `import <mod>;`. */
|
||||
if (rows[i].modname != NULL) {
|
||||
char moddir[224], modf[320];
|
||||
snprintf(moddir, sizeof moddir, "%s/%s", tmpdir,
|
||||
rows[i].modname);
|
||||
mkdir(moddir, 0755);
|
||||
snprintf(modf, sizeof modf, "%s/%s.ww", moddir,
|
||||
rows[i].modname);
|
||||
FILE *mf = fopen(modf, "wb");
|
||||
if (mf == NULL) {
|
||||
fail++;
|
||||
snprintf(cmd, sizeof cmd, "rm -rf %s", tmpdir);
|
||||
(void)runwait(cmd);
|
||||
continue;
|
||||
}
|
||||
fputs(rows[i].modsrc, mf);
|
||||
fclose(mf);
|
||||
}
|
||||
|
||||
/* #93 sep layout: build via `--sep -o <stem>` (the exported
|
||||
* probe table links across packages under separate compilation);
|
||||
* WW_PKGCACHE pinned under tmpdir. */
|
||||
char stem[200];
|
||||
snprintf(stem, sizeof stem, "%s/main915", tmpdir);
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && WW_PKGCACHE=%s/pkgc %s/ww build --sep -o %s %s "
|
||||
">/dev/null 2>&1", tmpdir, tmpdir, bin, stem, src);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "row[%s]: cstage build failed\n",
|
||||
rows[i].label);
|
||||
fail++;
|
||||
unlink(src); rmdir(tmpdir);
|
||||
snprintf(cmd, sizeof cmd, "rm -rf %s", tmpdir);
|
||||
(void)runwait(cmd);
|
||||
continue;
|
||||
}
|
||||
|
||||
char outbin[128];
|
||||
const char *base = strrchr(src, '/');
|
||||
base = base ? base + 1 : src;
|
||||
snprintf(outbin, sizeof outbin, "%s/%s", tmpdir, base);
|
||||
char *dot = strrchr(outbin, '.');
|
||||
if (dot && strcmp(dot, ".ww") == 0) *dot = '\0';
|
||||
|
||||
int got = runwait(outbin);
|
||||
int got = runwait(stem);
|
||||
if (got != rows[i].want_exit) {
|
||||
fprintf(stderr, "row[%s]: cstage exit %d, want %d\n",
|
||||
rows[i].label, got, rows[i].want_exit);
|
||||
fail++;
|
||||
}
|
||||
unlink(outbin); rmdir(tmpdir);
|
||||
|
||||
/* Byte-id only meaningful when the source compiles standalone
|
||||
* to a .s. Module-imported rows need the combined.ww shape
|
||||
* (which `ww build` produces inside tmpdir); we already ran
|
||||
* that above. For the byte-id leg, point at the combined.ww. */
|
||||
char combined[160];
|
||||
snprintf(combined, sizeof combined, "%s/%s.combined.ww",
|
||||
tmpdir, base);
|
||||
(void)combined;
|
||||
/* Both stages emit on the original .ww directly; the
|
||||
* combined.ww has the same surface for cgen purposes. We use
|
||||
* the original src for byte-id since w6c/w6c_ww handle the
|
||||
* import resolution when invoked on the file with -I and the
|
||||
* lib search. The probe row asserts module-qualified shape
|
||||
* via direct w6c{,_ww} on the .ww; if the stage can't find
|
||||
* the import, the build above would have failed first. */
|
||||
char cs_s[64], ws_s[64];
|
||||
snprintf(cs_s, sizeof cs_s, "/tmp/wwmoda_%d_%d_cs.s",
|
||||
getpid(), i);
|
||||
snprintf(ws_s, sizeof ws_s, "/tmp/wwmoda_%d_%d_ww.s",
|
||||
getpid(), i);
|
||||
|
||||
/* Skip byte-id leg for rows that need imports — w6c/w6c_ww
|
||||
* standalone won't resolve `import strconv;`. The runtime
|
||||
* leg above (via `ww build`) IS the byte-id+correctness
|
||||
* gate for these rows; the full bootstrap byte-id (994) is
|
||||
* the corpus check. */
|
||||
int needs_import = (strstr(rows[i].src, "import ") != NULL);
|
||||
if (!needs_import) {
|
||||
/* Byte-id leg — bare w6c vs w6c_ww (the compiler binaries, NOT
|
||||
* the driver, so layout-invariant). Only single-file rows can be
|
||||
* fed standalone; the module rows' runtime exit IS their gate
|
||||
* (+ the 994 bootstrap corpus for the cross-stage byte-id). */
|
||||
if (rows[i].modname == NULL) {
|
||||
char cs_s[200], ws_s[200];
|
||||
snprintf(cs_s, sizeof cs_s, "%s/cs.s", tmpdir);
|
||||
snprintf(ws_s, sizeof ws_s, "%s/ww.s", tmpdir);
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null",
|
||||
w6c, cs_s, src);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "row[%s]: w6c failed\n",
|
||||
rows[i].label);
|
||||
fail++; unlink(src); continue;
|
||||
}
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null",
|
||||
w6c_ww, ws_s, src);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "row[%s]: w6c_ww failed\n",
|
||||
rows[i].label);
|
||||
fail++; unlink(src); unlink(cs_s); continue;
|
||||
}
|
||||
if (slurp_eq(cs_s, ws_s) != 0) {
|
||||
fprintf(stderr,
|
||||
"row[%s]: cstage/wwstage .s DIFFER "
|
||||
"(rule-10 byte-id violation)\n",
|
||||
rows[i].label);
|
||||
fail++;
|
||||
} else {
|
||||
snprintf(cmd, sizeof cmd, "%s -o %s %s 2>/dev/null",
|
||||
w6c_ww, ws_s, src);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "row[%s]: w6c_ww failed\n",
|
||||
rows[i].label);
|
||||
fail++;
|
||||
} else if (slurp_eq(cs_s, ws_s) != 0) {
|
||||
fprintf(stderr,
|
||||
"row[%s]: cstage/wwstage .s DIFFER "
|
||||
"(rule-10 byte-id violation)\n",
|
||||
rows[i].label);
|
||||
fail++;
|
||||
}
|
||||
}
|
||||
unlink(cs_s); unlink(ws_s);
|
||||
}
|
||||
unlink(src);
|
||||
|
||||
snprintf(cmd, sizeof cmd, "rm -rf %s", tmpdir);
|
||||
(void)runwait(cmd);
|
||||
}
|
||||
|
||||
if (fail) {
|
||||
|
||||
@@ -174,9 +174,18 @@ main(void)
|
||||
for (int s = 0; s < 2; s++) {
|
||||
snprintf(stg[s].prog, sizeof stg[s].prog, "%s/prog.%s", td, stg[s].tag);
|
||||
snprintf(stg[s].sfile, sizeof stg[s].sfile, "%s/prog.%s.s", td, stg[s].tag);
|
||||
/* #93 sep layout: `--sep -o <prog>` splits the asm across
|
||||
* <prog>.sepwork/<pkg>.s — the bare user `TEXT run,` lands in
|
||||
* __root.s and the imported `TEXT aa.run,` in aa.s. Concat all
|
||||
* the per-unit .s (sorted glob order is deterministic) into the
|
||||
* flat <prog>.s the label-count + byte-id checks consume. The
|
||||
* `-I %s` source path is preserved; WW_PKGCACHE is pinned under
|
||||
* the tmpdir so the shared out/.pkgcache stays untouched. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"timeout 240 %s/%s build -o %s -I %s %s >/dev/null 2>&1",
|
||||
bin, stg[s].drv, stg[s].prog, td, rootww);
|
||||
"WW_PKGCACHE=%s/pkgc timeout 240 %s/%s build --sep -o %s "
|
||||
"-I %s %s >/dev/null 2>&1 && cat %s.sepwork/*.s > %s",
|
||||
td, bin, stg[s].drv, stg[s].prog, td, rootww,
|
||||
stg[s].prog, stg[s].sfile);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "84 FAIL: %s build\n", stg[s].drv);
|
||||
fail++;
|
||||
|
||||
@@ -51,13 +51,23 @@ static const struct check checks[] = {
|
||||
{ "TEXT utf8.runesz,", 0 },
|
||||
};
|
||||
|
||||
/* build_s — build `src` to `<stem>.s` via `driver`; returns 0 on success. */
|
||||
/* build_s — build `src` via `driver`, leaving the unit asm at `<stem>.s`;
|
||||
* returns 0 on success.
|
||||
* #93 sep layout: `--sep -o <stem>` splits the asm across
|
||||
* <stem>.sepwork/<pkg>.s (root in __root.s, the imported encoding.utf8 in
|
||||
* encoding.utf8.s). The mangled `encoding.utf8.runesz` definition lives in
|
||||
* the per-pkg .s and `TEXT main,` in __root.s, so we CONCAT all the
|
||||
* per-unit .s (sorted glob order is deterministic) into a single <stem>.s
|
||||
* for the needle scans + the rule-10 cmp downstream. WW_PKGCACHE is pinned
|
||||
* beside <stem> to leave the shared out/.pkgcache untouched. */
|
||||
static int
|
||||
build_s(const char *driver, const char *src, const char *stem)
|
||||
{
|
||||
char cmd[1024];
|
||||
snprintf(cmd, sizeof cmd, "%s build -o '%s' '%s' 2>/dev/null",
|
||||
driver, stem, src);
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"WW_PKGCACHE='%s.pkgc' timeout 180 %s build --sep -o '%s' '%s' "
|
||||
"2>/dev/null && cat '%s.sepwork/'*.s > '%s.s'",
|
||||
stem, driver, stem, src, stem, stem);
|
||||
return runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -137,7 +147,8 @@ main(void)
|
||||
}
|
||||
|
||||
char cmd[256];
|
||||
snprintf(cmd, sizeof cmd, "rm -f '%s' '%s'* '%s'*", src, cstem, wstem);
|
||||
/* #93: -rf to also drop the per-stem .sepwork scratch + pinned pkgc. */
|
||||
snprintf(cmd, sizeof cmd, "rm -rf '%s' '%s'* '%s'*", src, cstem, wstem);
|
||||
runwait(cmd);
|
||||
|
||||
if (fail) {
|
||||
|
||||
@@ -111,13 +111,17 @@ write_src(const char *path, const struct row *r)
|
||||
}
|
||||
|
||||
/* build_run — build `src` to `<stem>` binary via `driver`, run it; return
|
||||
* the binary's exit code, or -1 on a build failure. */
|
||||
* the binary's exit code, or -1 on a build failure.
|
||||
* #93 sep layout: `--sep -o <stem>` emits per-unit asm under
|
||||
* <stem>.sepwork/ (root in __root.s, encoding.utf8 in encoding.utf8.s); the
|
||||
* binary is still <stem>. WW_PKGCACHE is pinned beside <stem>. */
|
||||
static int
|
||||
build_run(const char *driver, const char *src, const char *stem)
|
||||
{
|
||||
char cmd[1024];
|
||||
snprintf(cmd, sizeof cmd, "%s build -o '%s' '%s' 2>/dev/null",
|
||||
driver, stem, src);
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"WW_PKGCACHE='%s.pkgc' timeout 180 %s build --sep -o '%s' '%s' "
|
||||
"2>/dev/null", stem, driver, stem, src);
|
||||
if (runwait(cmd) != 0) return -1;
|
||||
return runwait(stem);
|
||||
}
|
||||
@@ -172,9 +176,9 @@ main(void)
|
||||
fail++;
|
||||
}
|
||||
char cmd[256];
|
||||
snprintf(cmd, sizeof cmd, "rm -f '%s' '%s' '%s.s' "
|
||||
"'%s.o' '%s.combined.ww'", src, stem, stem, stem,
|
||||
stem);
|
||||
/* #93: drop the sep scratch + pinned pkgcache too. */
|
||||
snprintf(cmd, sizeof cmd, "rm -rf '%s' '%s' "
|
||||
"'%s.sepwork' '%s.pkgc'", src, stem, stem, stem);
|
||||
runwait(cmd);
|
||||
}
|
||||
}
|
||||
@@ -183,27 +187,38 @@ main(void)
|
||||
if (access(wdrv, X_OK) == 0) {
|
||||
total++;
|
||||
const struct row *r = &rows[n - 1]; /* all_arms */
|
||||
char csrc[80], cstem[80], cs[96], ws[96], cmd[512];
|
||||
char csrc[80], cstem[80], cmd[512];
|
||||
snprintf(csrc, sizeof csrc, "/tmp/m1union_bid_%d.ww", pid);
|
||||
snprintf(cstem, sizeof cstem, "/tmp/m1union_bid_c_%d", pid);
|
||||
snprintf(cs, sizeof cs, "%s.s", cstem);
|
||||
char wstem[80];
|
||||
snprintf(wstem, sizeof wstem, "/tmp/m1union_bid_w_%d", pid);
|
||||
snprintf(ws, sizeof ws, "%s.s", wstem);
|
||||
if (write_src(csrc, r) == 0) {
|
||||
snprintf(cmd, sizeof cmd, "%s build -o '%s' '%s' "
|
||||
"2>/dev/null", cdrv, cstem, csrc);
|
||||
/* #93 sep layout: each stage emits per-unit asm under
|
||||
* <stem>.sepwork/ (__root.s + encoding.utf8.s); the
|
||||
* rule-10 byte-id gate becomes a recursive diff of the
|
||||
* two sepwork trees. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"WW_PKGCACHE='%s.pkgc' %s build --sep -o '%s' '%s' "
|
||||
"2>/dev/null", cstem, cdrv, cstem, csrc);
|
||||
int cb = runwait(cmd);
|
||||
snprintf(cmd, sizeof cmd, "%s build -o '%s' '%s' "
|
||||
"2>/dev/null", wdrv, wstem, csrc);
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"WW_PKGCACHE='%s.pkgc' %s build --sep -o '%s' '%s' "
|
||||
"2>/dev/null", wstem, wdrv, wstem, csrc);
|
||||
int wb = runwait(cmd);
|
||||
if (cb != 0 || wb != 0) {
|
||||
fprintf(stderr, "m1union_run: byte-id build "
|
||||
"failed (cstage=%d wwstage=%d)\n", cb, wb);
|
||||
fail++;
|
||||
} else {
|
||||
snprintf(cmd, sizeof cmd, "cmp -s '%s' '%s'",
|
||||
cs, ws);
|
||||
/* Concat each tree's per-unit *.s (sorted glob
|
||||
* order is deterministic) and cmp — sidesteps a
|
||||
* stray <pkg>.md5tmp the wwstage drops in the
|
||||
* sep dir, which a full `diff -r` would flag. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cat '%s.sepwork/'*.s > '%s.scat' && "
|
||||
"cat '%s.sepwork/'*.s > '%s.scat' && "
|
||||
"cmp -s '%s.scat' '%s.scat'",
|
||||
cstem, cstem, wstem, wstem, cstem, wstem);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "m1union_run: cstage.s "
|
||||
"!= wwstage.s (byte-id break)\n");
|
||||
@@ -211,7 +226,7 @@ main(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
snprintf(cmd, sizeof cmd, "rm -f '%s' '%s'* '%s'*", csrc,
|
||||
snprintf(cmd, sizeof cmd, "rm -rf '%s' '%s'* '%s'*", csrc,
|
||||
cstem, wstem);
|
||||
runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -144,8 +144,13 @@ run_build(const char *driver, const struct row *r, int i)
|
||||
snprintf(dir, sizeof dir, "/tmp/m1usehint_%d_%d", getpid(), i);
|
||||
if (layout(dir, r) != 0) return -2;
|
||||
|
||||
snprintf(cmd, sizeof cmd, "cd '%s' && %s build main.ww 2>/dev/null",
|
||||
dir, driver);
|
||||
/* #93 sep layout: `--sep -o main` emits per-unit asm under
|
||||
* main.sepwork/ (each dir-pkg in its own <pkgpath>.s); binary stays
|
||||
* <dir>/main. WW_PKGCACHE pinned under <dir>; the whole tree is
|
||||
* rm -rf'd below, so the scratch dies with it. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd '%s' && WW_PKGCACHE='%s/pkgc' %s build --sep -o main "
|
||||
"main.ww 2>/dev/null", dir, dir, driver);
|
||||
int brc = runwait(cmd);
|
||||
|
||||
int got = -1;
|
||||
@@ -165,18 +170,29 @@ static int
|
||||
byteid(const char *cdrv, const char *wdrv, const struct row *r)
|
||||
{
|
||||
char dir[64], cmd[2048];
|
||||
char cs[96], ws[96];
|
||||
char cstem[80], wstem[80], cs[96], ws[96];
|
||||
snprintf(dir, sizeof dir, "/tmp/m1usehint_bid_%d", getpid());
|
||||
if (layout(dir, r) != 0) return -1;
|
||||
snprintf(cs, sizeof cs, "/tmp/m1usehint_c_%d.s", getpid());
|
||||
snprintf(ws, sizeof ws, "/tmp/m1usehint_w_%d.s", getpid());
|
||||
snprintf(cstem, sizeof cstem, "/tmp/m1usehint_c_%d", getpid());
|
||||
snprintf(wstem, sizeof wstem, "/tmp/m1usehint_w_%d", getpid());
|
||||
snprintf(cs, sizeof cs, "%s.s", cstem);
|
||||
snprintf(ws, sizeof ws, "%s.s", wstem);
|
||||
|
||||
/* #93 sep layout: each stage emits per-unit asm under <stem>.sepwork/
|
||||
* (a.math.s, b.math.s, one.s, two.s, __root.s). The rule-10 byte-id
|
||||
* gate concats each tree's per-unit *.s (sorted glob order is
|
||||
* deterministic) into a flat <stem>.s and cmps the two. WW_PKGCACHE
|
||||
* is pinned per-stem so the shared out/.pkgcache stays untouched. */
|
||||
int rc = -1;
|
||||
snprintf(cmd, sizeof cmd, "cd '%s' && %s build -o '/tmp/m1usehint_c_%d' "
|
||||
"main.ww 2>/dev/null", dir, cdrv, getpid());
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd '%s' && WW_PKGCACHE='%s.pkgc' %s build --sep -o '%s' "
|
||||
"main.ww 2>/dev/null && cat '%s.sepwork/'*.s > '%s'",
|
||||
dir, cstem, cdrv, cstem, cstem, cs);
|
||||
int cb = runwait(cmd);
|
||||
snprintf(cmd, sizeof cmd, "cd '%s' && %s build -o '/tmp/m1usehint_w_%d' "
|
||||
"main.ww 2>/dev/null", dir, wdrv, getpid());
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd '%s' && WW_PKGCACHE='%s.pkgc' %s build --sep -o '%s' "
|
||||
"main.ww 2>/dev/null && cat '%s.sepwork/'*.s > '%s'",
|
||||
dir, wstem, wdrv, wstem, wstem, ws);
|
||||
int wb = runwait(cmd);
|
||||
if (cb == 0 && wb == 0) {
|
||||
snprintf(cmd, sizeof cmd, "cmp -s '%s' '%s'", cs, ws);
|
||||
@@ -185,8 +201,7 @@ byteid(const char *cdrv, const char *wdrv, const struct row *r)
|
||||
fprintf(stderr, "m1usehint_run: byte-id build failed "
|
||||
"(cstage=%d wwstage=%d)\n", cb, wb);
|
||||
}
|
||||
snprintf(cmd, sizeof cmd, "rm -rf '%s' '/tmp/m1usehint_c_%d'* "
|
||||
"'/tmp/m1usehint_w_%d'*", dir, getpid(), getpid());
|
||||
snprintf(cmd, sizeof cmd, "rm -rf '%s' '%s'* '%s'*", dir, cstem, wstem);
|
||||
runwait(cmd);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <glob.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
static int
|
||||
@@ -102,34 +103,64 @@ main(void)
|
||||
char cwd[1024];
|
||||
if (getcwd(cwd, sizeof cwd) == NULL) return 1;
|
||||
|
||||
const char *files[] = {
|
||||
/* hand-written runtime — small, covers MOVQ/LEAQ/CALL/SYSCALL/RET. */
|
||||
"rt/start.s",
|
||||
"rt/syscall.s",
|
||||
"rt/abort.s",
|
||||
"rt/alloc.s",
|
||||
"rt/streq.s",
|
||||
/* generated .s from the existing selfhost stack — large,
|
||||
* exercises every encoding w6c emits (the only way to hit
|
||||
* the long tail of operand shapes). */
|
||||
"selfhost/cmd/wwdump/main.s",
|
||||
"selfhost/cmd/w6l/main.s",
|
||||
"selfhost/cmd/w6a/main.s",
|
||||
NULL,
|
||||
/* #93 sep layout: the selfhost tools no longer leave a single
|
||||
* next-to-source main.s. Self-build one real tool via `ww build
|
||||
* --sep` into /tmp and feed EVERY emitted <tool>.sepwork/<pkg>.s as
|
||||
* the generated-asm corpus — the root tool code plus each dep
|
||||
* package's .s (richer than the old 3 monolithic main.s). Flip-
|
||||
* invariant: --sep is live on trunk, default post-flip. */
|
||||
char stem[256], cmd[4096];
|
||||
snprintf(stem, sizeof stem, "/tmp/wwa_%d_sh", getpid());
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"WW_PKGCACHE=%s.pkgc timeout 400 %s/ww build --sep -o %s "
|
||||
"%s/selfhost/cmd/w6a >/dev/null 2>&1", stem, bin, stem, cwd);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "w6a_ww FAIL: cannot sep-build selfhost/cmd/w6a\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* hand-written runtime — small, covers MOVQ/LEAQ/CALL/SYSCALL/RET;
|
||||
* exists in-tree regardless of layout (not a casualty). */
|
||||
const char *rtfiles[] = {
|
||||
"rt/start.s", "rt/syscall.s", "rt/abort.s",
|
||||
"rt/alloc.s", "rt/streq.s", NULL,
|
||||
};
|
||||
int fail = 0;
|
||||
int n = 0;
|
||||
for (int i = 0; files[i]; i++) {
|
||||
for (int i = 0; rtfiles[i]; i++) {
|
||||
char p[2048];
|
||||
snprintf(p, sizeof p, "%s/%s", cwd, files[i]);
|
||||
snprintf(p, sizeof p, "%s/%s", cwd, rtfiles[i]);
|
||||
if (diff_one(bin, p) != 0) fail++;
|
||||
n++;
|
||||
}
|
||||
|
||||
/* generated .s from the real tool's sep build — large, exercises
|
||||
* every encoding w6c emits (the long tail of operand shapes). */
|
||||
glob_t g;
|
||||
char pat[320];
|
||||
snprintf(pat, sizeof pat, "%s.sepwork/*.s", stem);
|
||||
if (glob(pat, 0, NULL, &g) == 0) {
|
||||
for (size_t i = 0; i < g.gl_pathc; i++) {
|
||||
/* skip empty units (e.g. an import-only rt.s). */
|
||||
FILE *f = fopen(g.gl_pathv[i], "rb");
|
||||
long sz = -1;
|
||||
if (f) { fseek(f, 0, SEEK_END); sz = ftell(f); fclose(f); }
|
||||
if (sz <= 0) continue;
|
||||
if (diff_one(bin, g.gl_pathv[i]) != 0) fail++;
|
||||
n++;
|
||||
}
|
||||
globfree(&g);
|
||||
}
|
||||
|
||||
snprintf(cmd, sizeof cmd, "rm -rf %s.sepwork %s.pkgc %s",
|
||||
stem, stem, stem);
|
||||
if (system(cmd)) {}
|
||||
|
||||
if (fail) {
|
||||
fprintf(stderr, "w6a_ww: %d/%d diff(s) failed\n", fail, n);
|
||||
return 1;
|
||||
}
|
||||
printf("w6a_ww: byte-identical to C w6a on %d corpus files "
|
||||
"(rt/*.s + selfhost generated main.s)\n", n);
|
||||
"(rt/*.s + selfhost/cmd/w6a sep-built .s)\n", n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -56,40 +56,57 @@ slurp(const char *path, char **outbuf, size_t *outlen)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* link `inputs` (space-separated, the caller's responsibility to quote)
|
||||
* with both linkers, compare bytes. */
|
||||
/* #93 sep layout: the flip stops emitting a monolithic <tool>/main.o;
|
||||
* the linkable unit is now the per-package .o + reverse-topo .a set the
|
||||
* sep driver assembles (a raw `w6l <root>.o *.a libwwrt.a` from the test
|
||||
* side fails — `undefined reference` — because it can't reproduce the
|
||||
* driver's topo order). So isolate the LINKER by driving the sep build's
|
||||
* own link step twice over identical .o inputs (a shared pkgcache makes
|
||||
* the second build's package objects a cache hit → only the final link
|
||||
* re-runs): once with the default C w6l, once with WW_W6L=w6l_ww. Diff
|
||||
* the two real tool binaries. Exercises the full archive two-pass loader
|
||||
* + reverse-topo .a resolution — a stronger link than the old single
|
||||
* main.o. Flip-invariant: --sep is live on trunk, default post-flip. */
|
||||
static int
|
||||
diff_one(const char *bin, const char *label, const char *inputs)
|
||||
build_and_diff(const char *bin, const char *cwd, const char *tool,
|
||||
const char *cache)
|
||||
{
|
||||
char co[64], wo[64], cmd[4096];
|
||||
snprintf(co, sizeof co, "/tmp/wwl_%d_c", getpid());
|
||||
snprintf(wo, sizeof wo, "/tmp/wwl_%d_w", getpid());
|
||||
char cstem[256], wstem[256], cmd[4096];
|
||||
snprintf(cstem, sizeof cstem, "/tmp/wwl_%d_c", getpid());
|
||||
snprintf(wstem, sizeof wstem, "/tmp/wwl_%d_w", getpid());
|
||||
|
||||
snprintf(cmd, sizeof cmd, "timeout 180 %s/w6l -o %s %s 2>/dev/null", bin, co, inputs);
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"WW_PKGCACHE=%s timeout 300 %s/ww build --sep -o %s "
|
||||
"%s/selfhost/cmd/%s >/dev/null 2>&1", cache, bin, cstem, cwd, tool);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "w6l_ww FAIL: C w6l errored on %s\n", label);
|
||||
unlink(co);
|
||||
fprintf(stderr, "w6l_ww FAIL: C-link sep-build of %s\n", tool);
|
||||
return -1;
|
||||
}
|
||||
snprintf(cmd, sizeof cmd, "timeout 180 %s/w6l_ww -o %s %s 2>/dev/null", bin, wo, inputs);
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"WW_W6L=%s/w6l_ww WW_PKGCACHE=%s timeout 300 %s/ww build --sep "
|
||||
"-o %s %s/selfhost/cmd/%s >/dev/null 2>&1",
|
||||
bin, cache, bin, wstem, cwd, tool);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "w6l_ww FAIL: ww w6l errored on %s\n", label);
|
||||
unlink(co); unlink(wo);
|
||||
fprintf(stderr, "w6l_ww FAIL: ww-link sep-build of %s\n", tool);
|
||||
snprintf(cmd, sizeof cmd, "rm -rf %s %s.sepwork", cstem, cstem);
|
||||
if (system(cmd)) {}
|
||||
return -1;
|
||||
}
|
||||
char *bc = NULL, *bw = NULL;
|
||||
size_t nc = 0, nw = 0;
|
||||
int rc = 0;
|
||||
if (slurp(co, &bc, &nc) < 0 || slurp(wo, &bw, &nw) < 0) {
|
||||
fprintf(stderr, "w6l_ww FAIL: cannot read output for %s\n", label);
|
||||
if (slurp(cstem, &bc, &nc) < 0 || slurp(wstem, &bw, &nw) < 0) {
|
||||
fprintf(stderr, "w6l_ww FAIL: cannot read output for %s\n", tool);
|
||||
rc = -1;
|
||||
} else if (nc != nw || memcmp(bc, bw, nc) != 0) {
|
||||
fprintf(stderr, "w6l_ww FAIL: %s — C %zu vs ww %zu bytes\n",
|
||||
label, nc, nw);
|
||||
tool, nc, nw);
|
||||
rc = -1;
|
||||
}
|
||||
free(bc); free(bw);
|
||||
unlink(co); unlink(wo);
|
||||
snprintf(cmd, sizeof cmd, "rm -rf %s %s %s.sepwork %s.sepwork",
|
||||
cstem, wstem, cstem, wstem);
|
||||
if (system(cmd)) {}
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -102,36 +119,31 @@ main(void)
|
||||
char cwd[1024];
|
||||
if (getcwd(cwd, sizeof cwd) == NULL) return 1;
|
||||
|
||||
struct {
|
||||
const char *label;
|
||||
const char *inputs_fmt; /* %s = cwd */
|
||||
} cases[] = {
|
||||
/* Real bootstrap-style links: every selfhost main.o paired
|
||||
* with libwwrt.a. Exercises both the .o code path and the
|
||||
* archive two-pass loader (rt_malloc / rt_syscall / rt_abort
|
||||
* are pulled from libwwrt.a as undefs are encountered). */
|
||||
{ "wwdump+libwwrt",
|
||||
"%s/selfhost/cmd/wwdump/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 },
|
||||
};
|
||||
/* Real bootstrap-style links: each selfhost tool's full sep build
|
||||
* (root .o + reverse-topo dep .a set + libwwrt.a). One shared
|
||||
* pkgcache across all builds so each tool's second (w6l_ww) build
|
||||
* re-links only. (wwdump is excluded — it imports the compiler-
|
||||
* internal cmd packages syntax/check/cgen, which don't resolve
|
||||
* under the lib-path sep dep scan; w6a/w6l are self-contained
|
||||
* lib-only tools.) */
|
||||
const char *tools[] = { "w6a", "w6l", NULL };
|
||||
char cache[256];
|
||||
snprintf(cache, sizeof cache, "/tmp/wwl_%d_pkgc", getpid());
|
||||
|
||||
int fail = 0;
|
||||
int n = 0;
|
||||
for (int i = 0; cases[i].label; i++) {
|
||||
char inputs[2048];
|
||||
snprintf(inputs, sizeof inputs, cases[i].inputs_fmt, cwd, cwd);
|
||||
if (diff_one(bin, cases[i].label, inputs) != 0) fail++;
|
||||
for (int i = 0; tools[i]; i++) {
|
||||
if (build_and_diff(bin, cwd, tools[i], cache) != 0) fail++;
|
||||
n++;
|
||||
}
|
||||
char rmc[320];
|
||||
snprintf(rmc, sizeof rmc, "rm -rf %s", cache);
|
||||
if (system(rmc)) {}
|
||||
if (fail) {
|
||||
fprintf(stderr, "w6l_ww: %d/%d diff(s) failed\n", fail, n);
|
||||
return 1;
|
||||
}
|
||||
printf("w6l_ww: byte-identical to C w6l on %d corpus links "
|
||||
"(.o + libwwrt.a archive resolution)\n", n);
|
||||
printf("w6l_ww: byte-identical to C w6l on %d selfhost tool links "
|
||||
"(sep root .o + reverse-topo .a set + libwwrt.a)\n", n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -63,14 +63,17 @@ main(void)
|
||||
char cwd[1024];
|
||||
if (getcwd(cwd, sizeof cwd) == NULL) return 1;
|
||||
|
||||
/* Ensure mandelbrot.o exists. The example's Makefile produces it
|
||||
* via the C-side `ww build`. Re-run that so the test is
|
||||
* self-contained. */
|
||||
char cmd[4096];
|
||||
/* #93 sep layout: build the example via `ww build --sep` into a
|
||||
* private /tmp stem (NOT next to the tracked example source), then
|
||||
* link <stem>.sepwork/__root.o — the self-contained single-package
|
||||
* object the flip emits in place of the old next-to-source .o. */
|
||||
char cmd[4096], mbstem[256], mbobj[320];
|
||||
snprintf(mbstem, sizeof mbstem, "/tmp/wwld_%d_mb", getpid());
|
||||
snprintf(mbobj, sizeof mbobj, "%s.sepwork/__root.o", mbstem);
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s/examples/mandelbrot && %s/ww build mandelbrot.ww "
|
||||
"-L /usr/lib -l c >/dev/null 2>&1",
|
||||
cwd, bin);
|
||||
"cd %s/examples/mandelbrot && WW_PKGCACHE=%s.pkgc %s/ww build --sep "
|
||||
"-o %s mandelbrot.ww -L /usr/lib -l c >/dev/null 2>&1",
|
||||
cwd, mbstem, bin, mbstem);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "w6l_ww-dyn FAIL: cannot build mandelbrot.o via C driver\n");
|
||||
return 1;
|
||||
@@ -82,9 +85,9 @@ main(void)
|
||||
|
||||
/* C-side w6l with the dynamic flags. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"%s/w6l -o %s %s/examples/mandelbrot/mandelbrot.o -L /usr/lib "
|
||||
"%s/w6l -o %s %s -L /usr/lib "
|
||||
"-l c %s/out/lib/libwwrt.a 2>/dev/null",
|
||||
bin, co, cwd, cwd);
|
||||
bin, co, mbobj, cwd);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "w6l_ww-dyn FAIL: C w6l errored\n");
|
||||
unlink(co);
|
||||
@@ -93,9 +96,9 @@ main(void)
|
||||
|
||||
/* ww-side w6l with the same flags. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"%s/w6l_ww -o %s %s/examples/mandelbrot/mandelbrot.o -L /usr/lib "
|
||||
"%s/w6l_ww -o %s %s -L /usr/lib "
|
||||
"-l c %s/out/lib/libwwrt.a 2>/dev/null",
|
||||
bin, wo, cwd, cwd);
|
||||
bin, wo, mbobj, cwd);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "w6l_ww-dyn FAIL: ww w6l errored\n");
|
||||
unlink(co); unlink(wo);
|
||||
@@ -119,5 +122,8 @@ main(void)
|
||||
}
|
||||
free(bc); free(bw);
|
||||
unlink(co); unlink(wo);
|
||||
/* #93: the sep scratch + tmpdir-pinned pkgcache. */
|
||||
snprintf(cmd, sizeof cmd, "rm -rf %s.sepwork %s.pkgc %s", mbstem, mbstem, mbstem);
|
||||
if (system(cmd)) {}
|
||||
return rc;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user