wcc/ww: mangle imported symbols on dotted import path (#22 M1, #32)

Switch symbol mangling from the import leaf clause to the full dotted import path for directory packages; single-file imports keep package-clause mangling (isdir-gate: imported<=>directory-import). The root build unit's fn main stays bare, every other top-level decl mangles, closing #31's duplicate-main hazard by construction (#32). Both stages, byte-identical.

Single commit, not split: the bare rename (f244af3) is red on its own because it unmasks cross-module resolution gaps that do not reproduce pre-M1, so the fixes are intrinsic to making the rename correct. Included: wwstage fnret/fnparamslookupmod map import alias->path (#199b cross-module union-variant scrutinee resolved the wrong fn's union); cstage use_path prefers the referencing module's import for an ambiguous leaf alias (sha256 crypto.math vs strconv math). Tests table-driven: 989_m1mangle_run/_sym, 989_m1union_run (gate-visible per-arm exit codes + cs==ww byte-id).
This commit is contained in:
2026-06-15 17:37:18 +09:00
parent 64d6c15e41
commit f308818b4b
30 changed files with 1851 additions and 241 deletions

View File

@@ -1,3 +1,4 @@
//ww:module time
// time — clocks, instants, durations. Mirrors Hare's lib/time
// (ref/hare/time/duration.ha, instant.ha, arithm.ha,
// +linux/functions.ha). Calendar / date / strftime / timezone /
@@ -95,6 +96,7 @@ export fn compare(a: instant, b: instant) i8 = {
return 0i8;
};
//ww:module rt
// rt — runtime primitives exposed to ww programs.
// Mirrors Hare's rt:: module placement (ref/hare/rt/).
@@ -118,6 +120,7 @@ package rt;
// a future task (task #39). ref/hare/rt/malloc.ha:27.
@symbol("rt_malloc") export fn malloc(n: u64) *void;
//ww:module os
// os — process and filesystem facade. The body of each call lands
// either in libwwrt.a (rt_syscall trampoline) or libc bindings,
// depending on how the program was linked.
@@ -856,6 +859,7 @@ export fn exists(path: str) bool = {
return r >= 0i64;
};
//ww:module strconv
// strconv — arbitrary-precision decimal engine for float↔string
// conversion. Mirrors ref/hare/strconv/decimal.ha (Hare in turn ports
// Go's lib/strconv/decimal.go). Pure integer arithmetic; no f32/f64
@@ -1178,6 +1182,7 @@ fn decimal_round(d: *decimal) u64 = {
return n;
};
//ww:module math
// floats — f64 classification, sign, bit-reinterpret core, and the f64
// decompose half (subnormal-normalize + frexp). Ported from
// ref/hare/math/floats.ha (fold-1: classify/sign/bits; fold-2a:
@@ -1452,6 +1457,7 @@ export fn frexpf64(n: f64) (f64, i64) = {
return (mantissa, exp);
};
//ww:module math
// math — numeric helpers. Subset of Hare's math::; only the absolute-
// value pair for the signed integer types we currently care about. The
// return type is unsigned so that abs(I32_MIN) doesn't overflow.
@@ -1468,6 +1474,7 @@ export fn absi64(n: i64) u64 = {
return n: u64;
};
//ww:module strconv
// strconv — float→string via Ryū (shortest round-trippable decimal).
// Mirrors ref/hare/strconv/ftos_ryu.ha (the algorithm core) +
// ref/hare/strconv/ftos.ha:432 (the f64tos driver). Ryū: Ulf Adams,
@@ -2262,6 +2269,7 @@ export fn f32tos(n: f32) str = {
return r;
};
//ww:module strconv
// strconv — Ryū float→string lookup tables + bit-count constants.
// Mirrors ref/hare/strconv/ftos_ryu.ha:159-222 byte-exact. Pure data
// fold (strconv #106 fold-5): no logic, consumed by ftos.ww's
@@ -2373,6 +2381,7 @@ let POW5_TABLE: [26]u64 = [
59604644775390625u64, 298023223876953125u64,
];
//ww:module types
// types — integer limits. Mirrors Hare's types::limits (I8_MAX, …)
// platform-fixed for amd64. Numeric helpers live in lib/math, matching
// Hare's split between types::limits and math::.
@@ -2417,6 +2426,7 @@ def UINTPTR_MAX: uintptr = U64_MAX: uintptr;
def RUNE_MIN: rune = '\0';
//ww:module bytes
// bytes — slice operations over []u8. Mirrors Hare's bytes module
// (ref/hare/bytes/) for the in-tree subset: search/equality/prefix
// helpers used by lib/encoding, lib/bufio, lib/memio.
@@ -2968,6 +2978,7 @@ export fn rcut(in: []u8, delim: (u8 | []u8)) ([]u8, []u8) = {
};
};
//ww:module encoding.utf8
// encoding/utf8 — UTF-8 encode/decode. Hare port; see
// ref/hare/encoding/utf8/{types,rune,encode,decode,decodetable}.ha.
//
@@ -3425,6 +3436,7 @@ export fn position(d: *decoder) i32 = {
};
//ww:module strings
// strings — operations over str ({ptr,len}). Hare port; see
// ref/hare/strings/.
//
@@ -4377,6 +4389,7 @@ export fn rpad(s: str, p: rune, maxlen: i32) str = {
return frombytes(buf);
};
//ww:module ascii
// ascii — rune-class predicates and case folding for the ASCII range.
// Matches Hare's ascii::isdigit family (rune-taking signature). Runes
// outside 0..127 always answer `false`. The lexer hot path uses these
@@ -4581,6 +4594,7 @@ export fn strupper_buf(s: str, buf: []u8) (str | nomem) = {
return strings.frombytes(buf);
};
//ww:module strconv
// strconv — string-to-float. Mirrors ref/hare/strconv/stof.ha
// (Hare in turn adapts Go): Eisel-Lemire fast path [1] with the
// Simple-Decimal-Conversion slow path [2] (decimal.ww) as fallback.
@@ -5280,6 +5294,7 @@ export fn stof32(s: str, b: base) (f32 | invalid | overflow) = {
return 0: invalid; // unreachable (path-cov)
};
//ww:module strconv
// strconv — stof/ftos lookup tables. Mirrors ref/hare/strconv/stof_data.ha
// byte-exact. Pure-data fold (strconv #106 fold-2, was fold-3 before drew
// re-sequenced 2026-05-26): no logic, exercised transitively when fold-3's
@@ -5979,6 +5994,7 @@ let powers_of_ten: [596][2]u64 = [
[0x73832EEC6FFF3111u64, 0xD226FC195C6A2F8Cu64],
];
//ww:module strconv
// strconv — number↔string conversions.
//
// Mirrors Hare's strconv:: surface. The *tos functions return a
@@ -6397,6 +6413,7 @@ export fn strerror(e: error) str = {
return strings.dup("");
};
//ww:module-reset
// selfhost/test/smoke.ww — end-to-end smoke for the selfhost path.
//
// Exercises the patterns the real ww-side compiler port will use: