ww: separate package identity from declared name
This commit is contained in:
@@ -1226,33 +1226,31 @@ struct Use {
|
||||
const char *alias;
|
||||
const char *path;
|
||||
const char *module; /* owning module of the `use` decl (#40) */
|
||||
int sourceid; /* owning lexical source-file scope */
|
||||
Use *next;
|
||||
};
|
||||
static Use *use_map;
|
||||
|
||||
/*
|
||||
* use_hint — map a `use` alias to its dotted import path for the
|
||||
* qualified-ref mangle hint. NOT file-global: two modules in one unit
|
||||
* may bind the same leaf alias to different paths (#40 — module one's
|
||||
* `import a.math` and module two's `import b.math` both alias `math`).
|
||||
* The import declared in the SAME module as the reference (curmod) is
|
||||
* authoritative; preferring it routes each `math.pick()` to its own
|
||||
* package. Falls back to any matching alias when curmod has no own
|
||||
* import (single-occurrence case). Mirrors the checker's use_path
|
||||
* curmod-preference (check.c, M1 55f54fb). Returns the alias unchanged
|
||||
* when no `use` matches.
|
||||
* use_hint — map a declared default qualifier to its canonical import path
|
||||
* for qualified-ref mangling. It is source-file local: separate files may
|
||||
* bind the same declared name to different paths. Raw non-package compilation
|
||||
* retains its historical single-occurrence fallback. Returns the qualifier
|
||||
* unchanged when no `use` matches.
|
||||
*/
|
||||
static const char *
|
||||
use_hint(const char *curmod, const char *alias)
|
||||
use_hint(Cg *c, const char *alias)
|
||||
{
|
||||
const char *any = NULL;
|
||||
if (alias == NULL) return alias;
|
||||
for (Use *u = use_map; u; u = u->next) {
|
||||
if (strcmp(u->alias, alias) != 0) continue;
|
||||
int same = (u->module == NULL) ? (curmod == NULL)
|
||||
: (curmod != NULL && strcmp(u->module, curmod) == 0);
|
||||
int same = u->sourceid == c->cur_source
|
||||
&& ((u->module == NULL) ? (c->cur_mod == NULL)
|
||||
: (c->cur_mod != NULL
|
||||
&& strcmp(u->module, c->cur_mod) == 0));
|
||||
if (same) return u->path;
|
||||
if (any == NULL) any = u->path;
|
||||
if (!c->sep_mode && any == NULL) any = u->path;
|
||||
}
|
||||
return any ? any : alias;
|
||||
}
|
||||
@@ -1484,6 +1482,7 @@ mod_collect(Cg *c, Node *file)
|
||||
u->alias = d->str;
|
||||
u->path = d->usepath;
|
||||
u->module = d->module;
|
||||
u->sourceid = d->sourceid;
|
||||
u->next = use_map;
|
||||
use_map = u;
|
||||
continue;
|
||||
@@ -4564,7 +4563,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
if (lu && lu->kind == TY_FN)
|
||||
ins2(c, A_LEAQ,
|
||||
mafn(c, opnd->str,
|
||||
use_hint(c->cur_mod, opnd->lhs->str)),
|
||||
use_hint(c, opnd->lhs->str)),
|
||||
areg(D_AX));
|
||||
else
|
||||
/* #229: dotted-module value
|
||||
@@ -4573,7 +4572,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
* same-leaf collision. */
|
||||
ins2(c, A_LEAQ,
|
||||
mafn(c, opnd->str,
|
||||
use_hint(c->cur_mod, opnd->lhs->str)),
|
||||
use_hint(c, opnd->lhs->str)),
|
||||
areg(D_AX));
|
||||
break;
|
||||
}
|
||||
@@ -10976,7 +10975,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
* same-leaf exports resolve correctly. */
|
||||
ins1(c, A_CALL,
|
||||
mafn(c, n->lhs->str,
|
||||
use_hint(c->cur_mod, n->lhs->lhs->str)));
|
||||
use_hint(c, n->lhs->lhs->str)));
|
||||
} else {
|
||||
cgexpr(c, n->lhs, locals); /* AX = fn ptr */
|
||||
ins1(c, A_CALL, areg(D_AX));
|
||||
@@ -11906,7 +11905,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
/* `mod.fn` address-of via N_DOT — pass the
|
||||
* module bareword as the disambiguation hint. */
|
||||
ins2(c, A_LEAQ,
|
||||
mafn(c, n->str, use_hint(c->cur_mod, n->lhs->str)),
|
||||
mafn(c, n->str, use_hint(c, n->lhs->str)),
|
||||
areg(D_AX));
|
||||
break;
|
||||
}
|
||||
@@ -11923,7 +11922,7 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
for (s = sdefs; s; s = s->next) {
|
||||
if (strcmp(s->name, n->str) != 0)
|
||||
continue;
|
||||
if (sdef_mod_match_hint(s, use_hint(c->cur_mod, n->lhs->str)))
|
||||
if (sdef_mod_match_hint(s, use_hint(c, n->lhs->str)))
|
||||
break;
|
||||
}
|
||||
if (s == NULL) {
|
||||
@@ -11955,11 +11954,11 @@ cgexpr(Cg *c, Node *n, Local *locals)
|
||||
* branch above already uses n->lhs->str via mafn. */
|
||||
if (mqop == A_MOVQ) {
|
||||
ins2(c, A_MOVQ,
|
||||
mafn(c, n->str, use_hint(c->cur_mod, n->lhs->str)),
|
||||
mafn(c, n->str, use_hint(c, n->lhs->str)),
|
||||
areg(D_AX));
|
||||
} else {
|
||||
ins2(c, A_LEAQ,
|
||||
mafn(c, n->str, use_hint(c->cur_mod, n->lhs->str)),
|
||||
mafn(c, n->str, use_hint(c, n->lhs->str)),
|
||||
areg(D_CX));
|
||||
ins2(c, mqop, amem(D_CX, 0), areg(D_AX));
|
||||
}
|
||||
@@ -15800,6 +15799,7 @@ cgfn(Cg *c, FILE *out, Node *fn)
|
||||
c->head = c->tail = NULL;
|
||||
c->fnname = fn->str;
|
||||
c->cur_mod = (fn->module && fn->module[0]) ? fn->module : NULL;
|
||||
c->cur_source = fn->sourceid;
|
||||
c->labelseq = 0;
|
||||
cg_stack_arg_cursor = 0;
|
||||
ndefers = 0;
|
||||
@@ -16913,7 +16913,7 @@ node_fnptr_sym(Cg *c, Node *ev)
|
||||
return NULL;
|
||||
Type *du = type_chase_named(opnd->type);
|
||||
if (du == NULL || du->kind != TY_FN) return NULL;
|
||||
return mod_mangle_fn(c, opnd->str, use_hint(c->cur_mod, opnd->lhs->str));
|
||||
return mod_mangle_fn(c, opnd->str, use_hint(c, opnd->lhs->str));
|
||||
}
|
||||
if (opnd == NULL || opnd->kind != N_IDENT) return NULL;
|
||||
Type *ou = type_chase_named(opnd->type);
|
||||
@@ -17205,8 +17205,12 @@ emit_slice_data(FILE *out, Cg *c, const char *directive, const char *name,
|
||||
static void
|
||||
emit_lets(Cg *c, FILE *out, Node *file)
|
||||
{
|
||||
const char *save_mod = c->cur_mod;
|
||||
int save_source = c->cur_source;
|
||||
for (Node *d = file->list; d; d = d->next) {
|
||||
if (d->kind != N_LET) continue;
|
||||
c->cur_mod = (d->module && d->module[0]) ? d->module : NULL;
|
||||
c->cur_source = d->sourceid;
|
||||
if (d->str == NULL || d->str[0] == '\0') continue;
|
||||
/* #22 M3 THE ONE REAL GUARD: a `.wwi` dep value-global is
|
||||
* initializer-less; emitting a DATAW for it would DUPLICATE the
|
||||
@@ -17377,6 +17381,8 @@ emit_lets(Cg *c, FILE *out, Node *file)
|
||||
emit_data_row_zero(out, "DATAW",
|
||||
mod_mangle_fn(c, d->str, d->module), sz);
|
||||
}
|
||||
c->cur_mod = save_mod;
|
||||
c->cur_source = save_source;
|
||||
}
|
||||
|
||||
/* Emit DATA directives for top-level `def` constants whose value
|
||||
@@ -17392,8 +17398,12 @@ emit_lets(Cg *c, FILE *out, Node *file)
|
||||
static void
|
||||
emit_defs(Cg *c, FILE *out, Node *file)
|
||||
{
|
||||
const char *save_mod = c->cur_mod;
|
||||
int save_source = c->cur_source;
|
||||
for (Node *d = file->list; d; d = d->next) {
|
||||
if (d->kind != N_DEF || d->rhs == NULL) continue;
|
||||
c->cur_mod = (d->module && d->module[0]) ? d->module : NULL;
|
||||
c->cur_source = d->sourceid;
|
||||
/* #22 M3: a `.wwi` dep def with DATA storage (int-fold / float /
|
||||
* struct / array) must NOT re-emit — the dep's own .o owns the
|
||||
* symbol. Str defs are inline-spliced (sdef_collect), never
|
||||
@@ -17455,7 +17465,8 @@ emit_defs(Cg *c, FILE *out, Node *file)
|
||||
"asm.c:362); read-only `def` unsupported (#10, "
|
||||
"rule 7)");
|
||||
}
|
||||
(void)c;
|
||||
c->cur_mod = save_mod;
|
||||
c->cur_source = save_source;
|
||||
}
|
||||
|
||||
/* Collect str-typed `def`s so cgexpr N_IDENT can splice them inline.
|
||||
@@ -17537,8 +17548,10 @@ let_pre_intern(Cg *c, Node *file)
|
||||
* they did before. let_pre_intern itself only interns, so driving
|
||||
* cur_mod here has no other effect. */
|
||||
const char *save_mod = c->cur_mod;
|
||||
int save_source = c->cur_source;
|
||||
for (Node *d = file->list; d; d = d->next) {
|
||||
c->cur_mod = (d->module && d->module[0]) ? d->module : NULL;
|
||||
c->cur_source = d->sourceid;
|
||||
/* #22 M3: skip imported deps so the strlit table (and its _S_
|
||||
* sequence) is a pure function of THIS package's own decls. A
|
||||
* dep's body initializer would intern here, but its `.wwi`
|
||||
@@ -17658,6 +17671,7 @@ let_pre_intern(Cg *c, Node *file)
|
||||
(void)intern_strlit(c, r->str, r->strlen);
|
||||
}
|
||||
c->cur_mod = save_mod;
|
||||
c->cur_source = save_source;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user