wcc/ww: per-unit prefix on _S_ strlit labels (#49)
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.
This commit is contained in:
@@ -34,11 +34,11 @@
|
||||
* Pin: 2 rows. Row 1 (bare ident, single module) sentinel-flips the
|
||||
* cgenexpr.ww:555 deflookup-strlit-inline branch on wwstage — revert
|
||||
* the branch and row 1 fails (`MOVQ\talpha.MSG(SB)` appears instead
|
||||
* of `LEAQ\t_S_`). Row 2 (mod-qualified, two modules) sentinel-flips
|
||||
* the cgenexpr.ww:1730 cgdot deflookup-strlit-inline branch — revert
|
||||
* and row 2 fails the same way (`MOVQ\talpha.MSG(SB)` appears in
|
||||
* of `LEAQ\t<mod>._S_`). Row 2 (mod-qualified, two modules) sentinel-
|
||||
* flips the cgenexpr.ww:1730 cgdot deflookup-strlit-inline branch —
|
||||
* revert and row 2 fails the same way (`MOVQ\talpha.MSG(SB)` appears in
|
||||
* beta.b). Asserts the strlit-inline pair lands inside the right
|
||||
* TEXT sym (LEAQ\t_S_ + MOVQ\t$<strlit_len>,) with the bad_movq
|
||||
* TEXT sym (LEAQ\t<mod>._S_ + MOVQ\t$<strlit_len>,) with the bad_movq
|
||||
* anti-check on each stage plus cs-vs-ws byte-id per row.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
@@ -77,7 +77,9 @@ static const struct row rows[] = {
|
||||
"def MSG: str = \"strdef_inline_pin_aaaaaaaaaaaaaaa_43chr\";\n"
|
||||
"export fn afn() str = { return MSG; };\n"
|
||||
"export fn main() i32 = { return 0; };\n",
|
||||
"TEXT alpha.afn", "LEAQ\t_S_", "MOVQ\t$39,", "alpha.MSG(SB)" },
|
||||
/* #49: strlit labels carry the interning module's path prefix
|
||||
* (here alpha — MSG's def interns in alpha's compile). */
|
||||
"TEXT alpha.afn", "LEAQ\talpha._S_", "MOVQ\t$39,", "alpha.MSG(SB)" },
|
||||
{ "mod_qualified_strdef",
|
||||
"package alpha;\n"
|
||||
"def MSG: str = \"strdef_inline_pin_aaaaaaaaaaaaaaa_43chr\";\n"
|
||||
@@ -85,7 +87,9 @@ static const struct row rows[] = {
|
||||
"import alpha;\n"
|
||||
"export fn bfn() str = { return alpha.MSG; };\n"
|
||||
"export fn main() i32 = { return 0; };\n",
|
||||
"TEXT beta.bfn", "LEAQ\t_S_", "MOVQ\t$39,", "alpha.MSG(SB)" },
|
||||
/* #49: the inlined sdef interns at the USE site (beta.bfn), so the
|
||||
* strlit label carries beta's path prefix, not alpha's. */
|
||||
"TEXT beta.bfn", "LEAQ\tbeta._S_", "MOVQ\t$39,", "alpha.MSG(SB)" },
|
||||
};
|
||||
|
||||
static int
|
||||
|
||||
Reference in New Issue
Block a user