wcc/ww: tag sep-built dotted-path packages by full path not leaf (#57)

A separately-compiled package's primary body was emitted under a bare
`//ww:module-reset`, so its own `package <leaf>;` clause set curmod to
the leaf (e.g. utf8) while the importer spliced the .wwi under the full
`//ww:module encoding.utf8` — definer mangled `utf8.X`, importer wanted
`encoding.utf8.X`, unresolved. Thread the dotted path through the
directive: `//ww:module-reset <path>` sets curmod to the dotted path
(imported stays 0, so the root `fn main` stays bare per #32), and the
body's package clause is demoted to a leaf==last-component assertion
instead of overwriting curmod. Aligns sep-build to the M1 path-mangle
model; only the SEP emitter changes (the combined build_one arm is
untouched, so all combined byte-id gates hold). Both stages mirrored.

Commit-6 broad-soak prerequisite. Gate 989_sepdotpath_run sep-builds a
2-level dotted package and proves definer==importer qualification +
single-component non-vacuity, cs==ww.
This commit is contained in:
2026-06-16 16:36:03 +09:00
parent 7b36f961a9
commit 747475174a
12 changed files with 639 additions and 58 deletions

View File

@@ -787,7 +787,7 @@ sep_mark_deps(struct sepgraph *g, int pi, char *inset)
* body); FILE imports fold in (intra-package split). */
static void
sep_emit_body(FILE *out, const char *path, struct ImportSet *visited,
const char *searchpath)
const char *searchpath, const char *modpath)
{
if (import_seen(visited, path)) return;
import_add(visited, path);
@@ -818,9 +818,15 @@ sep_emit_body(FILE *out, const char *path, struct ImportSet *visited,
&is_dir))
continue;
if (!is_dir)
sep_emit_body(out, ipath, visited, searchpath);
sep_emit_body(out, ipath, visited, searchpath, modpath);
}
fputs("//ww:module-reset\n", out);
/* #57: tag the primary body by its full dotted import path so the
* definer mangles == the importer reference; a root build (path "")
* stays a bare reset (keeps bare main). */
if (modpath != NULL && modpath[0] != '\0')
fprintf(out, "//ww:module-reset %s\n", modpath);
else
fputs("//ww:module-reset\n", out);
rewind(in);
int ch;
while ((ch = fgetc(in)) != EOF) fputc(ch, out);
@@ -830,14 +836,14 @@ sep_emit_body(FILE *out, const char *path, struct ImportSet *visited,
static void
sep_emit_dir_body(FILE *out, const char *dir, struct ImportSet *visited,
const char *searchpath)
const char *searchpath, const char *modpath)
{
char **files = NULL;
int n = enumerate_dir_ww(dir, &files);
for (int i = 0; i < n; i++) {
char fp[1024];
snprintf(fp, sizeof fp, "%s/%s", dir, files[i]);
sep_emit_body(out, fp, visited, searchpath);
sep_emit_body(out, fp, visited, searchpath, modpath);
free(files[i]);
}
free(files);
@@ -876,9 +882,11 @@ sep_compose_unit(struct sepgraph *g, int pi, const char *scratch,
}
struct ImportSet bodyvisit = {0};
if (g->pkg[pi].is_dir)
sep_emit_dir_body(u, g->pkg[pi].entry, &bodyvisit, searchpath);
sep_emit_dir_body(u, g->pkg[pi].entry, &bodyvisit, searchpath,
g->pkg[pi].path);
else
sep_emit_body(u, g->pkg[pi].entry, &bodyvisit, searchpath);
sep_emit_body(u, g->pkg[pi].entry, &bodyvisit, searchpath,
g->pkg[pi].path);
for (int i = 0; i < bodyvisit.n; i++) free(bodyvisit.paths[i]);
free(bodyvisit.paths);
fclose(u);