w6c: classify tagged call-result args by the stamped type

taggedcallslot gated on an N_IDENT callee + fnretlookup, so every
N_DOT / wwi-decl'd cross-module callee (and every fn-pointer call)
returned 0 and its tagged call-result ARG fell off the cursor-push
path into a 16B scratch spill where cstage PUSHQes AX/DX (cstage keys
the same push on args[i]->type, cgen.c tagged_arg_size). Read the
stamped result type instead — the #209/#211 predicate-to-stamp
discipline, same class as the fn-value cgident fix.

Graduates BOTH remaining DATABYTEID_DIVERGED pins
(r700_strings_byteindex frame 80->64, r839_xmod_nominal_match frame
32->16) — the ledger is EMPTY; the byteid gate ran 1389 data fixtures
at 0 pinned-divergent. Lang rows cover the same-module control,
fn-pointer, float-member, and str-member shapes (byte-identical each).

Separate latent lead banked, NOT closed here: the tagged
subset-widening call arg ((i64|bool) passed as (i64|bool|void))
byte-diverges pre-existing — cstage stages through a 16B local,
wwstage passes direct; runtime-equivalent.
This commit is contained in:
2026-08-08 18:09:08 +09:00
parent 192ddd4c66
commit 854a532feb
3 changed files with 58 additions and 16 deletions

View File

@@ -1446,12 +1446,14 @@ fn pushargsrev(c: *cgen, arg: *syntax.node, param: *syntax.node, memphase: bool,
export fn taggedcallslot(c: *cgen, n: *syntax.node) i32 = {
if (n == nil) { return 0; };
if (n.kind != syntax.nkind.N_CALL) { return 0; };
let callee: *syntax.node = n.lhs;
if (callee == nil) { return 0; };
if (callee.kind != syntax.nkind.N_IDENT) { return 0; };
let rtyp: *syntax.node = fnretlookup(c, callee.str);
if (!istaggedtype(c, rtyp)) { return 0; };
return slotsize(c, rtyp);
// Stamped result type, never a callee-name lookup (#209/#211
// discipline): the old N_IDENT + fnretlookup gate returned 0 for
// every N_DOT / wwi-decl'd cross-module callee, so their tagged
// call-result ARGS fell off the cursor-push path into a 16B
// scratch spill. cstage keys the same push on args[i]->type
// (cgen.c tagged_arg_size).
if (!istaggedtype(c, n)) { return 0; };
return slotsize(c, n);
};
fn nodeisslice(c: *cgen, n: *syntax.node) bool = {