Strlit labels were emitted as `_S_<n>` from a global counter with no per-unit prefix (cgen.c intern_strlit + wwstage internstrlit twin). Under separate compilation two str-bearing packages both emit `_S_0`.. -> w6l link collision. Prefix the label with the owning package PATH (`<module>._S_<n>`, matching mklabel's spelling). The prefix is c->cur_mod, set per-fn by cgfn and now per-decl by let_pre_intern (save/restore so the later emit passes, which read cur_mod for fn-ptr relocs, are unaffected). Pure function of the module path — NOT a build-nonce — so the self-host fixed-point holds across ww2/ww3/ww4. Both stages, symmetric. Transparent rename on the live combined path: the label is interned once and shared by every reference, so ref and def move in lockstep. cs==ww byte-id holds; the w6c/wwdump combined.ww embed wcc/cgen.ww and are regenerated. 746_strdef_inline: the strdef-inline sentinel pinned the bare `LEAQ\t_S_` shape; update to the module-prefixed form (alpha._S_ for the in-module def, beta._S_ for the use-site-interned cross-module inline). 989_m3sep_run: add the #49 LINK leg. The str sub-fixture (sleaf+smid) was keystone-only — never linked — precisely because the global counter made both emit `_S_0`. With the prefix, compile both `-c` separately, link (w6l) + run (sroot reads a distinguishing byte through each string's .ptr, so a collided label would corrupt the exit), both stages + cs==ww final exe.
7.9 KiB
7.9 KiB