cstage+selfhost+test: mangle fn labels by module (#9)
Both stages emitted fn TEXT labels by leaf only; lib/os and lib/io
exporting the same leaves (read, write, close) collided at link.
lib/fmt + lib/log worked around with @symbol("rt_syscall") stubs.
Drop d->export from the fn skip rule in mod_collect (both stages) so
exported fns mangle as <module>.<name>. Let/def/type keep current
behavior. Skip retained for {@symbol, main, empty-module}.
Add cur_mod thread through cgfn + mod_lookup_for_fn(name, hint) at
all 4 label-emit sites (TEXT def, LEAQ N_IDENT, CALL N_IDENT, CALL
N_DOT). Wwstage mirror: emitfnname + modlookupforfn + curmod.
Invariant comment pinned in both stages.
ww2 == ww3 == ww4 byte-identical at the new label format.
706_fnlabel_mangle covers same-leaf cross-module CALL + private-leaf
cur_mod disambiguation through a fn-pointer rvalue.
Wwstage LEAQ-of-fn N_DOT (`let p = mod.fn` rvalue) is a pre-existing
gap; deferred to a follow-up. fmt/log rt_syscall stubs untouched
here; cleanup follows.
This commit is contained in:
@@ -528,13 +528,14 @@ fn cgident(c: *cgen, n: *node) void = {
|
||||
};
|
||||
// Fn-name used as a value (e.g. `let f = some_fn;` or
|
||||
// `... = some_fn;`). LEAQ the symbol address into AX. The
|
||||
// emitsymname helper handles ffiresolve and module-mangling
|
||||
// emitfnname helper handles ffiresolve and module-mangling
|
||||
// in one go, so a body-less FFI binding emits the C symbol
|
||||
// it was declared with via @symbol(), not the ww-side ident.
|
||||
// Bare ident → same-module by ww's resolver, hint with c.curmod.
|
||||
let rt: *node = fnretlookup(c, nm);
|
||||
if (rt != nil) {
|
||||
emitline("\tLEAQ\t");
|
||||
emitsymname(c, nm);
|
||||
emitfnname(c, nm, c.curmod);
|
||||
emitline("(SB), AX\n");
|
||||
return;
|
||||
};
|
||||
@@ -3126,11 +3127,23 @@ fn cgcall(c: *cgen, n: *node) void = {
|
||||
emitline("\tCALL\t");
|
||||
if (callee != nil) {
|
||||
if (callee.kind == nkind.N_IDENT) {
|
||||
// Bare `f()` — same-module by ww's resolver,
|
||||
// so c.curmod is the disambiguation hint.
|
||||
calleename = callee.str;
|
||||
emitsymname(c, calleename);
|
||||
emitfnname(c, calleename, c.curmod);
|
||||
} else { if (callee.kind == nkind.N_DOT) {
|
||||
// `m.f()` — pass the explicit module bareword
|
||||
// so cross-module same-leaf exports resolve.
|
||||
calleename = callee.str;
|
||||
emitsymname(c, calleename);
|
||||
let hint: str;
|
||||
hint.ptr = nil;
|
||||
hint.len = 0;
|
||||
if (callee.lhs != nil) {
|
||||
if (callee.lhs.kind == nkind.N_IDENT) {
|
||||
hint = callee.lhs.str;
|
||||
};
|
||||
};
|
||||
emitfnname(c, calleename, hint);
|
||||
};};
|
||||
};
|
||||
emitline("(SB)\n");
|
||||
|
||||
Reference in New Issue
Block a user