selfhost+cstage+test: graduate deflookup mod-qualified same-module-first (#11)
cstage Sdef walk #2 N_DOT branch used c->cur_mod where n->lhs->str is the correct module hint. Sister of #4c wwstage graduation; same shape as the TY_FN branch which already uses mafn(c, n->str, n->lhs->str). cmd/w6c/cgen.c: add sdef_mod_match_hint(s, hint); walk #2 routes hint first then head-pick fallback, matching #4a/#28/#31/#34 *mod variant pattern. selfhost: add deflookuprhsmod(c, name, mod); cgdot N_DOT mod-qualified str-def value-load routes through it. Rule-10 symmetric stages: both stages now share the lhs.str polarity (was: both used cur_mod / cur-module hint). 747_def_modqual_modshadow: table-driven sentinel — gamma calls alpha.MSG with beta.MSG (same-leaf-name) at head of c.defs/sdefs. want_imm "$38," (alpha strlit len), bad_imm "$27," (beta strlit len), plus cs-vs-ws byte-id. Reverting cstage walk #2 to head-pick → fails $38 on cstage + diverges cs-vs-ws; reverting wwstage cgdot to plain deflookuprhs → fails $38 on wwstage. make test 121/121; ww2==ww3==ww4 byte-id holds.
This commit is contained in:
@@ -12673,8 +12673,11 @@ fn cgdot(c: *cgen, n: *node) void = {
|
||||
// strlit-inline matches cstage Sdef walk #2 in
|
||||
// cmd/w6c/cgen.c N_DOT mod-qualified. Without this
|
||||
// the MOVQ leaf(SB) fallback emits a bogus ref
|
||||
// (`alpha.MSG(SB)`, never DATAW-defined). Filed #12.
|
||||
let drhs: *node = deflookuprhs(c, fld);
|
||||
// (`alpha.MSG(SB)`, never DATAW-defined). lhs.str is
|
||||
// the explicit module hint — a 3rd-module qualifier
|
||||
// `alpha.MSG` from gamma needs alpha (not c.curmod)
|
||||
// to beat a head-of-c.defs beta.MSG collision (#11).
|
||||
let drhs: *node = deflookuprhsmod(c, fld, lhs.str);
|
||||
if (drhs != nil) {
|
||||
if (drhs.kind == nkind.N_STRLIT) {
|
||||
let bytes: str = drhs.str;
|
||||
@@ -20880,6 +20883,29 @@ fn deflookuprhs(c: *cgen, name: str) *node = {
|
||||
return nil;
|
||||
};
|
||||
|
||||
// deflookuprhsmod — same-module-first walk for `mod.NAME` references.
|
||||
// Trio-leaf *mod variant mirroring fnretlookupmod (#31) / fnparamslookupmod
|
||||
// (#28) / enumlookupmod (#4a). Module-qualified `alpha.MSG` from a third
|
||||
// module needs the explicit alpha hint; deflookuprhs prefers c.curmod
|
||||
// (which doesn't match either source module on a 3rd-module qualifier)
|
||||
// and falls back to head-pick, possibly inlining beta.MSG's strlit when
|
||||
// both alpha and beta declare same-leaf str defs. cgdot's mod-qualified
|
||||
// str-def value-load routes here so a cross-module N_DOT collision
|
||||
// resolves to the explicit module. Falls back to deflookuprhs's bare-
|
||||
// leaf two-pass when no module matches.
|
||||
fn deflookuprhsmod(c: *cgen, name: str, mod: str) *node = {
|
||||
if (mod.len > 0) {
|
||||
let e: *defent = c.defs;
|
||||
for (e != nil) {
|
||||
if (streq(e.dname, name)) {
|
||||
if (streq(e.dmod, mod)) { return e.drhs; };
|
||||
};
|
||||
e = e.dnext;
|
||||
};
|
||||
};
|
||||
return deflookuprhs(c, name);
|
||||
};
|
||||
|
||||
// ---- module-private symbol map --------------------------------------
|
||||
//
|
||||
// Every non-FFI top-level fn decl lives in its module's namespace —
|
||||
|
||||
@@ -1730,6 +1730,29 @@ fn deflookuprhs(c: *cgen, name: str) *node = {
|
||||
return nil;
|
||||
};
|
||||
|
||||
// deflookuprhsmod — same-module-first walk for `mod.NAME` references.
|
||||
// Trio-leaf *mod variant mirroring fnretlookupmod (#31) / fnparamslookupmod
|
||||
// (#28) / enumlookupmod (#4a). Module-qualified `alpha.MSG` from a third
|
||||
// module needs the explicit alpha hint; deflookuprhs prefers c.curmod
|
||||
// (which doesn't match either source module on a 3rd-module qualifier)
|
||||
// and falls back to head-pick, possibly inlining beta.MSG's strlit when
|
||||
// both alpha and beta declare same-leaf str defs. cgdot's mod-qualified
|
||||
// str-def value-load routes here so a cross-module N_DOT collision
|
||||
// resolves to the explicit module. Falls back to deflookuprhs's bare-
|
||||
// leaf two-pass when no module matches.
|
||||
fn deflookuprhsmod(c: *cgen, name: str, mod: str) *node = {
|
||||
if (mod.len > 0) {
|
||||
let e: *defent = c.defs;
|
||||
for (e != nil) {
|
||||
if (streq(e.dname, name)) {
|
||||
if (streq(e.dmod, mod)) { return e.drhs; };
|
||||
};
|
||||
e = e.dnext;
|
||||
};
|
||||
};
|
||||
return deflookuprhs(c, name);
|
||||
};
|
||||
|
||||
// ---- module-private symbol map --------------------------------------
|
||||
//
|
||||
// Every non-FFI top-level fn decl lives in its module's namespace —
|
||||
|
||||
@@ -1744,8 +1744,11 @@ fn cgdot(c: *cgen, n: *node) void = {
|
||||
// strlit-inline matches cstage Sdef walk #2 in
|
||||
// cmd/w6c/cgen.c N_DOT mod-qualified. Without this
|
||||
// the MOVQ leaf(SB) fallback emits a bogus ref
|
||||
// (`alpha.MSG(SB)`, never DATAW-defined). Filed #12.
|
||||
let drhs: *node = deflookuprhs(c, fld);
|
||||
// (`alpha.MSG(SB)`, never DATAW-defined). lhs.str is
|
||||
// the explicit module hint — a 3rd-module qualifier
|
||||
// `alpha.MSG` from gamma needs alpha (not c.curmod)
|
||||
// to beat a head-of-c.defs beta.MSG collision (#11).
|
||||
let drhs: *node = deflookuprhsmod(c, fld, lhs.str);
|
||||
if (drhs != nil) {
|
||||
if (drhs.kind == nkind.N_STRLIT) {
|
||||
let bytes: str = drhs.str;
|
||||
|
||||
@@ -12673,8 +12673,11 @@ fn cgdot(c: *cgen, n: *node) void = {
|
||||
// strlit-inline matches cstage Sdef walk #2 in
|
||||
// cmd/w6c/cgen.c N_DOT mod-qualified. Without this
|
||||
// the MOVQ leaf(SB) fallback emits a bogus ref
|
||||
// (`alpha.MSG(SB)`, never DATAW-defined). Filed #12.
|
||||
let drhs: *node = deflookuprhs(c, fld);
|
||||
// (`alpha.MSG(SB)`, never DATAW-defined). lhs.str is
|
||||
// the explicit module hint — a 3rd-module qualifier
|
||||
// `alpha.MSG` from gamma needs alpha (not c.curmod)
|
||||
// to beat a head-of-c.defs beta.MSG collision (#11).
|
||||
let drhs: *node = deflookuprhsmod(c, fld, lhs.str);
|
||||
if (drhs != nil) {
|
||||
if (drhs.kind == nkind.N_STRLIT) {
|
||||
let bytes: str = drhs.str;
|
||||
@@ -20880,6 +20883,29 @@ fn deflookuprhs(c: *cgen, name: str) *node = {
|
||||
return nil;
|
||||
};
|
||||
|
||||
// deflookuprhsmod — same-module-first walk for `mod.NAME` references.
|
||||
// Trio-leaf *mod variant mirroring fnretlookupmod (#31) / fnparamslookupmod
|
||||
// (#28) / enumlookupmod (#4a). Module-qualified `alpha.MSG` from a third
|
||||
// module needs the explicit alpha hint; deflookuprhs prefers c.curmod
|
||||
// (which doesn't match either source module on a 3rd-module qualifier)
|
||||
// and falls back to head-pick, possibly inlining beta.MSG's strlit when
|
||||
// both alpha and beta declare same-leaf str defs. cgdot's mod-qualified
|
||||
// str-def value-load routes here so a cross-module N_DOT collision
|
||||
// resolves to the explicit module. Falls back to deflookuprhs's bare-
|
||||
// leaf two-pass when no module matches.
|
||||
fn deflookuprhsmod(c: *cgen, name: str, mod: str) *node = {
|
||||
if (mod.len > 0) {
|
||||
let e: *defent = c.defs;
|
||||
for (e != nil) {
|
||||
if (streq(e.dname, name)) {
|
||||
if (streq(e.dmod, mod)) { return e.drhs; };
|
||||
};
|
||||
e = e.dnext;
|
||||
};
|
||||
};
|
||||
return deflookuprhs(c, name);
|
||||
};
|
||||
|
||||
// ---- module-private symbol map --------------------------------------
|
||||
//
|
||||
// Every non-FFI top-level fn decl lives in its module's namespace —
|
||||
|
||||
Reference in New Issue
Block a user