wcc/ww: path-qualify exported decls + drop exact-or-bare value mangle (#53)
Under M1 mangling, EXPORTED non-fn decls (let/def/type) skipped path- qualification and emitted a BARE symbol (`types.I64_MAX` -> `I64_MAX`). Under separate compilation two packages exporting the same data leaf would then collide at w6l. Masked in-tree only because no two packages export the same non-fn leaf. §7-A (USER-locked, harec's model): path-qualify EVERY exported decl (fn AND data) at the single mangle choke-point — mod_collect / collectmods. Retire the `!isfn && d->export` (cstage) and `exported==0` (wwstage) skips: every decl with a module now mangles `<mod>.<name>`. The ONLY bare symbols left are @symbol FFI overrides (ffi_resolve at emit) and the ROOT unit's `main` — both already carved out before the map insert. With exported decls in the map the exact-(name,hint)-or-bare value dance is dead — its sole purpose was the bare-exported case. Delete mod_lookup_value / mod_mangle_value / mahint (cstage) and modlookupvalue / emitsymnamehint (wwstage); the value-global sites now route through the same hint-aware-with-fallback lookup as fns (mod_mangle_fn/mafn, emitfnname). Net negative LOC in the mangler. Transparent rename on the live combined path: ref and def move in lockstep, so cs==ww byte-id holds and the self-host still builds + runs (fixed-point/995). Byte-id REBASELINE — all 5 ww binaries shift. The w6c/wwdump combined.ww embed wcc cgen and are regenerated.
This commit is contained in:
@@ -1184,7 +1184,7 @@ fn cgident(c: *cgen, n: *node) void = {
|
||||
let mov: str = "MOVSD";
|
||||
if (isf32type(c, n)) { mov = "MOVSS"; };
|
||||
emitline("\tLEAQ\t");
|
||||
emitsymnamehint(c, nm, c.curmod);
|
||||
emitfnname(c, nm, c.curmod);
|
||||
emitline("(SB), CX\n");
|
||||
emitline("\t");
|
||||
emitline(mov);
|
||||
@@ -1192,7 +1192,7 @@ fn cgident(c: *cgen, n: *node) void = {
|
||||
return;
|
||||
};
|
||||
emitline("\tMOVQ\t");
|
||||
emitsymnamehint(c, nm, c.curmod);
|
||||
emitfnname(c, nm, c.curmod);
|
||||
emitline("(SB), AX\n");
|
||||
return;
|
||||
};
|
||||
@@ -1242,7 +1242,7 @@ fn cgident(c: *cgen, n: *node) void = {
|
||||
// is overwritten by the cap as the last step, after
|
||||
// ptr/len are already loaded (#1/Phase 3).
|
||||
emitline("\tLEAQ\t");
|
||||
emitsymnamehint(c, nm, c.curmod);
|
||||
emitfnname(c, nm, c.curmod);
|
||||
emitline("(SB), CX\n");
|
||||
emitline("\tMOVQ\t(CX), AX\n");
|
||||
emitline("\tMOVQ\t8(CX), BX\n");
|
||||
@@ -1275,7 +1275,7 @@ fn cgident(c: *cgen, n: *node) void = {
|
||||
let mov: str = "MOVSD";
|
||||
if (is32) { mov = "MOVSS"; };
|
||||
emitline("\tLEAQ\t");
|
||||
emitsymnamehint(c, nm, c.curmod);
|
||||
emitfnname(c, nm, c.curmod);
|
||||
emitline("(SB), CX\n");
|
||||
emitline("\t");
|
||||
emitline(mov);
|
||||
@@ -1291,11 +1291,11 @@ fn cgident(c: *cgen, n: *node) void = {
|
||||
let glop: str = localloadop(c, lvtnode);
|
||||
if (streq(glop, "MOVQ")) {
|
||||
emitline("\tMOVQ\t");
|
||||
emitsymnamehint(c, nm, c.curmod);
|
||||
emitfnname(c, nm, c.curmod);
|
||||
emitline("(SB), AX\n");
|
||||
} else {
|
||||
emitline("\tLEAQ\t");
|
||||
emitsymnamehint(c, nm, c.curmod);
|
||||
emitfnname(c, nm, c.curmod);
|
||||
emitline("(SB), CX\n");
|
||||
emitline("\t");
|
||||
emitline(glop);
|
||||
@@ -2937,7 +2937,7 @@ fn cgmatch(c: *cgen, n: *node) void = {
|
||||
let gspill: i32 = matchspillsz(c, gtt);
|
||||
scrutoff = localalloc(c, "@match_spill", gspill, nil);
|
||||
emitline("\tLEAQ\t");
|
||||
emitsymnamehint(c, scrut.str, c.curmod);
|
||||
emitfnname(c, scrut.str, c.curmod);
|
||||
emitline("(SB), AX\n");
|
||||
let gk: i32 = 0;
|
||||
for (gk < gspill) {
|
||||
@@ -4342,11 +4342,11 @@ fn cgdot(c: *cgen, n: *node) void = {
|
||||
// threads lhs.str via emitfnname.
|
||||
if (streq(mqop, "MOVQ")) {
|
||||
emitline("\tMOVQ\t");
|
||||
emitsymnamehint(c, fld, usehint(c, lhs.str));
|
||||
emitfnname(c, fld, usehint(c, lhs.str));
|
||||
emitline("(SB), AX\n");
|
||||
} else {
|
||||
emitline("\tLEAQ\t");
|
||||
emitsymnamehint(c, fld, usehint(c, lhs.str));
|
||||
emitfnname(c, fld, usehint(c, lhs.str));
|
||||
emitline("(SB), CX\n");
|
||||
emitline("\t");
|
||||
emitline(mqop);
|
||||
@@ -5238,7 +5238,7 @@ fn cgun(c: *cgen, n: *node) void = {
|
||||
// &aa.v takes aa's global, not a
|
||||
// same-leaf collision.
|
||||
emitline("\tLEAQ\t");
|
||||
emitsymnamehint(c, fld, usehint(c, basenm));
|
||||
emitfnname(c, fld, usehint(c, basenm));
|
||||
emitline("(SB), AX\n");
|
||||
return;
|
||||
};
|
||||
@@ -5516,7 +5516,7 @@ fn cgstreqpush(c: *cgen, op: *node) void = {
|
||||
let lc: *local = localfindnode(c, nm);
|
||||
if (lc == nil && isletvar(c, nm)) {
|
||||
emitline("\tLEAQ\t");
|
||||
emitsymnamehint(c, nm, c.curmod);
|
||||
emitfnname(c, nm, c.curmod);
|
||||
emitline("(SB), BX\n");
|
||||
emitline("\tMOVQ\t8(BX), AX\n");
|
||||
emitline("\tPUSHQ\tAX\n");
|
||||
@@ -7368,7 +7368,7 @@ fn cgcall(c: *cgen, n: *node) void = {
|
||||
// mis-resolved.
|
||||
if (isletvar(c, a.str)) {
|
||||
emitline("\tLEAQ\t");
|
||||
emitsymnamehint(c, a.str, c.curmod);
|
||||
emitfnname(c, a.str, c.curmod);
|
||||
emitline("(SB), CX\n");
|
||||
emitline("\tMOVQ\t8(CX), AX\n");
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user