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:
@@ -711,33 +711,16 @@ fn cgfnparams(c: *cgen, params: *node) void = {
|
||||
fn cgfn(c: *cgen, fn_: *node) void = {
|
||||
cgeninit(c, c.a);
|
||||
c.fnname = fn_.str;
|
||||
c.curmod = fn_.module;
|
||||
c.fnret = fn_.lhs;
|
||||
|
||||
// Emit the TEXT label via emitfnname so the def site picks up the
|
||||
// same skip rule (FFI / `main` / empty-module) and the same module
|
||||
// hint (this fn's own module) that the call sites use. Drops the
|
||||
// `exported == 0` skip in the legacy inline form — exported fns
|
||||
// now mangle too, so cross-module same-leaf exports coexist.
|
||||
emitline("TEXT ");
|
||||
if (fn_.exported == 0) {
|
||||
if (fn_.module.len > 0) {
|
||||
let isffi: bool = false;
|
||||
let a: *node = fn_.attr;
|
||||
for (a != nil) {
|
||||
if (a.kind == nkind.N_ATTR) {
|
||||
let an: str = a.str;
|
||||
if (streq(an, "symbol")) { isffi = true; };
|
||||
};
|
||||
a = a.next;
|
||||
};
|
||||
// `main` is the linker entry-point convention; even
|
||||
// when not marked `export`, it must keep its bare
|
||||
// name so w6l's _start can resolve `CALL main(SB)`.
|
||||
// Mirror of cmd/w6c/cgen.c collectmods exemption.
|
||||
let isentry: bool = streq(fn_.str, "main");
|
||||
if (!isffi && !isentry) {
|
||||
os.write(1, fn_.module.ptr, fn_.module.len: u64);
|
||||
os.write(1, ".".ptr, 1u64);
|
||||
};
|
||||
};
|
||||
};
|
||||
let nm: str = fn_.str;
|
||||
os.write(1, nm.ptr, nm.len: u64);
|
||||
emitfnname(c, fn_.str, fn_.module);
|
||||
emitline(",$");
|
||||
|
||||
// Pre-scan total frame: only count params that land in a local
|
||||
|
||||
Reference in New Issue
Block a user