Files
ww/selfhost/cmd
Hojun-Cho 6ab865d933 selfhost+test: route tagged-CALL arg through natural push (#21)
Wwstage call-arg-emit recognized tagged args only when the source
was an IDENT (already-materialized var). For N_CALL returning a
tagged-union, the natural-push path mis-routed: AX (tag) pushed
twice, AX clobbered with widentag(=0) between pushes, DX (payload)
dropped entirely. After POP, DI ← 0, SI ← tag — both reversed and
the payload word lost. Class A runtime miscompile, masked by zero
in-tree call sites of the shape until lib/encoding/utf8's iterator
API surfaced it via pre-flight A probe.

Fix aligns wwstage DOWN to cstage (rule 10). cgenutil.ww:pushargsrev
aistagged guard now fires for N_CALL whose callee returns a tagged
whose slot matches the param's tagged slot (mirrors cmd/w6c/cgen.c:
4216-4221's type_eq guard), and the natural-push fallthrough adds a
tagged-CALL arm pushing R8/CX/DX/AX high→low by slot size (mirrors
cmd/w6c/cgen.c:4373-4387). cgenexpr.ww:cgcall's per-arg pop-count
picks up the same taggedcallslot helper so the next arg's POPQ
doesn't land on residual tag/payload words.

Sister-family to #11/#14 in the variant-widen ABI chain — call-site/
caller-side surface, distinct from callee-side #11 (param decompose)
and scratch-side #14 (return slot). Fifth corpus-coverage-blind
unmask this session (catalog: i64 div/mod CQO #16; wwstage IDENT-
local /= no-op #16-B2; cstage signed-DATA module-scope #19; wwstage
silent-zero arrays #19 mirror; #21 call-arg DX drop).

Test: 720_tagged_call_arg asm-presence row (PUSHQ DX appears
between CALL and next CALL, before PUSHQ AX) + 924_tagged_call_arg_
run 9xx semantic row (5 rows: 4-variant CALL-source, 4-variant
IDENT-source regression guard, 2-variant ptr/err, multi-arg tagged
+ scalar). Bootstrap byte-id (ww2 == ww3 == ww4) holds.
2026-05-17 07:33:55 +09:00
..